• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 // Note: ported from Chromium commit head: 1323b9c
8 
9 #ifndef VP8_PARSER_H_
10 #define VP8_PARSER_H_
11 
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #include "base/macros.h"
16 #include "vp8_bool_decoder.h"
17 
18 namespace media {
19 
20 // See spec for definitions of values/fields.
21 const size_t kMaxMBSegments = 4;
22 const size_t kNumMBFeatureTreeProbs = 3;
23 
24 // Member of Vp8FrameHeader and will be 0-initialized
25 // in Vp8FrameHeader's constructor.
26 struct Vp8SegmentationHeader {
27   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 
40 const size_t kNumBlockContexts = 4;
41 
42 // Member of Vp8FrameHeader and will be 0-initialized
43 // in Vp8FrameHeader's constructor.
44 struct Vp8LoopFilterHeader {
45   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.
58 struct Vp8QuantizationHeader {
59   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 
67 const size_t kNumBlockTypes = 4;
68 const size_t kNumCoeffBands = 8;
69 const size_t kNumPrevCoeffContexts = 3;
70 const size_t kNumEntropyNodes = 11;
71 
72 const size_t kNumMVContexts = 2;
73 const size_t kNumMVProbs = 19;
74 
75 const size_t kNumYModeProbs = 4;
76 const size_t kNumUVModeProbs = 3;
77 
78 // Member of Vp8FrameHeader and will be 0-initialized
79 // in Vp8FrameHeader's constructor.
80 struct 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 
90 const size_t kMaxDCTPartitions = 8;
91 
92 struct Vp8FrameHeader {
93   Vp8FrameHeader();
94 
95   enum FrameType { KEYFRAME = 0, INTERFRAME = 1 };
IsKeyframeVp8FrameHeader96   bool IsKeyframe() const { return key_frame == KEYFRAME; }
97 
98   enum GoldenRefreshMode {
99     COPY_LAST_TO_GOLDEN = 1,
100     COPY_ALT_TO_GOLDEN = 2,
101   };
102 
103   enum AltRefreshMode {
104     COPY_LAST_TO_ALT = 1,
105     COPY_GOLDEN_TO_ALT = 2,
106   };
107 
108   FrameType key_frame;
109   uint8_t version;
110   bool is_experimental;
111   bool show_frame;
112   size_t first_part_size;
113 
114   uint16_t width;
115   uint8_t horizontal_scale;
116   uint16_t height;
117   uint8_t vertical_scale;
118 
119   Vp8SegmentationHeader segmentation_hdr;
120   Vp8LoopFilterHeader loopfilter_hdr;
121   Vp8QuantizationHeader quantization_hdr;
122 
123   size_t num_of_dct_partitions;
124 
125   Vp8EntropyHeader entropy_hdr;
126 
127   bool refresh_entropy_probs;
128   bool refresh_golden_frame;
129   bool refresh_alternate_frame;
130   GoldenRefreshMode copy_buffer_to_golden;
131   AltRefreshMode copy_buffer_to_alternate;
132   uint8_t sign_bias_golden;
133   uint8_t sign_bias_alternate;
134   bool refresh_last;
135 
136   bool mb_no_skip_coeff;
137   uint8_t prob_skip_false;
138   uint8_t prob_intra;
139   uint8_t prob_last;
140   uint8_t prob_gf;
141 
142   const uint8_t* data;
143   size_t frame_size;
144 
145   size_t dct_partition_sizes[kMaxDCTPartitions];
146   // Offset in bytes from data.
147   off_t first_part_offset;
148   // Offset in bits from first_part_offset.
149   off_t macroblock_bit_offset;
150 
151   // Bool decoder state
152   uint8_t bool_dec_range;
153   uint8_t bool_dec_value;
154   uint8_t bool_dec_count;
155 };
156 
157 // A parser for raw VP8 streams as specified in RFC 6386.
158 class Vp8Parser {
159  public:
160   Vp8Parser();
161   ~Vp8Parser();
162 
163   // Try to parse exactly one VP8 frame starting at |ptr| and of size |size|,
164   // filling the parsed data in |fhdr|. Return true on success.
165   // Size has to be exactly the size of the frame and coming from the caller,
166   // who needs to acquire it from elsewhere (normally from a container).
167   bool ParseFrame(const uint8_t* ptr, size_t size, Vp8FrameHeader* fhdr);
168 
169  private:
170   bool ParseFrameTag(Vp8FrameHeader* fhdr);
171   bool ParseFrameHeader(Vp8FrameHeader* fhdr);
172 
173   bool ParseSegmentationHeader(bool keyframe);
174   bool ParseLoopFilterHeader(bool keyframe);
175   bool ParseQuantizationHeader(Vp8QuantizationHeader* qhdr);
176   bool ParseTokenProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
177   bool ParseIntraProbs(Vp8EntropyHeader* ehdr,
178                        bool update_curr_probs,
179                        bool keyframe);
180   bool ParseMVProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
181   bool ParsePartitions(Vp8FrameHeader* fhdr);
182   void ResetProbs();
183 
184   // These persist across calls to ParseFrame() and may be used and/or updated
185   // for subsequent frames if the stream instructs us to do so.
186   Vp8SegmentationHeader curr_segmentation_hdr_;
187   Vp8LoopFilterHeader curr_loopfilter_hdr_;
188   Vp8EntropyHeader curr_entropy_hdr_;
189 
190   const uint8_t* stream_;
191   size_t bytes_left_;
192   Vp8BoolDecoder bd_;
193 
194   DISALLOW_COPY_AND_ASSIGN(Vp8Parser);
195 };
196 
197 }  // namespace media
198 
199 #endif  // VP8_PARSER_H_
200