Home | History | Annotate | Download | only in vda
      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 };
     96   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