Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Unified Diff: media/filters/vp9_parser.h

Issue 2133993002: Parse VP9 compressed header (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Implement VP9 compressed header parsing Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/vp9_parser.h
diff --git a/media/filters/vp9_parser.h b/media/filters/vp9_parser.h
index 4d430494170f48dae739febfd283fee09750f50b..176b2654c42182481802be7c0017e93a87a14beb 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 int kVp9NumFrameContext = 4;
Pawel Osciak 2016/08/04 10:20:19 size_t ? s/Context/Contexts/ ?
kcwu 2016/08/05 11:38:47 Done.
+
+typedef uint8_t Vp9Prob;
Pawel Osciak 2016/08/04 10:20:19 Nit: perhaps "using" syntax? Perhaps move to into
kcwu 2016/08/05 11:38:47 It's not only used in context class.
enum class Vp9ColorSpace {
UNKNOWN = 0,
@@ -41,15 +45,46 @@ enum class Vp9ColorSpace {
SRGB = 7,
};
-enum Vp9InterpFilter {
+enum Vp9InterpolationFilter {
EIGHTTAP = 0,
EIGHTTAP_SMOOTH = 1,
EIGHTTAP_SHARP = 2,
BILINEAR = 3,
- SWICHABLE = 4,
+ SWITCHABLE = 4,
+};
+
+enum Vp9FrameType {
Pawel Osciak 2016/08/04 10:20:19 Perhaps RefType? We already have FrameType in head
kcwu 2016/08/05 11:38:48 Done.
+ VP9_FRAME_INTRA = 0,
+ VP9_FRAME_LAST = 1,
+ VP9_FRAME_GOLDEN = 2,
+ VP9_FRAME_ALTREF = 3,
+ VP9_FRAME_MAX = 4,
+};
+
+enum Vp9TxMode {
Pawel Osciak 2016/08/04 10:20:19 Perhaps move to Vp9Compressed header?
kcwu 2016/08/05 11:38:48 Done.
+ ONLY_4X4 = 0,
+ ALLOW_8X8 = 1,
+ ALLOW_16X16 = 2,
+ ALLOW_32X32 = 3,
+ TX_MODE_SELECT = 4,
+ TX_MODES = 5,
+};
+
+enum Vp9TxSize {
Pawel Osciak 2016/08/04 10:20:19 Perhaps we should move this to ReadCoefProbs()?
kcwu 2016/08/05 11:38:47 Done.
+ TX_4X4 = 0,
+ TX_8X8 = 1,
+ TX_16X16 = 2,
+ TX_32X32 = 3,
+ TX_SIZES = 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 +104,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 +120,71 @@ 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
Pawel Osciak 2016/08/04 10:20:19 Nit: to match the style, please capitalize first l
kcwu 2016/08/05 11:38:48 Done.
+ 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 {
+ Vp9TxMode tx_mode;
+ Vp9ReferenceMode reference_mode;
};
// VP9 frame header.
@@ -130,12 +195,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 +212,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[Vp9FrameType::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| may change later, backup the original value parsed
+ // from the stream.
+ uint8_t frame_context_idx_backup;
Pawel Osciak 2016/08/04 10:20:19 Perhaps frame_context_idx and frame_context_idx_to
kcwu 2016/08/05 11:38:48 Done. However, it seem look odd for vaapi_vda.
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 +251,40 @@ 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:
+ using ContextRefreshCallback = base::Callback<void(const Vp9FrameContext&)>;
Pawel Osciak 2016/08/04 10:20:19 Please document.
kcwu 2016/08/05 11:38:48 Done.
+
+ static bool IsValidFrameContext(const Vp9FrameContext& context);
+
+ Vp9FrameContextManager();
+ ~Vp9FrameContextManager();
+ bool initialized() const { return initialized_; }
+ bool need_update() const { return need_update_; }
Pawel Osciak 2016/08/04 10:20:19 s/need/needs/
kcwu 2016/08/05 11:38:48 Done.
+ const Vp9FrameContext& frame_context() const;
+
+ void Reset();
Pawel Osciak 2016/08/04 10:20:19 Please document methods.
kcwu 2016/08/05 11:38:48 Done.
+ ContextRefreshCallback SetNeedUpdate();
+ void Update(const Vp9FrameContext& frame_context);
+
+ private:
+ bool initialized_;
+ bool need_update_;
+ Vp9FrameContext frame_context_;
+
+ base::WeakPtrFactory<Vp9FrameContextManager> weak_ptr_factory_;
};
// A parser for VP9 bitstream.
@@ -194,9 +295,38 @@ 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.
Pawel Osciak 2016/08/04 10:20:19 I think color_space we also use to copy to frame_h
kcwu 2016/08/05 11:38:48 Yes, but it is not mentioned in spec 8.10. I list
Pawel Osciak 2016/08/08 08:13:36 Acknowledged.
+ 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[kVp9NumFrameContext];
};
- Vp9Parser();
+ explicit Vp9Parser(bool parsing_compressed_header);
Pawel Osciak 2016/08/04 10:20:19 Please document, maybe referring to ParseNextFrame
kcwu 2016/08/05 11:38:47 Done.
~Vp9Parser();
// Set a new stream buffer to read from, starting at |stream| and of size
@@ -207,51 +337,40 @@ 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
Pawel Osciak 2016/08/04 10:20:19 s/parsing_compressed_header/parsing_compressed_hea
kcwu 2016/08/05 11:38:47 Done.
+ // |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,
+ base::Callback<void(const Vp9FrameContext&)>* 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;
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();
size_t GetQIndex(const Vp9QuantizationParams& quant, size_t segid) const;
- void SetupSegmentationDequant(const Vp9QuantizationParams& quant);
+ void SetupSegmentationDequant(const Vp9FrameHeader* fhdr);
void SetupLoopFilter();
+ void UpdateSlots(const Vp9FrameHeader* fhdr);
// Current address in the bitstream buffer.
const uint8_t* stream_;
@@ -270,18 +389,12 @@ class MEDIA_EXPORT Vp9Parser {
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_;
-
- // The parsing context to keep track of references.
- ReferenceSlot ref_slots_[kVp9NumRefFrames];
+ Context context_;
DISALLOW_COPY_AND_ASSIGN(Vp9Parser);
};

Powered by Google App Engine
This is Rietveld 408576698