blob: 9227fabae552c5390a0166ffce88b1d60148f129 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/time.h"
#include "cobalt/base/wrap_main.h"
#include "cobalt/media/sandbox/demuxer_helper.h"
#include "cobalt/media/sandbox/media_sandbox.h"
#include "cobalt/render_tree/image.h"
#include "media/base/bind_to_loop.h"
#include "media/base/video_frame.h"
#if defined(__LB_LINUX__)
#include "media/filters/shell_raw_video_decoder_linux.h"
#elif defined(__LB_PS3__)
#include "media/filters/shell_raw_video_decoder_ps3.h"
#else
#include "media/filters/shell_raw_video_decoder_stub.h"
#endif
using base::Bind;
using base::Unretained;
using cobalt::render_tree::Image;
using ::media::BindToCurrentLoop;
using ::media::DecoderBuffer;
using ::media::Demuxer;
using ::media::DemuxerStream;
using ::media::PipelineStatus;
using ::media::ShellRawVideoDecoder;
using ::media::VideoDecoder;
using ::media::VideoFrame;
namespace cobalt {
namespace media {
namespace sandbox {
namespace {
class RawVideoDecoderSandbox {
public:
void SetDemuxer(const scoped_refptr<Demuxer>& demuxer) {
DCHECK(demuxer);
scoped_refptr<DemuxerStream> stream =
demuxer->GetStream(::media::DemuxerStream::VIDEO);
DCHECK(stream);
demuxer_ = demuxer;
#if defined(__LB_LINUX__)
decoder_ = ::media::CreateShellRawVideoDecoderLinux(
stream->video_decoder_config(), NULL, false);
#elif defined(__LB_PS3__)
decoder_ = ::media::CreateShellRawVideoDecoderPS3(
stream->video_decoder_config(), NULL, false);
#else
decoder_ = ::media::CreateShellRawVideoDecoderStub(
stream->video_decoder_config(), NULL, false);
#endif
stream->Read(Bind(&RawVideoDecoderSandbox::ReadCB, Unretained(this)));
}
scoped_refptr<Image> GetCurrentFrame(const base::TimeDelta& time) {
UNREFERENCED_PARAMETER(time);
return current_frame_
? reinterpret_cast<Image*>(current_frame_->texture_id())
: NULL;
}
private:
void DecodeCB(const scoped_refptr<DecoderBuffer>& buffer,
ShellRawVideoDecoder::DecodeStatus status,
const scoped_refptr<VideoFrame>& frame) {
scoped_refptr<DemuxerStream> stream =
demuxer_->GetStream(::media::DemuxerStream::VIDEO);
if (status == ShellRawVideoDecoder::FRAME_DECODED) {
DCHECK(frame);
if (frame->IsEndOfStream()) {
current_frame_ = NULL;
decoder_.reset();
demuxer_->Stop(MessageLoop::QuitWhenIdleClosure());
return;
} else {
current_frame_ = frame;
}
stream->Read(Bind(&RawVideoDecoderSandbox::ReadCB, Unretained(this)));
} else if (status == ShellRawVideoDecoder::NEED_MORE_DATA) {
stream->Read(Bind(&RawVideoDecoderSandbox::ReadCB, Unretained(this)));
} else if (status == ShellRawVideoDecoder::RETRY_WITH_SAME_BUFFER) {
if (frame) {
current_frame_ = frame;
}
decoder_->Decode(buffer,
BindToCurrentLoop(Bind(&RawVideoDecoderSandbox::DecodeCB,
Unretained(this), buffer)));
} else {
NOTREACHED();
}
}
void ReadCB(DemuxerStream::Status status,
const scoped_refptr<DecoderBuffer>& buffer) {
DCHECK_EQ(status, DemuxerStream::kOk);
decoder_->Decode(buffer,
BindToCurrentLoop(Bind(&RawVideoDecoderSandbox::DecodeCB,
Unretained(this), buffer)));
}
scoped_refptr<Demuxer> demuxer_;
scoped_ptr<ShellRawVideoDecoder> decoder_;
scoped_refptr<VideoFrame> current_frame_;
};
int SandboxMain(int argc, char** argv) {
DCHECK_GT(argc, 1) << " Usage: " << argv[0] << " <url>";
GURL video_url(argv[1]);
DCHECK(video_url.is_valid()) << " \"" << argv[1] << "\" is not a valid URL.";
MediaSandbox media_sandbox(
argc, argv,
FilePath(FILE_PATH_LITERAL("raw_video_decoder_sandbox_trace.json")));
RawVideoDecoderSandbox decoder_sandbox;
DemuxerHelper demuxer_helper(
base::MessageLoopProxy::current(), media_sandbox.GetFetcherFactory(),
video_url, BindToCurrentLoop(Bind(&RawVideoDecoderSandbox::SetDemuxer,
Unretained(&decoder_sandbox))));
media_sandbox.RegisterFrameCB(Bind(&RawVideoDecoderSandbox::GetCurrentFrame,
Unretained(&decoder_sandbox)));
MessageLoop::current()->Run();
LOG(INFO) << "Video playback finished successfully.";
media_sandbox.RegisterFrameCB(MediaSandbox::FrameCB());
return 0;
}
} // namespace
} // namespace sandbox
} // namespace media
} // namespace cobalt
COBALT_WRAP_SIMPLE_MAIN(cobalt::media::sandbox::SandboxMain);