You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

361 lines
11KB

  1. /*
  2. * This file is part of Libav.
  3. *
  4. * Libav is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * Libav is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with Libav; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "libavutil/avstring.h"
  19. #include "libavutil/common.h"
  20. #include "libavutil/opt.h"
  21. #include "bsf.h"
  22. #include "cbs.h"
  23. #include "cbs_mpeg2.h"
  24. typedef struct MPEG2MetadataContext {
  25. const AVClass *class;
  26. CodedBitstreamContext cbc;
  27. CodedBitstreamFragment fragment;
  28. MPEG2RawExtensionData sequence_display_extension;
  29. AVRational display_aspect_ratio;
  30. AVRational frame_rate;
  31. int video_format;
  32. int colour_primaries;
  33. int transfer_characteristics;
  34. int matrix_coefficients;
  35. int mpeg1_warned;
  36. } MPEG2MetadataContext;
  37. static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
  38. CodedBitstreamFragment *frag)
  39. {
  40. MPEG2MetadataContext *ctx = bsf->priv_data;
  41. MPEG2RawSequenceHeader *sh = NULL;
  42. MPEG2RawSequenceExtension *se = NULL;
  43. MPEG2RawSequenceDisplayExtension *sde = NULL;
  44. int i, se_pos, add_sde = 0;
  45. for (i = 0; i < frag->nb_units; i++) {
  46. if (frag->units[i].type == MPEG2_START_SEQUENCE_HEADER) {
  47. sh = frag->units[i].content;
  48. } else if (frag->units[i].type == MPEG2_START_EXTENSION) {
  49. MPEG2RawExtensionData *ext = frag->units[i].content;
  50. if (ext->extension_start_code_identifier ==
  51. MPEG2_EXTENSION_SEQUENCE) {
  52. se = &ext->data.sequence;
  53. se_pos = i;
  54. } else if (ext->extension_start_code_identifier ==
  55. MPEG2_EXTENSION_SEQUENCE_DISPLAY) {
  56. sde = &ext->data.sequence_display;
  57. }
  58. }
  59. }
  60. if (!sh || !se) {
  61. // No sequence header and sequence extension: not an MPEG-2 video
  62. // sequence.
  63. if (sh && !ctx->mpeg1_warned) {
  64. av_log(bsf, AV_LOG_WARNING, "Stream contains a sequence "
  65. "header but not a sequence extension: maybe it's "
  66. "actually MPEG-1?\n");
  67. ctx->mpeg1_warned = 1;
  68. }
  69. return 0;
  70. }
  71. if (ctx->display_aspect_ratio.num && ctx->display_aspect_ratio.den) {
  72. int num, den;
  73. av_reduce(&num, &den, ctx->display_aspect_ratio.num,
  74. ctx->display_aspect_ratio.den, 65535);
  75. if (num == 4 && den == 3)
  76. sh->aspect_ratio_information = 2;
  77. else if (num == 16 && den == 9)
  78. sh->aspect_ratio_information = 3;
  79. else if (num == 221 && den == 100)
  80. sh->aspect_ratio_information = 4;
  81. else
  82. sh->aspect_ratio_information = 1;
  83. }
  84. if (ctx->frame_rate.num && ctx->frame_rate.den) {
  85. // Table 6-4.
  86. static AVRational frame_rate_table[] = {
  87. { 0, 0 },
  88. { 24000, 1001 },
  89. { 24, 1 },
  90. { 25, 1 },
  91. { 30000, 1001 },
  92. { 30, 1 },
  93. { 50, 1 },
  94. { 60000, 1001 },
  95. { 60, 1 },
  96. };
  97. int code, ext_n, ext_d;
  98. AVRational best_error = { INT_MAX, 1 };
  99. for (i = 1; i < FF_ARRAY_ELEMS(frame_rate_table); i++) {
  100. if (av_cmp_q(ctx->frame_rate, frame_rate_table[i]) == 0) {
  101. code = i;
  102. ext_n = 1;
  103. ext_d = 1;
  104. goto found_frame_rate;
  105. }
  106. }
  107. for (i = 1; i < FF_ARRAY_ELEMS(frame_rate_table); i++) {
  108. AVRational fr, error;
  109. int n, d, cmp;
  110. for (n = 1; n <= 4; n++) {
  111. for (d = 1; d <= 32; d++) {
  112. fr = av_mul_q(frame_rate_table[i],
  113. (AVRational) { n, d });
  114. cmp = av_cmp_q(fr, ctx->frame_rate);
  115. if (cmp == 0) {
  116. code = i;
  117. ext_n = n;
  118. ext_d = d;
  119. goto found_frame_rate;
  120. }
  121. if (cmp < 0)
  122. error = av_div_q(ctx->frame_rate, fr);
  123. else
  124. error = av_div_q(fr, ctx->frame_rate);
  125. cmp = av_cmp_q(error, best_error);
  126. if (cmp < 0 || (cmp == 0 && n == 1 && d == 1)) {
  127. code = i;
  128. ext_n = n;
  129. ext_d = d;
  130. best_error = error;
  131. }
  132. }
  133. }
  134. }
  135. found_frame_rate:
  136. sh->frame_rate_code = code;
  137. se->frame_rate_extension_n = ext_n - 1;
  138. se->frame_rate_extension_d = ext_d - 1;
  139. }
  140. if (ctx->video_format >= 0 ||
  141. ctx->colour_primaries >= 0 ||
  142. ctx->transfer_characteristics >= 0 ||
  143. ctx->matrix_coefficients >= 0) {
  144. if (!sde) {
  145. add_sde = 1;
  146. ctx->sequence_display_extension.extension_start_code =
  147. MPEG2_START_EXTENSION;
  148. ctx->sequence_display_extension.extension_start_code_identifier =
  149. MPEG2_EXTENSION_SEQUENCE_DISPLAY;
  150. sde = &ctx->sequence_display_extension.data.sequence_display;
  151. *sde = (MPEG2RawSequenceDisplayExtension) {
  152. .video_format = 5,
  153. .colour_description = 0,
  154. .colour_primaries = 2,
  155. .transfer_characteristics = 2,
  156. .matrix_coefficients = 2,
  157. .display_horizontal_size =
  158. se->horizontal_size_extension << 12 | sh->horizontal_size_value,
  159. .display_vertical_size =
  160. se->vertical_size_extension << 12 | sh->vertical_size_value,
  161. };
  162. }
  163. if (ctx->video_format >= 0)
  164. sde->video_format = ctx->video_format;
  165. if (ctx->colour_primaries >= 0 ||
  166. ctx->transfer_characteristics >= 0 ||
  167. ctx->matrix_coefficients >= 0) {
  168. sde->colour_description = 1;
  169. if (ctx->colour_primaries >= 0)
  170. sde->colour_primaries = ctx->colour_primaries;
  171. else if (add_sde)
  172. sde->colour_primaries = 2;
  173. if (ctx->transfer_characteristics >= 0)
  174. sde->transfer_characteristics = ctx->transfer_characteristics;
  175. else if (add_sde)
  176. sde->transfer_characteristics = 2;
  177. if (ctx->matrix_coefficients >= 0)
  178. sde->matrix_coefficients = ctx->matrix_coefficients;
  179. else if (add_sde)
  180. sde->matrix_coefficients = 2;
  181. }
  182. }
  183. if (add_sde) {
  184. int err;
  185. err = ff_cbs_insert_unit_content(&ctx->cbc, frag, se_pos + 1,
  186. MPEG2_START_EXTENSION,
  187. &ctx->sequence_display_extension);
  188. if (err < 0) {
  189. av_log(bsf, AV_LOG_ERROR, "Failed to insert new sequence "
  190. "display extension.\n");
  191. return err;
  192. }
  193. }
  194. return 0;
  195. }
  196. static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *out)
  197. {
  198. MPEG2MetadataContext *ctx = bsf->priv_data;
  199. AVPacket *in = NULL;
  200. CodedBitstreamFragment *frag = &ctx->fragment;
  201. int err;
  202. err = ff_bsf_get_packet(bsf, &in);
  203. if (err < 0)
  204. goto fail;
  205. err = ff_cbs_read_packet(&ctx->cbc, frag, in);
  206. if (err < 0) {
  207. av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
  208. goto fail;
  209. }
  210. err = mpeg2_metadata_update_fragment(bsf, frag);
  211. if (err < 0) {
  212. av_log(bsf, AV_LOG_ERROR, "Failed to update frame fragment.\n");
  213. goto fail;
  214. }
  215. err = ff_cbs_write_packet(&ctx->cbc, out, frag);
  216. if (err < 0) {
  217. av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
  218. goto fail;
  219. }
  220. err = av_packet_copy_props(out, in);
  221. if (err < 0) {
  222. av_packet_unref(out);
  223. goto fail;
  224. }
  225. err = 0;
  226. fail:
  227. ff_cbs_fragment_uninit(&ctx->cbc, frag);
  228. av_packet_free(&in);
  229. return err;
  230. }
  231. static int mpeg2_metadata_init(AVBSFContext *bsf)
  232. {
  233. MPEG2MetadataContext *ctx = bsf->priv_data;
  234. CodedBitstreamFragment *frag = &ctx->fragment;
  235. int err;
  236. err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf);
  237. if (err < 0)
  238. return err;
  239. if (bsf->par_in->extradata) {
  240. err = ff_cbs_read_extradata(&ctx->cbc, frag, bsf->par_in);
  241. if (err < 0) {
  242. av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
  243. goto fail;
  244. }
  245. err = mpeg2_metadata_update_fragment(bsf, frag);
  246. if (err < 0) {
  247. av_log(bsf, AV_LOG_ERROR, "Failed to update metadata fragment.\n");
  248. goto fail;
  249. }
  250. err = ff_cbs_write_extradata(&ctx->cbc, bsf->par_out, frag);
  251. if (err < 0) {
  252. av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
  253. goto fail;
  254. }
  255. }
  256. err = 0;
  257. fail:
  258. ff_cbs_fragment_uninit(&ctx->cbc, frag);
  259. return err;
  260. }
  261. static void mpeg2_metadata_close(AVBSFContext *bsf)
  262. {
  263. MPEG2MetadataContext *ctx = bsf->priv_data;
  264. ff_cbs_close(&ctx->cbc);
  265. }
  266. #define OFFSET(x) offsetof(MPEG2MetadataContext, x)
  267. static const AVOption mpeg2_metadata_options[] = {
  268. { "display_aspect_ratio", "Set display aspect ratio (table 6-3)",
  269. OFFSET(display_aspect_ratio), AV_OPT_TYPE_RATIONAL,
  270. { .i64 = 0 }, 0, 65535 },
  271. { "frame_rate", "Set frame rate",
  272. OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL,
  273. { .i64 = 0 }, 0, UINT_MAX },
  274. { "video_format", "Set video format (table 6-6)",
  275. OFFSET(video_format), AV_OPT_TYPE_INT,
  276. { .i64 = -1 }, -1, 7 },
  277. { "colour_primaries", "Set colour primaries (table 6-7)",
  278. OFFSET(colour_primaries), AV_OPT_TYPE_INT,
  279. { .i64 = -1 }, -1, 255 },
  280. { "transfer_characteristics", "Set transfer characteristics (table 6-8)",
  281. OFFSET(transfer_characteristics), AV_OPT_TYPE_INT,
  282. { .i64 = -1 }, -1, 255 },
  283. { "matrix_coefficients", "Set matrix coefficients (table 6-9)",
  284. OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
  285. { .i64 = -1 }, -1, 255 },
  286. { NULL }
  287. };
  288. static const AVClass mpeg2_metadata_class = {
  289. .class_name = "mpeg2_metadata_bsf",
  290. .item_name = av_default_item_name,
  291. .option = mpeg2_metadata_options,
  292. .version = LIBAVCODEC_VERSION_MAJOR,
  293. };
  294. static const enum AVCodecID mpeg2_metadata_codec_ids[] = {
  295. AV_CODEC_ID_MPEG2VIDEO, AV_CODEC_ID_NONE,
  296. };
  297. const AVBitStreamFilter ff_mpeg2_metadata_bsf = {
  298. .name = "mpeg2_metadata",
  299. .priv_data_size = sizeof(MPEG2MetadataContext),
  300. .priv_class = &mpeg2_metadata_class,
  301. .init = &mpeg2_metadata_init,
  302. .close = &mpeg2_metadata_close,
  303. .filter = &mpeg2_metadata_filter,
  304. .codec_ids = mpeg2_metadata_codec_ids,
  305. };