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 "cbs.h"
25 #include "cbs_mpeg2.h"
26 #include "mpeg12.h"
27 
28 typedef struct MPEG2MetadataContext {
29  const AVClass *class;
30 
33 
35 
37 
39 
44 
47 
48 
51 {
56  int i, se_pos;
57 
58  for (i = 0; i < frag->nb_units; i++) {
59  if (frag->units[i].type == MPEG2_START_SEQUENCE_HEADER) {
60  sh = frag->units[i].content;
61  } else if (frag->units[i].type == MPEG2_START_EXTENSION) {
62  MPEG2RawExtensionData *ext = frag->units[i].content;
65  se = &ext->data.sequence;
66  se_pos = i;
67  } else if (ext->extension_start_code_identifier ==
69  sde = &ext->data.sequence_display;
70  }
71  }
72  }
73 
74  if (!sh || !se) {
75  // No sequence header and sequence extension: not an MPEG-2 video
76  // sequence.
77  if (sh && !ctx->mpeg1_warned) {
78  av_log(bsf, AV_LOG_WARNING, "Stream contains a sequence "
79  "header but not a sequence extension: maybe it's "
80  "actually MPEG-1?\n");
81  ctx->mpeg1_warned = 1;
82  }
83  return 0;
84  }
85 
87  int num, den;
88 
89  av_reduce(&num, &den, ctx->display_aspect_ratio.num,
90  ctx->display_aspect_ratio.den, 65535);
91 
92  if (num == 4 && den == 3)
94  else if (num == 16 && den == 9)
96  else if (num == 221 && den == 100)
98  else
100  }
101 
102  if (ctx->frame_rate.num && ctx->frame_rate.den) {
103  int code, ext_n, ext_d;
104 
106  &code, &ext_n, &ext_d, 0);
107 
108  sh->frame_rate_code = code;
109  se->frame_rate_extension_n = ext_n;
110  se->frame_rate_extension_d = ext_d;
111  }
112 
113  if (ctx->video_format >= 0 ||
114  ctx->colour_primaries >= 0 ||
115  ctx->transfer_characteristics >= 0 ||
116  ctx->matrix_coefficients >= 0) {
117  if (!sde) {
118  int err;
124 
126  .video_format = 5,
127 
128  .colour_description = 0,
129  .colour_primaries = 2,
130  .transfer_characteristics = 2,
131  .matrix_coefficients = 2,
132 
133  .display_horizontal_size =
135  .display_vertical_size =
137  };
138 
139  err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1,
142  NULL);
143  if (err < 0) {
144  av_log(bsf, AV_LOG_ERROR, "Failed to insert new sequence "
145  "display extension.\n");
146  return err;
147  }
148  }
149 
150  if (ctx->video_format >= 0)
151  sde->video_format = ctx->video_format;
152 
153  if (ctx->colour_primaries >= 0 ||
154  ctx->transfer_characteristics >= 0 ||
155  ctx->matrix_coefficients >= 0) {
156  sde->colour_description = 1;
157 
158  if (ctx->colour_primaries >= 0)
160 
161  if (ctx->transfer_characteristics >= 0)
163 
164  if (ctx->matrix_coefficients >= 0)
166  }
167  }
168 
169  return 0;
170 }
171 
173 {
175  CodedBitstreamFragment *frag = &ctx->fragment;
176  int err;
177 
178  err = ff_bsf_get_packet_ref(bsf, pkt);
179  if (err < 0)
180  return err;
181 
182  err = ff_cbs_read_packet(ctx->cbc, frag, pkt);
183  if (err < 0) {
184  av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
185  goto fail;
186  }
187 
188  err = mpeg2_metadata_update_fragment(bsf, frag);
189  if (err < 0) {
190  av_log(bsf, AV_LOG_ERROR, "Failed to update frame fragment.\n");
191  goto fail;
192  }
193 
194  err = ff_cbs_write_packet(ctx->cbc, pkt, frag);
195  if (err < 0) {
196  av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
197  goto fail;
198  }
199 
200  err = 0;
201 fail:
202  ff_cbs_fragment_reset(ctx->cbc, frag);
203 
204  if (err < 0)
205  av_packet_unref(pkt);
206 
207  return err;
208 }
209 
211 {
213  CodedBitstreamFragment *frag = &ctx->fragment;
214  int err;
215 
216  err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf);
217  if (err < 0)
218  return err;
219 
220  if (bsf->par_in->extradata) {
221  err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in);
222  if (err < 0) {
223  av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
224  goto fail;
225  }
226 
227  err = mpeg2_metadata_update_fragment(bsf, frag);
228  if (err < 0) {
229  av_log(bsf, AV_LOG_ERROR, "Failed to update metadata fragment.\n");
230  goto fail;
231  }
232 
233  err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag);
234  if (err < 0) {
235  av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
236  goto fail;
237  }
238  }
239 
240  err = 0;
241 fail:
242  ff_cbs_fragment_reset(ctx->cbc, frag);
243  return err;
244 }
245 
247 {
249 
250  ff_cbs_fragment_free(ctx->cbc, &ctx->fragment);
251  ff_cbs_close(&ctx->cbc);
252 }
253 
254 #define OFFSET(x) offsetof(MPEG2MetadataContext, x)
255 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
257  { "display_aspect_ratio", "Set display aspect ratio (table 6-3)",
259  { .dbl = 0.0 }, 0, 65535, FLAGS },
260 
261  { "frame_rate", "Set frame rate",
263  { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
264 
265  { "video_format", "Set video format (table 6-6)",
267  { .i64 = -1 }, -1, 7, FLAGS },
268  { "colour_primaries", "Set colour primaries (table 6-7)",
270  { .i64 = -1 }, -1, 255, FLAGS },
271  { "transfer_characteristics", "Set transfer characteristics (table 6-8)",
273  { .i64 = -1 }, -1, 255, FLAGS },
274  { "matrix_coefficients", "Set matrix coefficients (table 6-9)",
276  { .i64 = -1 }, -1, 255, FLAGS },
277 
278  { NULL }
279 };
280 
282  .class_name = "mpeg2_metadata_bsf",
283  .item_name = av_default_item_name,
284  .option = mpeg2_metadata_options,
285  .version = LIBAVUTIL_VERSION_INT,
286 };
287 
288 static const enum AVCodecID mpeg2_metadata_codec_ids[] = {
290 };
291 
293  .name = "mpeg2_metadata",
294  .priv_data_size = sizeof(MPEG2MetadataContext),
295  .priv_class = &mpeg2_metadata_class,
297  .close = &mpeg2_metadata_close,
300 };
#define NULL
Definition: coverity.c:32
int nb_units
Number of units in this fragment.
Definition: cbs.h:147
uint8_t extension_start_code_identifier
Definition: cbs_mpeg2.h:173
AVCodecParameters * par_out
Parameters of the output stream.
Definition: avcodec.h:5797
#define se(name, range_min, range_max)
Definition: cbs_h2645.c:263
AVOption.
Definition: opt.h:246
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#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:345
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
MPEG2RawSequenceExtension sequence
Definition: cbs_mpeg2.h:176
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:68
int num
Numerator.
Definition: rational.h:59
The bitstream filter state.
Definition: avcodec.h:5763
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, 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:666
static AVPacket pkt
void * priv_data
Opaque filter-specific private data.
Definition: avcodec.h:5784
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.
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:239
const char * name
Definition: avcodec.h:5813
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:101
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:162
#define av_log(a,...)
void ff_cbs_fragment_free(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition: cbs.c:154
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:120
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:320
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: avcodec.h:220
union MPEG2RawExtensionData::@62 data
MPEG2RawSequenceDisplayExtension sequence_display
Definition: cbs_mpeg2.h:177
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:116
#define FLAGS
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
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
void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, 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:139
Context structure for coded bitstream operations.
Definition: cbs.h:168
Rational number (pair of numerator and denominator).
Definition: rational.h:58
uint8_t extension_start_code
Definition: cbs_mpeg2.h:172
uint16_t horizontal_size_value
Definition: cbs_mpeg2.h:62
void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:113
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:221
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: avcodec.h:3971
#define OFFSET(x)
static int mpeg2_metadata_init(AVBSFContext *bsf)
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5791
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:238