190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "media/filters/fake_video_decoder.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/callback_helpers.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/location.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "media/base/bind_to_loop.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/base/test_helpers.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace media { 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)FakeVideoDecoder::FakeVideoDecoder(int decoding_delay) 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : message_loop_(base::MessageLoopProxy::current()), 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_(this), 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoding_delay_(decoding_delay), 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) state_(UNINITIALIZED), 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch total_bytes_decoded_(0) { 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_GE(decoding_delay, 0); 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)FakeVideoDecoder::~FakeVideoDecoder() { 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(state_, UNINITIALIZED); 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeVideoDecoder::Initialize(const VideoDecoderConfig& config, 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const PipelineStatusCB& status_cb) { 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(config.IsValidConfig()); 33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(decode_cb_.IsNull()) << "No reinitialization during pending decode."; 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(reset_cb_.IsNull()) << "No reinitialization during pending reset."; 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_this_ = weak_factory_.GetWeakPtr(); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch current_config_ = config; 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) init_cb_.SetCallback(BindToCurrentLoop(status_cb)); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!decoded_frames_.empty()) { 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DVLOG(1) << "Decoded frames dropped during reinitialization."; 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoded_frames_.clear(); 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) state_ = NORMAL; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) init_cb_.RunOrHold(PIPELINE_OK); 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const DecodeCB& decode_cb) { 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(decode_cb_.IsNull()) << "Overlapping decodes are not supported."; 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(reset_cb_.IsNull()); 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_LE(decoded_frames_.size(), static_cast<size_t>(decoding_delay_)); 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch decode_cb_.SetCallback(BindToCurrentLoop(base::Bind( 59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch &FakeVideoDecoder::OnFrameDecoded, weak_this_, buffer_size, decode_cb))); 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (buffer->end_of_stream() && decoded_frames_.empty()) { 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) decode_cb_.RunOrHold(kOk, VideoFrame::CreateEOSFrame()); 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!buffer->end_of_stream()) { 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(VerifyFakeVideoBufferForTest(buffer, current_config_)); 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateColorFrame( 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch current_config_.coded_size(), 0, 0, 0, buffer->timestamp()); 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch decoded_frames_.push_back(video_frame); 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (decoded_frames_.size() <= static_cast<size_t>(decoding_delay_)) { 73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch decode_cb_.RunOrHold(kNotEnoughData, scoped_refptr<VideoFrame>()); 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<VideoFrame> frame = decoded_frames_.front(); 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch decoded_frames_.pop_front(); 80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch decode_cb_.RunOrHold(kOk, frame); 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::Reset(const base::Closure& closure) { 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(reset_cb_.IsNull()); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reset_cb_.SetCallback(BindToCurrentLoop(closure)); 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Defer the reset if a decode is pending. 89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!decode_cb_.IsNull()) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DoReset(); 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::Stop(const base::Closure& closure) { 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stop_cb_.SetCallback(BindToCurrentLoop(closure)); 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Defer the stop if an init, a decode or a reset is pending. 100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!init_cb_.IsNull() || !decode_cb_.IsNull() || !reset_cb_.IsNull()) 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DoStop(); 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::HoldNextInit() { 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) init_cb_.HoldCallback(); 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::HoldNextRead() { 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch decode_cb_.HoldCallback(); 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::HoldNextReset() { 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reset_cb_.HoldCallback(); 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::HoldNextStop() { 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stop_cb_.HoldCallback(); 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::SatisfyInit() { 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 128558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(decode_cb_.IsNull()); 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(reset_cb_.IsNull()); 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) init_cb_.RunHeldCallback(); 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!stop_cb_.IsNull()) 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DoStop(); 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::SatisfyRead() { 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch decode_cb_.RunHeldCallback(); 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!reset_cb_.IsNull()) 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DoReset(); 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (reset_cb_.IsNull() && !stop_cb_.IsNull()) 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DoStop(); 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::SatisfyReset() { 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(decode_cb_.IsNull()); 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reset_cb_.RunHeldCallback(); 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!stop_cb_.IsNull()) 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DoStop(); 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::SatisfyStop() { 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(decode_cb_.IsNull()); 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(reset_cb_.IsNull()); 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stop_cb_.RunHeldCallback(); 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::DoReset() { 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(decode_cb_.IsNull()); 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!reset_cb_.IsNull()); 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoded_frames_.clear(); 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reset_cb_.RunOrHold(); 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void FakeVideoDecoder::DoStop() { 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(message_loop_->BelongsToCurrentThread()); 175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(decode_cb_.IsNull()); 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(reset_cb_.IsNull()); 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!stop_cb_.IsNull()); 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) state_ = UNINITIALIZED; 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) decoded_frames_.clear(); 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stop_cb_.RunOrHold(); 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FakeVideoDecoder::OnFrameDecoded( 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int buffer_size, 186558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const DecodeCB& decode_cb, 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Status status, 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const scoped_refptr<VideoFrame>& video_frame) { 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (status == kOk || status == kNotEnoughData) 1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch total_bytes_decoded_ += buffer_size; 191558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch decode_cb.Run(status, video_frame); 1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace media 195