diff options
Diffstat (limited to 'accel/h264_dpb.h')
-rw-r--r-- | accel/h264_dpb.h | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/accel/h264_dpb.h b/accel/h264_dpb.h new file mode 100644 index 0000000..3da284e --- /dev/null +++ b/accel/h264_dpb.h @@ -0,0 +1,181 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file contains an implementation of an H.264 Decoded Picture Buffer +// used in H264 decoders. +// Note: ported from Chromium commit head: 70340ce + +#ifndef H264_DPB_H_ +#define H264_DPB_H_ + +#include <stddef.h> + +#include <vector> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "h264_parser.h" +#include "rect.h" + +namespace media { + +class V4L2H264Picture; + +// A picture (a frame or a field) in the H.264 spec sense. +// See spec at http://www.itu.int/rec/T-REC-H.264 +class H264Picture : public base::RefCountedThreadSafe<H264Picture> { + public: + using Vector = std::vector<scoped_refptr<H264Picture>>; + + enum Field { + FIELD_NONE, + FIELD_TOP, + FIELD_BOTTOM, + }; + + H264Picture(); + + virtual V4L2H264Picture* AsV4L2H264Picture(); + + // Values calculated per H.264 specification or taken from slice header. + // See spec for more details on each (some names have been converted from + // CamelCase in spec to Chromium-style names). + int pic_order_cnt_type; + int top_field_order_cnt; + int bottom_field_order_cnt; + int pic_order_cnt; + int pic_order_cnt_msb; + int pic_order_cnt_lsb; + int delta_pic_order_cnt_bottom; + int delta_pic_order_cnt0; + int delta_pic_order_cnt1; + + int pic_num; + int long_term_pic_num; + int frame_num; // from slice header + int frame_num_offset; + int frame_num_wrap; + int long_term_frame_idx; + + H264SliceHeader::Type type; + int nal_ref_idc; + bool idr; // IDR picture? + int idr_pic_id; // Valid only if idr == true. + bool ref; // reference picture? + bool long_term; // long term reference picture? + bool outputted; + // Does memory management op 5 needs to be executed after this + // picture has finished decoding? + bool mem_mgmt_5; + + // Created by the decoding process for gaps in frame_num. + // Not for decode or output. + bool nonexisting; + + Field field; + + // Values from slice_hdr to be used during reference marking and + // memory management after finishing this picture. + bool long_term_reference_flag; + bool adaptive_ref_pic_marking_mode_flag; + H264DecRefPicMarking ref_pic_marking[H264SliceHeader::kRefListSize]; + + // Position in DPB (i.e. index in DPB). + int dpb_position; + + // The visible size of picture. This could be either parsed from SPS, or set + // to Rect(0, 0) for indicating invalid values or not available. + Rect visible_rect; + + protected: + friend class base::RefCountedThreadSafe<H264Picture>; + virtual ~H264Picture(); + + private: + DISALLOW_COPY_AND_ASSIGN(H264Picture); +}; + +// DPB - Decoded Picture Buffer. +// Stores decoded pictures that will be used for future display +// and/or reference. +class H264DPB { + public: + H264DPB(); + ~H264DPB(); + + void set_max_num_pics(size_t max_num_pics); + size_t max_num_pics() const { return max_num_pics_; } + + // Remove unused (not reference and already outputted) pictures from DPB + // and free it. + void DeleteUnused(); + + // Remove a picture by its pic_order_cnt and free it. + void DeleteByPOC(int poc); + + // Clear DPB. + void Clear(); + + // Store picture in DPB. DPB takes ownership of its resources. + void StorePic(const scoped_refptr<H264Picture>& pic); + + // Return the number of reference pictures in DPB. + int CountRefPics(); + + // Mark all pictures in DPB as unused for reference. + void MarkAllUnusedForRef(); + + // Return a short-term reference picture by its pic_num. + scoped_refptr<H264Picture> GetShortRefPicByPicNum(int pic_num); + + // Return a long-term reference picture by its long_term_pic_num. + scoped_refptr<H264Picture> GetLongRefPicByLongTermPicNum(int pic_num); + + // Return the short reference picture with lowest frame_num. Used for sliding + // window memory management. + scoped_refptr<H264Picture> GetLowestFrameNumWrapShortRefPic(); + + // Append all pictures that have not been outputted yet to the passed |out| + // vector, sorted by lowest pic_order_cnt (in output order). + void GetNotOutputtedPicsAppending(H264Picture::Vector* out); + + // Append all short term reference pictures to the passed |out| vector. + void GetShortTermRefPicsAppending(H264Picture::Vector* out); + + // Append all long term reference pictures to the passed |out| vector. + void GetLongTermRefPicsAppending(H264Picture::Vector* out); + + // Iterators for direct access to DPB contents. + // Will be invalidated after any of Remove* calls. + H264Picture::Vector::iterator begin() { return pics_.begin(); } + H264Picture::Vector::iterator end() { return pics_.end(); } + H264Picture::Vector::const_iterator begin() const { return pics_.begin(); } + H264Picture::Vector::const_iterator end() const { return pics_.end(); } + H264Picture::Vector::const_reverse_iterator rbegin() const { + return pics_.rbegin(); + } + H264Picture::Vector::const_reverse_iterator rend() const { + return pics_.rend(); + } + + size_t size() const { return pics_.size(); } + bool IsFull() const { return pics_.size() == max_num_pics_; } + + // Per H264 spec, increase to 32 if interlaced video is supported. + enum { + kDPBMaxSize = 16, + }; + + private: + void UpdatePicPositions(); + + H264Picture::Vector pics_; + size_t max_num_pics_; + + DISALLOW_COPY_AND_ASSIGN(H264DPB); +}; + +} // namespace media + +#endif // H264_DPB_H_ |