// 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 #include #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 { public: using Vector = std::vector>; 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; 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& 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 GetShortRefPicByPicNum(int pic_num); // Return a long-term reference picture by its long_term_pic_num. scoped_refptr GetLongRefPicByLongTermPicNum(int pic_num); // Return the short reference picture with lowest frame_num. Used for sliding // window memory management. scoped_refptr 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_