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 
86  if (ctx->display_aspect_ratio.num && ctx->display_aspect_ratio.den) {
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;
119  ctx->sequence_display_extension.extension_start_code =
121  ctx->sequence_display_extension.extension_start_code_identifier =
123  sde = &ctx->sequence_display_extension.data.sequence_display;
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 =
134  se->horizontal_size_extension << 12 | sh->horizontal_size_value,
135  .display_vertical_size =
136  se->vertical_size_extension << 12 | sh->vertical_size_value,
137  };
138 
139  err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1,
141  &ctx->sequence_display_extension,
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)
159  sde->colour_primaries = ctx->colour_primaries;
160 
161  if (ctx->transfer_characteristics >= 0)
162  sde->transfer_characteristics = ctx->transfer_characteristics;
163 
164  if (ctx->matrix_coefficients >= 0)
165  sde->matrix_coefficients = ctx->matrix_coefficients;
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)
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)
223  VALIDITY_CHECK(colour_primaries);
225  VALIDITY_CHECK(matrix_coefficients);
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)",
270  OFFSET(display_aspect_ratio), AV_OPT_TYPE_RATIONAL,
271  { .dbl = 0.0 }, 0, 65535, FLAGS },
272 
273  { "frame_rate", "Set frame rate",
274  OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL,
275  { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
276 
277  { "video_format", "Set video format (table 6-6)",
278  OFFSET(video_format), AV_OPT_TYPE_INT,
279  { .i64 = -1 }, -1, 7, FLAGS },
280  { "colour_primaries", "Set colour primaries (table 6-7)",
281  OFFSET(colour_primaries), AV_OPT_TYPE_INT,
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)",
287  OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
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 };
MPEG2MetadataContext::display_aspect_ratio
AVRational display_aspect_ratio
Definition: mpeg2_metadata_bsf.c:36
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
OFFSET
#define OFFSET(x)
Definition: mpeg2_metadata_bsf.c:266
AVBSFContext::par_in
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5791
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3971
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
opt.h
ff_cbs_read_extradata
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
CodedBitstreamUnit::content
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:101
AVBitStreamFilter::name
const char * name
Definition: avcodec.h:5813
MPEG2MetadataContext::transfer_characteristics
int transfer_characteristics
Definition: mpeg2_metadata_bsf.c:42
se
#define se(name, range_min, range_max)
Definition: cbs_h2645.c:263
MPEG2_EXTENSION_SEQUENCE_DISPLAY
@ MPEG2_EXTENSION_SEQUENCE_DISPLAY
Definition: cbs_mpeg2.h:46
MPEG2RawExtensionData::sequence_display
MPEG2RawSequenceDisplayExtension sequence_display
Definition: cbs_mpeg2.h:183
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:168
ff_cbs_close
void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:115
AVOption
AVOption.
Definition: opt.h:246
ff_cbs_fragment_free
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
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:68
cbs.h
filter
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
Definition: filter_design.txt:228
MPEG2RawExtensionData
Definition: cbs_mpeg2.h:177
MPEG2MetadataContext::video_format
int video_format
Definition: mpeg2_metadata_bsf.c:40
MPEG2MetadataContext::cbc
CodedBitstreamContext * cbc
Definition: mpeg2_metadata_bsf.c:31
AV_OPT_TYPE_RATIONAL
@ AV_OPT_TYPE_RATIONAL
Definition: opt.h:228
MPEG2RawSequenceHeader::frame_rate_code
uint8_t frame_rate_code
Definition: cbs_mpeg2.h:65
AVBSFContext
The bitstream filter state.
Definition: avcodec.h:5763
ff_mpeg12_find_best_frame_rate
void ff_mpeg12_find_best_frame_rate(AVRational frame_rate, int *code, int *ext_n, int *ext_d, int nonstandard)
Definition: mpeg12framerate.c:44
bsf.h
fail
#define fail()
Definition: checkasm.h:120
mpeg2_metadata_init
static int mpeg2_metadata_init(AVBSFContext *bsf)
Definition: mpeg2_metadata_bsf.c:210
ff_cbs_write_extradata
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
AVBSFContext::par_out
AVCodecParameters * par_out
Parameters of the output stream.
Definition: avcodec.h:5797
av_reduce
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
MPEG2RawSequenceDisplayExtension::colour_description
uint8_t colour_description
Definition: cbs_mpeg2.h:100
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:162
mpeg12.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
MPEG2RawSequenceExtension
Definition: cbs_mpeg2.h:84
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:116
ff_cbs_write_packet
int ff_cbs_write_packet(CodedBitstreamContext *ctx, AVPacket *pkt, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to a packet.
Definition: cbs.c:401
MPEG2RawSequenceDisplayExtension
Definition: cbs_mpeg2.h:97
ctx
AVFormatContext * ctx
Definition: movenc.c:48
MPEG2RawSequenceDisplayExtension::video_format
uint8_t video_format
Definition: cbs_mpeg2.h:98
MPEG2RawSequenceHeader::vertical_size_value
uint16_t vertical_size_value
Definition: cbs_mpeg2.h:63
MPEG2MetadataContext
Definition: mpeg2_metadata_bsf.c:28
FLAGS
#define FLAGS
Definition: mpeg2_metadata_bsf.c:267
mpeg2_metadata_filter
static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
Definition: mpeg2_metadata_bsf.c:172
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
MPEG2RawSequenceDisplayExtension::colour_primaries
uint8_t colour_primaries
Definition: cbs_mpeg2.h:101
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
MPEG2MetadataContext::matrix_coefficients
int matrix_coefficients
Definition: mpeg2_metadata_bsf.c:43
NULL
#define NULL
Definition: coverity.c:32
mpeg2_metadata_codec_ids
static enum AVCodecID mpeg2_metadata_codec_ids[]
Definition: mpeg2_metadata_bsf.c:300
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
cbs_mpeg2.h
MPEG2MetadataContext::mpeg1_warned
int mpeg1_warned
Definition: mpeg2_metadata_bsf.c:45
MPEG2RawSequenceDisplayExtension::matrix_coefficients
uint8_t matrix_coefficients
Definition: cbs_mpeg2.h:103
MPEG2MetadataContext::colour_primaries
int colour_primaries
Definition: mpeg2_metadata_bsf.c:41
MPEG2RawSequenceHeader::horizontal_size_value
uint16_t horizontal_size_value
Definition: cbs_mpeg2.h:62
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
MPEG2RawExtensionData::sequence
MPEG2RawSequenceExtension sequence
Definition: cbs_mpeg2.h:182
VALIDITY_CHECK
#define VALIDITY_CHECK(name)
MPEG2RawExtensionData::extension_start_code_identifier
uint8_t extension_start_code_identifier
Definition: cbs_mpeg2.h:179
mpeg2_metadata_options
static const AVOption mpeg2_metadata_options[]
Definition: mpeg2_metadata_bsf.c:268
MPEG2_EXTENSION_SEQUENCE
@ MPEG2_EXTENSION_SEQUENCE
Definition: cbs_mpeg2.h:45
transfer_characteristics
static const struct TransferCharacteristics transfer_characteristics[AVCOL_TRC_NB]
Definition: vf_colorspace.c:176
MPEG2RawSequenceHeader
Definition: cbs_mpeg2.h:59
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: avcodec.h:216
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
code
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
Definition: filter_design.txt:178
common.h
MPEG2RawSequenceHeader::aspect_ratio_information
uint8_t aspect_ratio_information
Definition: cbs_mpeg2.h:64
MPEG2MetadataContext::frame_rate
AVRational frame_rate
Definition: mpeg2_metadata_bsf.c:38
MPEG2RawSequenceDisplayExtension::transfer_characteristics
uint8_t transfer_characteristics
Definition: cbs_mpeg2.h:102
AVBSFContext::priv_data
void * priv_data
Opaque filter-specific private data.
Definition: avcodec.h:5784
AVClass::class_name
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
ff_mpeg2_metadata_bsf
const AVBitStreamFilter ff_mpeg2_metadata_bsf
Definition: mpeg2_metadata_bsf.c:304
MPEG2MetadataContext::sequence_display_extension
MPEG2RawExtensionData sequence_display_extension
Definition: mpeg2_metadata_bsf.c:34
mpeg2_metadata_close
static void mpeg2_metadata_close(AVBSFContext *bsf)
Definition: mpeg2_metadata_bsf.c:258
ff_cbs_init
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
MPEG2_START_SEQUENCE_HEADER
@ MPEG2_START_SEQUENCE_HEADER
Definition: cbs_mpeg2.h:33
mpeg2_metadata_update_fragment
static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, CodedBitstreamFragment *frag)
Definition: mpeg2_metadata_bsf.c:49
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AVBitStreamFilter
Definition: avcodec.h:5812
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
ff_cbs_fragment_reset
void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment's own data buffer, but not the units a...
Definition: cbs.c:142
ff_cbs_read_packet
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
MPEG2_START_EXTENSION
@ MPEG2_START_EXTENSION
Definition: cbs_mpeg2.h:35
ff_cbs_insert_unit_content
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
codec_ids
static enum AVCodecID codec_ids[]
Definition: aac_adtstoasc_bsf.c:148
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
MPEG2RawExtensionData::data
union MPEG2RawExtensionData::@62 data
MPEG2MetadataContext::fragment
CodedBitstreamFragment fragment
Definition: mpeg2_metadata_bsf.c:32
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_bsf_get_packet_ref
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:239
avstring.h
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: avcodec.h:220
mpeg2_metadata_class
static const AVClass mpeg2_metadata_class
Definition: mpeg2_metadata_bsf.c:293
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:147