| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 static int32_t ReleaseVP9FrameBuffer(void* user_priv, | 193 static int32_t ReleaseVP9FrameBuffer(void* user_priv, |
| 194 vpx_codec_frame_buffer* fb); | 194 vpx_codec_frame_buffer* fb); |
| 195 | 195 |
| 196 // Generates a "no_longer_needed" closure that holds a reference to this pool. | 196 // Generates a "no_longer_needed" closure that holds a reference to this pool. |
| 197 base::Closure CreateFrameCallback(void* fb_priv_data); | 197 base::Closure CreateFrameCallback(void* fb_priv_data); |
| 198 | 198 |
| 199 // base::MemoryDumpProvider. | 199 // base::MemoryDumpProvider. |
| 200 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, | 200 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, |
| 201 base::trace_event::ProcessMemoryDump* pmd) override; | 201 base::trace_event::ProcessMemoryDump* pmd) override; |
| 202 | 202 |
| 203 private: | |
| 204 friend class base::RefCountedThreadSafe<VpxVideoDecoder::MemoryPool>; | |
| 205 ~MemoryPool() override; | |
| 206 | |
| 207 // Reference counted frame buffers used for VP9 decoding. Reference counting | 203 // Reference counted frame buffers used for VP9 decoding. Reference counting |
| 208 // is done manually because both chromium and libvpx has to release this | 204 // is done manually because both chromium and libvpx has to release this |
| 209 // before a buffer can be re-used. | 205 // before a buffer can be re-used. |
| 210 struct VP9FrameBuffer { | 206 struct VP9FrameBuffer { |
| 211 VP9FrameBuffer() : ref_cnt(0) {} | 207 VP9FrameBuffer() : ref_cnt(0) {} |
| 212 std::vector<uint8_t> data; | 208 std::vector<uint8_t> data; |
| 209 std::vector<uint8_t> alpha_data; |
| 213 uint32_t ref_cnt; | 210 uint32_t ref_cnt; |
| 214 }; | 211 }; |
| 215 | 212 |
| 213 private: |
| 214 friend class base::RefCountedThreadSafe<VpxVideoDecoder::MemoryPool>; |
| 215 ~MemoryPool() override; |
| 216 |
| 216 // Gets the next available frame buffer for use by libvpx. | 217 // Gets the next available frame buffer for use by libvpx. |
| 217 VP9FrameBuffer* GetFreeFrameBuffer(size_t min_size); | 218 VP9FrameBuffer* GetFreeFrameBuffer(size_t min_size); |
| 218 | 219 |
| 219 // Method that gets called when a VideoFrame that references this pool gets | 220 // Method that gets called when a VideoFrame that references this pool gets |
| 220 // destroyed. | 221 // destroyed. |
| 221 void OnVideoFrameDestroyed(VP9FrameBuffer* frame_buffer); | 222 void OnVideoFrameDestroyed(VP9FrameBuffer* frame_buffer); |
| 222 | 223 |
| 223 // Frame buffers to be used by libvpx for VP9 Decoding. | 224 // Frame buffers to be used by libvpx for VP9 Decoding. |
| 224 std::vector<VP9FrameBuffer*> frame_buffers_; | 225 std::vector<VP9FrameBuffer*> frame_buffers_; |
| 225 | 226 |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 state_ = kNormal; | 440 state_ = kNormal; |
| 440 // PostTask() to avoid calling |closure| inmediately. | 441 // PostTask() to avoid calling |closure| inmediately. |
| 441 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); | 442 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); |
| 442 } | 443 } |
| 443 | 444 |
| 444 bool VpxVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) { | 445 bool VpxVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) { |
| 445 if (config.codec() != kCodecVP8 && config.codec() != kCodecVP9) | 446 if (config.codec() != kCodecVP8 && config.codec() != kCodecVP9) |
| 446 return false; | 447 return false; |
| 447 | 448 |
| 448 // These are the combinations of codec-pixel format supported in principle. | 449 // These are the combinations of codec-pixel format supported in principle. |
| 449 // Note that VP9 does not support Alpha in the current implementation. | |
| 450 DCHECK( | 450 DCHECK( |
| 451 (config.codec() == kCodecVP8 && config.format() == PIXEL_FORMAT_YV12) || | 451 (config.codec() == kCodecVP8 && config.format() == PIXEL_FORMAT_YV12) || |
| 452 (config.codec() == kCodecVP8 && config.format() == PIXEL_FORMAT_YV12A) || | 452 (config.codec() == kCodecVP8 && config.format() == PIXEL_FORMAT_YV12A) || |
| 453 (config.codec() == kCodecVP9 && config.format() == PIXEL_FORMAT_YV12) || | 453 (config.codec() == kCodecVP9 && config.format() == PIXEL_FORMAT_YV12) || |
| 454 (config.codec() == kCodecVP9 && config.format() == PIXEL_FORMAT_YV12A) || |
| 454 (config.codec() == kCodecVP9 && config.format() == PIXEL_FORMAT_YV24)); | 455 (config.codec() == kCodecVP9 && config.format() == PIXEL_FORMAT_YV24)); |
| 455 | 456 |
| 456 #if !defined(DISABLE_FFMPEG_VIDEO_DECODERS) | 457 #if !defined(DISABLE_FFMPEG_VIDEO_DECODERS) |
| 457 // When FFmpegVideoDecoder is available it handles VP8 that doesn't have | 458 // When FFmpegVideoDecoder is available it handles VP8 that doesn't have |
| 458 // alpha, and VpxVideoDecoder will handle VP8 with alpha. | 459 // alpha, and VpxVideoDecoder will handle VP8 with alpha. |
| 459 if (config.codec() == kCodecVP8 && config.format() != PIXEL_FORMAT_YV12A) | 460 if (config.codec() == kCodecVP8 && config.format() != PIXEL_FORMAT_YV12A) |
| 460 return false; | 461 return false; |
| 461 #endif | 462 #endif |
| 462 | 463 |
| 463 CloseDecoder(); | 464 CloseDecoder(); |
| 464 | 465 |
| 465 vpx_codec_ = InitializeVpxContext(vpx_codec_, config); | 466 vpx_codec_ = InitializeVpxContext(vpx_codec_, config); |
| 466 if (!vpx_codec_) | 467 if (!vpx_codec_) |
| 467 return false; | 468 return false; |
| 468 | 469 |
| 469 // Configure VP9 to decode on our buffers to skip a data copy on decoding. | 470 // Configure VP9 to decode on our buffers to skip a data copy on |
| 471 // decoding. For YV12A-VP9, we use our buffers for the Y, U and V planes and |
| 472 // copy the A plane. |
| 470 if (config.codec() == kCodecVP9) { | 473 if (config.codec() == kCodecVP9) { |
| 471 DCHECK_NE(PIXEL_FORMAT_YV12A, config.format()); | |
| 472 DCHECK(vpx_codec_get_caps(vpx_codec_->iface) & | 474 DCHECK(vpx_codec_get_caps(vpx_codec_->iface) & |
| 473 VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER); | 475 VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER); |
| 474 | 476 |
| 475 // Move high resolution vp9 decodes off of the main media thread (otherwise | 477 // Move high resolution vp9 decodes off of the main media thread (otherwise |
| 476 // decode may block audio decoding, demuxing, and other control activities). | 478 // decode may block audio decoding, demuxing, and other control activities). |
| 477 if (config.coded_size().width() >= 1024) { | 479 if (config.coded_size().width() >= 1024) { |
| 478 offload_task_runner_ = | 480 offload_task_runner_ = |
| 479 g_vpx_offload_thread.Pointer()->RequestOffloadThread(); | 481 g_vpx_offload_thread.Pointer()->RequestOffloadThread(); |
| 480 } | 482 } |
| 481 | 483 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 if (!vpx_image) { | 544 if (!vpx_image) { |
| 543 *video_frame = nullptr; | 545 *video_frame = nullptr; |
| 544 return true; | 546 return true; |
| 545 } | 547 } |
| 546 | 548 |
| 547 if (vpx_image->user_priv != user_priv) { | 549 if (vpx_image->user_priv != user_priv) { |
| 548 DLOG(ERROR) << "Invalid output timestamp."; | 550 DLOG(ERROR) << "Invalid output timestamp."; |
| 549 return false; | 551 return false; |
| 550 } | 552 } |
| 551 | 553 |
| 552 if (!CopyVpxImageToVideoFrame(vpx_image, video_frame)) | 554 const vpx_image_t* vpx_image_alpha = nullptr; |
| 555 AlphaDecodeStatus alpha_decode_status = |
| 556 DecodeAlphaPlane(vpx_image, &vpx_image_alpha, buffer); |
| 557 if (alpha_decode_status == kAlphaPlaneError) { |
| 553 return false; | 558 return false; |
| 559 } else if (alpha_decode_status == kNoAlphaPlaneData) { |
| 560 *video_frame = nullptr; |
| 561 return true; |
| 562 } |
| 563 if (!CopyVpxImageToVideoFrame(vpx_image, vpx_image_alpha, video_frame)) { |
| 564 return false; |
| 565 } |
| 566 if (vpx_image_alpha && config_.codec() == kCodecVP8) { |
| 567 libyuv::CopyPlane(vpx_image_alpha->planes[VPX_PLANE_Y], |
| 568 vpx_image_alpha->stride[VPX_PLANE_Y], |
| 569 (*video_frame)->visible_data(VideoFrame::kAPlane), |
| 570 (*video_frame)->stride(VideoFrame::kAPlane), |
| 571 (*video_frame)->visible_rect().width(), |
| 572 (*video_frame)->visible_rect().height()); |
| 573 } |
| 554 | 574 |
| 555 (*video_frame)->set_timestamp(base::TimeDelta::FromMicroseconds(timestamp)); | 575 (*video_frame)->set_timestamp(base::TimeDelta::FromMicroseconds(timestamp)); |
| 556 | 576 |
| 557 // Default to the color space from the config, but if the bistream specifies | 577 // Default to the color space from the config, but if the bistream specifies |
| 558 // one, prefer that instead. | 578 // one, prefer that instead. |
| 559 ColorSpace color_space = config_.color_space(); | 579 ColorSpace color_space = config_.color_space(); |
| 560 if (vpx_image->cs == VPX_CS_BT_709) | 580 if (vpx_image->cs == VPX_CS_BT_709) |
| 561 color_space = COLOR_SPACE_HD_REC709; | 581 color_space = COLOR_SPACE_HD_REC709; |
| 562 else if (vpx_image->cs == VPX_CS_BT_601) | 582 else if (vpx_image->cs == VPX_CS_BT_601) |
| 563 color_space = COLOR_SPACE_SD_REC601; | 583 color_space = COLOR_SPACE_SD_REC601; |
| 564 (*video_frame) | 584 (*video_frame) |
| 565 ->metadata() | 585 ->metadata() |
| 566 ->SetInteger(VideoFrameMetadata::COLOR_SPACE, color_space); | 586 ->SetInteger(VideoFrameMetadata::COLOR_SPACE, color_space); |
| 587 return true; |
| 588 } |
| 567 | 589 |
| 568 if (!vpx_codec_alpha_) | 590 VpxVideoDecoder::AlphaDecodeStatus VpxVideoDecoder::DecodeAlphaPlane( |
| 569 return true; | 591 const struct vpx_image* vpx_image, |
| 570 | 592 const struct vpx_image** vpx_image_alpha, |
| 571 if (buffer->side_data_size() < 8) { | 593 const scoped_refptr<DecoderBuffer>& buffer) { |
| 572 // TODO(mcasas): Is this a warning or an error? | 594 if (!vpx_codec_alpha_ || buffer->side_data_size() < 8) { |
| 573 DLOG(WARNING) << "Making Alpha channel opaque due to missing input"; | 595 return kAlphaPlaneProcessed; |
| 574 const uint32_t kAlphaOpaqueValue = 255; | |
| 575 libyuv::SetPlane((*video_frame)->visible_data(VideoFrame::kAPlane), | |
| 576 (*video_frame)->stride(VideoFrame::kAPlane), | |
| 577 (*video_frame)->visible_rect().width(), | |
| 578 (*video_frame)->visible_rect().height(), | |
| 579 kAlphaOpaqueValue); | |
| 580 return true; | |
| 581 } | 596 } |
| 582 | 597 |
| 583 // First 8 bytes of side data is |side_data_id| in big endian. | 598 // First 8 bytes of side data is |side_data_id| in big endian. |
| 584 const uint64_t side_data_id = base::NetToHost64( | 599 const uint64_t side_data_id = base::NetToHost64( |
| 585 *(reinterpret_cast<const uint64_t*>(buffer->side_data()))); | 600 *(reinterpret_cast<const uint64_t*>(buffer->side_data()))); |
| 586 if (side_data_id != 1) | 601 if (side_data_id != 1) { |
| 587 return true; | 602 return kAlphaPlaneProcessed; |
| 603 } |
| 588 | 604 |
| 589 // Try and decode buffer->side_data() minus the first 8 bytes as a full frame. | 605 // Try and decode buffer->side_data() minus the first 8 bytes as a full |
| 606 // frame. |
| 590 int64_t timestamp_alpha = buffer->timestamp().InMicroseconds(); | 607 int64_t timestamp_alpha = buffer->timestamp().InMicroseconds(); |
| 591 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); | 608 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); |
| 592 { | 609 { |
| 593 TRACE_EVENT1("media", "vpx_codec_decode_alpha", "timestamp_alpha", | 610 TRACE_EVENT1("media", "vpx_codec_decode_alpha", "timestamp_alpha", |
| 594 timestamp_alpha); | 611 timestamp_alpha); |
| 595 vpx_codec_err_t status = vpx_codec_decode( | 612 vpx_codec_err_t status = vpx_codec_decode( |
| 596 vpx_codec_alpha_, buffer->side_data() + 8, buffer->side_data_size() - 8, | 613 vpx_codec_alpha_, buffer->side_data() + 8, buffer->side_data_size() - 8, |
| 597 user_priv_alpha, 0 /* deadline */); | 614 user_priv_alpha, 0 /* deadline */); |
| 598 if (status != VPX_CODEC_OK) { | 615 if (status != VPX_CODEC_OK) { |
| 599 DLOG(ERROR) << "vpx_codec_decode() failed for the alpha: " | 616 DLOG(ERROR) << "vpx_codec_decode() failed for the alpha: " |
| 600 << vpx_codec_error(vpx_codec_); | 617 << vpx_codec_error(vpx_codec_); |
| 601 return false; | 618 return kAlphaPlaneError; |
| 602 } | 619 } |
| 603 } | 620 } |
| 604 | 621 |
| 605 vpx_codec_iter_t iter_alpha = NULL; | 622 vpx_codec_iter_t iter_alpha = NULL; |
| 606 const vpx_image_t* vpx_image_alpha = | 623 *vpx_image_alpha = vpx_codec_get_frame(vpx_codec_alpha_, &iter_alpha); |
| 607 vpx_codec_get_frame(vpx_codec_alpha_, &iter_alpha); | 624 if (!(*vpx_image_alpha)) { |
| 608 if (!vpx_image_alpha) { | 625 return kNoAlphaPlaneData; |
| 609 *video_frame = nullptr; | |
| 610 return true; | |
| 611 } | 626 } |
| 612 | 627 |
| 613 if (vpx_image_alpha->user_priv != user_priv_alpha) { | 628 if ((*vpx_image_alpha)->user_priv != user_priv_alpha) { |
| 614 DLOG(ERROR) << "Invalid output timestamp on alpha."; | 629 DLOG(ERROR) << "Invalid output timestamp on alpha."; |
| 615 return false; | 630 return kAlphaPlaneError; |
| 616 } | 631 } |
| 617 | 632 |
| 618 if (vpx_image_alpha->d_h != vpx_image->d_h || | 633 if ((*vpx_image_alpha)->d_h != vpx_image->d_h || |
| 619 vpx_image_alpha->d_w != vpx_image->d_w) { | 634 (*vpx_image_alpha)->d_w != vpx_image->d_w) { |
| 620 DLOG(ERROR) << "The alpha plane dimensions are not the same as the " | 635 DLOG(ERROR) << "The alpha plane dimensions are not the same as the " |
| 621 "image dimensions."; | 636 "image dimensions."; |
| 622 return false; | 637 return kAlphaPlaneError; |
| 623 } | 638 } |
| 624 | 639 |
| 625 libyuv::CopyPlane(vpx_image_alpha->planes[VPX_PLANE_Y], | 640 if (config_.codec() == kCodecVP9) { |
| 626 vpx_image_alpha->stride[VPX_PLANE_Y], | 641 VpxVideoDecoder::MemoryPool::VP9FrameBuffer* frame_buffer = |
| 627 (*video_frame)->visible_data(VideoFrame::kAPlane), | 642 static_cast<VpxVideoDecoder::MemoryPool::VP9FrameBuffer*>( |
| 628 (*video_frame)->stride(VideoFrame::kAPlane), | 643 vpx_image->fb_priv); |
| 629 (*video_frame)->visible_rect().width(), | 644 uint64_t alpha_plane_size = |
| 630 (*video_frame)->visible_rect().height()); | 645 (*vpx_image_alpha)->stride[VPX_PLANE_Y] * (*vpx_image_alpha)->d_h; |
| 631 return true; | 646 if (frame_buffer->alpha_data.size() < alpha_plane_size) { |
| 647 frame_buffer->alpha_data.resize(alpha_plane_size); |
| 648 } |
| 649 libyuv::CopyPlane((*vpx_image_alpha)->planes[VPX_PLANE_Y], |
| 650 (*vpx_image_alpha)->stride[VPX_PLANE_Y], |
| 651 &frame_buffer->alpha_data[0], |
| 652 (*vpx_image_alpha)->stride[VPX_PLANE_Y], |
| 653 (*vpx_image_alpha)->d_w, (*vpx_image_alpha)->d_h); |
| 654 } |
| 655 return kAlphaPlaneProcessed; |
| 632 } | 656 } |
| 633 | 657 |
| 634 bool VpxVideoDecoder::CopyVpxImageToVideoFrame( | 658 bool VpxVideoDecoder::CopyVpxImageToVideoFrame( |
| 635 const struct vpx_image* vpx_image, | 659 const struct vpx_image* vpx_image, |
| 660 const struct vpx_image* vpx_image_alpha, |
| 636 scoped_refptr<VideoFrame>* video_frame) { | 661 scoped_refptr<VideoFrame>* video_frame) { |
| 637 DCHECK(vpx_image); | 662 DCHECK(vpx_image); |
| 638 | 663 |
| 639 VideoPixelFormat codec_format; | 664 VideoPixelFormat codec_format; |
| 640 switch (vpx_image->fmt) { | 665 switch (vpx_image->fmt) { |
| 641 case VPX_IMG_FMT_I420: | 666 case VPX_IMG_FMT_I420: |
| 642 codec_format = vpx_codec_alpha_ ? PIXEL_FORMAT_YV12A : PIXEL_FORMAT_YV12; | 667 codec_format = vpx_image_alpha ? PIXEL_FORMAT_YV12A : PIXEL_FORMAT_YV12; |
| 643 break; | 668 break; |
| 644 | 669 |
| 645 case VPX_IMG_FMT_I444: | 670 case VPX_IMG_FMT_I444: |
| 646 codec_format = PIXEL_FORMAT_YV24; | 671 codec_format = PIXEL_FORMAT_YV24; |
| 647 break; | 672 break; |
| 648 | 673 |
| 649 default: | 674 default: |
| 650 DLOG(ERROR) << "Unsupported pixel format: " << vpx_image->fmt; | 675 DLOG(ERROR) << "Unsupported pixel format: " << vpx_image->fmt; |
| 651 return false; | 676 return false; |
| 652 } | 677 } |
| 653 | 678 |
| 654 // The mixed |w|/|d_h| in |coded_size| is intentional. Setting the correct | 679 // The mixed |w|/|d_h| in |coded_size| is intentional. Setting the correct |
| 655 // coded width is necessary to allow coalesced memory access, which may avoid | 680 // coded width is necessary to allow coalesced memory access, which may avoid |
| 656 // frame copies. Setting the correct coded height however does not have any | 681 // frame copies. Setting the correct coded height however does not have any |
| 657 // benefit, and only risk copying too much data. | 682 // benefit, and only risk copying too much data. |
| 658 const gfx::Size coded_size(vpx_image->w, vpx_image->d_h); | 683 const gfx::Size coded_size(vpx_image->w, vpx_image->d_h); |
| 659 const gfx::Size visible_size(vpx_image->d_w, vpx_image->d_h); | 684 const gfx::Size visible_size(vpx_image->d_w, vpx_image->d_h); |
| 660 | 685 |
| 661 if (memory_pool_.get()) { | 686 if (memory_pool_.get()) { |
| 662 DCHECK_EQ(kCodecVP9, config_.codec()); | 687 DCHECK_EQ(kCodecVP9, config_.codec()); |
| 663 DCHECK(!vpx_codec_alpha_) << "Uh-oh, VP9 and Alpha shouldn't coexist."; | 688 if (vpx_image_alpha) { |
| 664 *video_frame = VideoFrame::WrapExternalYuvData( | 689 VpxVideoDecoder::MemoryPool::VP9FrameBuffer* frame_buffer = |
| 665 codec_format, | 690 static_cast<VpxVideoDecoder::MemoryPool::VP9FrameBuffer*>( |
| 666 coded_size, gfx::Rect(visible_size), config_.natural_size(), | 691 vpx_image->fb_priv); |
| 667 vpx_image->stride[VPX_PLANE_Y], | 692 *video_frame = VideoFrame::WrapExternalYuvaData( |
| 668 vpx_image->stride[VPX_PLANE_U], | 693 codec_format, coded_size, gfx::Rect(visible_size), |
| 669 vpx_image->stride[VPX_PLANE_V], | 694 config_.natural_size(), vpx_image->stride[VPX_PLANE_Y], |
| 670 vpx_image->planes[VPX_PLANE_Y], | 695 vpx_image->stride[VPX_PLANE_U], vpx_image->stride[VPX_PLANE_V], |
| 671 vpx_image->planes[VPX_PLANE_U], | 696 vpx_image_alpha->stride[VPX_PLANE_Y], vpx_image->planes[VPX_PLANE_Y], |
| 672 vpx_image->planes[VPX_PLANE_V], | 697 vpx_image->planes[VPX_PLANE_U], vpx_image->planes[VPX_PLANE_V], |
| 673 kNoTimestamp()); | 698 &frame_buffer->alpha_data[0], kNoTimestamp()); |
| 699 } else { |
| 700 *video_frame = VideoFrame::WrapExternalYuvData( |
| 701 codec_format, coded_size, gfx::Rect(visible_size), |
| 702 config_.natural_size(), vpx_image->stride[VPX_PLANE_Y], |
| 703 vpx_image->stride[VPX_PLANE_U], vpx_image->stride[VPX_PLANE_V], |
| 704 vpx_image->planes[VPX_PLANE_Y], vpx_image->planes[VPX_PLANE_U], |
| 705 vpx_image->planes[VPX_PLANE_V], kNoTimestamp()); |
| 706 } |
| 674 if (!(*video_frame)) | 707 if (!(*video_frame)) |
| 675 return false; | 708 return false; |
| 676 | 709 |
| 677 video_frame->get()->AddDestructionObserver( | 710 video_frame->get()->AddDestructionObserver( |
| 678 memory_pool_->CreateFrameCallback(vpx_image->fb_priv)); | 711 memory_pool_->CreateFrameCallback(vpx_image->fb_priv)); |
| 679 return true; | 712 return true; |
| 680 } | 713 } |
| 681 | 714 |
| 682 DCHECK(codec_format == PIXEL_FORMAT_YV12 || | 715 DCHECK(codec_format == PIXEL_FORMAT_YV12 || |
| 683 codec_format == PIXEL_FORMAT_YV12A); | 716 codec_format == PIXEL_FORMAT_YV12A); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 697 (*video_frame)->visible_data(VideoFrame::kUPlane), | 730 (*video_frame)->visible_data(VideoFrame::kUPlane), |
| 698 (*video_frame)->stride(VideoFrame::kUPlane), | 731 (*video_frame)->stride(VideoFrame::kUPlane), |
| 699 (*video_frame)->visible_data(VideoFrame::kVPlane), | 732 (*video_frame)->visible_data(VideoFrame::kVPlane), |
| 700 (*video_frame)->stride(VideoFrame::kVPlane), coded_size.width(), | 733 (*video_frame)->stride(VideoFrame::kVPlane), coded_size.width(), |
| 701 coded_size.height()); | 734 coded_size.height()); |
| 702 | 735 |
| 703 return true; | 736 return true; |
| 704 } | 737 } |
| 705 | 738 |
| 706 } // namespace media | 739 } // namespace media |
| OLD | NEW |