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