FFmpeg
codecstring.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Martin Storsjo
3  * Copyright (c) 2018 Akamai Technologies, Inc.
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/avstring.h"
23 #include "libavutil/bprint.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/rational.h"
27 
28 #include "av1.h"
29 #include "avc.h"
30 #include "avformat.h"
31 #include "internal.h"
32 #include "nal.h"
33 #include "vpcc.h"
34 
35 static const struct codec_string {
36  enum AVCodecID id;
37  char str[8];
38 } codecs[] = {
39  { AV_CODEC_ID_VP8, "vp8" },
40  { AV_CODEC_ID_VP9, "vp9" },
41  { AV_CODEC_ID_VORBIS, "vorbis" },
42  { AV_CODEC_ID_OPUS, "opus" },
43  { AV_CODEC_ID_FLAC, "flac" },
45 };
46 
47 static void set_vp9_codec_str(void *logctx, const AVCodecParameters *par,
48  const AVRational *frame_rate, AVBPrint *out)
49 {
50  VPCC vpcc;
51  int ret = ff_isom_get_vpcc_features(logctx, par, NULL, 0, frame_rate, &vpcc);
52  if (ret == 0) {
53  av_bprintf(out, "vp09.%02d.%02d.%02d",
54  vpcc.profile, vpcc.level, vpcc.bitdepth);
55  } else {
56  // Default to just vp9 in case of error while finding out profile or level
57  av_log(logctx, AV_LOG_WARNING, "Could not find VP9 profile and/or level\n");
58  av_bprintf(out, "vp9");
59  }
60 }
61 
62 int ff_make_codec_str(void *logctx, const AVCodecParameters *par,
63  const AVRational *frame_rate, struct AVBPrint *out)
64 {
65  int i;
66 
67  // common Webm codecs are not part of RFC 6381
68  for (i = 0; codecs[i].id != AV_CODEC_ID_NONE; i++)
69  if (codecs[i].id == par->codec_id) {
70  if (codecs[i].id == AV_CODEC_ID_VP9) {
71  set_vp9_codec_str(logctx, par, frame_rate, out);
72  } else {
73  av_bprintf(out, "%s", codecs[i].str);
74  }
75  return 0;
76  }
77 
78  if (par->codec_id == AV_CODEC_ID_H264) {
79  // RFC 6381
80  uint8_t *data = par->extradata;
81  if (data) {
82  const uint8_t *p;
83 
84  if (AV_RB32(data) == 0x01 && (data[4] & 0x1F) == 7)
85  p = &data[5];
86  else if (AV_RB24(data) == 0x01 && (data[3] & 0x1F) == 7)
87  p = &data[4];
88  else if (data[0] == 0x01) /* avcC */
89  p = &data[1];
90  else
91  return AVERROR(EINVAL);
92  av_bprintf(out, "avc1.%02x%02x%02x", p[0], p[1], p[2]);
93  } else {
94  return AVERROR(EINVAL);
95  }
96  } else if (par->codec_id == AV_CODEC_ID_HEVC) {
97  // 3GPP TS 26.244
98  uint8_t *data = par->extradata;
100  uint32_t profile_compatibility = AV_PROFILE_UNKNOWN;
101  char tier = 0;
102  int level = AV_LEVEL_UNKNOWN;
103  char constraints[8] = "";
104 
105  if (par->profile != AV_PROFILE_UNKNOWN)
106  profile = par->profile;
107  if (par->level != AV_LEVEL_UNKNOWN)
108  level = par->level;
109 
110  /* check the boundary of data which from current position is small than extradata_size */
111  while (data && (data - par->extradata + 19) < par->extradata_size) {
112  /* get HEVC SPS NAL and seek to profile_tier_level */
113  if (!(data[0] | data[1] | data[2]) && data[3] == 1 && ((data[4] & 0x7E) == 0x42)) {
114  uint8_t *rbsp_buf;
115  int remain_size = 0;
116  int rbsp_size = 0;
117  uint32_t profile_compatibility_flags = 0;
118  uint8_t high_nibble = 0;
119  /* skip start code + nalu header */
120  data += 6;
121  /* process by reference General NAL unit syntax */
122  remain_size = par->extradata_size - (data - par->extradata);
123  rbsp_buf = ff_nal_unit_extract_rbsp(data, remain_size, &rbsp_size, 0);
124  if (!rbsp_buf)
125  return AVERROR(EINVAL);
126  if (rbsp_size < 13) {
127  av_freep(&rbsp_buf);
128  break;
129  }
130  /* skip sps_video_parameter_set_id u(4),
131  * sps_max_sub_layers_minus1 u(3),
132  * and sps_temporal_id_nesting_flag u(1)
133  *
134  * TIER represents the general_tier_flag, with 'L' indicating the flag is 0,
135  * and 'H' indicating the flag is 1
136  */
137  tier = (rbsp_buf[1] & 0x20) == 0 ? 'L' : 'H';
138  profile = rbsp_buf[1] & 0x1f;
139  /* PROFILE_COMPATIBILITY is general_profile_compatibility_flags, but in reverse bit order,
140  * in a hexadecimal representation (leading zeroes may be omitted).
141  */
142  profile_compatibility_flags = AV_RB32(rbsp_buf + 2);
143  /* revise these bits to get the profile compatibility value */
144  profile_compatibility_flags = ((profile_compatibility_flags & 0x55555555U) << 1) | ((profile_compatibility_flags >> 1) & 0x55555555U);
145  profile_compatibility_flags = ((profile_compatibility_flags & 0x33333333U) << 2) | ((profile_compatibility_flags >> 2) & 0x33333333U);
146  profile_compatibility_flags = ((profile_compatibility_flags & 0x0F0F0F0FU) << 4) | ((profile_compatibility_flags >> 4) & 0x0F0F0F0FU);
147  profile_compatibility_flags = ((profile_compatibility_flags & 0x00FF00FFU) << 8) | ((profile_compatibility_flags >> 8) & 0x00FF00FFU);
148  profile_compatibility = (profile_compatibility_flags << 16) | (profile_compatibility_flags >> 16);
149  /* skip 8 + 8 + 32
150  * CONSTRAINTS is a hexadecimal representation of the general_constraint_indicator_flags.
151  * each byte is separated by a '.', and trailing zero bytes may be omitted.
152  * drop the trailing zero bytes refer to ISO/IEC14496-15.
153  */
154  high_nibble = rbsp_buf[7] >> 4;
155  snprintf(constraints, sizeof(constraints),
156  high_nibble ? "%02x.%x" : "%02x",
157  rbsp_buf[6], high_nibble);
158  /* skip 8 + 8 + 32 + 4 + 43 + 1 bit */
159  level = rbsp_buf[12];
160  av_freep(&rbsp_buf);
161  break;
162  }
163  data++;
164  }
165  if (par->codec_tag == MKTAG('h','v','c','1') &&
167  profile_compatibility != AV_PROFILE_UNKNOWN &&
168  tier != 0 &&
169  level != AV_LEVEL_UNKNOWN &&
170  constraints[0] != '\0') {
171  av_bprintf(out, "%s.%d.%x.%c%d.%s",
173  profile_compatibility, tier, level, constraints);
174  } else
175  return AVERROR(EINVAL);
176  } else if (par->codec_id == AV_CODEC_ID_AV1) {
177  // https://aomediacodec.github.io/av1-isobmff/#codecsparam
179  int err;
180  if (!par->extradata_size)
181  return AVERROR(EINVAL);
182  if ((err = ff_av1_parse_seq_header(&seq, par->extradata, par->extradata_size)) < 0)
183  return err;
184 
185  av_bprintf(out, "av01.%01u.%02u%s.%02u",
186  seq.profile, seq.level, seq.tier ? "H" : "M", seq.bitdepth);
188  av_bprintf(out, ".%01u.%01u%01u%01u.%02u.%02u.%02u.%01u",
189  seq.monochrome,
192  seq.color_range);
193  } else if (par->codec_id == AV_CODEC_ID_MPEG4) {
194  // RFC 6381
195  av_bprintf(out, "mp4v.20");
196  // Unimplemented, should output ProfileLevelIndication as a decimal number
197  av_log(logctx, AV_LOG_WARNING, "Incomplete RFC 6381 codec string for mp4v\n");
198  } else if (par->codec_id == AV_CODEC_ID_MP2) {
199  av_bprintf(out, "mp4a.40.33");
200  } else if (par->codec_id == AV_CODEC_ID_MP3) {
201  av_bprintf(out, "mp4a.40.34");
202  } else if (par->codec_id == AV_CODEC_ID_AAC) {
203  // RFC 6381
204  int aot = 2;
205  if (par->extradata_size >= 2) {
206  aot = par->extradata[0] >> 3;
207  if (aot == 31)
208  aot = ((AV_RB16(par->extradata) >> 5) & 0x3f) + 32;
209  } else if (par->profile != AV_PROFILE_UNKNOWN)
210  aot = par->profile + 1;
211  av_bprintf(out, "mp4a.40.%d", aot);
212  } else if (par->codec_id == AV_CODEC_ID_AC3) {
213  av_bprintf(out, "ac-3");
214  } else if (par->codec_id == AV_CODEC_ID_EAC3) {
215  av_bprintf(out, "ec-3");
216  } else {
217  return AVERROR(EINVAL);
218  }
219  return 0;
220 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
level
uint8_t level
Definition: svq3.c:208
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:462
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
out
FILE * out
Definition: movenc.c:55
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
rational.h
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
set_vp9_codec_str
static void set_vp9_codec_str(void *logctx, const AVCodecParameters *par, const AVRational *frame_rate, AVBPrint *out)
Definition: codecstring.c:47
data
const char data[16]
Definition: mxf.c:149
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:471
AV1SequenceParameters::chroma_subsampling_y
uint8_t chroma_subsampling_y
Definition: av1.h:35
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:460
vpcc.h
AV1SequenceParameters::color_description_present_flag
uint8_t color_description_present_flag
Definition: av1.h:37
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
intreadwrite.h
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:459
AV1SequenceParameters::color_range
uint8_t color_range
Definition: av1.h:41
codec_string::str
char str[8]
Definition: codecstring.c:37
tier
int tier
Definition: av1_levels.c:48
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
internal.h
AV1SequenceParameters::chroma_sample_position
uint8_t chroma_sample_position
Definition: av1.h:36
NULL
#define NULL
Definition: coverity.c:32
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
VPCC::bitdepth
int bitdepth
Definition: vpcc.h:37
AV_LEVEL_UNKNOWN
#define AV_LEVEL_UNKNOWN
Definition: defs.h:209
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ff_nal_unit_extract_rbsp
uint8_t * ff_nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len, uint32_t *dst_len, int header_len)
Definition: nal.c:160
AV1SequenceParameters::transfer_characteristics
uint8_t transfer_characteristics
Definition: av1.h:39
avc.h
AV1SequenceParameters::tier
uint8_t tier
Definition: av1.h:31
AVCodecParameters::level
int level
Definition: codec_par.h:129
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:499
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:461
AV1SequenceParameters::monochrome
uint8_t monochrome
Definition: av1.h:33
ff_isom_get_vpcc_features
int ff_isom_get_vpcc_features(void *logctx, const AVCodecParameters *par, const uint8_t *data, int len, const AVRational *frame_rate, VPCC *vpcc)
Definition: vpcc.c:155
AV1SequenceParameters::matrix_coefficients
uint8_t matrix_coefficients
Definition: av1.h:40
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AVCodecParameters::profile
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition: codec_par.h:128
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:519
codecs
static const struct codec_string codecs[]
AV1SequenceParameters::profile
uint8_t profile
Definition: av1.h:29
AV1SequenceParameters::color_primaries
uint8_t color_primaries
Definition: av1.h:38
ff_make_codec_str
int ff_make_codec_str(void *logctx, const AVCodecParameters *par, const AVRational *frame_rate, struct AVBPrint *out)
Make a RFC 4281/6381 like string describing a codec.
Definition: codecstring.c:62
bprint.h
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
AV1SequenceParameters::level
uint8_t level
Definition: av1.h:30
profile
int profile
Definition: mxfenc.c:2297
nal.h
codec_string::id
enum AVCodecID id
Definition: codecstring.c:36
ff_av1_parse_seq_header
int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int size)
Parses a Sequence Header from the the provided buffer.
Definition: av1.c:336
ret
ret
Definition: filter_design.txt:187
avformat.h
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:122
VPCC::level
int level
Definition: vpcc.h:36
U
#define U(x)
Definition: vpx_arith.h:37
VPCC
Definition: vpcc.h:34
AV1SequenceParameters::chroma_subsampling_x
uint8_t chroma_subsampling_x
Definition: av1.h:34
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
mem.h
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
codec_string
Definition: codecstring.c:35
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV1SequenceParameters::bitdepth
uint8_t bitdepth
Definition: av1.h:32
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
av1.h
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:464
AV1SequenceParameters
Definition: av1.h:28
VPCC::profile
int profile
Definition: vpcc.h:35
avstring.h
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:97
snprintf
#define snprintf
Definition: snprintf.h:34
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347