|
Packit |
1244b8 |
/*
|
|
Packit |
1244b8 |
* Copyright 2015 The Chromium Authors. All rights reserved.
|
|
Packit |
1244b8 |
* Copyright 2016 Intel Corporation. All rights reserved.
|
|
Packit |
1244b8 |
*
|
|
Packit |
1244b8 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
1244b8 |
* modification, are permitted provided that the following conditions are
|
|
Packit |
1244b8 |
* met:
|
|
Packit |
1244b8 |
*
|
|
Packit |
1244b8 |
* * Redistributions of source code must retain the above copyright
|
|
Packit |
1244b8 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
1244b8 |
*
|
|
Packit |
1244b8 |
* * Redistributions in binary form must reproduce the above copyright
|
|
Packit |
1244b8 |
* notice, this list of conditions and the following disclaimer in
|
|
Packit |
1244b8 |
* the documentation and/or other materials provided with the
|
|
Packit |
1244b8 |
* distribution.
|
|
Packit |
1244b8 |
*
|
|
Packit |
1244b8 |
* * Neither the name of Google, nor the WebM Project, nor the names
|
|
Packit |
1244b8 |
* of its contributors may be used to endorse or promote products
|
|
Packit |
1244b8 |
* derived from this software without specific prior written
|
|
Packit |
1244b8 |
* permission.
|
|
Packit |
1244b8 |
*
|
|
Packit |
1244b8 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
1244b8 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
1244b8 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
1244b8 |
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
1244b8 |
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
1244b8 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
1244b8 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
1244b8 |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
1244b8 |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
1244b8 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
1244b8 |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
1244b8 |
*/
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
//
|
|
Packit |
1244b8 |
// This file contains an implementation of a VP8 raw stream parser,
|
|
Packit |
1244b8 |
// as defined in RFC 6386.
|
|
Packit |
1244b8 |
// This is taken from Chromium Project and adapted to use within libyami
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
#ifndef VP8_PARSER_H_
|
|
Packit |
1244b8 |
#define VP8_PARSER_H_
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
#include "common/NonCopyable.h"
|
|
Packit |
1244b8 |
#include "VideoCommonDefs.h"
|
|
Packit |
1244b8 |
#include <stdio.h>
|
|
Packit |
1244b8 |
#include <string.h>
|
|
Packit |
1244b8 |
#include "vp8_bool_decoder.h"
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
#define CHECK_GE(X, Y) assert(X >= Y)
|
|
Packit |
1244b8 |
#define CHECK_LE(X, Y) assert(X <= Y)
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
namespace YamiParser {
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// See spec for definitions of values/fields.
|
|
Packit |
1244b8 |
const size_t kMaxMBSegments = 4;
|
|
Packit |
1244b8 |
const size_t kNumMBFeatureTreeProbs = 3;
|
|
Packit |
1244b8 |
enum Vp8ParserResult {
|
|
Packit |
1244b8 |
VP8_PARSER_OK = 0,
|
|
Packit |
1244b8 |
VP8_PARSER_BROKEN_DATA,
|
|
Packit |
1244b8 |
VP8_PARSER_ERROR,
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// Member of Vp8FrameHeader and will be 0-initialized
|
|
Packit |
1244b8 |
// in Vp8FrameHeader's constructor.
|
|
Packit |
1244b8 |
struct Vp8SegmentationHeader {
|
|
Packit |
1244b8 |
enum SegmentFeatureMode { FEATURE_MODE_DELTA = 0, FEATURE_MODE_ABSOLUTE = 1 };
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
bool segmentation_enabled;
|
|
Packit |
1244b8 |
bool update_mb_segmentation_map;
|
|
Packit |
1244b8 |
bool update_segment_feature_data;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
int8_t quantizer_update_value[kMaxMBSegments];
|
|
Packit |
1244b8 |
int8_t lf_update_value[kMaxMBSegments];
|
|
Packit |
1244b8 |
static const int kDefaultSegmentProb = 255;
|
|
Packit |
1244b8 |
uint8_t segment_prob[kNumMBFeatureTreeProbs];
|
|
Packit |
1244b8 |
SegmentFeatureMode segment_feature_mode;
|
|
Packit |
1244b8 |
//Because these variables is non pod type, it can not use memset and use offsetof to weed out it
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
const size_t kNumBlockContexts = 4;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// Member of Vp8FrameHeader and will be 0-initialized
|
|
Packit |
1244b8 |
// in Vp8FrameHeader's constructor.
|
|
Packit |
1244b8 |
struct Vp8LoopFilterHeader {
|
|
Packit |
1244b8 |
enum Type { LOOP_FILTER_TYPE_NORMAL = 0, LOOP_FILTER_TYPE_SIMPLE = 1 };
|
|
Packit |
1244b8 |
uint8_t level;
|
|
Packit |
1244b8 |
uint8_t sharpness_level;
|
|
Packit |
1244b8 |
bool loop_filter_adj_enable;
|
|
Packit |
1244b8 |
bool mode_ref_lf_delta_update;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
int8_t ref_frame_delta[kNumBlockContexts];
|
|
Packit |
1244b8 |
int8_t mb_mode_delta[kNumBlockContexts];
|
|
Packit |
1244b8 |
Type type;
|
|
Packit |
1244b8 |
//Because these variables is non pod type, it can not use memset and use offsetof to weed out it
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// Member of Vp8FrameHeader and will be 0-initialized
|
|
Packit |
1244b8 |
// in Vp8FrameHeader's constructor.
|
|
Packit |
1244b8 |
struct Vp8QuantizationHeader {
|
|
Packit |
1244b8 |
uint8_t y_ac_qi;
|
|
Packit |
1244b8 |
int8_t y_dc_delta;
|
|
Packit |
1244b8 |
int8_t y2_dc_delta;
|
|
Packit |
1244b8 |
int8_t y2_ac_delta;
|
|
Packit |
1244b8 |
int8_t uv_dc_delta;
|
|
Packit |
1244b8 |
int8_t uv_ac_delta;
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
const size_t kNumBlockTypes = 4;
|
|
Packit |
1244b8 |
const size_t kNumCoeffBands = 8;
|
|
Packit |
1244b8 |
const size_t kNumPrevCoeffContexts = 3;
|
|
Packit |
1244b8 |
const size_t kNumEntropyNodes = 11;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
const size_t kNumMVContexts = 2;
|
|
Packit |
1244b8 |
const size_t kNumMVProbs = 19;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
const size_t kNumYModeProbs = 4;
|
|
Packit |
1244b8 |
const size_t kNumUVModeProbs = 3;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// Member of Vp8FrameHeader and will be 0-initialized
|
|
Packit |
1244b8 |
// in Vp8FrameHeader's constructor.
|
|
Packit |
1244b8 |
struct Vp8EntropyHeader {
|
|
Packit |
1244b8 |
uint8_t coeff_probs[kNumBlockTypes][kNumCoeffBands][kNumPrevCoeffContexts]
|
|
Packit |
1244b8 |
[kNumEntropyNodes];
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
uint8_t y_mode_probs[kNumYModeProbs];
|
|
Packit |
1244b8 |
uint8_t uv_mode_probs[kNumUVModeProbs];
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
uint8_t mv_probs[kNumMVContexts][kNumMVProbs];
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
const size_t kMaxDCTPartitions = 8;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
struct Vp8FrameHeader {
|
|
Packit |
1244b8 |
Vp8FrameHeader();
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
enum FrameType { KEYFRAME = 0, INTERFRAME = 1 };
|
|
Packit |
1244b8 |
bool IsKeyframe() const { return key_frame == KEYFRAME; }
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
enum GoldenRefreshMode {
|
|
Packit |
1244b8 |
COPY_LAST_TO_GOLDEN = 1,
|
|
Packit |
1244b8 |
COPY_ALT_TO_GOLDEN = 2,
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
enum AltRefreshMode {
|
|
Packit |
1244b8 |
COPY_LAST_TO_ALT = 1,
|
|
Packit |
1244b8 |
COPY_GOLDEN_TO_ALT = 2,
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
FrameType key_frame;
|
|
Packit |
1244b8 |
uint8_t version;
|
|
Packit |
1244b8 |
bool is_experimental;
|
|
Packit |
1244b8 |
bool show_frame;
|
|
Packit |
1244b8 |
size_t first_part_size;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
uint16_t width;
|
|
Packit |
1244b8 |
uint8_t horizontal_scale;
|
|
Packit |
1244b8 |
uint16_t height;
|
|
Packit |
1244b8 |
uint8_t vertical_scale;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
Vp8SegmentationHeader segmentation_hdr;
|
|
Packit |
1244b8 |
Vp8LoopFilterHeader loopfilter_hdr;
|
|
Packit |
1244b8 |
Vp8QuantizationHeader quantization_hdr;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
size_t num_of_dct_partitions;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
Vp8EntropyHeader entropy_hdr;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
bool refresh_entropy_probs;
|
|
Packit |
1244b8 |
bool refresh_golden_frame;
|
|
Packit |
1244b8 |
bool refresh_alternate_frame;
|
|
Packit |
1244b8 |
GoldenRefreshMode copy_buffer_to_golden;
|
|
Packit |
1244b8 |
AltRefreshMode copy_buffer_to_alternate;
|
|
Packit |
1244b8 |
uint8_t sign_bias_golden;
|
|
Packit |
1244b8 |
uint8_t sign_bias_alternate;
|
|
Packit |
1244b8 |
bool refresh_last;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
bool mb_no_skip_coeff;
|
|
Packit |
1244b8 |
uint8_t prob_skip_false;
|
|
Packit |
1244b8 |
uint8_t prob_intra;
|
|
Packit |
1244b8 |
uint8_t prob_last;
|
|
Packit |
1244b8 |
uint8_t prob_gf;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
const uint8_t* data;
|
|
Packit |
1244b8 |
size_t frame_size;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
size_t dct_partition_sizes[kMaxDCTPartitions];
|
|
Packit |
1244b8 |
// Offset in bytes from data.
|
|
Packit |
1244b8 |
off_t first_part_offset;
|
|
Packit |
1244b8 |
// Offset in bits from first_part_offset.
|
|
Packit |
1244b8 |
off_t macroblock_bit_offset;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// Bool decoder state
|
|
Packit |
1244b8 |
uint8_t bool_dec_range;
|
|
Packit |
1244b8 |
uint8_t bool_dec_value;
|
|
Packit |
1244b8 |
uint8_t bool_dec_count;
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// A parser for raw VP8 streams as specified in RFC 6386.
|
|
Packit |
1244b8 |
class Vp8Parser {
|
|
Packit |
1244b8 |
public:
|
|
Packit |
1244b8 |
Vp8Parser();
|
|
Packit |
1244b8 |
~Vp8Parser();
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// Try to parse exactly one VP8 frame starting at |ptr| and of size |size|,
|
|
Packit |
1244b8 |
// filling the parsed data in |fhdr|. Return true on success.
|
|
Packit |
1244b8 |
// Size has to be exactly the size of the frame and coming from the caller,
|
|
Packit |
1244b8 |
// who needs to acquire it from elsewhere (normally from a container).
|
|
Packit |
1244b8 |
Vp8ParserResult ParseFrame(const uint8_t* ptr, size_t size, Vp8FrameHeader* fhdr);
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
private:
|
|
Packit |
1244b8 |
friend class Vp8ParserTest;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
bool ParseFrameTag(Vp8FrameHeader* fhdr);
|
|
Packit |
1244b8 |
bool ParseFrameHeader(Vp8FrameHeader* fhdr);
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
bool ParseSegmentationHeader(bool keyframe);
|
|
Packit |
1244b8 |
bool ParseLoopFilterHeader(bool keyframe);
|
|
Packit |
1244b8 |
bool ParseQuantizationHeader(Vp8QuantizationHeader* qhdr);
|
|
Packit |
1244b8 |
bool ParseTokenProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
|
|
Packit |
1244b8 |
bool ParseIntraProbs(Vp8EntropyHeader* ehdr,
|
|
Packit |
1244b8 |
bool update_curr_probs,
|
|
Packit |
1244b8 |
bool keyframe);
|
|
Packit |
1244b8 |
bool ParseMVProbs(Vp8EntropyHeader* ehdr, bool update_curr_probs);
|
|
Packit |
1244b8 |
bool ParsePartitions(Vp8FrameHeader* fhdr);
|
|
Packit |
1244b8 |
void ResetProbs();
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
// These persist across calls to ParseFrame() and may be used and/or updated
|
|
Packit |
1244b8 |
// for subsequent frames if the stream instructs us to do so.
|
|
Packit |
1244b8 |
Vp8SegmentationHeader curr_segmentation_hdr_;
|
|
Packit |
1244b8 |
Vp8LoopFilterHeader curr_loopfilter_hdr_;
|
|
Packit |
1244b8 |
Vp8EntropyHeader curr_entropy_hdr_;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
const uint8_t* stream_;
|
|
Packit |
1244b8 |
size_t bytes_left_;
|
|
Packit |
1244b8 |
Vp8BoolDecoder bd_;
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
DISALLOW_COPY_AND_ASSIGN(Vp8Parser);
|
|
Packit |
1244b8 |
};
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
} // namespace YamiParser
|
|
Packit |
1244b8 |
|
|
Packit |
1244b8 |
#endif // MEDIA_FILTERS_VP8_PARSER_H_
|