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

Side by Side Diff: content/common/gpu/media/mac_video_decode_accelerator.mm

Issue 10411085: Build AVC decoder configuration record (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/mac_video_decode_accelerator.h" 5 #include "content/common/gpu/media/mac_video_decode_accelerator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #import "base/mac/foundation_util.h" 9 #import "base/mac/foundation_util.h"
10 #import "base/memory/ref_counted_memory.h" 10 #import "base/memory/ref_counted_memory.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 if (glGetError() != GL_NO_ERROR) 78 if (glGetError() != GL_NO_ERROR)
79 return false; 79 return false;
80 80
81 return true; 81 return true;
82 } 82 }
83 83
84 MacVideoDecodeAccelerator::MacVideoDecodeAccelerator( 84 MacVideoDecodeAccelerator::MacVideoDecodeAccelerator(
85 media::VideoDecodeAccelerator::Client* client) 85 media::VideoDecodeAccelerator::Client* client)
86 : client_(client), 86 : client_(client),
87 cgl_context_(NULL), 87 cgl_context_(NULL),
88 nalu_len_field_size_(0), 88 did_build_config_record_(false) {
89 frame_width_(0),
90 frame_height_(0),
91 did_request_pictures_(false) {
92 } 89 }
93 90
94 void MacVideoDecodeAccelerator::SetGLContext(void* gl_context) { 91 void MacVideoDecodeAccelerator::SetGLContext(void* gl_context) {
95 cgl_context_ = static_cast<CGLContextObj>(gl_context); 92 cgl_context_ = static_cast<CGLContextObj>(gl_context);
96 } 93 }
97 94
98 bool MacVideoDecodeAccelerator::SetConfigInfo(
99 uint32_t frame_width,
100 uint32_t frame_height,
101 const std::vector<uint8_t>& avc_data) {
102 frame_width_ = frame_width;
103 frame_height_ = frame_height;
104 nalu_len_field_size_ = (avc_data[4] & 0x03) + 1;
105
106 DCHECK(!vda_.get());
107 vda_ = new gfx::VideoDecodeAccelerationSupport();
108 gfx::VideoDecodeAccelerationSupport::Status status = vda_->Create(
109 frame_width_, frame_height_,
110 kCVPixelFormatType_422YpCbCr8, &avc_data.front(), avc_data.size());
111 if (status != gfx::VideoDecodeAccelerationSupport::VDA_SUCCESS)
112 return false;
113 return true;
114 }
115
116 bool MacVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile) { 95 bool MacVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile) {
117 if (client_) 96 if (client_)
118 client_->NotifyInitializeDone(); 97 client_->NotifyInitializeDone();
119 return true; 98 return true;
120 } 99 }
121 100
122 void MacVideoDecodeAccelerator::Decode( 101 void MacVideoDecodeAccelerator::Decode(
123 const media::BitstreamBuffer& bitstream_buffer) { 102 const media::BitstreamBuffer& bitstream_buffer) {
124 base::SharedMemory memory(bitstream_buffer.handle(), true); 103 base::SharedMemory memory(bitstream_buffer.handle(), true);
125 if (!memory.Map(bitstream_buffer.size())) { 104 if (!memory.Map(bitstream_buffer.size())) {
126 CHECK(false); 105 CHECK(false);
127 return; 106 return;
128 } 107 }
129 108
130 size_t buffer_size = bitstream_buffer.size(); 109 h264_parser_.SetStream(static_cast<const uint8_t*>(memory.memory()),
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 The fact that you feed all bitstreambuffers to the
sail 2012/05/28 21:45:46 I'd like to keep using the parser so that I can ha
131 if (buffer_size < nalu_len_field_size_ + 1) { 110 bitstream_buffer.size());
132 if (client_) 111 while (true) {
133 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer.id()); 112 content::H264NALU nalu;
134 return; 113 content::H264Parser::Result result = h264_parser_.AdvanceToNextNALU(&nalu);
135 } 114 if (result == content::H264Parser::kEOStream) {
115 if (client_)
116 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer.id());
117 return;
118 }
119 if (result != content::H264Parser::kOk) {
120 if (client_)
121 client_->NotifyError(UNREADABLE_INPUT);
122 return;
123 }
136 124
137 // The decoder can only handle slice types (1-5). 125 if (!did_build_config_record_) {
138 const uint8_t* buffer = static_cast<const uint8_t*>(memory.memory()); 126 bool did_consume_nalu = false;
139 uint8_t nalu_type = buffer[nalu_len_field_size_] & 0x1f; 127 if (!config_record_builder_.ProcessNextNALU(
140 if (nalu_type < 1 || nalu_type > 5) { 128 &h264_parser_, &nalu, &did_consume_nalu)) {
141 if (client_) 129 if (client_)
142 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer.id()); 130 client_->NotifyError(UNREADABLE_INPUT);
143 return; 131 return;
144 } 132 }
145 133
146 // Keep a ref counted copy of the buffer. 134 if (config_record_builder_.can_build_record()) {
147 std::vector<uint8_t> vector(buffer, buffer + buffer_size); 135 did_build_config_record_ = true;
148 scoped_refptr<base::RefCountedBytes> bytes( 136 CreateDecoder();
149 base::RefCountedBytes::TakeVector(&vector)); 137 }
150 138
151 // Store the buffer size at the beginning of the buffer as the decoder 139 if (did_consume_nalu)
152 // expects. 140 continue;
153 size_t frame_buffer_size = buffer_size - nalu_len_field_size_; 141 }
154 for (size_t i = 0; i < nalu_len_field_size_; ++i) {
155 size_t shift = nalu_len_field_size_ * 8 - (i + 1) * 8;
156 bytes->data()[i] = (frame_buffer_size >> shift) & 0xff;
157 }
158 142
159 vda_->Decode(bytes->front(), bytes->size(), 143 // If the decoder has been created and this is a slice type then pass it
160 base::Bind(&MacVideoDecodeAccelerator::OnFrameReady, this, 144 // to the decoder.
161 bitstream_buffer.id(), bytes)); 145 if (vda_.get() && nalu.nal_unit_type >= 1 && nalu.nal_unit_type <= 5)
162 146 DecodeNALU(&nalu, bitstream_buffer.id());
163 if (!did_request_pictures_) {
164 did_request_pictures_ = true;
165 if (client_)
166 client_->ProvidePictureBuffers(
167 kNumPictureBuffers, gfx::Size(frame_width_, frame_height_));
168 } 147 }
169 } 148 }
170 149
171 void MacVideoDecodeAccelerator::AssignPictureBuffers( 150 void MacVideoDecodeAccelerator::AssignPictureBuffers(
172 const std::vector<media::PictureBuffer>& buffers) { 151 const std::vector<media::PictureBuffer>& buffers) {
173 available_pictures_.insert( 152 available_pictures_.insert(
174 available_pictures_.end(), buffers.begin(), buffers.end()); 153 available_pictures_.end(), buffers.begin(), buffers.end());
175 SendImages(); 154 SendImages();
176 } 155 }
177 156
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 if (client_) 229 if (client_)
251 client_->NotifyFlushDone(); 230 client_->NotifyFlushDone();
252 } 231 }
253 232
254 void MacVideoDecodeAccelerator::NotifyResetDone() { 233 void MacVideoDecodeAccelerator::NotifyResetDone() {
255 decoded_images_.clear(); 234 decoded_images_.clear();
256 if (client_) 235 if (client_)
257 client_->NotifyResetDone(); 236 client_->NotifyResetDone();
258 } 237 }
259 238
239 void MacVideoDecodeAccelerator::CreateDecoder() {
240 std::vector<uint8_t> extra_data(
241 config_record_builder_.BuildConfigRecord());
242 vda_ = new gfx::VideoDecodeAccelerationSupport();
243 gfx::VideoDecodeAccelerationSupport::Status status = vda_->Create(
244 config_record_builder_.coded_width(),
245 config_record_builder_.coded_height(),
246 kCVPixelFormatType_422YpCbCr8,
247 &extra_data[0], extra_data.size());
248 if (status != gfx::VideoDecodeAccelerationSupport::VDA_SUCCESS) {
249 if (client_)
250 client_->NotifyError(PLATFORM_FAILURE);
251 return;
252 }
253
254 if (client_) {
255 client_->ProvidePictureBuffers(
256 kNumPictureBuffers,
257 gfx::Size(config_record_builder_.coded_width(),
258 config_record_builder_.coded_height()));
259 }
260 }
261
262 void MacVideoDecodeAccelerator::DecodeNALU(const content::H264NALU* nalu,
263 int32 bitstream_buffer_id) {
264 // Assume the NALU lenght field size is 4 bytes.
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 typo: length
sail 2012/05/28 21:45:46 Done.
265 const int kNALULengthFieldSize = 4;
266 std::vector<uint8_t> data(kNALULengthFieldSize + nalu->size, 0);
Ami GONE FROM CHROMIUM 2012/05/23 19:41:19 Why the ", 0"?
sail 2012/05/28 21:45:46 Done.
267
268 // Store the buffer size at the beginning of the buffer as the decoder
269 // expects.
270 for (size_t i = 0; i < kNALULengthFieldSize; ++i) {
271 size_t shift = kNALULengthFieldSize * 8 - (i + 1) * 8;
272 data[i] = (nalu->size >> shift) & 0xff;
273 }
274
275 // Copy the NALU data.
276 memcpy(&data[kNALULengthFieldSize], nalu->data, nalu->size);
277
278 // Keep a ref counted copy of the buffer.
279 scoped_refptr<base::RefCountedBytes> bytes(
280 base::RefCountedBytes::TakeVector(&data));
281 vda_->Decode(bytes->front(), bytes->size(),
282 base::Bind(&MacVideoDecodeAccelerator::OnFrameReady, this,
283 bitstream_buffer_id, bytes));
284 }
285
260 MacVideoDecodeAccelerator::PendingPictureInfo::PendingPictureInfo( 286 MacVideoDecodeAccelerator::PendingPictureInfo::PendingPictureInfo(
261 media::PictureBuffer pic) 287 media::PictureBuffer pic)
262 : picture_buffer(pic.id(), pic.size(), pic.texture_id()) { 288 : picture_buffer(pic.id(), pic.size(), pic.texture_id()) {
263 } 289 }
264 290
265 MacVideoDecodeAccelerator::PendingPictureInfo::~PendingPictureInfo() { 291 MacVideoDecodeAccelerator::PendingPictureInfo::~PendingPictureInfo() {
266 } 292 }
267 293
268 MacVideoDecodeAccelerator::DecodedImageInfo::DecodedImageInfo() { 294 MacVideoDecodeAccelerator::DecodedImageInfo::DecodedImageInfo() {
269 } 295 }
270 296
271 MacVideoDecodeAccelerator::DecodedImageInfo::~DecodedImageInfo() { 297 MacVideoDecodeAccelerator::DecodedImageInfo::~DecodedImageInfo() {
272 } 298 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698