Index: content/common/gpu/media/h264_dpb.cc |
diff --git a/content/common/gpu/media/h264_dpb.cc b/content/common/gpu/media/h264_dpb.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..85c054b83822905cb807f5a9e8dd9311df2aa2c2 |
--- /dev/null |
+++ b/content/common/gpu/media/h264_dpb.cc |
@@ -0,0 +1,155 @@ |
+// 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. |
+ |
+#include "h264_dpb.h" |
+ |
+#include <algorithm> |
+ |
+#include "base/logging.h" |
+#include "base/stl_util.h" |
+ |
+struct PicByPOC : public std::binary_function<H264Picture*, int, bool> { |
+ bool operator()(const H264Picture* pic, const int& pic_num) const { |
+ return pic->PicOrderCnt == pic_num; |
+ } |
+}; |
+ |
+struct ShortRefPicByPicNum |
+ : public std::binary_function<H264Picture*, int, bool> { |
+ bool operator()(const H264Picture* pic, const int& pic_num) const { |
+ return (pic->ref && |
+ !pic->long_term && |
+ pic->PicNum == pic_num); |
+ } |
+}; |
+ |
+struct LongRefPicByLongTermPicNum |
+ : public std::binary_function<H264Picture*, int, bool> { |
+ bool operator()(const H264Picture* pic, const int& pic_num) const { |
+ return (pic->ref && |
+ pic->long_term && |
+ pic->LongTermPicNum == pic_num); |
+ } |
+}; |
+ |
+struct IsH264ShortTermRefPic : public std::unary_function<H264Picture*, bool> { |
+ bool operator()(const H264Picture* pic) const { |
+ return (pic->ref && !pic->long_term); |
+ } |
+}; |
+ |
+H264DPB::H264DPB() {} |
+ |
+H264DPB::~H264DPB() { |
+ Clear(); |
+} |
+ |
+void H264DPB::Clear() { |
+ STLDeleteElements(&pics_); |
+} |
+ |
+void H264DPB::RemovePic(const PicsVector::iterator iter) { |
+ DVLOG(3) << "Removing picnum: " << (*iter)->PicNum << " from DPB"; |
+ delete *iter; |
+ pics_.erase(iter); |
+} |
+ |
+void H264DPB::RemoveByPOC(int poc) { |
+ PicsVector::iterator iter = std::find_if(pics_.begin(), pics_.end(), |
Ami GONE FROM CHROMIUM
2012/03/21 13:16:24
I don't think using the STL algorithm business is
Pawel Osciak
2012/04/05 10:37:20
Done.
|
+ std::bind2nd(PicByPOC(), poc)); |
+ DCHECK(iter != pics_.end()); |
+ RemovePic(iter); |
+} |
+ |
+void H264DPB::RemoveUnused() { |
+ PicsVector::iterator iter = pics_.begin(); |
Ami GONE FROM CHROMIUM
2012/03/21 13:16:24
Ditto replace functional style w/ explicit:
for (P
Pawel Osciak
2012/04/05 10:37:20
Done.
|
+ |
+ while (1) { |
+ // TODO posciak: for_each? |
+ iter = std::find_if(iter, pics_.end(), H264Picture::IsUnused()); |
+ if (iter == pics_.end()) |
+ break; |
+ RemovePic(iter); |
+ } |
+} |
+ |
+void H264DPB::StorePic(H264Picture* pic) { |
+ DCHECK_LT(pics_.size(), kDPBMaxSize); |
+ DVLOG(3) << "Adding picnum: " << pic->PicNum << " ref: " << (int)pic->ref |
+ << " longterm: " << (int)pic->long_term << " to DPB"; |
+ pics_.push_back(pic); |
+} |
+ |
+int H264DPB::CountRefPics() { |
+ return std::count_if(pics_.begin(), pics_.end(), H264Picture::IsReference()); |
+} |
+ |
+struct MarkPicUnusedForRef { |
+ void operator()(H264Picture*& pic) { |
+ pic->ref = false; |
+ } |
+}; |
+ |
+void H264DPB::MarkAllUnusedForRef() { |
+ std::for_each(pics_.begin(), pics_.end(), MarkPicUnusedForRef()); |
+} |
+ |
+H264Picture* H264DPB::GetRefPicByPicNum(int pic_num, bool long_term) { |
Ami GONE FROM CHROMIUM
2012/03/21 13:16:24
I suspect you'll want to simply drop this function
Pawel Osciak
2012/04/05 10:37:20
Done.
|
+ PicsVector::iterator iter; |
+ |
+ if (long_term) |
+ iter = std::find_if(pics_.begin(), pics_.end(), |
+ std::bind2nd(LongRefPicByLongTermPicNum(), pic_num)); |
+ else |
+ iter = std::find_if(pics_.begin(), pics_.end(), |
+ std::bind2nd(ShortRefPicByPicNum(), pic_num)); |
+ |
+ if (iter == pics_.end()) { |
+ DLOG(ERROR) << "Requested " << (long_term ? "LongTerm" : "") |
+ << "PicNum " << pic_num << " not found in DPB"; |
+ return NULL; |
+ } else { |
+ return *iter; |
+ } |
+} |
+ |
+H264Picture* H264DPB::GetShortRefPicByPicNum(int pic_num) { |
+ return GetRefPicByPicNum(pic_num, false); |
+} |
+ |
+H264Picture* H264DPB::GetLongRefPicByLongTermPicNum(int pic_num) { |
+ return GetRefPicByPicNum(pic_num, true); |
+} |
+ |
+H264Picture* H264DPB::GetLowestFrameNumWrapRefPic() { |
+ PicsVector short_refs; |
+ |
+ GetShortTermRefPicsAppending(short_refs); |
+ if (short_refs.empty()) |
+ return NULL; |
+ |
+ return *(std::min_element(short_refs.begin(), short_refs.end(), |
Ami GONE FROM CHROMIUM
2012/03/21 13:16:24
Ow, that hurted my brain!
Pawel Osciak
2012/03/21 18:40:35
Blame STL :) Do you see a way to make it simpler?
Ami GONE FROM CHROMIUM
2012/03/22 17:01:36
why not the much simpler
H264Picture* ret = NULL;
Pawel Osciak
2012/04/05 10:37:20
Agreed on copying, although this thing is actually
|
+ H264Picture::FrameNumWrapAscCompare())); |
+} |
+ |
+void H264DPB::GetNotOutputtedPicsSortedByPOCAppending(PicsVector& out) { |
+ // append to ret all not outputted pictures |
+ std::remove_copy_if(pics_.begin(), pics_.end(), std::back_inserter(out), |
+ H264Picture::IsOutputted()); |
+ // and sort them by ascending POC |
+ std::sort(out.begin(), out.end(), H264Picture::POCAscCompare()); |
+} |
+ |
+void H264DPB::GetShortTermRefPicsAppending(PicsVector& out) { |
+ // copy_if in terms of remove_copy_if |
+ std::remove_copy_if(pics_.begin(), pics_.end(), std::back_inserter(out), |
+ std::not1(IsH264ShortTermRefPic())); |
+} |
+ |
+void H264DPB::GetLongTermRefPicsAppending(PicsVector& out) { |
+ // copy_if in terms of remove_copy_if |
+ std::remove_copy_if(pics_.begin(), pics_.end(), std::back_inserter(out), |
+ std::not1(H264Picture::IsLongTermRefPic())); |
+} |
+ |