FFmpeg
mpeg2_metadata_bsf.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/avstring.h"
20 #include "libavutil/common.h"
21 #include "libavutil/opt.h"
22 
23 #include "bsf.h"
24 #include "bsf_internal.h"
25 #include "cbs.h"
26 #include "cbs_mpeg2.h"
27 #include "mpeg12.h"
28 
29 typedef struct MPEG2MetadataContext {
30  const AVClass *class;
31 
34 
36 
38 
40 
45 
48 
49 
52 {
57  int i, se_pos;
58 
59  for (i = 0; i < frag->nb_units; i++) {
60  if (frag->units[i].type == MPEG2_START_SEQUENCE_HEADER) {
61  sh = frag->units[i].content;
62  } else if (frag->units[i].type == MPEG2_START_EXTENSION) {
63  MPEG2RawExtensionData *ext = frag->units[i].content;
66  se = &ext->data.sequence;
67  se_pos = i;
68  } else if (ext->extension_start_code_identifier ==
70  sde = &ext->data.sequence_display;
71  }
72  }
73  }
74 
75  if (!sh || !se) {
76  // No sequence header and sequence extension: not an MPEG-2 video
77  // sequence.
78  if (sh && !ctx->mpeg1_warned) {
79  av_log(bsf, AV_LOG_WARNING, "Stream contains a sequence "
80  "header but not a sequence extension: maybe it's "
81  "actually MPEG-1?\n");
82  ctx->mpeg1_warned = 1;
83  }
84  return 0;
85  }
86 
88  int num, den;
89 
90  av_reduce(&num, &den, ctx->display_aspect_ratio.num,
91  ctx->display_aspect_ratio.den, 65535);
92 
93  if (num == 4 && den == 3)
95  else if (num == 16 && den == 9)
97  else if (num == 221 && den == 100)
99  else
100  sh->aspect_ratio_information = 1;
101  }
102 
103  if (ctx->frame_rate.num && ctx->frame_rate.den) {
104  int code, ext_n, ext_d;
105 
107  &code, &ext_n, &ext_d, 0);
108 
109  sh->frame_rate_code = code;
110  se->frame_rate_extension_n = ext_n;
111  se->frame_rate_extension_d = ext_d;
112  }
113 
114  if (ctx->video_format >= 0 ||
115  ctx->colour_primaries >= 0 ||
116  ctx->transfer_characteristics >= 0 ||
117  ctx->matrix_coefficients >= 0) {
118  if (!sde) {
119  int err;
125 
127  .video_format = 5,
128 
129  .colour_description = 0,
130  .colour_primaries = 2,
131  .transfer_characteristics = 2,
132  .matrix_coefficients = 2,
133 
134  .display_horizontal_size =
136  .display_vertical_size =
138  };
139 
140  err = ff_cbs_insert_unit_content(frag, se_pos + 1,
143  NULL);
144  if (err < 0) {
145  av_log(bsf, AV_LOG_ERROR, "Failed to insert new sequence "
146  "display extension.\n");
147  return err;
148  }
149  }
150 
151  if (ctx->video_format >= 0)
152  sde->video_format = ctx->video_format;
153 
154  if (ctx->colour_primaries >= 0 ||
155  ctx->transfer_characteristics >= 0 ||
156  ctx->matrix_coefficients >= 0) {
157  sde->colour_description = 1;
158 
159  if (ctx->colour_primaries >= 0)
161 
162  if (ctx->transfer_characteristics >= 0)
164 
165  if (ctx->matrix_coefficients >= 0)
167  }
168  }
169 
170  return 0;
171 }
172 
174 {
176  CodedBitstreamFragment *frag = &ctx->fragment;
177  int err;
178 
179  err = ff_bsf_get_packet_ref(bsf, pkt);
180  if (err < 0)
181  return err;
182 
183  err = ff_cbs_read_packet(ctx->cbc, frag, pkt);
184  if (err < 0) {
185  av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
186  goto fail;
187  }
188 
189  err = mpeg2_metadata_update_fragment(bsf, frag);
190  if (err < 0) {
191  av_log(bsf, AV_LOG_ERROR, "Failed to update frame fragment.\n");
192  goto fail;
193  }
194 
195  err = ff_cbs_write_packet(ctx->cbc, pkt, frag);
196  if (err < 0) {
197  av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
198  goto fail;
199  }
200 
201  err = 0;
202 fail:
203  ff_cbs_fragment_reset(frag);
204 
205  if (err < 0)
206  av_packet_unref(pkt);
207 
208  return err;
209 }
210 
212 {
214  CodedBitstreamFragment *frag = &ctx->fragment;
215  int err;
216 
217 #define VALIDITY_CHECK(name) do { \
218  if (!ctx->name) { \
219  av_log(bsf, AV_LOG_ERROR, "The value 0 for %s is " \
220  "forbidden.\n", #name); \
221  return AVERROR(EINVAL); \
222  } \
223  } while (0)
227 #undef VALIDITY_CHECK
228 
229  err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf);
230  if (err < 0)
231  return err;
232 
233  if (bsf->par_in->extradata) {
234  err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in);
235  if (err < 0) {
236  av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
237  goto fail;
238  }
239 
240  err = mpeg2_metadata_update_fragment(bsf, frag);
241  if (err < 0) {
242  av_log(bsf, AV_LOG_ERROR, "Failed to update metadata fragment.\n");
243  goto fail;
244  }
245 
246  err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag);
247  if (err < 0) {
248  av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
249  goto fail;
250  }
251  }
252 
253  err = 0;
254 fail:
255  ff_cbs_fragment_reset(frag);
256  return err;
257 }
258 
260 {
262 
264  ff_cbs_close(&ctx->cbc);
265 }
266 
267 #define OFFSET(x) offsetof(MPEG2MetadataContext, x)
268 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
270  { "display_aspect_ratio", "Set display aspect ratio (table 6-3)",
272  { .dbl = 0.0 }, 0, 65535, FLAGS },
273 
274  { "frame_rate", "Set frame rate",
276  { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
277 
278  { "video_format", "Set video format (table 6-6)",
280  { .i64 = -1 }, -1, 7, FLAGS },
281  { "colour_primaries", "Set colour primaries (table 6-7)",
283  { .i64 = -1 }, -1, 255, FLAGS },
284  { "transfer_characteristics", "Set transfer characteristics (table 6-8)",
286  { .i64 = -1 }, -1, 255, FLAGS },
287  { "matrix_coefficients", "Set matrix coefficients (table 6-9)",
289  { .i64 = -1 }, -1, 255, FLAGS },
290 
291  { NULL }
292 };
293 
295  .class_name = "mpeg2_metadata_bsf",
296  .item_name = av_default_item_name,
297  .option = mpeg2_metadata_options,
298  .version = LIBAVUTIL_VERSION_INT,
299 };
300 
301 static const enum AVCodecID mpeg2_metadata_codec_ids[] = {
303 };
304 
306  .name = "mpeg2_metadata",
307  .priv_data_size = sizeof(MPEG2MetadataContext),
308  .priv_class = &mpeg2_metadata_class,
310  .close = &mpeg2_metadata_close,
313 };
#define NULL
Definition: coverity.c:32
int nb_units
Number of units in this fragment.
Definition: cbs.h:149
uint8_t extension_start_code_identifier
Definition: cbs_mpeg2.h:179
AVCodecParameters * par_out
Parameters of the output stream.
Definition: bsf.h:83
#define se(name, range_min, range_max)
Definition: cbs_h2645.c:273
AVOption.
Definition: opt.h:248
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
int ff_cbs_write_packet(CodedBitstreamContext *ctx, AVPacket *pkt, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to a packet.
Definition: cbs.c:397
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
MPEG2RawSequenceExtension sequence
Definition: cbs_mpeg2.h:182
union MPEG2RawExtensionData::@41 data
int ff_cbs_init(CodedBitstreamContext **ctx_ptr, enum AVCodecID codec_id, void *log_ctx)
Create and initialise a new context for the given codec.
Definition: cbs.c:74
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:70
int num
Numerator.
Definition: rational.h:59
The bitstream filter state.
Definition: bsf.h:49
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
static AVPacket pkt
void * priv_data
Opaque filter-specific private data.
Definition: bsf.h:70
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
uint16_t vertical_size_value
Definition: cbs_mpeg2.h:63
AVOptions.
#define VALIDITY_CHECK(name)
int ff_cbs_read_packet(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVPacket *pkt)
Read the data bitstream from a packet into a fragment, then split into units and decompose.
Definition: cbs.c:238
const char * name
Definition: bsf.h:99
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:103
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:164
#define av_log(a,...)
void ff_cbs_fragment_reset(CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment&#39;s own data buffer, but not the units a...
Definition: cbs.c:141
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
void ff_mpeg12_find_best_frame_rate(AVRational frame_rate, int *code, int *ext_n, int *ext_d, int nonstandard)
#define fail()
Definition: checkasm.h:123
static void mpeg2_metadata_close(AVBSFContext *bsf)
const AVBitStreamFilter ff_mpeg2_metadata_bsf
int ff_cbs_write_extradata(CodedBitstreamContext *ctx, AVCodecParameters *par, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to the extradata in codec parameters.
Definition: cbs.c:372
MPEG2RawExtensionData sequence_display_extension
AVFormatContext * ctx
Definition: movenc.c:48
uint8_t horizontal_size_extension
Definition: cbs_mpeg2.h:88
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:51
MPEG2RawSequenceDisplayExtension sequence_display
Definition: cbs_mpeg2.h:183
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:118
#define FLAGS
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:606
static const AVClass mpeg2_metadata_class
uint8_t frame_rate_extension_n
Definition: cbs_mpeg2.h:93
uint8_t frame_rate_extension_d
Definition: cbs_mpeg2.h:94
static enum AVCodecID mpeg2_metadata_codec_ids[]
Describe the class of an AVClass context structure.
Definition: log.h:67
Context structure for coded bitstream operations.
Definition: cbs.h:170
Rational number (pair of numerator and denominator).
Definition: rational.h:58
uint8_t extension_start_code
Definition: cbs_mpeg2.h:178
uint16_t horizontal_size_value
Definition: cbs_mpeg2.h:62
int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, AVBufferRef *content_buf)
Insert a new unit into a fragment with the given content.
Definition: cbs.c:715
void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:115
uint8_t aspect_ratio_information
Definition: cbs_mpeg2.h:64
int ff_cbs_read_extradata(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVCodecParameters *par)
Read the extradata bitstream found in codec parameters into a fragment, then split into units and dec...
Definition: cbs.c:220
CodedBitstreamContext * cbc
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
CodedBitstreamFragment fragment
static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
common internal and external API header
static enum AVCodecID codec_ids[]
int den
Denominator.
Definition: rational.h:60
static const AVOption mpeg2_metadata_options[]
uint8_t vertical_size_extension
Definition: cbs_mpeg2.h:89
static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, CodedBitstreamFragment *frag)
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:74
void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition: cbs.c:155
#define OFFSET(x)
static int mpeg2_metadata_init(AVBSFContext *bsf)
This structure stores compressed data.
Definition: packet.h:340
AVCodecParameters * par_in
Parameters of the input stream.
Definition: bsf.h:77
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:252
int i
Definition: input.c:407