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 
87  if (ctx->display_aspect_ratio.num && ctx->display_aspect_ratio.den) {
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;
120  ctx->sequence_display_extension.extension_start_code =
122  ctx->sequence_display_extension.extension_start_code_identifier =
124  sde = &ctx->sequence_display_extension.data.sequence_display;
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 =
135  se->horizontal_size_extension << 12 | sh->horizontal_size_value,
136  .display_vertical_size =
137  se->vertical_size_extension << 12 | sh->vertical_size_value,
138  };
139 
140  err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1,
142  &ctx->sequence_display_extension,
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)
160  sde->colour_primaries = ctx->colour_primaries;
161 
162  if (ctx->transfer_characteristics >= 0)
163  sde->transfer_characteristics = ctx->transfer_characteristics;
164 
165  if (ctx->matrix_coefficients >= 0)
166  sde->matrix_coefficients = ctx->matrix_coefficients;
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(ctx->cbc, frag);
204 
205  if (err < 0)
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)
224  VALIDITY_CHECK(colour_primaries);
226  VALIDITY_CHECK(matrix_coefficients);
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(ctx->cbc, frag);
256  return err;
257 }
258 
260 {
262 
263  ff_cbs_fragment_free(ctx->cbc, &ctx->fragment);
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)",
271  OFFSET(display_aspect_ratio), AV_OPT_TYPE_RATIONAL,
272  { .dbl = 0.0 }, 0, 65535, FLAGS },
273 
274  { "frame_rate", "Set frame rate",
275  OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL,
276  { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
277 
278  { "video_format", "Set video format (table 6-6)",
279  OFFSET(video_format), AV_OPT_TYPE_INT,
280  { .i64 = -1 }, -1, 7, FLAGS },
281  { "colour_primaries", "Set colour primaries (table 6-7)",
282  OFFSET(colour_primaries), AV_OPT_TYPE_INT,
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)",
288  OFFSET(matrix_coefficients), AV_OPT_TYPE_INT,
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 };
MPEG2MetadataContext::display_aspect_ratio
AVRational display_aspect_ratio
Definition: mpeg2_metadata_bsf.c:37
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:605
MPEG2_START_EXTENSION
@ MPEG2_START_EXTENSION
Definition: cbs_mpeg2.h:35
OFFSET
#define OFFSET(x)
Definition: mpeg2_metadata_bsf.c:267
AVBSFContext::par_in
AVCodecParameters * par_in
Parameters of the input stream.
Definition: bsf.h:77
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: codec_par.h:74
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
bsf_internal.h
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: bsf.h:99
MPEG2MetadataContext::transfer_characteristics
int transfer_characteristics
Definition: mpeg2_metadata_bsf.c:43
se
#define se(name, range_min, range_max)
Definition: cbs_h2645.c:273
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
MPEG2_EXTENSION_SEQUENCE
@ MPEG2_EXTENSION_SEQUENCE
Definition: cbs_mpeg2.h:45
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:41
MPEG2MetadataContext::cbc
CodedBitstreamContext * cbc
Definition: mpeg2_metadata_bsf.c:32
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: bsf.h:49
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:123
mpeg2_metadata_init
static int mpeg2_metadata_init(AVBSFContext *bsf)
Definition: mpeg2_metadata_bsf.c:211
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: bsf.h:83
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:29
MPEG2_EXTENSION_SEQUENCE_DISPLAY
@ MPEG2_EXTENSION_SEQUENCE_DISPLAY
Definition: cbs_mpeg2.h:46
FLAGS
#define FLAGS
Definition: mpeg2_metadata_bsf.c:268
mpeg2_metadata_filter
static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
Definition: mpeg2_metadata_bsf.c:173
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:44
NULL
#define NULL
Definition: coverity.c:32
mpeg2_metadata_codec_ids
static enum AVCodecID mpeg2_metadata_codec_ids[]
Definition: mpeg2_metadata_bsf.c:301
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
MPEG2_START_SEQUENCE_HEADER
@ MPEG2_START_SEQUENCE_HEADER
Definition: cbs_mpeg2.h:33
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
cbs_mpeg2.h
MPEG2MetadataContext::mpeg1_warned
int mpeg1_warned
Definition: mpeg2_metadata_bsf.c:46
MPEG2RawSequenceDisplayExtension::matrix_coefficients
uint8_t matrix_coefficients
Definition: cbs_mpeg2.h:103
MPEG2MetadataContext::colour_primaries
int colour_primaries
Definition: mpeg2_metadata_bsf.c:42
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: codec_id.h:46
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:269
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: codec_id.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:39
MPEG2RawSequenceDisplayExtension::transfer_characteristics
uint8_t transfer_characteristics
Definition: cbs_mpeg2.h:102
AVBSFContext::priv_data
void * priv_data
Opaque filter-specific private data.
Definition: bsf.h:70
MPEG2RawExtensionData::data
union MPEG2RawExtensionData::@39 data
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:305
MPEG2MetadataContext::sequence_display_extension
MPEG2RawExtensionData sequence_display_extension
Definition: mpeg2_metadata_bsf.c:35
mpeg2_metadata_close
static void mpeg2_metadata_close(AVBSFContext *bsf)
Definition: mpeg2_metadata_bsf.c:259
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_metadata_update_fragment
static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, CodedBitstreamFragment *frag)
Definition: mpeg2_metadata_bsf.c:50
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AVBitStreamFilter
Definition: bsf.h:98
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
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: packet.h:332
MPEG2MetadataContext::fragment
CodedBitstreamFragment fragment
Definition: mpeg2_metadata_bsf.c:33
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:249
avstring.h
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:51
mpeg2_metadata_class
static const AVClass mpeg2_metadata_class
Definition: mpeg2_metadata_bsf.c:294
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:147