| Index: media/filters/vp9_parser.h
|
| diff --git a/media/filters/vp9_parser.h b/media/filters/vp9_parser.h
|
| index 4d430494170f48dae739febfd283fee09750f50b..acb88d7e76a443cfc12ac6ff20238ecc1699fd53 100644
|
| --- a/media/filters/vp9_parser.h
|
| +++ b/media/filters/vp9_parser.h
|
| @@ -18,9 +18,10 @@
|
|
|
| #include <deque>
|
|
|
| +#include "base/callback.h"
|
| #include "base/macros.h"
|
| +#include "base/memory/weak_ptr.h"
|
| #include "media/base/media_export.h"
|
| -#include "media/filters/vp9_raw_bits_reader.h"
|
|
|
| namespace media {
|
|
|
| @@ -29,6 +30,9 @@ const int kVp9NumRefFramesLog2 = 3;
|
| const size_t kVp9NumRefFrames = 1 << kVp9NumRefFramesLog2;
|
| const uint8_t kVp9MaxProb = 255;
|
| const size_t kVp9NumRefsPerFrame = 3;
|
| +const size_t kVp9NumFrameContexts = 4;
|
| +
|
| +using Vp9Prob = uint8_t;
|
|
|
| enum class Vp9ColorSpace {
|
| UNKNOWN = 0,
|
| @@ -41,15 +45,29 @@ enum class Vp9ColorSpace {
|
| SRGB = 7,
|
| };
|
|
|
| -enum Vp9InterpFilter {
|
| +enum Vp9InterpolationFilter {
|
| EIGHTTAP = 0,
|
| EIGHTTAP_SMOOTH = 1,
|
| EIGHTTAP_SHARP = 2,
|
| BILINEAR = 3,
|
| - SWICHABLE = 4,
|
| + SWITCHABLE = 4,
|
| +};
|
| +
|
| +enum Vp9RefType {
|
| + VP9_FRAME_INTRA = 0,
|
| + VP9_FRAME_LAST = 1,
|
| + VP9_FRAME_GOLDEN = 2,
|
| + VP9_FRAME_ALTREF = 3,
|
| + VP9_FRAME_MAX = 4,
|
| +};
|
| +
|
| +enum Vp9ReferenceMode {
|
| + SINGLE_REFERENCE = 0,
|
| + COMPOUND_REFERENCE = 1,
|
| + REFERENCE_MODE_SELECT = 2,
|
| };
|
|
|
| -struct MEDIA_EXPORT Vp9Segmentation {
|
| +struct MEDIA_EXPORT Vp9SegmentationParams {
|
| static const size_t kNumSegments = 8;
|
| static const size_t kNumTreeProbs = kNumSegments - 1;
|
| static const size_t kNumPredictionProbs = 3;
|
| @@ -69,7 +87,7 @@ struct MEDIA_EXPORT Vp9Segmentation {
|
| uint8_t pred_probs[kNumPredictionProbs];
|
|
|
| bool update_data;
|
| - bool abs_delta;
|
| + bool abs_or_delta_update;
|
| bool feature_enabled[kNumSegments][SEG_LVL_MAX];
|
| int16_t feature_data[kNumSegments][SEG_LVL_MAX];
|
|
|
| @@ -85,41 +103,80 @@ struct MEDIA_EXPORT Vp9Segmentation {
|
| }
|
| };
|
|
|
| -struct MEDIA_EXPORT Vp9LoopFilter {
|
| - enum Vp9FrameType {
|
| - VP9_FRAME_INTRA = 0,
|
| - VP9_FRAME_LAST = 1,
|
| - VP9_FRAME_GOLDEN = 2,
|
| - VP9_FRAME_ALTREF = 3,
|
| - VP9_FRAME_MAX = 4,
|
| - };
|
| -
|
| +struct MEDIA_EXPORT Vp9LoopFilterParams {
|
| static const size_t kNumModeDeltas = 2;
|
|
|
| - uint8_t filter_level;
|
| - uint8_t sharpness_level;
|
| + uint8_t level;
|
| + uint8_t sharpness;
|
|
|
| - bool mode_ref_delta_enabled;
|
| - bool mode_ref_delta_update;
|
| + bool delta_enabled;
|
| + bool delta_update;
|
| bool update_ref_deltas[VP9_FRAME_MAX];
|
| int8_t ref_deltas[VP9_FRAME_MAX];
|
| bool update_mode_deltas[kNumModeDeltas];
|
| int8_t mode_deltas[kNumModeDeltas];
|
|
|
| - uint8_t lvl[Vp9Segmentation::kNumSegments][VP9_FRAME_MAX][kNumModeDeltas];
|
| + // Calculated from above fields.
|
| + uint8_t lvl[Vp9SegmentationParams::kNumSegments][VP9_FRAME_MAX]
|
| + [kNumModeDeltas];
|
| };
|
|
|
| // Members of Vp9FrameHeader will be 0-initialized by Vp9Parser::ParseNextFrame.
|
| struct MEDIA_EXPORT Vp9QuantizationParams {
|
| bool IsLossless() const {
|
| - return base_qindex == 0 && y_dc_delta == 0 && uv_dc_delta == 0 &&
|
| - uv_ac_delta == 0;
|
| + return base_q_idx == 0 && delta_q_y_dc == 0 && delta_q_uv_dc == 0 &&
|
| + delta_q_uv_ac == 0;
|
| }
|
|
|
| - uint8_t base_qindex;
|
| - int8_t y_dc_delta;
|
| - int8_t uv_dc_delta;
|
| - int8_t uv_ac_delta;
|
| + uint8_t base_q_idx;
|
| + int8_t delta_q_y_dc;
|
| + int8_t delta_q_uv_dc;
|
| + int8_t delta_q_uv_ac;
|
| +};
|
| +
|
| +// Entropy context for frame parsing
|
| +struct MEDIA_EXPORT Vp9FrameContext {
|
| + Vp9Prob tx_probs_8x8[2][1];
|
| + Vp9Prob tx_probs_16x16[2][2];
|
| + Vp9Prob tx_probs_32x32[2][3];
|
| +
|
| + Vp9Prob coef_probs[4][2][2][6][6][3];
|
| + Vp9Prob skip_prob[3];
|
| + Vp9Prob inter_mode_probs[7][3];
|
| + Vp9Prob interp_filter_probs[4][2];
|
| + Vp9Prob is_inter_prob[4];
|
| +
|
| + Vp9Prob comp_mode_prob[5];
|
| + Vp9Prob single_ref_prob[5][2];
|
| + Vp9Prob comp_ref_prob[5];
|
| +
|
| + Vp9Prob y_mode_probs[4][9];
|
| + Vp9Prob uv_mode_probs[10][9];
|
| + Vp9Prob partition_probs[16][3];
|
| +
|
| + Vp9Prob mv_joint_probs[3];
|
| + Vp9Prob mv_sign_prob[2];
|
| + Vp9Prob mv_class_probs[2][10];
|
| + Vp9Prob mv_class0_bit_prob[2];
|
| + Vp9Prob mv_bits_prob[2][10];
|
| + Vp9Prob mv_class0_fr_probs[2][2][3];
|
| + Vp9Prob mv_fr_probs[2][3];
|
| + Vp9Prob mv_class0_hp_prob[2];
|
| + Vp9Prob mv_hp_prob[2];
|
| +};
|
| +
|
| +struct MEDIA_EXPORT Vp9CompressedHeader {
|
| + enum Vp9TxMode {
|
| + ONLY_4X4 = 0,
|
| + ALLOW_8X8 = 1,
|
| + ALLOW_16X16 = 2,
|
| + ALLOW_32X32 = 3,
|
| + TX_MODE_SELECT = 4,
|
| + TX_MODES = 5,
|
| + };
|
| +
|
| + Vp9TxMode tx_mode;
|
| + Vp9ReferenceMode reference_mode;
|
| };
|
|
|
| // VP9 frame header.
|
| @@ -130,12 +187,15 @@ struct MEDIA_EXPORT Vp9FrameHeader {
|
| };
|
|
|
| bool IsKeyframe() const;
|
| - bool RefreshFlag(size_t i) const { return !!(refresh_flags & (1u << i)); }
|
| + bool IsIntra() const;
|
| + bool RefreshFlag(size_t i) const {
|
| + return !!(refresh_frame_flags & (1u << i));
|
| + }
|
|
|
| uint8_t profile;
|
|
|
| bool show_existing_frame;
|
| - uint8_t frame_to_show;
|
| + uint8_t frame_to_show_map_idx;
|
|
|
| FrameType frame_type;
|
|
|
| @@ -144,32 +204,35 @@ struct MEDIA_EXPORT Vp9FrameHeader {
|
|
|
| uint8_t bit_depth;
|
| Vp9ColorSpace color_space;
|
| - bool yuv_range;
|
| + bool color_range;
|
| uint8_t subsampling_x;
|
| uint8_t subsampling_y;
|
|
|
| - // The range of width and height is 1..2^16.
|
| - uint32_t width;
|
| - uint32_t height;
|
| - uint32_t display_width;
|
| - uint32_t display_height;
|
| + // The range of frame_width and frame_height is 1..2^16.
|
| + uint32_t frame_width;
|
| + uint32_t frame_height;
|
| + uint32_t render_width;
|
| + uint32_t render_height;
|
|
|
| bool intra_only;
|
| - uint8_t reset_context;
|
| - uint8_t refresh_flags;
|
| - uint8_t frame_refs[kVp9NumRefsPerFrame];
|
| - bool ref_sign_biases[kVp9NumRefsPerFrame];
|
| + uint8_t reset_frame_context;
|
| + uint8_t refresh_frame_flags;
|
| + uint8_t ref_frame_idx[kVp9NumRefsPerFrame];
|
| + bool ref_frame_sign_bias[Vp9RefType::VP9_FRAME_MAX];
|
| bool allow_high_precision_mv;
|
| - Vp9InterpFilter interp_filter;
|
| + Vp9InterpolationFilter interpolation_filter;
|
|
|
| bool refresh_frame_context;
|
| bool frame_parallel_decoding_mode;
|
| uint8_t frame_context_idx;
|
| + // |frame_context_idx_to_save_probs| is to be used by save_probs() only, and
|
| + // |frame_context_idx| otherwise.
|
| + uint8_t frame_context_idx_to_save_probs;
|
|
|
| Vp9QuantizationParams quant_params;
|
|
|
| - uint8_t log2_tile_cols;
|
| - uint8_t log2_tile_rows;
|
| + uint8_t tile_cols_log2;
|
| + uint8_t tile_rows_log2;
|
|
|
| // Pointer to the beginning of frame data. It is a responsibility of the
|
| // client of the Vp9Parser to maintain validity of this data while it is
|
| @@ -180,10 +243,51 @@ struct MEDIA_EXPORT Vp9FrameHeader {
|
| size_t frame_size;
|
|
|
| // Size of compressed header in bytes.
|
| - size_t first_partition_size;
|
| + size_t header_size_in_bytes;
|
|
|
| // Size of uncompressed header in bytes.
|
| size_t uncompressed_header_size;
|
| +
|
| + Vp9CompressedHeader compressed_header;
|
| + // Initial frame entropy context after load_probs2(frame_context_idx).
|
| + Vp9FrameContext initial_frame_context;
|
| + // Current frame entropy context after header parsing.
|
| + Vp9FrameContext frame_context;
|
| +};
|
| +
|
| +class Vp9FrameContextManager {
|
| + public:
|
| + // If context update is needed after decoding a frame, the client must
|
| + // execute this callback, passing the updated context state.
|
| + using ContextRefreshCallback = base::Callback<void(const Vp9FrameContext&)>;
|
| +
|
| + static bool IsValidFrameContext(const Vp9FrameContext& context);
|
| +
|
| + Vp9FrameContextManager();
|
| + ~Vp9FrameContextManager();
|
| + bool initialized() const { return initialized_; }
|
| + bool needs_client_update() const { return needs_client_update_; }
|
| + const Vp9FrameContext& frame_context() const;
|
| +
|
| + // Resets to uninitialized state.
|
| + void Reset();
|
| +
|
| + // Sets this context need update from parser's client. Returns a callback for
|
| + // update.
|
| + ContextRefreshCallback SetNeedsClientUpdate();
|
| +
|
| + // Updates frame context.
|
| + void Update(const Vp9FrameContext& frame_context);
|
| +
|
| + private:
|
| + // Updates frame context from parser's client.
|
| + void UpdateFromClient(const Vp9FrameContext& frame_context);
|
| +
|
| + bool initialized_ = false;
|
| + bool needs_client_update_ = false;
|
| + Vp9FrameContext frame_context_;
|
| +
|
| + base::WeakPtrFactory<Vp9FrameContextManager> weak_ptr_factory_;
|
| };
|
|
|
| // A parser for VP9 bitstream.
|
| @@ -194,9 +298,40 @@ class MEDIA_EXPORT Vp9Parser {
|
| kOk,
|
| kInvalidStream,
|
| kEOStream,
|
| + kAwaitingRefresh,
|
| + };
|
| +
|
| + // The parsing context to keep track of references.
|
| + struct ReferenceSlot {
|
| + bool initialized;
|
| + uint32_t frame_width;
|
| + uint32_t frame_height;
|
| + uint8_t subsampling_x;
|
| + uint8_t subsampling_y;
|
| + uint8_t bit_depth;
|
| +
|
| + // More fields for consistency checking.
|
| + uint8_t profile;
|
| + Vp9ColorSpace color_space;
|
| + };
|
| +
|
| + // The parsing context that persists across frames.
|
| + struct Context {
|
| + void Reset();
|
| +
|
| + // Segmentation and loop filter state.
|
| + Vp9SegmentationParams segmentation;
|
| + Vp9LoopFilterParams loop_filter;
|
| +
|
| + // Frame references.
|
| + ReferenceSlot ref_slots[kVp9NumRefFrames];
|
| +
|
| + Vp9FrameContextManager frame_context_managers[kVp9NumFrameContexts];
|
| };
|
|
|
| - Vp9Parser();
|
| + // The constructor. See ParseNextFrame() for comments for
|
| + // |parsing_compressed_header|.
|
| + explicit Vp9Parser(bool parsing_compressed_header);
|
| ~Vp9Parser();
|
|
|
| // Set a new stream buffer to read from, starting at |stream| and of size
|
| @@ -207,51 +342,54 @@ class MEDIA_EXPORT Vp9Parser {
|
|
|
| // Parse the next frame in the current stream buffer, filling |fhdr| with
|
| // the parsed frame header and updating current segmentation and loop filter
|
| - // state. Return kOk if a frame has successfully been parsed, kEOStream if
|
| - // there is no more data in the current stream buffer, or kInvalidStream
|
| - // on error.
|
| - Result ParseNextFrame(Vp9FrameHeader* fhdr);
|
| + // state. If |parsing_compressed_header_|, this function also fills
|
| + // |context_refresh_cb|, which is used to update frame context. If
|
| + // |*context_refresh_cb| is null, no callback is necessary.
|
| + // Return kOk if a frame has successfully been parsed,
|
| + // kEOStream if there is no more data in the current stream buffer,
|
| + // kAwaitingRefresh if this frame awaiting frame context update, or
|
| + // kInvalidStream on error.
|
| + Result ParseNextFrame(
|
| + Vp9FrameHeader* fhdr,
|
| + Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb);
|
|
|
| // Return current segmentation state.
|
| - const Vp9Segmentation& GetSegmentation() const { return segmentation_; }
|
| + const Vp9SegmentationParams& GetSegmentation() const {
|
| + return context_.segmentation;
|
| + }
|
|
|
| // Return current loop filter state.
|
| - const Vp9LoopFilter& GetLoopFilter() const { return loop_filter_; }
|
| + const Vp9LoopFilterParams& GetLoopFilter() const {
|
| + return context_.loop_filter;
|
| + }
|
|
|
| // Clear parser state and return to an initialized state.
|
| void Reset();
|
|
|
| private:
|
| - // The parsing context to keep track of references.
|
| - struct ReferenceSlot {
|
| - uint32_t width;
|
| - uint32_t height;
|
| + class UncompressedHeaderParser;
|
| + class CompressedHeaderParser;
|
| +
|
| + // Stores start pointer and size of each frame within the current superframe.
|
| + struct FrameInfo {
|
| + FrameInfo() = default;
|
| + FrameInfo(const uint8_t* ptr, off_t size);
|
| + bool IsValid() const { return ptr != nullptr; }
|
| + void Reset() { ptr = nullptr; }
|
| +
|
| + // Starting address of the frame.
|
| + const uint8_t* ptr = nullptr;
|
| +
|
| + // Size of the frame in bytes.
|
| + off_t size = 0;
|
| };
|
|
|
| - bool ParseSuperframe();
|
| - uint8_t ReadProfile();
|
| - bool VerifySyncCode();
|
| - bool ReadBitDepthColorSpaceSampling(Vp9FrameHeader* fhdr);
|
| - void ReadFrameSize(Vp9FrameHeader* fhdr);
|
| - bool ReadFrameSizeFromRefs(Vp9FrameHeader* fhdr);
|
| - void ReadDisplayFrameSize(Vp9FrameHeader* fhdr);
|
| - Vp9InterpFilter ReadInterpFilter();
|
| - void ReadLoopFilter();
|
| - void ReadQuantization(Vp9QuantizationParams* quants);
|
| - void ReadSegmentationMap();
|
| - void ReadSegmentationData();
|
| - void ReadSegmentation();
|
| - void ReadTiles(Vp9FrameHeader* fhdr);
|
| - bool ParseUncompressedHeader(const uint8_t* stream,
|
| - off_t frame_size,
|
| - Vp9FrameHeader* fhdr);
|
| - void UpdateSlots(const Vp9FrameHeader* fhdr);
|
| -
|
| - void ResetLoopfilter();
|
| - void SetupPastIndependence();
|
| + std::deque<FrameInfo> ParseSuperframe();
|
| +
|
| size_t GetQIndex(const Vp9QuantizationParams& quant, size_t segid) const;
|
| - void SetupSegmentationDequant(const Vp9QuantizationParams& quant);
|
| + void SetupSegmentationDequant();
|
| void SetupLoopFilter();
|
| + void UpdateSlots();
|
|
|
| // Current address in the bitstream buffer.
|
| const uint8_t* stream_;
|
| @@ -259,29 +397,15 @@ class MEDIA_EXPORT Vp9Parser {
|
| // Remaining bytes in stream_.
|
| off_t bytes_left_;
|
|
|
| - // Stores start pointer and size of each frame within the current superframe.
|
| - struct FrameInfo {
|
| - FrameInfo(const uint8_t* ptr, off_t size);
|
| -
|
| - // Starting address of the frame.
|
| - const uint8_t* ptr;
|
| -
|
| - // Size of the frame in bytes.
|
| - off_t size;
|
| - };
|
| + bool parsing_compressed_header_;
|
|
|
| // FrameInfo for the remaining frames in the current superframe to be parsed.
|
| std::deque<FrameInfo> frames_;
|
|
|
| - // Raw bits decoder for uncompressed frame header.
|
| - Vp9RawBitsReader reader_;
|
| -
|
| - // Segmentation and loop filter state that persists across frames.
|
| - Vp9Segmentation segmentation_;
|
| - Vp9LoopFilter loop_filter_;
|
| + Context context_;
|
|
|
| - // The parsing context to keep track of references.
|
| - ReferenceSlot ref_slots_[kVp9NumRefFrames];
|
| + FrameInfo curr_frame_info_;
|
| + Vp9FrameHeader curr_frame_header_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(Vp9Parser);
|
| };
|
|
|