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 8 #ifndef VP8_PARSER_H_ 9 #define VP8_PARSER_H_ 10 11 #include <stddef.h> 12 #include <stdint.h> 13 14 #include "base/macros.h" 15 #include "vp8_bool_decoder.h" 16 17 namespace media { 18 19 // See spec for definitions of values/fields. 20 const size_t kMaxMBSegments = 4; 21 const size_t kNumMBFeatureTreeProbs = 3; 22 23 // Member of Vp8FrameHeader and will be 0-initialized 24 // in Vp8FrameHeader's constructor. 25 struct Vp8SegmentationHeader { 26 enum SegmentFeatureMode { FEATURE_MODE_DELTA = 0, FEATURE_MODE_ABSOLUTE = 1 }; 27 28 bool segmentation_enabled; 29 bool update_mb_segmentation_map; 30 bool update_segment_feature_data; 31 SegmentFeatureMode segment_feature_mode; 32 33 int8_t quantizer_update_value[kMaxMBSegments]; 34 int8_t lf_update_value[kMaxMBSegments]; 35 static const int kDefaultSegmentProb = 255; 36 uint8_t segment_prob[kNumMBFeatureTreeProbs]; 37 }; 38 39 const size_t kNumBlockContexts = 4; 40 41 // Member of Vp8FrameHeader and will be 0-initialized 42 // in Vp8FrameHeader's constructor. 43 struct Vp8LoopFilterHeader { 44 enum Type { LOOP_FILTER_TYPE_NORMAL = 0, LOOP_FILTER_TYPE_SIMPLE = 1 }; 45 Type type; 46 uint8_t level; 47 uint8_t sharpness_level; 48 bool loop_filter_adj_enable; 49 bool mode_ref_lf_delta_update; 50 51 int8_t ref_frame_delta[kNumBlockContexts]; 52 int8_t mb_mode_delta[kNumBlockContexts]; 53 }; 54 55 // Member of Vp8FrameHeader and will be 0-initialized 56 // in Vp8FrameHeader's constructor. 57 struct Vp8QuantizationHeader { 58 uint8_t y_ac_qi; 59 int8_t y_dc_delta; 60 int8_t y2_dc_delta; 61 int8_t y2_ac_delta; 62 int8_t uv_dc_delta; 63 int8_t uv_ac_delta; 64 }; 65 66 const size_t kNumBlockTypes = 4; 67 const size_t kNumCoeffBands = 8; 68 const size_t kNumPrevCoeffContexts = 3; 69 const size_t kNumEntropyNodes = 11; 70 71 const size_t kNumMVContexts = 2; 72 const size_t kNumMVProbs = 19; 73 74 const size_t kNumYModeProbs = 4; 75 const size_t kNumUVModeProbs = 3; 76 77 // Member of Vp8FrameHeader and will be 0-initialized 78 // in Vp8FrameHeader's constructor. 79 struct Vp8EntropyHeader { 80 uint8_t coeff_probs[kNumBlockTypes][kNumCoeffBands][kNumPrevCoeffContexts] 81 [kNumEntropyNodes]; 82 83 uint8_t y_mode_probs[kNumYModeProbs]; 84 uint8_t uv_mode_probs[kNumUVModeProbs]; 85 86 uint8_t mv_probs[kNumMVContexts][kNumMVProbs]; 87 }; 88 89 const size_t kMaxDCTPartitions = 8; 90 91 struct Vp8FrameHeader { 92 Vp8FrameHeader(); 93 94 enum FrameType { KEYFRAME = 0, INTERFRAME = 1 }; IsKeyframeVp8FrameHeader95 bool IsKeyframe() const { return key_frame == KEYFRAME; } 96 97 enum GoldenRefreshMode { 98 COPY_LAST_TO_GOLDEN = 1, 99 COPY_ALT_TO_GOLDEN = 2, 100 }; 101 102 enum AltRefreshMode { 103 COPY_LAST_TO_ALT = 1, 104 COPY_GOLDEN_TO_ALT = 2, 105 }; 106 107 FrameType key_frame; 108 uint8_t version; 109 bool is_experimental; 110 bool show_frame; 111 size_t first_part_size; 112 113 uint16_t width; 114 uint8_t horizontal_scale; 115 uint16_t height; 116 uint8_t vertical_scale; 117 118 Vp8SegmentationHeader segmentation_hdr; 119 Vp8LoopFilterHeader loopfilter_hdr; 120 Vp8QuantizationHeader quantization_hdr; 121 122 size_t num_of_dct_partitions; 123 124 Vp8EntropyHeader entropy_hdr; 125 126 bool refresh_entropy_probs; 127 bool refresh_golden_frame; 128 bool refresh_alternate_frame; 129 GoldenRefreshMode copy_buffer_to_golden; 130 AltRefreshMode copy_buffer_to_alternate; 131 uint8_t sign_bias_golden; 132 uint8_t sign_bias_alternate; 133 bool refresh_last; 134 135 bool mb_no_skip_coeff; 136 uint8_t prob_skip_false; 137 uint8_t prob_intra; 138 uint8_t prob_last; 139 uint8_t prob_gf; 140 141 const uint8_t* data; 142 size_t frame_size; 143 144 size_t dct_partition_sizes[kMaxDCTPartitions]; 145 // Offset in bytes from data. 146 off_t first_part_offset; 147 // Offset in bits from first_part_offset. 148 off_t macroblock_bit_offset; 149 150 // Bool decoder state 151 uint8_t bool_dec_range; 152 uint8_t bool_dec_value; 153 uint8_t bool_dec_count; 154 }; 155 156 // A parser for raw VP8 streams as specified in RFC 6386. 157 class Vp8Parser { 158 public: 159 Vp8Parser(); 160 ~Vp8Parser(); 161 162 // Try to parse exactly one VP8 frame starting at |ptr| and of size |size|, 163 // filling the parsed data in |fhdr|. Return true on success. 164 // Size has to be exactly the size of the frame and coming from the caller, 165 // who needs to acquire it from elsewhere (normally from a container). 166 bool ParseFrame(const uint8_t* ptr, size_t size, Vp8FrameHeader* fhdr); 167 168 private: 169 bool ParseFrameTag(Vp8FrameHeader* fhdr); 170 bool ParseFrameHeader(Vp8FrameHeader* fhdr); 171 172 bool ParseSegmentationHeader(bool keyframe); 173 bool ParseLoopFilterHeader(bool keyframe); 174 bool ParseQuantizationHeader(Vp8QuantizationHeader* qhdr); 175 bool ParseTokenProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs); 176 bool ParseIntraProbs(Vp8EntropyHeader* ehdr, 177 bool update_curr_probs, 178 bool keyframe); 179 bool ParseMVProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs); 180 bool ParsePartitions(Vp8FrameHeader* fhdr); 181 void ResetProbs(); 182 183 // These persist across calls to ParseFrame() and may be used and/or updated 184 // for subsequent frames if the stream instructs us to do so. 185 Vp8SegmentationHeader curr_segmentation_hdr_; 186 Vp8LoopFilterHeader curr_loopfilter_hdr_; 187 Vp8EntropyHeader curr_entropy_hdr_; 188 189 const uint8_t* stream_; 190 size_t bytes_left_; 191 Vp8BoolDecoder bd_; 192 193 DISALLOW_COPY_AND_ASSIGN(Vp8Parser); 194 }; 195 196 } // namespace media 197 198 #endif // VP8_PARSER_H_ 199