| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 const scoped_refptr<DecoderBuffer>& buffer) { | 256 const scoped_refptr<DecoderBuffer>& buffer) { |
| 257 DCHECK(message_loop_->BelongsToCurrentThread()); | 257 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 258 DCHECK_NE(state_, kUninitialized); | 258 DCHECK_NE(state_, kUninitialized); |
| 259 DCHECK_NE(state_, kDecodeFinished); | 259 DCHECK_NE(state_, kDecodeFinished); |
| 260 DCHECK_NE(state_, kError); | 260 DCHECK_NE(state_, kError); |
| 261 DCHECK(reset_cb_.is_null()); | 261 DCHECK(reset_cb_.is_null()); |
| 262 DCHECK(!read_cb_.is_null()); | 262 DCHECK(!read_cb_.is_null()); |
| 263 DCHECK(buffer.get()); | 263 DCHECK(buffer.get()); |
| 264 | 264 |
| 265 // Transition to kDecodeFinished on the first end of stream buffer. | 265 // Transition to kDecodeFinished on the first end of stream buffer. |
| 266 if (state_ == kNormal && buffer->IsEndOfStream()) { | 266 if (state_ == kNormal && buffer->end_of_stream()) { |
| 267 state_ = kDecodeFinished; | 267 state_ = kDecodeFinished; |
| 268 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); | 268 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); |
| 269 return; | 269 return; |
| 270 } | 270 } |
| 271 | 271 |
| 272 scoped_refptr<VideoFrame> video_frame; | 272 scoped_refptr<VideoFrame> video_frame; |
| 273 if (!Decode(buffer, &video_frame)) { | 273 if (!Decode(buffer, &video_frame)) { |
| 274 state_ = kError; | 274 state_ = kError; |
| 275 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 275 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
| 276 return; | 276 return; |
| 277 } | 277 } |
| 278 | 278 |
| 279 // Any successful decode counts! | 279 // Any successful decode counts! |
| 280 if (buffer->GetDataSize() && buffer->GetSideDataSize()) { | 280 if (buffer->data_size() && buffer->side_data_size()) { |
| 281 PipelineStatistics statistics; | 281 PipelineStatistics statistics; |
| 282 statistics.video_bytes_decoded = buffer->GetDataSize(); | 282 statistics.video_bytes_decoded = buffer->data_size(); |
| 283 statistics_cb_.Run(statistics); | 283 statistics_cb_.Run(statistics); |
| 284 } | 284 } |
| 285 | 285 |
| 286 // If we didn't get a frame we need more data. | 286 // If we didn't get a frame we need more data. |
| 287 if (!video_frame.get()) { | 287 if (!video_frame.get()) { |
| 288 ReadFromDemuxerStream(); | 288 ReadFromDemuxerStream(); |
| 289 return; | 289 return; |
| 290 } | 290 } |
| 291 | 291 |
| 292 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame); | 292 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame); |
| 293 } | 293 } |
| 294 | 294 |
| 295 bool VpxVideoDecoder::Decode( | 295 bool VpxVideoDecoder::Decode( |
| 296 const scoped_refptr<DecoderBuffer>& buffer, | 296 const scoped_refptr<DecoderBuffer>& buffer, |
| 297 scoped_refptr<VideoFrame>* video_frame) { | 297 scoped_refptr<VideoFrame>* video_frame) { |
| 298 DCHECK(video_frame); | 298 DCHECK(video_frame); |
| 299 DCHECK(!buffer->IsEndOfStream()); | 299 DCHECK(!buffer->end_of_stream()); |
| 300 | 300 |
| 301 // Pass |buffer| to libvpx. | 301 // Pass |buffer| to libvpx. |
| 302 int64 timestamp = buffer->GetTimestamp().InMicroseconds(); | 302 int64 timestamp = buffer->timestamp().InMicroseconds(); |
| 303 void* user_priv = reinterpret_cast<void*>(×tamp); | 303 void* user_priv = reinterpret_cast<void*>(×tamp); |
| 304 vpx_codec_err_t status = vpx_codec_decode(vpx_codec_, | 304 vpx_codec_err_t status = vpx_codec_decode(vpx_codec_, |
| 305 buffer->GetData(), | 305 buffer->data(), |
| 306 buffer->GetDataSize(), | 306 buffer->data_size(), |
| 307 user_priv, | 307 user_priv, |
| 308 0); | 308 0); |
| 309 if (status != VPX_CODEC_OK) { | 309 if (status != VPX_CODEC_OK) { |
| 310 LOG(ERROR) << "vpx_codec_decode() failed, status=" << status; | 310 LOG(ERROR) << "vpx_codec_decode() failed, status=" << status; |
| 311 return false; | 311 return false; |
| 312 } | 312 } |
| 313 | 313 |
| 314 // Gets pointer to decoded data. | 314 // Gets pointer to decoded data. |
| 315 vpx_codec_iter_t iter = NULL; | 315 vpx_codec_iter_t iter = NULL; |
| 316 const vpx_image_t* vpx_image = vpx_codec_get_frame(vpx_codec_, &iter); | 316 const vpx_image_t* vpx_image = vpx_codec_get_frame(vpx_codec_, &iter); |
| 317 if (!vpx_image) { | 317 if (!vpx_image) { |
| 318 *video_frame = NULL; | 318 *video_frame = NULL; |
| 319 return true; | 319 return true; |
| 320 } | 320 } |
| 321 | 321 |
| 322 if (vpx_image->user_priv != reinterpret_cast<void*>(×tamp)) { | 322 if (vpx_image->user_priv != reinterpret_cast<void*>(×tamp)) { |
| 323 LOG(ERROR) << "Invalid output timestamp."; | 323 LOG(ERROR) << "Invalid output timestamp."; |
| 324 return false; | 324 return false; |
| 325 } | 325 } |
| 326 | 326 |
| 327 const vpx_image_t* vpx_image_alpha = NULL; | 327 const vpx_image_t* vpx_image_alpha = NULL; |
| 328 if (vpx_codec_alpha_ && buffer->GetSideDataSize() >= 8) { | 328 if (vpx_codec_alpha_ && buffer->side_data_size() >= 8) { |
| 329 // Pass alpha data to libvpx. | 329 // Pass alpha data to libvpx. |
| 330 int64 timestamp_alpha = buffer->GetTimestamp().InMicroseconds(); | 330 int64 timestamp_alpha = buffer->timestamp().InMicroseconds(); |
| 331 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); | 331 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); |
| 332 | 332 |
| 333 // First 8 bytes of side data is side_data_id in big endian. | 333 // First 8 bytes of side data is side_data_id in big endian. |
| 334 const uint64 side_data_id = base::NetToHost64( | 334 const uint64 side_data_id = base::NetToHost64( |
| 335 *(reinterpret_cast<const uint64*>(buffer->GetSideData()))); | 335 *(reinterpret_cast<const uint64*>(buffer->side_data()))); |
| 336 if (side_data_id == 1) { | 336 if (side_data_id == 1) { |
| 337 status = vpx_codec_decode(vpx_codec_alpha_, | 337 status = vpx_codec_decode(vpx_codec_alpha_, |
| 338 buffer->GetSideData() + 8, | 338 buffer->side_data() + 8, |
| 339 buffer->GetSideDataSize() - 8, | 339 buffer->side_data_size() - 8, |
| 340 user_priv_alpha, | 340 user_priv_alpha, |
| 341 0); | 341 0); |
| 342 | 342 |
| 343 if (status != VPX_CODEC_OK) { | 343 if (status != VPX_CODEC_OK) { |
| 344 LOG(ERROR) << "vpx_codec_decode() failed on alpha, status=" << status; | 344 LOG(ERROR) << "vpx_codec_decode() failed on alpha, status=" << status; |
| 345 return false; | 345 return false; |
| 346 } | 346 } |
| 347 | 347 |
| 348 // Gets pointer to decoded data. | 348 // Gets pointer to decoded data. |
| 349 vpx_codec_iter_t iter_alpha = NULL; | 349 vpx_codec_iter_t iter_alpha = NULL; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 vpx_image->stride[VPX_PLANE_Y], vpx_image->d_h, video_frame->get()); | 415 vpx_image->stride[VPX_PLANE_Y], vpx_image->d_h, video_frame->get()); |
| 416 return; | 416 return; |
| 417 } | 417 } |
| 418 CopyAPlane(vpx_image_alpha->planes[VPX_PLANE_Y], | 418 CopyAPlane(vpx_image_alpha->planes[VPX_PLANE_Y], |
| 419 vpx_image->stride[VPX_PLANE_Y], | 419 vpx_image->stride[VPX_PLANE_Y], |
| 420 vpx_image->d_h, | 420 vpx_image->d_h, |
| 421 video_frame->get()); | 421 video_frame->get()); |
| 422 } | 422 } |
| 423 | 423 |
| 424 } // namespace media | 424 } // namespace media |
| OLD | NEW |