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

Side by Side Diff: content/common/gpu/media/vp8_decoder.cc

Issue 833063003: Add accelerated video decoder interface, VP8 and H.264 implementations and hook up to V4L2SVDA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/media/vp8_decoder.h"
6 #include "media/base/limits.h"
7
8 namespace content {
9
10 VP8Decoder::VP8Decoder(VP8Accelerator* accelerator)
11 : state_(kNeedStreamMetadata),
12 curr_frame_start_(nullptr),
13 frame_size_(0),
14 accelerator_(accelerator) {
15 DCHECK(accelerator_);
16 }
17
18 VP8Decoder::~VP8Decoder() {
19 }
20
21 bool VP8Decoder::Flush() {
22 DVLOG(2) << "Decoder flush";
23 Reset();
24 return true;
25 }
26
27 void VP8Decoder::SetStream(const uint8_t* ptr, size_t size) {
28 DCHECK(ptr);
29 DCHECK(size);
30
31 curr_frame_start_ = ptr;
32 frame_size_ = size;
33 DVLOG(4) << "New input stream at: " << (void*)ptr << " size: " << size;
34 }
35
36 void VP8Decoder::Reset() {
37 curr_pic_ = nullptr;
38 curr_frame_hdr_ = nullptr;
39 curr_frame_start_ = nullptr;
40 frame_size_ = 0;
41
42 last_frame_ = nullptr;
43 golden_frame_ = nullptr;
44 alt_frame_ = nullptr;
45
46 if (state_ == kDecoding)
47 state_ = kAfterReset;
48 }
49
50 VP8Decoder::DecResult VP8Decoder::Decode() {
51 if (!curr_frame_start_ || frame_size_ == 0)
52 return kRanOutOfStreamData;
53
54 if (!curr_frame_hdr_) {
55 curr_frame_hdr_.reset(new media::VP8FrameHeader());
56 if (!parser_.ParseFrame(curr_frame_start_, frame_size_,
57 curr_frame_hdr_.get())) {
58 DVLOG(1) << "Error during decode";
59 state_ = kError;
60 return VP8Decoder::kDecodeError;
61 }
62 }
63
64 if (curr_frame_hdr_->IsKeyframe()) {
65 gfx::Size new_pic_size(curr_frame_hdr_->width, curr_frame_hdr_->height);
66 if (new_pic_size.IsEmpty())
67 return kDecodeError;
68
69 if (pic_size_.IsEmpty() || new_pic_size != pic_size_) {
70 DVLOG(2) << "New resolution: " << new_pic_size.ToString();
71 pic_size_ = new_pic_size;
72 return kAllocateNewSurfaces;
73 }
74
75 state_ = kDecoding;
76 } else {
77 if (state_ != kDecoding) {
78 // Need a resume point.
79 curr_frame_hdr_.reset();
80 return kRanOutOfStreamData;
81 }
82 }
83
84 curr_pic_ = accelerator_->CreateVP8Picture();
85 if (!curr_pic_)
86 return kRanOutOfSurfaces;
87
88 if (!DecodeAndOutputCurrentFrame())
89 return kDecodeError;
90
91 return kRanOutOfStreamData;
92 }
93
94 void VP8Decoder::RefreshReferenceFrames() {
95 if (curr_frame_hdr_->IsKeyframe()) {
96 last_frame_ = curr_pic_;
97 golden_frame_ = curr_pic_;
98 alt_frame_ = curr_pic_;
99 return;
100 }
101
102 // Save current golden since we overwrite it here,
103 // but may have to use it to update alt below.
104 scoped_refptr<VP8Picture> curr_golden = golden_frame_;
105
106 if (curr_frame_hdr_->refresh_golden_frame) {
107 golden_frame_ = curr_pic_;
108 } else {
109 switch (curr_frame_hdr_->copy_buffer_to_golden) {
110 case media::VP8FrameHeader::kCopyLastToGolden:
111 DCHECK(last_frame_);
112 golden_frame_ = last_frame_;
113 break;
114
115 case media::VP8FrameHeader::kCopyAltToGolden:
116 DCHECK(alt_frame_);
117 golden_frame_ = alt_frame_;
118 break;
119 }
120 }
121
122 if (curr_frame_hdr_->refresh_alternate_frame) {
123 alt_frame_ = curr_pic_;
124 } else {
125 switch (curr_frame_hdr_->copy_buffer_to_alternate) {
126 case media::VP8FrameHeader::kCopyLastToAlt:
127 DCHECK(last_frame_);
128 alt_frame_ = last_frame_;
129 break;
130
131 case media::VP8FrameHeader::kCopyGoldenToAlt:
132 DCHECK(curr_golden);
133 alt_frame_ = curr_golden;
134 break;
135 }
136 }
137
138 if (curr_frame_hdr_->refresh_last)
139 last_frame_ = curr_pic_;
140 }
141
142 void VP8Decoder::BeginFrame() {
143 if (curr_frame_hdr_->IsKeyframe()) {
144 horizontal_scale_ = curr_frame_hdr_->horizontal_scale;
145 vertical_scale_ = curr_frame_hdr_->vertical_scale;
146 } else {
147 // Populate fields from decoder state instead.
148 curr_frame_hdr_->width = pic_size_.width();
149 curr_frame_hdr_->height = pic_size_.height();
150 curr_frame_hdr_->horizontal_scale = horizontal_scale_;
151 curr_frame_hdr_->vertical_scale = vertical_scale_;
152 }
153 }
154
155 bool VP8Decoder::DecodeAndOutputCurrentFrame() {
156 DCHECK(!pic_size_.IsEmpty());
157 DCHECK(curr_pic_);
158 DCHECK(curr_frame_hdr_);
159
160 BeginFrame();
161
162 if (!accelerator_->SubmitDecode(curr_pic_, curr_frame_hdr_.get(), last_frame_,
163 golden_frame_, alt_frame_))
164 return false;
165
166 if (!accelerator_->OutputPicture(curr_pic_))
167 return false;
168
169 RefreshReferenceFrames();
170
171 curr_pic_ = nullptr;
172 curr_frame_hdr_ = nullptr;
173 curr_frame_start_ = nullptr;
174 frame_size_ = 0;
175 return true;
176 }
177
178 size_t VP8Decoder::GetRequiredNumOfPictures() {
179 static const size_t kVP8NumFramesActive = 4;
180 static const size_t kPicsInPipeline = media::limits::kMaxVideoFrames + 2;
181 return kVP8NumFramesActive + kPicsInPipeline;
182 }
183
184 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698