History

avformat/vpcc: parse bitstream data to get profile and bitdepth

Profile can be derived from values codecpar pixel format only with software formats. For hardware formats, we're forced to parse a frame header to get the required information.

James Almer committed 4 years ago

Commit cb925c01 parent e9a67ab4 files · +62 −4Browse files

Unified · Split

4 files
  1. libavformat/dashenc.c +1 −1
  2. libavformat/movenc.c +3 −1
  3. libavformat/vpcc.c +53 −2
  4. libavformat/vpcc.h +5 −0
libavformat/dashenc.c+1−1
@@ -338,7 +338,7 @@ static int init_segment_types(AVFormatContext *s) · 337 unmodified lines
338338 static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par,
339339 AVRational *frame_rate, char *str, int size) {
340340 VPCC vpcc;
341− int ret = ff_isom_get_vpcc_features(s, par, frame_rate, &vpcc);
341+ int ret = ff_isom_get_vpcc_features(s, par, NULL, 0, frame_rate, &vpcc);
342342 if (ret == 0) {
343343 av_strlcatf(str, size, "vp09.%02d.%02d.%02d",
344344 vpcc.profile, vpcc.level, vpcc.bitdepth);
libavformat/movenc.c+3−1
@@ -1375,7 +1375,8 @@ static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra · 1374 unmodified lines
13751375 ffio_wfourcc(pb, "vpcC");
13761376 avio_w8(pb, 1); /* version */
13771377 avio_wb24(pb, 0); /* flags */
1378− ff_isom_write_vpcc(s, pb, track->par);
1378+ ff_isom_write_vpcc(s, pb, track->vos_data, track->vos_len, track->par);
1379+
13791380 return update_size(pb, pos);
13801381 }
13811382
@@ -6033,6 +6034,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) · 4651 unmodified lines
60336034 if ((par->codec_id == AV_CODEC_ID_DNXHD ||
60346035 par->codec_id == AV_CODEC_ID_H264 ||
60356036 par->codec_id == AV_CODEC_ID_HEVC ||
6037+ par->codec_id == AV_CODEC_ID_VP9 ||
60366038 par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->vos_len &&
60376039 !TAG_IS_AVCI(trk->tag)) {
60386040 /* copy frame to create needed atoms */
libavformat/vpcc.c+53−2
@@ -22,8 +22,11 @@ · 21 unmodified lines
2222 #include "libavutil/pixdesc.h"
2323 #include "libavutil/pixfmt.h"
2424 #include "libavcodec/avcodec.h"
25+#include "libavcodec/get_bits.h"
2526 #include "vpcc.h"
2627
28+#define VP9_SYNCCODE 0x498342
29+
2730 enum VPX_CHROMA_SUBSAMPLING
2831 {
2932 VPX_SUBSAMPLING_420_VERTICAL = 0,
@@ -114,7 +117,41 @@ static int get_vp9_level(AVCodecParameters *par, AVRational *frame_rate) { · 84 unmodified lines
114117 }
115118 }
116119
120+static void parse_bitstream(GetBitContext *gb, int *profile, int *bit_depth) {
121+ int keyframe, invisible;
122+
123+ if (get_bits(gb, 2) != 0x2) // frame marker
124+ return;
125+ *profile = get_bits1(gb);
126+ *profile |= get_bits1(gb) << 1;
127+ if (*profile == 3)
128+ *profile += get_bits1(gb);
129+
130+ if (get_bits1(gb))
131+ return;
132+
133+ keyframe = !get_bits1(gb);
134+ invisible = !get_bits1(gb);
135+ get_bits1(gb);
136+
137+ if (keyframe) {
138+ if (get_bits(gb, 24) != VP9_SYNCCODE)
139+ return;
140+ } else {
141+ int intraonly = invisible ? get_bits1(gb) : 0;
142+ if (!intraonly || get_bits(gb, 24) != VP9_SYNCCODE)
143+ return;
144+ if (*profile < 1) {
145+ *bit_depth = 8;
146+ return;
147+ }
148+ }
149+
150+ *bit_depth = *profile <= 1 ? 8 : 10 + get_bits1(gb) * 2;
151+}
152+
117153 int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par,
154+ const uint8_t *data, int len,
118155 AVRational *frame_rate, VPCC *vpcc)
119156 {
120157 int profile = par->profile;
@@ -129,7 +166,17 @@ int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par, · 8 unmodified lines
129166 if (bit_depth < 0 || vpx_chroma_subsampling < 0)
130167 return AVERROR_INVALIDDATA;
131168
132− if (profile == FF_PROFILE_UNKNOWN) {
169+ if (len && (profile == FF_PROFILE_UNKNOWN || !bit_depth)) {
170+ GetBitContext gb;
171+
172+ int ret = init_get_bits8(&gb, data, len);
173+ if (ret < 0)
174+ return ret;
175+
176+ parse_bitstream(&gb, &profile, &bit_depth);
177+ }
178+
179+ if (profile == FF_PROFILE_UNKNOWN && bit_depth) {
133180 if (vpx_chroma_subsampling == VPX_SUBSAMPLING_420_VERTICAL ||
134181 vpx_chroma_subsampling == VPX_SUBSAMPLING_420_COLLOCATED_WITH_LUMA) {
135182 profile = (bit_depth == 8) ? FF_PROFILE_VP9_0 : FF_PROFILE_VP9_2;
@@ -138,6 +185,9 @@ int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par, · 2 unmodified lines
138185 }
139186 }
140187
188+ if (profile == FF_PROFILE_UNKNOWN || !bit_depth)
189+ av_log(s, AV_LOG_WARNING, "VP9 profile and/or bit depth not set or could not be derived\n");
190+
141191 vpcc->profile = profile;
142192 vpcc->level = level;
143193 vpcc->bitdepth = bit_depth;
@@ -148,12 +198,13 @@ int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par, · 4 unmodified lines
148198 }
149199
150200 int ff_isom_write_vpcc(AVFormatContext *s, AVIOContext *pb,
201+ const uint8_t *data, int len,
151202 AVCodecParameters *par)
152203 {
153204 VPCC vpcc;
154205 int ret;
155206
156− ret = ff_isom_get_vpcc_features(s, par, NULL, &vpcc);
207+ ret = ff_isom_get_vpcc_features(s, par, data, len, NULL, &vpcc);
157208 if (ret < 0)
158209 return ret;
159210
libavformat/vpcc.h+5−0
@@ -45,14 +45,19 @@ typedef struct VPCC { · 44 unmodified lines
4545 *
4646 * @param s address of the AVFormatContext for the logging context.
4747 * @param pb address of the AVIOContext where the vpcC shall be written.
48+ * @param data address of a data array which contains coded bitstream data from
49+ * which codec information can be extracted. May be NULL.
50+ * @param len length of the data array.
4851 * @param par address of the AVCodecParameters which contains codec information.
4952 * @return >=0 in case of success, a negative value corresponding to an AVERROR
5053 * code in case of failure
5154 */
5255 int ff_isom_write_vpcc(AVFormatContext *s, AVIOContext *pb,
56+ const uint8_t *data, int len,
5357 AVCodecParameters *par);
5458
5559 int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par,
60+ const uint8_t *data, int len,
5661 AVRational *frame_rate, VPCC *vpcc);
5762
5863 #endif /* AVFORMAT_VPCC_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t