blob: 11585bc04e1f8b85f5556796b04f86886b14b082 [file] [log] [blame]
posciak3e644c792015-01-11 03:45:061// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// This file contains an implementation of a VP8 raw stream parser,
6// as defined in RFC 6386.
7
Gil Dekelbf308632019-05-28 22:24:178#ifndef MEDIA_PARSERS_VP8_PARSER_H_
9#define MEDIA_PARSERS_VP8_PARSER_H_
posciak3e644c792015-01-11 03:45:0610
avi1323b9c22015-12-23 06:22:3611#include <stddef.h>
12#include <stdint.h>
13
avia82b9b52015-12-19 04:27:0814#include "base/macros.h"
Gil Dekelbf308632019-05-28 22:24:1715#include "media/parsers/media_parsers_export.h"
16#include "media/parsers/vp8_bool_decoder.h"
posciak3e644c792015-01-11 03:45:0617
18namespace media {
19
20// See spec for definitions of values/fields.
21const size_t kMaxMBSegments = 4;
22const size_t kNumMBFeatureTreeProbs = 3;
23
24// Member of Vp8FrameHeader and will be 0-initialized
25// in Vp8FrameHeader's constructor.
Gil Dekelbf308632019-05-28 22:24:1726struct Vp8SegmentationHeader {
posciak3e644c792015-01-11 03:45:0627 enum SegmentFeatureMode { FEATURE_MODE_DELTA = 0, FEATURE_MODE_ABSOLUTE = 1 };
28
29 bool segmentation_enabled;
30 bool update_mb_segmentation_map;
31 bool update_segment_feature_data;
32 SegmentFeatureMode segment_feature_mode;
33
34 int8_t quantizer_update_value[kMaxMBSegments];
35 int8_t lf_update_value[kMaxMBSegments];
36 static const int kDefaultSegmentProb = 255;
37 uint8_t segment_prob[kNumMBFeatureTreeProbs];
38};
39
40const size_t kNumBlockContexts = 4;
41
42// Member of Vp8FrameHeader and will be 0-initialized
43// in Vp8FrameHeader's constructor.
Gil Dekelbf308632019-05-28 22:24:1744struct Vp8LoopFilterHeader {
posciak3e644c792015-01-11 03:45:0645 enum Type { LOOP_FILTER_TYPE_NORMAL = 0, LOOP_FILTER_TYPE_SIMPLE = 1 };
46 Type type;
47 uint8_t level;
48 uint8_t sharpness_level;
49 bool loop_filter_adj_enable;
50 bool mode_ref_lf_delta_update;
51
52 int8_t ref_frame_delta[kNumBlockContexts];
53 int8_t mb_mode_delta[kNumBlockContexts];
54};
55
56// Member of Vp8FrameHeader and will be 0-initialized
57// in Vp8FrameHeader's constructor.
Gil Dekelbf308632019-05-28 22:24:1758struct Vp8QuantizationHeader {
posciak3e644c792015-01-11 03:45:0659 uint8_t y_ac_qi;
60 int8_t y_dc_delta;
61 int8_t y2_dc_delta;
62 int8_t y2_ac_delta;
63 int8_t uv_dc_delta;
64 int8_t uv_ac_delta;
65};
66
67const size_t kNumBlockTypes = 4;
68const size_t kNumCoeffBands = 8;
69const size_t kNumPrevCoeffContexts = 3;
70const size_t kNumEntropyNodes = 11;
71
72const size_t kNumMVContexts = 2;
73const size_t kNumMVProbs = 19;
74
75const size_t kNumYModeProbs = 4;
76const size_t kNumUVModeProbs = 3;
77
78// Member of Vp8FrameHeader and will be 0-initialized
79// in Vp8FrameHeader's constructor.
80struct Vp8EntropyHeader {
81 uint8_t coeff_probs[kNumBlockTypes][kNumCoeffBands][kNumPrevCoeffContexts]
82 [kNumEntropyNodes];
83
84 uint8_t y_mode_probs[kNumYModeProbs];
85 uint8_t uv_mode_probs[kNumUVModeProbs];
86
87 uint8_t mv_probs[kNumMVContexts][kNumMVProbs];
88};
89
90const size_t kMaxDCTPartitions = 8;
Pawel Osciak13de15a2018-05-21 05:48:2591const size_t kNumVp8ReferenceBuffers = 3;
92
93enum Vp8RefType : size_t {
94 VP8_FRAME_LAST = 0,
95 VP8_FRAME_GOLDEN = 1,
96 VP8_FRAME_ALTREF = 2,
97};
posciak3e644c792015-01-11 03:45:0698
Gil Dekelbf308632019-05-28 22:24:1799struct MEDIA_PARSERS_EXPORT Vp8FrameHeader {
posciak3e644c792015-01-11 03:45:06100 Vp8FrameHeader();
101
102 enum FrameType { KEYFRAME = 0, INTERFRAME = 1 };
Pawel Osciak13de15a2018-05-21 05:48:25103 bool IsKeyframe() const { return frame_type == KEYFRAME; }
posciak3e644c792015-01-11 03:45:06104
105 enum GoldenRefreshMode {
Pawel Osciak13de15a2018-05-21 05:48:25106 NO_GOLDEN_REFRESH = 0,
posciaka86e8af2015-01-15 14:06:00107 COPY_LAST_TO_GOLDEN = 1,
108 COPY_ALT_TO_GOLDEN = 2,
posciak3e644c792015-01-11 03:45:06109 };
110
111 enum AltRefreshMode {
Pawel Osciak13de15a2018-05-21 05:48:25112 NO_ALT_REFRESH = 0,
posciaka86e8af2015-01-15 14:06:00113 COPY_LAST_TO_ALT = 1,
114 COPY_GOLDEN_TO_ALT = 2,
posciak3e644c792015-01-11 03:45:06115 };
116
Pawel Osciak13de15a2018-05-21 05:48:25117 FrameType frame_type;
posciak3e644c792015-01-11 03:45:06118 uint8_t version;
119 bool is_experimental;
120 bool show_frame;
121 size_t first_part_size;
122
123 uint16_t width;
124 uint8_t horizontal_scale;
125 uint16_t height;
126 uint8_t vertical_scale;
127
128 Vp8SegmentationHeader segmentation_hdr;
129 Vp8LoopFilterHeader loopfilter_hdr;
130 Vp8QuantizationHeader quantization_hdr;
131
132 size_t num_of_dct_partitions;
133
134 Vp8EntropyHeader entropy_hdr;
135
136 bool refresh_entropy_probs;
137 bool refresh_golden_frame;
138 bool refresh_alternate_frame;
139 GoldenRefreshMode copy_buffer_to_golden;
140 AltRefreshMode copy_buffer_to_alternate;
141 uint8_t sign_bias_golden;
142 uint8_t sign_bias_alternate;
143 bool refresh_last;
144
145 bool mb_no_skip_coeff;
146 uint8_t prob_skip_false;
147 uint8_t prob_intra;
148 uint8_t prob_last;
149 uint8_t prob_gf;
150
151 const uint8_t* data;
152 size_t frame_size;
153
154 size_t dct_partition_sizes[kMaxDCTPartitions];
155 // Offset in bytes from data.
156 off_t first_part_offset;
157 // Offset in bits from first_part_offset.
158 off_t macroblock_bit_offset;
159
160 // Bool decoder state
161 uint8_t bool_dec_range;
162 uint8_t bool_dec_value;
163 uint8_t bool_dec_count;
164};
165
166// A parser for raw VP8 streams as specified in RFC 6386.
Gil Dekelbf308632019-05-28 22:24:17167class MEDIA_PARSERS_EXPORT Vp8Parser {
posciak3e644c792015-01-11 03:45:06168 public:
169 Vp8Parser();
170 ~Vp8Parser();
171
172 // Try to parse exactly one VP8 frame starting at |ptr| and of size |size|,
173 // filling the parsed data in |fhdr|. Return true on success.
174 // Size has to be exactly the size of the frame and coming from the caller,
175 // who needs to acquire it from elsewhere (normally from a container).
176 bool ParseFrame(const uint8_t* ptr, size_t size, Vp8FrameHeader* fhdr);
177
178 private:
179 bool ParseFrameTag(Vp8FrameHeader* fhdr);
180 bool ParseFrameHeader(Vp8FrameHeader* fhdr);
181
182 bool ParseSegmentationHeader(bool keyframe);
183 bool ParseLoopFilterHeader(bool keyframe);
184 bool ParseQuantizationHeader(Vp8QuantizationHeader* qhdr);
185 bool ParseTokenProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
posciake8812c62015-05-06 05:42:17186 bool ParseIntraProbs(Vp8EntropyHeader* ehdr,
187 bool update_curr_probs,
188 bool keyframe);
posciak3e644c792015-01-11 03:45:06189 bool ParseMVProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
190 bool ParsePartitions(Vp8FrameHeader* fhdr);
posciake8812c62015-05-06 05:42:17191 void ResetProbs();
posciak3e644c792015-01-11 03:45:06192
193 // These persist across calls to ParseFrame() and may be used and/or updated
194 // for subsequent frames if the stream instructs us to do so.
195 Vp8SegmentationHeader curr_segmentation_hdr_;
196 Vp8LoopFilterHeader curr_loopfilter_hdr_;
197 Vp8EntropyHeader curr_entropy_hdr_;
198
199 const uint8_t* stream_;
200 size_t bytes_left_;
201 Vp8BoolDecoder bd_;
202
203 DISALLOW_COPY_AND_ASSIGN(Vp8Parser);
204};
205
206} // namespace media
207
Gil Dekelbf308632019-05-28 22:24:17208#endif // MEDIA_PARSERS_VP8_PARSER_H_