OLD | NEW |
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 "media/filters/vpx_video_decoder.h" | 5 #include "media/filters/vpx_video_decoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 void VpxVideoDecoder::DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { | 215 void VpxVideoDecoder::DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { |
216 DCHECK(message_loop_->BelongsToCurrentThread()); | 216 DCHECK(message_loop_->BelongsToCurrentThread()); |
217 DCHECK_NE(state_, kUninitialized); | 217 DCHECK_NE(state_, kUninitialized); |
218 DCHECK_NE(state_, kDecodeFinished); | 218 DCHECK_NE(state_, kDecodeFinished); |
219 DCHECK_NE(state_, kError); | 219 DCHECK_NE(state_, kError); |
220 DCHECK(reset_cb_.is_null()); | 220 DCHECK(reset_cb_.is_null()); |
221 DCHECK(!read_cb_.is_null()); | 221 DCHECK(!read_cb_.is_null()); |
222 DCHECK(buffer); | 222 DCHECK(buffer); |
223 | 223 |
224 // Transition to kDecodeFinished on the first end of stream buffer. | 224 // Transition to kDecodeFinished on the first end of stream buffer. |
225 if (state_ == kNormal && buffer->IsEndOfStream()) { | 225 if (state_ == kNormal && buffer->end_of_stream()) { |
226 state_ = kDecodeFinished; | 226 state_ = kDecodeFinished; |
227 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); | 227 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); |
228 return; | 228 return; |
229 } | 229 } |
230 | 230 |
231 scoped_refptr<VideoFrame> video_frame; | 231 scoped_refptr<VideoFrame> video_frame; |
232 if (!VpxDecode(buffer, &video_frame)) { | 232 if (!VpxDecode(buffer, &video_frame)) { |
233 state_ = kError; | 233 state_ = kError; |
234 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 234 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
235 return; | 235 return; |
236 } | 236 } |
237 | 237 |
| 238 // If we didn't get a frame we need more data. |
238 if (!video_frame.get()) { | 239 if (!video_frame.get()) { |
239 base::ResetAndReturn(&read_cb_).Run(kNotEnoughData, NULL); | 240 base::ResetAndReturn(&read_cb_).Run(kNotEnoughData, NULL); |
240 return; | 241 return; |
241 } | 242 } |
242 | 243 |
243 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame); | 244 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame); |
244 } | 245 } |
245 | 246 |
246 bool VpxVideoDecoder::VpxDecode(const scoped_refptr<DecoderBuffer>& buffer, | 247 bool VpxVideoDecoder::VpxDecode(const scoped_refptr<DecoderBuffer>& buffer, |
247 scoped_refptr<VideoFrame>* video_frame) { | 248 scoped_refptr<VideoFrame>* video_frame) { |
248 DCHECK(video_frame); | 249 DCHECK(video_frame); |
249 DCHECK(!buffer->IsEndOfStream()); | 250 DCHECK(!buffer->end_of_stream()); |
250 | 251 |
251 // Pass |buffer| to libvpx. | 252 // Pass |buffer| to libvpx. |
252 int64 timestamp = buffer->GetTimestamp().InMicroseconds(); | 253 int64 timestamp = buffer->timestamp().InMicroseconds(); |
253 void* user_priv = reinterpret_cast<void*>(×tamp); | 254 void* user_priv = reinterpret_cast<void*>(×tamp); |
254 vpx_codec_err_t status = vpx_codec_decode(vpx_codec_, | 255 vpx_codec_err_t status = vpx_codec_decode(vpx_codec_, |
255 buffer->GetData(), | 256 buffer->data(), |
256 buffer->GetDataSize(), | 257 buffer->data_size(), |
257 user_priv, | 258 user_priv, |
258 0); | 259 0); |
259 if (status != VPX_CODEC_OK) { | 260 if (status != VPX_CODEC_OK) { |
260 LOG(ERROR) << "vpx_codec_decode() failed, status=" << status; | 261 LOG(ERROR) << "vpx_codec_decode() failed, status=" << status; |
261 return false; | 262 return false; |
262 } | 263 } |
263 | 264 |
264 // Gets pointer to decoded data. | 265 // Gets pointer to decoded data. |
265 vpx_codec_iter_t iter = NULL; | 266 vpx_codec_iter_t iter = NULL; |
266 const vpx_image_t* vpx_image = vpx_codec_get_frame(vpx_codec_, &iter); | 267 const vpx_image_t* vpx_image = vpx_codec_get_frame(vpx_codec_, &iter); |
267 if (!vpx_image) { | 268 if (!vpx_image) { |
268 *video_frame = NULL; | 269 *video_frame = NULL; |
269 return true; | 270 return true; |
270 } | 271 } |
271 | 272 |
272 if (vpx_image->user_priv != reinterpret_cast<void*>(×tamp)) { | 273 if (vpx_image->user_priv != reinterpret_cast<void*>(×tamp)) { |
273 LOG(ERROR) << "Invalid output timestamp."; | 274 LOG(ERROR) << "Invalid output timestamp."; |
274 return false; | 275 return false; |
275 } | 276 } |
276 | 277 |
277 const vpx_image_t* vpx_image_alpha = NULL; | 278 const vpx_image_t* vpx_image_alpha = NULL; |
278 if (vpx_codec_alpha_ && buffer->GetSideDataSize() >= 8) { | 279 if (vpx_codec_alpha_ && buffer->side_data_size() >= 8) { |
279 // Pass alpha data to libvpx. | 280 // Pass alpha data to libvpx. |
280 int64 timestamp_alpha = buffer->GetTimestamp().InMicroseconds(); | 281 int64 timestamp_alpha = buffer->timestamp().InMicroseconds(); |
281 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); | 282 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); |
282 | 283 |
283 // First 8 bytes of side data is side_data_id in big endian. | 284 // First 8 bytes of side data is side_data_id in big endian. |
284 const uint64 side_data_id = base::NetToHost64( | 285 const uint64 side_data_id = base::NetToHost64( |
285 *(reinterpret_cast<const uint64*>(buffer->GetSideData()))); | 286 *(reinterpret_cast<const uint64*>(buffer->side_data()))); |
286 if (side_data_id == 1) { | 287 if (side_data_id == 1) { |
287 status = vpx_codec_decode(vpx_codec_alpha_, | 288 status = vpx_codec_decode(vpx_codec_alpha_, |
288 buffer->GetSideData() + 8, | 289 buffer->side_data() + 8, |
289 buffer->GetSideDataSize() - 8, | 290 buffer->side_data_size() - 8, |
290 user_priv_alpha, | 291 user_priv_alpha, |
291 0); | 292 0); |
292 | 293 |
293 if (status != VPX_CODEC_OK) { | 294 if (status != VPX_CODEC_OK) { |
294 LOG(ERROR) << "vpx_codec_decode() failed on alpha, status=" << status; | 295 LOG(ERROR) << "vpx_codec_decode() failed on alpha, status=" << status; |
295 return false; | 296 return false; |
296 } | 297 } |
297 | 298 |
298 // Gets pointer to decoded data. | 299 // Gets pointer to decoded data. |
299 vpx_codec_iter_t iter_alpha = NULL; | 300 vpx_codec_iter_t iter_alpha = NULL; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 vpx_image->stride[VPX_PLANE_Y], vpx_image->d_h, video_frame->get()); | 362 vpx_image->stride[VPX_PLANE_Y], vpx_image->d_h, video_frame->get()); |
362 return; | 363 return; |
363 } | 364 } |
364 CopyAPlane(vpx_image_alpha->planes[VPX_PLANE_Y], | 365 CopyAPlane(vpx_image_alpha->planes[VPX_PLANE_Y], |
365 vpx_image->stride[VPX_PLANE_Y], | 366 vpx_image->stride[VPX_PLANE_Y], |
366 vpx_image->d_h, | 367 vpx_image->d_h, |
367 video_frame->get()); | 368 video_frame->get()); |
368 } | 369 } |
369 | 370 |
370 } // namespace media | 371 } // namespace media |
OLD | NEW |