7 #include "packager/media/filters/vp8_parser.h"
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/base/rcheck.h"
13 namespace edash_packager {
17 const uint32_t MB_FEATURE_TREE_PROBS = 3;
18 const uint32_t MAX_MB_SEGMENTS = 4;
19 const uint32_t MAX_REF_LF_DELTAS = 4;
20 const uint32_t MAX_MODE_LF_DELTAS = 4;
21 const uint32_t MB_LVL_MAX = 2;
22 const uint32_t MB_FEATURE_DATA_BITS[MB_LVL_MAX] = {7, 6};
24 bool VerifySyncCode(
const uint8_t* data) {
25 return data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a;
28 bool ReadSegmentation(BitReader* reader) {
30 RCHECK(reader->ReadBits(1, &enabled));
35 RCHECK(reader->ReadBits(1, &update_map));
37 RCHECK(reader->ReadBits(1, &update_data));
40 RCHECK(reader->SkipBits(1));
41 for (uint32_t i = 0; i < MAX_MB_SEGMENTS; ++i)
42 for (uint32_t j = 0; j < MB_LVL_MAX; ++j) {
43 RCHECK(reader->SkipBitsConditional(
true, MB_FEATURE_DATA_BITS[j] + 1));
47 for (uint32_t i = 0; i < MB_FEATURE_TREE_PROBS; ++i)
48 RCHECK(reader->SkipBitsConditional(
true, 8));
53 bool ReadLoopFilter(BitReader* reader) {
54 RCHECK(reader->SkipBits(10));
56 bool mode_ref_delta_enabled;
57 RCHECK(reader->ReadBits(1, &mode_ref_delta_enabled));
58 if (!mode_ref_delta_enabled)
60 bool mode_ref_delta_update;
61 RCHECK(reader->ReadBits(1, &mode_ref_delta_update));
62 if (!mode_ref_delta_update)
65 for (uint32_t i = 0; i < MAX_REF_LF_DELTAS + MAX_MODE_LF_DELTAS; ++i)
66 RCHECK(reader->SkipBitsConditional(
true, 6 + 1));
70 bool ReadQuantization(BitReader* reader) {
72 RCHECK(reader->ReadBits(7, &yac_index));
73 VLOG(4) <<
"yac_index: " << yac_index;
74 RCHECK(reader->SkipBitsConditional(
true, 4 + 1));
75 RCHECK(reader->SkipBitsConditional(
true, 4 + 1));
76 RCHECK(reader->SkipBitsConditional(
true, 4 + 1));
77 RCHECK(reader->SkipBitsConditional(
true, 4 + 1));
78 RCHECK(reader->SkipBitsConditional(
true, 4 + 1));
82 bool ReadRefreshFrame(BitReader* reader) {
83 bool refresh_golden_frame;
84 RCHECK(reader->ReadBits(1, &refresh_golden_frame));
85 bool refresh_altref_frame;
86 RCHECK(reader->ReadBits(1, &refresh_altref_frame));
87 if (!refresh_golden_frame)
88 RCHECK(reader->SkipBits(2));
89 if (!refresh_altref_frame)
90 RCHECK(reader->SkipBits(2));
91 RCHECK(reader->SkipBits(2));
97 VP8Parser::VP8Parser() : width_(0), height_(0) {}
98 VP8Parser::~VP8Parser() {}
102 std::vector<VPxFrameInfo>* vpx_frames) {
111 bool is_interframe = data[0] & 1;
114 uint8_t profile = (data[0] >> 1) & 3;
118 uint32_t header_size = (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
119 RCHECK(header_size <= data_size);
121 if (!is_interframe) {
125 RCHECK(VerifySyncCode(&data[3]));
128 width_ = data[6] | ((data[7] & 0x3f) << 8);
129 height_ = data[8] | ((data[9] & 0x3f) << 8);
134 RCHECK(ReadSegmentation(&reader));
135 RCHECK(ReadLoopFilter(&reader));
137 RCHECK(ReadQuantization(&reader));
140 RCHECK(ReadRefreshFrame(&reader));
151 writable_codec_config()->set_profile(profile);
154 writable_codec_config()->set_bit_depth(8);
155 writable_codec_config()->set_chroma_subsampling(
156 VPCodecConfiguration::CHROMA_420_COLLOCATED_WITH_LUMA);
159 writable_codec_config()->set_color_space(
160 VPCodecConfiguration::COLOR_SPACE_BT_601);
163 vpx_frame.frame_size = data_size;
164 vpx_frame.uncompressed_header_size =
166 vpx_frame.is_keyframe = !is_interframe;
167 vpx_frame.width = width_;
168 vpx_frame.height = height_;
171 vpx_frames->push_back(vpx_frame);
173 VLOG(3) <<
"\n frame_size: " << vpx_frame.frame_size
174 <<
"\n uncompressed_header_size: "
175 << vpx_frame.uncompressed_header_size
177 <<
"\n header_size: " << header_size
178 <<
"\n width: " << vpx_frame.width
179 <<
"\n height: " << vpx_frame.height;
189 if ((data[0] & 0x01) != 0)
191 return VerifySyncCode(&data[3]);