blob: 8b634c107f993dc88c4e80e57b99e6f28372b887 [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/path_service.h"
#include "base/time.h"
#include "cobalt/base/wrap_main.h"
#include "cobalt/media/sandbox/media_sandbox.h"
#include "cobalt/media/sandbox/web_media_player_helper.h"
#include "cobalt/render_tree/image.h"
#if defined(COBALT_MEDIA_SOURCE_2016)
#include "cobalt/media/base/shell_video_frame_provider.h"
#else // defined(COBALT_MEDIA_SOURCE_2016)
#include "media/base/video_frame.h"
#endif // defined(COBALT_MEDIA_SOURCE_2016)
#include "net/base/net_util.h"
namespace cobalt {
namespace media {
namespace sandbox {
namespace {
// Allows args to be pushed into a stack. This allows passing variables to
// functions that take in the int, char** args format.
struct Args {
Args(int argc, char** argv) {
for (int i = 0; i < argc; ++i) {
PushBack(argv[i]);
}
}
~Args() {
while (size()) {
PopBack();
}
}
char** get_argv() {
if (buffs_.empty()) {
return NULL;
} else {
return &buffs_[0];
}
}
char* get(int i) {
return buffs_[i];
}
int size() const {
return static_cast<int>(buffs_.size());
}
void PushBack(const char* in) {
char* string_cp = new char[strlen(in) + 1];
strcpy(string_cp, in);
buffs_.push_back(string_cp);
}
void PopBack() {
if (!buffs_.empty()) {
delete buffs_.back();
buffs_.pop_back();
}
}
std::vector<char*> buffs_;
};
using render_tree::Image;
#if !defined(COBALT_MEDIA_SOURCE_2016)
using ::media::VideoFrame;
#endif // !defined(COBALT_MEDIA_SOURCE_2016)
GURL ResolveUrl(const char* arg) {
GURL video_url(arg);
if (!video_url.is_valid()) {
// Assume the input is a path.
// Try to figure out the path to this file and convert it to a URL.
FilePath result(arg);
if (!result.IsAbsolute()) {
FilePath content_path;
PathService::Get(base::DIR_EXE, &content_path);
DCHECK(content_path.IsAbsolute());
// TODO: Get the "real" exe path.
result = content_path.DirName().DirName().Append(result);
}
video_url = net::FilePathToFileURL(result);
}
return video_url;
}
scoped_refptr<Image> FrameCB(WebMediaPlayerHelper* player_helper,
const base::TimeDelta& time) {
UNREFERENCED_PARAMETER(time);
scoped_refptr<VideoFrame> frame = player_helper->GetCurrentFrame();
return frame ? reinterpret_cast<Image*>(frame->texture_id()) : NULL;
}
int SandboxMain(int argc, char** argv) {
Args args(argc, argv);
// 2nd argument is supposed to be the url. If this doesn't exist then
// a default url pointing to the resource is used instead.
if (args.size() < 2) {
LOG(INFO) << "Warning: " << argv[0]
<< " had no url, defaulting to hard-coded path.";
const char kHardcodedMp4Url[] =
"https://storage.googleapis.com/yt-cobalt-media-element-demo/"
"progressive.mp4";
args.PushBack(kHardcodedMp4Url);
}
MediaSandbox media_sandbox(
args.size(), args.get_argv(),
FilePath(FILE_PATH_LITERAL("web_media_player_sandbox_trace.json")));
const char* mp4_hard_coded_url = args.get(1);
// Note that we can't access PathService until MediaSandbox is initialized.
GURL video_url = ResolveUrl(mp4_hard_coded_url);
if (!video_url.is_valid()) {
LOG(ERROR) << " Invalid URL: " << video_url;
return 1;
}
LOG(INFO) << "Loading " << video_url;
WebMediaPlayerHelper player_helper(media_sandbox.GetMediaModule(),
media_sandbox.GetFetcherFactory(),
video_url);
media_sandbox.RegisterFrameCB(
base::Bind(FrameCB, base::Unretained(&player_helper)));
for (;;) {
if (player_helper.IsPlaybackFinished()) {
break;
}
MessageLoop::current()->RunUntilIdle();
}
media_sandbox.RegisterFrameCB(MediaSandbox::FrameCB());
LOG(INFO) << "Playback finished.";
return 0;
}
} // namespace
} // namespace sandbox
} // namespace media
} // namespace cobalt
COBALT_WRAP_SIMPLE_MAIN(cobalt::media::sandbox::SandboxMain);