Chromium Code Reviews| 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())); |
| +} |
| + |