File: vp8_parser.h

package info (click to toggle)
libyami 1.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,152 kB
  • sloc: cpp: 44,247; ansic: 1,255; makefile: 728; lisp: 479; sh: 21; python: 19
file content (242 lines) | stat: -rw-r--r-- 7,467 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
 * Copyright 2015 The Chromium Authors. All rights reserved.
 * Copyright 2016 Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *   * Neither the name of Google, nor the WebM Project, nor the names
 *     of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written
 *     permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

//
// This file contains an implementation of a VP8 raw stream parser,
// as defined in RFC 6386.
// This is taken from Chromium Project and adapted to use within libyami

#ifndef VP8_PARSER_H_
#define VP8_PARSER_H_

#include "common/NonCopyable.h"
#include "VideoCommonDefs.h"
#include <stdio.h>
#include <string.h>
#include "vp8_bool_decoder.h"

#define CHECK_GE(X, Y) assert(X >= Y)
#define CHECK_LE(X, Y) assert(X <= Y)

namespace YamiParser {

// See spec for definitions of values/fields.
const size_t kMaxMBSegments = 4;
const size_t kNumMBFeatureTreeProbs = 3;
enum Vp8ParserResult {
  VP8_PARSER_OK = 0,
  VP8_PARSER_BROKEN_DATA,
  VP8_PARSER_ERROR,
};

// Member of Vp8FrameHeader and will be 0-initialized
// in Vp8FrameHeader's constructor.
struct Vp8SegmentationHeader {
  enum SegmentFeatureMode { FEATURE_MODE_DELTA = 0, FEATURE_MODE_ABSOLUTE = 1 };

  bool segmentation_enabled;
  bool update_mb_segmentation_map;
  bool update_segment_feature_data;

  int8_t quantizer_update_value[kMaxMBSegments];
  int8_t lf_update_value[kMaxMBSegments];
  static const int kDefaultSegmentProb = 255;
  uint8_t segment_prob[kNumMBFeatureTreeProbs];
  SegmentFeatureMode segment_feature_mode;
  //Because these variables is non pod type, it can not use memset and use offsetof to weed out it
};

const size_t kNumBlockContexts = 4;

// Member of Vp8FrameHeader and will be 0-initialized
// in Vp8FrameHeader's constructor.
struct Vp8LoopFilterHeader {
  enum Type { LOOP_FILTER_TYPE_NORMAL = 0, LOOP_FILTER_TYPE_SIMPLE = 1 };
  uint8_t level;
  uint8_t sharpness_level;
  bool loop_filter_adj_enable;
  bool mode_ref_lf_delta_update;

  int8_t ref_frame_delta[kNumBlockContexts];
  int8_t mb_mode_delta[kNumBlockContexts];
  Type type;
  //Because these variables is non pod type, it can not use memset and use offsetof to weed out it
};

// Member of Vp8FrameHeader and will be 0-initialized
// in Vp8FrameHeader's constructor.
struct Vp8QuantizationHeader {
  uint8_t y_ac_qi;
  int8_t y_dc_delta;
  int8_t y2_dc_delta;
  int8_t y2_ac_delta;
  int8_t uv_dc_delta;
  int8_t uv_ac_delta;
};

const size_t kNumBlockTypes = 4;
const size_t kNumCoeffBands = 8;
const size_t kNumPrevCoeffContexts = 3;
const size_t kNumEntropyNodes = 11;

const size_t kNumMVContexts = 2;
const size_t kNumMVProbs = 19;

const size_t kNumYModeProbs = 4;
const size_t kNumUVModeProbs = 3;

// Member of Vp8FrameHeader and will be 0-initialized
// in Vp8FrameHeader's constructor.
struct Vp8EntropyHeader {
  uint8_t coeff_probs[kNumBlockTypes][kNumCoeffBands][kNumPrevCoeffContexts]
                     [kNumEntropyNodes];

  uint8_t y_mode_probs[kNumYModeProbs];
  uint8_t uv_mode_probs[kNumUVModeProbs];

  uint8_t mv_probs[kNumMVContexts][kNumMVProbs];
};

const size_t kMaxDCTPartitions = 8;

struct Vp8FrameHeader {
  Vp8FrameHeader();

  enum FrameType { KEYFRAME = 0, INTERFRAME = 1 };
  bool IsKeyframe() const { return key_frame == KEYFRAME; }

  enum GoldenRefreshMode {
    COPY_LAST_TO_GOLDEN = 1,
    COPY_ALT_TO_GOLDEN = 2,
  };

  enum AltRefreshMode {
    COPY_LAST_TO_ALT = 1,
    COPY_GOLDEN_TO_ALT = 2,
  };

  FrameType key_frame;
  uint8_t version;
  bool is_experimental;
  bool show_frame;
  size_t first_part_size;

  uint16_t width;
  uint8_t horizontal_scale;
  uint16_t height;
  uint8_t vertical_scale;

  Vp8SegmentationHeader segmentation_hdr;
  Vp8LoopFilterHeader loopfilter_hdr;
  Vp8QuantizationHeader quantization_hdr;

  size_t num_of_dct_partitions;

  Vp8EntropyHeader entropy_hdr;

  bool refresh_entropy_probs;
  bool refresh_golden_frame;
  bool refresh_alternate_frame;
  GoldenRefreshMode copy_buffer_to_golden;
  AltRefreshMode copy_buffer_to_alternate;
  uint8_t sign_bias_golden;
  uint8_t sign_bias_alternate;
  bool refresh_last;

  bool mb_no_skip_coeff;
  uint8_t prob_skip_false;
  uint8_t prob_intra;
  uint8_t prob_last;
  uint8_t prob_gf;

  const uint8_t* data;
  size_t frame_size;

  size_t dct_partition_sizes[kMaxDCTPartitions];
  // Offset in bytes from data.
  off_t first_part_offset;
  // Offset in bits from first_part_offset.
  off_t macroblock_bit_offset;

  // Bool decoder state
  uint8_t bool_dec_range;
  uint8_t bool_dec_value;
  uint8_t bool_dec_count;
};

// A parser for raw VP8 streams as specified in RFC 6386.
class Vp8Parser {
 public:
  Vp8Parser();
  ~Vp8Parser();

  // Try to parse exactly one VP8 frame starting at |ptr| and of size |size|,
  // filling the parsed data in |fhdr|. Return true on success.
  // Size has to be exactly the size of the frame and coming from the caller,
  // who needs to acquire it from elsewhere (normally from a container).
  Vp8ParserResult ParseFrame(const uint8_t* ptr, size_t size, Vp8FrameHeader* fhdr);

 private:
  friend class Vp8ParserTest;

  bool ParseFrameTag(Vp8FrameHeader* fhdr);
  bool ParseFrameHeader(Vp8FrameHeader* fhdr);

  bool ParseSegmentationHeader(bool keyframe);
  bool ParseLoopFilterHeader(bool keyframe);
  bool ParseQuantizationHeader(Vp8QuantizationHeader* qhdr);
  bool ParseTokenProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
  bool ParseIntraProbs(Vp8EntropyHeader* ehdr,
                       bool update_curr_probs,
                       bool keyframe);
  bool ParseMVProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
  bool ParsePartitions(Vp8FrameHeader* fhdr);
  void ResetProbs();

  // These persist across calls to ParseFrame() and may be used and/or updated
  // for subsequent frames if the stream instructs us to do so.
  Vp8SegmentationHeader curr_segmentation_hdr_;
  Vp8LoopFilterHeader curr_loopfilter_hdr_;
  Vp8EntropyHeader curr_entropy_hdr_;

  const uint8_t* stream_;
  size_t bytes_left_;
  Vp8BoolDecoder bd_;

  DISALLOW_COPY_AND_ASSIGN(Vp8Parser);
};

}  // namespace YamiParser

#endif  // MEDIA_FILTERS_VP8_PARSER_H_