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 #define VALIDITY_CHECK(name) do { \
217  if (!ctx->name) { \
218  av_log(bsf, AV_LOG_ERROR, "The value 0 for %s is " \
219  "forbidden.\n", #name); \
220  return AVERROR(EINVAL); \
221  } \
222  } while (0)
226 #undef VALIDITY_CHECK
227 
228  err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_MPEG2VIDEO, bsf);
229  if (err < 0)
230  return err;
231 
232  if (bsf->par_in->extradata) {
233  err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in);
234  if (err < 0) {
235  av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
236  goto fail;
237  }
238 
239  err = mpeg2_metadata_update_fragment(bsf, frag);
240  if (err < 0) {
241  av_log(bsf, AV_LOG_ERROR, "Failed to update metadata fragment.\n");
242  goto fail;
243  }
244 
245  err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag);
246  if (err < 0) {
247  av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
248  goto fail;
249  }
250  }
251 
252  err = 0;
253 fail:
254  ff_cbs_fragment_reset(ctx->cbc, frag);
255  return err;
256 }
257 
259 {
261 
262  ff_cbs_fragment_free(ctx->cbc, &ctx->fragment);
263  ff_cbs_close(&ctx->cbc);
264 }
265 
266 #define OFFSET(x) offsetof(MPEG2MetadataContext, x)
267 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
269  { "display_aspect_ratio", "Set display aspect ratio (table 6-3)",
271  { .dbl = 0.0 }, 0, 65535, FLAGS },
272 
273  { "frame_rate", "Set frame rate",
275  { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
276 
277  { "video_format", "Set video format (table 6-6)",
279  { .i64 = -1 }, -1, 7, FLAGS },
280  { "colour_primaries", "Set colour primaries (table 6-7)",
282  { .i64 = -1 }, -1, 255, FLAGS },
283  { "transfer_characteristics", "Set transfer characteristics (table 6-8)",
285  { .i64 = -1 }, -1, 255, FLAGS },
286  { "matrix_coefficients", "Set matrix coefficients (table 6-9)",
288  { .i64 = -1 }, -1, 255, FLAGS },
289 
290  { NULL }
291 };
292 
294  .class_name = "mpeg2_metadata_bsf",
295  .item_name = av_default_item_name,
296  .option = mpeg2_metadata_options,
297  .version = LIBAVUTIL_VERSION_INT,
298 };
299 
300 static const enum AVCodecID mpeg2_metadata_codec_ids[] = {
302 };
303 
305  .name = "mpeg2_metadata",
306  .priv_data_size = sizeof(MPEG2MetadataContext),
307  .priv_class = &mpeg2_metadata_class,
309  .close = &mpeg2_metadata_close,
312 };
#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:179
AVCodecParameters * par_out
Parameters of the output stream.
Definition: avcodec.h:5808
#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:401
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
MPEG2RawSequenceExtension sequence
Definition: cbs_mpeg2.h:182
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:5774
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:722
static AVPacket pkt
void * priv_data
Opaque filter-specific private data.
Definition: avcodec.h:5795
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:242
const char * name
Definition: avcodec.h:5824
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:157
#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:122
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:376
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:183
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:142
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:178
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: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:224
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:3982
#define OFFSET(x)
static int mpeg2_metadata_init(AVBSFContext *bsf)
This structure stores compressed data.
Definition: avcodec.h:1457
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5802
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:239