avfilter/avfiltergraph: fix constant string comparision
[ffmpeg.git] / libavformat / codecstring.c
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" },
44 { AV_CODEC_ID_NONE }
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;
99 int profile = AV_PROFILE_UNKNOWN;
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') &&
166 profile != AV_PROFILE_UNKNOWN &&
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",
172 av_fourcc2str(par->codec_tag), profile,
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
178 AV1SequenceParameters seq;
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);
187 if (seq.color_description_present_flag)
188 av_bprintf(out, ".%01u.%01u%01u%01u.%02u.%02u.%02u.%01u",
189 seq.monochrome,
190 seq.chroma_subsampling_x, seq.chroma_subsampling_y, seq.chroma_sample_position,
191 seq.color_primaries, seq.transfer_characteristics, seq.matrix_coefficients,
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 }