summaryrefslogtreecommitdiffstats
path: root/media/tools
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-30 06:13:25 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-30 06:13:25 +0000
commitf7ca36ad23d11a43fe7fec520cbe9cd7d51b76fe (patch)
treec3acb238d18f6f5352e72072ccc3689938822720 /media/tools
parent65acb404991f9ad0aee5cee1301805855373402b (diff)
downloadchromium_src-f7ca36ad23d11a43fe7fec520cbe9cd7d51b76fe.zip
chromium_src-f7ca36ad23d11a43fe7fec520cbe9cd7d51b76fe.tar.gz
chromium_src-f7ca36ad23d11a43fe7fec520cbe9cd7d51b76fe.tar.bz2
Removing mfplayer and mfdecoder tools.
They've been unused for a year and are trivial to revert should we need them again. Review URL: http://codereview.chromium.org/8083011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103430 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/tools')
-rw-r--r--media/tools/mfdecoder/README.chromium46
-rw-r--r--media/tools/mfdecoder/mfdecoder.cc323
-rw-r--r--media/tools/mfdecoder/mfdecoder.h89
-rw-r--r--media/tools/mfplayer/README.chromium27
-rw-r--r--media/tools/mfplayer/mf_playback_main.cc326
-rw-r--r--media/tools/mfplayer/mfplayer.cc823
-rw-r--r--media/tools/mfplayer/mfplayer.h168
7 files changed, 0 insertions, 1802 deletions
diff --git a/media/tools/mfdecoder/README.chromium b/media/tools/mfdecoder/README.chromium
deleted file mode 100644
index 422161d..0000000
--- a/media/tools/mfdecoder/README.chromium
+++ /dev/null
@@ -1,46 +0,0 @@
-This tool decodes a H.264 format video into YV12 frames and draws them onto
-a window.
-
-The program uses Media Foundation to do much of the work. Specifically, it
-uses the Source Reader (IMFSourceReader) to read from a file and the built-in
-H.264 decoder (as an IMFTransform) to decode the video file into YV12 frames.
-The decoding can be done with or without hardware acceleration.
-
-If decoding is done without hardware acceleration, then the YV12 frames are
-converted into RGB using ConvertYUVToRGB32() provided in
-media/base/yuv_convert.h. They are then drawn to a window using StretchDIBits()
-provided in ui/gfx/gdi_util.h.
-
-If decoding is done with hardware acceleration, then the frames are obtained
-from a D3D surface (IDirect3DSurface9). It is then drawn through calling
-methods of a D3D device (IDirect3DDevice9) that is associated with the
-video window that we created during initialization.
-
-The painting is done using a MessageLoop that posts paint tasks every 30ms
-until the end of stream is reached. Thus the painting part acts like a
-playback.
-
-Note: The current version uses a synchronous version of source reader. An
-asynchronous version will likely to be more useful and have better
-performance.
-
-Note2: The maximum resolution supported by Microsoft's H.264 decoder is
-1920 by 1088 pixels. If you try to feed it a larger video, it will "fail
-to determine frame size." This is an inherent limitation that cannot be fixed
-unless a different decoder is used.
-
-
-Requirements: Windows 7
-
-usage: mfdecoder (-s|-h) (-d|-r|-f) input-file
-flags:
--s: Use software decoding
--h: Uses hardware decoding
-
--d: Decode to YV12 as fast as possible, no rendering or color-space conversion
--r: Render to window
--f: Decode+render as fast as possible
-
-WARNING: Using both -h and -f, or opening too many windows with -h may lead to
-driver crash / system instability. Realistically, you will never want to
-do this unless you want to push the limits of the GPU ...
diff --git a/media/tools/mfdecoder/mfdecoder.cc b/media/tools/mfdecoder/mfdecoder.cc
deleted file mode 100644
index cef40d42..0000000
--- a/media/tools/mfdecoder/mfdecoder.cc
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifdef WINVER
-#undef WINVER
-#define WINVER 0x0601 // Windows 7
-#endif
-
-#include <d3d9.h>
-#include <dxva2api.h>
-#include <evr.h>
-#include <mfapi.h>
-#include <mferror.h>
-#include <mfreadwrite.h> // depends on evr.h
-#include <windows.h>
-
-#include "base/logging.h"
-#include "base/win/scoped_comptr.h"
-#include "media/tools/mfdecoder/mfdecoder.h"
-
-#pragma comment(lib, "shlwapi.lib")
-#pragma comment(lib, "strmiids.lib")
-#pragma comment(lib, "dxva2.lib")
-#pragma comment(lib, "d3d9.lib")
-#pragma comment(lib, "mfuuid.lib")
-#pragma comment(lib, "mfplat.lib")
-#pragma comment(lib, "mf.lib")
-#pragma comment(lib, "evr.lib")
-#pragma comment(lib, "mfreadwrite.lib")
-
-namespace media {
-
-MFDecoder::MFDecoder(bool use_dxva2)
- : width_(0),
- height_(0),
- use_dxva2_(use_dxva2),
- initialized_(false),
- com_lib_initialized_(false),
- mf_lib_initialized_(false),
- reader_(NULL),
- video_stream_index_(-1),
- mfbuffer_stride_(0),
- end_of_stream_(false) {
-}
-
-MFDecoder::~MFDecoder() {
- if (reader_)
- reader_->Release();
- if (com_lib_initialized_)
- CoUninitialize();
- if (mf_lib_initialized_)
- MFShutdown();
-}
-
-bool MFDecoder::Init(const wchar_t* source_url,
- IDirect3DDeviceManager9* dev_manager) {
- if (initialized_)
- return true;
- if (source_url == NULL) {
- LOG(ERROR) << "Init: source_url cannot be NULL";
- return false;
- }
- if (use_dxva2_ && dev_manager == NULL) {
- LOG(ERROR) << "Init failed: DXVA2 specified, but no manager provided";
- return false;
- } else if (!use_dxva2_ && dev_manager != NULL) {
- LOG(WARNING) << "Init: Warning: DXVA2 not specified but manager is "
- << "provided -- the manager will be ignored";
- dev_manager = NULL;
- }
- if (!InitLibraries())
- return false;
- if (!InitSourceReader(source_url, dev_manager))
- return false;
-
- // By now, |reader_| should be initialized.
- if (!SelectVideoStreamOnly())
- return false;
-
- // |video_stream_index_| should be pointing to the video stream now.
- if (!InitVideoInfo(dev_manager))
- return false;
-
- initialized_ = true;
- return true;
-}
-
-IMFSample* MFDecoder::ReadVideoSample() {
- CHECK(reader_ != NULL);
- CHECK_GE(video_stream_index_, 0);
- base::win::ScopedComPtr<IMFSample> video_sample;
- DWORD actual_stream_index;
- DWORD output_flags;
-
- // TODO(imcheng): Get timestamp back instead by passing in a timestamp pointer
- // instead of NULL.
- // TODO(imcheng): Read samples asynchronously and use callbacks.
- HRESULT hr = reader_->ReadSample(video_stream_index_,
- 0, // No flags.
- &actual_stream_index,
- &output_flags,
- NULL,
- video_sample.Receive());
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to read video sample";
- return NULL;
- } else {
- if (output_flags & MF_SOURCE_READERF_ERROR) {
- LOG(ERROR) << "output_flag error while reading video sample";
- return NULL;
- }
- if (output_flags & MF_SOURCE_READERF_ENDOFSTREAM) {
- VLOG(1) << "Video sample reading has reached the end of stream";
- end_of_stream_ = true;
- return NULL;
- }
- if (static_cast<int>(actual_stream_index) != video_stream_index_) {
- LOG(ERROR) << "Received sample from stream " << actual_stream_index
- << " instead of intended video stream " << video_stream_index_;
- return NULL;
- }
- if (video_sample.get() == NULL)
- LOG(WARNING) << "Video sample is NULL and not at end of stream!";
- return video_sample.Detach();
- }
-}
-
-// Private methods
-
-bool MFDecoder::InitLibraries() {
- // TODO(imcheng): Move initialization to a singleton.
- HRESULT hr;
- hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
- if (FAILED(hr)) {
- LOG(ERROR) << "CoInitializeEx failed during InitLibraries()";
- return false;
- }
- com_lib_initialized_ = true;
-
- hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
- if (FAILED(hr)) {
- LOG(ERROR) << "MFStartup failed during InitLibraries()";
- CoUninitialize();
- com_lib_initialized_ = false;
- return false;
- }
- mf_lib_initialized_ = true;
-
- return true;
-}
-
-bool MFDecoder::InitSourceReader(const wchar_t* source_url,
- IDirect3DDeviceManager9* dev_manager) {
- CHECK(source_url != NULL);
- base::win::ScopedComPtr<IMFAttributes> reader_attributes;
- if (use_dxva2_) {
- reader_attributes.Attach(GetDXVA2AttributesForSourceReader(dev_manager));
- if (reader_attributes == NULL) {
- LOG(ERROR) << "Failed to create DXVA2 attributes for source reader";
- return false;
- }
- }
- HRESULT hr = MFCreateSourceReaderFromURL(source_url, reader_attributes.get(),
- &reader_);
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to create source reader";
- return false;
- }
- VLOG(1) << "Source reader created";
- return true;
-}
-
-IMFAttributes* MFDecoder::GetDXVA2AttributesForSourceReader(
- IDirect3DDeviceManager9* dev_manager) {
- if (!use_dxva2_)
- return NULL;
- CHECK(dev_manager != NULL);
- base::win::ScopedComPtr<IMFAttributes> attributes;
-
- // Create an attribute store with an initial size of 2.
- HRESULT hr = MFCreateAttributes(attributes.Receive(), 2);
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to create DXVA2 attributes for source reader";
- return NULL;
- }
- hr = attributes->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, dev_manager);
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to set D3D9 manager to attribute";
- return NULL;
- }
- hr = attributes->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, FALSE);
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to set DISABLE_DXVA to false";
- return NULL;
- }
- return attributes.Detach();
-}
-
-bool MFDecoder::SelectVideoStreamOnly() {
- CHECK(reader_ != NULL);
- HRESULT hr;
- for (DWORD stream_index = 0; ; stream_index++) {
- base::win::ScopedComPtr<IMFMediaType> media_type;
- hr = reader_->GetCurrentMediaType(stream_index, media_type.Receive());
- if (SUCCEEDED(hr)) {
- GUID major_type;
- hr = media_type->GetMajorType(&major_type);
- if (FAILED(hr)) {
- LOG(ERROR) << "Could not determine major type for stream "
- << stream_index;
- return false;
- }
- if (major_type != MFMediaType_Video) {
- // Deselect any non-video streams.
- hr = reader_->SetStreamSelection(stream_index, FALSE);
- if (FAILED(hr)) {
- LOG(ERROR) << "Could not deselect stream " << stream_index;
- return false;
- }
- } else {
- // Ensure that the video stream is selected.
- hr = reader_->SetStreamSelection(stream_index, TRUE);
- if (FAILED(hr)) {
- LOG(ERROR) << "Could not select video stream " << stream_index;
- return false;
- }
- video_stream_index_ = stream_index;
- VLOG(1) << "Video stream is at " << video_stream_index_;
- }
- } else if (hr == MF_E_INVALIDSTREAMNUMBER) {
- break; // No more streams, quit.
- } else {
- LOG(ERROR) << "Error occurred while getting stream " << stream_index;
- return false;
- }
- } // end of for-loop
- return video_stream_index_ >= 0;
-}
-
-bool MFDecoder::InitVideoInfo(IDirect3DDeviceManager9* dev_manager) {
- CHECK(reader_ != NULL);
- CHECK_GE(video_stream_index_, 0);
- base::win::ScopedComPtr<IMFMediaType> video_type;
- HRESULT hr = reader_->GetCurrentMediaType(video_stream_index_,
- video_type.Receive());
- if (FAILED(hr)) {
- LOG(ERROR) << "InitVideoInfo: Failed to get video stream";
- return false;
- }
- GUID video_subtype;
- hr = video_type->GetGUID(MF_MT_SUBTYPE, &video_subtype);
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to determine video subtype";
- return false;
- }
- VLOG(1) << "Video subtype is "
- << ((video_subtype == MFVideoFormat_H264) ? "" : "NOT ") << "H.264";
- hr = MFGetAttributeSize(video_type, MF_MT_FRAME_SIZE,
- reinterpret_cast<UINT32*>(&width_),
- reinterpret_cast<UINT32*>(&height_));
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to determine frame size";
- return false;
- }
- VLOG(1) << "Video width: " << width_ << ", height: " << height_;
-
- // Try to change to YV12 output format.
- const GUID kOutputVideoSubtype = MFVideoFormat_YV12;
- base::win::ScopedComPtr<IMFMediaType> output_video_format;
- hr = MFCreateMediaType(output_video_format.Receive());
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to create a IMFMediaType object for video output";
- return false;
- }
- if (SUCCEEDED(hr))
- hr = output_video_format->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
- if (SUCCEEDED(hr))
- hr = output_video_format->SetGUID(MF_MT_SUBTYPE, kOutputVideoSubtype);
- if (SUCCEEDED(hr)) {
- hr = MFSetAttributeSize(output_video_format, MF_MT_FRAME_SIZE, width_,
- height_);
- }
- if (SUCCEEDED(hr)) {
- hr = reader_->SetCurrentMediaType(video_stream_index_,
- NULL, // Reserved.
- output_video_format);
- }
- if (SUCCEEDED(hr)) {
- hr = MFGetStrideForBitmapInfoHeader(
- kOutputVideoSubtype.Data1,
- width_,
- reinterpret_cast<LONG*>(&mfbuffer_stride_));
- }
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to change output video format and determine stride";
- return false;
- }
- VLOG(1) << "IMFMediaBuffer stride: " << mfbuffer_stride_;
-
- // Send a message to the decoder to tell it to use DXVA2.
- if (use_dxva2_) {
- // Call GetServiceForStream to get the interface to the video decoder.
- base::win::ScopedComPtr<IMFTransform> video_decoder;
- hr = reader_->GetServiceForStream(video_stream_index_, GUID_NULL,
- IID_PPV_ARGS(video_decoder.Receive()));
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to obtain interface to decoder";
- return false;
- } else {
- hr = video_decoder->ProcessMessage(
- MFT_MESSAGE_SET_D3D_MANAGER,
- reinterpret_cast<ULONG_PTR>(dev_manager));
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to send DXVA message to decoder";
- return false;
- }
- }
- }
- return true;
-}
-
-} // namespace media
diff --git a/media/tools/mfdecoder/mfdecoder.h b/media/tools/mfdecoder/mfdecoder.h
deleted file mode 100644
index e280f9c..0000000
--- a/media/tools/mfdecoder/mfdecoder.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
-// source code is governed by a BSD-style license that can be found in the
-// LICENSE file.
-
-#ifndef MEDIA_TOOLS_MFDECODER_MFDECODER_H_
-#define MEDIA_TOOLS_MFDECODER_MFDECODER_H_
-
-#include "base/basictypes.h"
-
-struct IDirect3DDeviceManager9;
-struct IMFAttributes;
-struct IMFSample;
-struct IMFSourceReader;
-
-namespace media {
-
-class MFDecoder {
- public:
- explicit MFDecoder(bool use_dxva2);
- ~MFDecoder();
-
- // This method is to be called after the constructor. This method
- // creates a source reader with the given URL, and initializes the member
- // variables that are related to the video, such as the dimensions of the
- // video, stride, index of video stream, etc.
- // If DXVA2 was specified in the constructor, then the given device manager
- // is passed into the source reader so that it can do hardware accelerated
- // decoding.
- // Returns: true on success.
- bool Init(const wchar_t* source_url, IDirect3DDeviceManager9* dev_manager);
- int width() const { return width_; }
- int height() const { return height_; }
- bool use_dxva2() const { return use_dxva2_; }
- bool initialized() const { return initialized_; }
- int mfbuffer_stride() const { return mfbuffer_stride_; }
- bool end_of_stream() const { return end_of_stream_; }
-
- // Reads a single video sample. If end of stream is reached, |end_of_stream_|
- // will be set to true.
- // Returns: Pointer to a IMFSample on success, NULL otherwise. Caller is
- // responsible for releasing the sample.
- IMFSample* ReadVideoSample();
-
- private:
- // Initializes the COM and MF libraries for this decoder. The two libraries
- // are either both initialized, or both uninitialized.
- // Returns: true if both libraries were successfully initialized.
- bool InitLibraries();
-
- // Initializes the source reader with the given URL, and device manager if
- // DXVA2 is enabled on the decoder.
- // Returns: true on success.
- bool InitSourceReader(const wchar_t* source_url,
- IDirect3DDeviceManager9* dev_manager);
-
- // Called by InitSourceReader() if DXVA2 is to be used. Creates an attribute
- // store that can be passed to the source reader constructor.
- // Caller is responsible for releasing the attribute object.
- // Returns: pointer to an IMFAttributes object if successful, NULL otherwise.
- IMFAttributes* GetDXVA2AttributesForSourceReader(
- IDirect3DDeviceManager9* dev_manager);
-
- // Deselects any non-video streams, ensures the video stream is selected, and
- // initializes |video_stream_index_| to that video stream.
- // Returns: true on success.
- bool SelectVideoStreamOnly();
-
- // Obtains information about the video (height, width, etc.) and sets the
- // output format to YV12.
- // Returns: true on success.
- bool InitVideoInfo(IDirect3DDeviceManager9* dev_manager);
-
- int width_;
- int height_;
- bool use_dxva2_;
- bool initialized_;
- bool com_lib_initialized_;
- bool mf_lib_initialized_;
- IMFSourceReader* reader_;
- int video_stream_index_;
- int mfbuffer_stride_;
- bool end_of_stream_;
-
- DISALLOW_COPY_AND_ASSIGN(MFDecoder);
-};
-
-} // namespace media
-
-#endif // MEDIA_TOOLS_MFDECODER_MFDECODER_H_
diff --git a/media/tools/mfplayer/README.chromium b/media/tools/mfplayer/README.chromium
deleted file mode 100644
index 18a4517..0000000
--- a/media/tools/mfplayer/README.chromium
+++ /dev/null
@@ -1,27 +0,0 @@
-This sample demonstrates how to play clear content in Media Foundation. The
-code is taken and modified from Media Foundation sample code website:
-http://code.msdn.microsoft.com/mediafoundation
-
-Requirements: Windows 7
-
-6/28/2010 - Version 1
-6/29/2010 - Added option for saving file in .mp4 format
-7/1/2010 - Changed return types of public methods, disabled audio since the
-purpose is to use Media Foundation's video capabilities only.
-
-Usage: mf_playback.exe (-r|-f) (-s|-h) input-file [output-file]
-There are two flags that needs to be specified, plus an input file.
-
-Flag 1:
--r: Render to window. This is the playback mode. During playback mode, press
- spacebar to switch between play/pause.
--f: Transcode. A media file is transcoded into mp4 format (H.264/AAC). An
- output file needs to be specified as the argument after input file.
-
-Flag 2:
--s: Software decoding.
--h: Hardware decoding using DXVA2. Not implemented yet.
-
-
-Todos:
- - Add flags to support hardware decoding
diff --git a/media/tools/mfplayer/mf_playback_main.cc b/media/tools/mfplayer/mf_playback_main.cc
deleted file mode 100644
index 3ce897c..0000000
--- a/media/tools/mfplayer/mf_playback_main.cc
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This header is placed first to avoid compiler warning.
-#include "media/tools/mfplayer/mfplayer.h"
-
-#include <mfapi.h>
-#define STRSAFE_NO_DEPRECATE
-#include <strsafe.h>
-
-#include <cassert>
-
-namespace mfplayer {
-
-const wchar_t g_window_title[] = L"MFBasicPlayback";
-const wchar_t g_window_class[] = L"Chrome_MFBasicPlayback";
-
-// True if there is no video playing, so we have to paint the window ourselves.
-bool g_repaint_client = true;
-
-// Global player object.
-// Note: After WM_CREATE is processed, g_main_player remains valid until the
-// window is destroyed.
-MFPlayer* g_main_player = NULL;
-
-wchar_t* g_input_file_name = NULL;
-
-void Usage() {
- fprintf(stderr, "Usage: mf_playback (-r|-f) (-h|-s) file [out-file]\n");
-}
-
-void UpdateUI(HWND window_handle, MFPlayer::PlayerState state) {
- assert(g_main_player != NULL);
-
- bool playback_started = state == MFPlayer::STARTED ||
- state == MFPlayer::PAUSED;
- g_repaint_client = !playback_started || !g_main_player->HasVideo();
-}
-
-// Shows a message box with an error message.
-void NotifyError(HWND window_handle, PCWSTR error_message, HRESULT error_code) {
- const size_t kMessageLen = 512;
- wchar_t message[kMessageLen];
-
- HRESULT hr = StringCchPrintf(message, kMessageLen, L"%s (HRESULT = 0x%X)",
- error_message, error_code);
- if (SUCCEEDED(hr))
- MessageBox(window_handle, message, NULL, MB_OK | MB_ICONERROR);
-}
-
-// Converts a ANSI string to an Unicode string. It is caller's responsibility
-// to call delete[] on the returned string when it is no longer being used.
-int ConvertANSIStringToUnicode(const char* source, wchar_t** dest) {
- DWORD string_length = MultiByteToWideChar(CP_ACP, 0, source, -1, NULL, 0);
- if (string_length == 0) {
- fprintf(stderr, "Error getting size of ansi string: %s\n", source);
- return 1;
- }
- *dest = new wchar_t[string_length];
- if (*dest == NULL) {
- fprintf(stderr, "Error allocating unicode string buffer\n");
- return 1;
- }
- if (MultiByteToWideChar(CP_ACP, 0, source, string_length, *dest,
- string_length) == 0) {
- fprintf(stderr, "Error converting ansi string to unicode: %#X",
- GetLastError());
- return 1;
- }
- return 0;
-}
-
-// Callback when window is created. It has been modified to both create
-// the media player and starts playing the provided file in one go.
-LRESULT OnCreateWindow(HWND window_handle) {
- // Initialize the player object.
- HRESULT hr = MFPlayer::CreateInstance(window_handle, window_handle,
- true, &g_main_player);
- if (SUCCEEDED(hr)) {
- UpdateUI(window_handle, MFPlayer::CLOSED);
- } else {
- NotifyError(NULL, L"Could not initialize the player object.", hr);
- return -1; // Destroy the window
- }
-
- // Play the video
- assert(g_input_file_name != NULL);
-
- // No output URL, just the window.
- hr = g_main_player->OpenURL(g_input_file_name, NULL);
- if (SUCCEEDED(hr)) {
- UpdateUI(window_handle, MFPlayer::OPEN_PENDING);
- return 0;
- } else {
- _fwprintf_p(stderr, L"Fatal error: cannot open file %s\n",
- g_input_file_name);
- return -1; // Destroy the window
- }
-}
-
-void OnPaint(HWND window_handle) {
- if (g_repaint_client) {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(window_handle, &ps);
- // The video is not playing, so we must paint the application window.
- RECT rc;
- GetClientRect(window_handle, &rc);
- FillRect(hdc, &rc, reinterpret_cast<HBRUSH>(COLOR_WINDOW));
- EndPaint(window_handle, &ps);
- } else {
- // Video is playing. Ask the player to repaint.
- g_main_player->Repaint();
- }
-}
-
-void OnKeyPress(WPARAM key) {
- switch (key) {
- // Space key toggles between running and paused.
- case VK_SPACE:
- if (g_main_player->state() == MFPlayer::STARTED)
- g_main_player->Pause();
- else if (g_main_player->state() == MFPlayer::PAUSED)
- g_main_player->Play();
- break;
- }
-}
-
-void OnPlayerEvent(HWND window_handle, WPARAM event) {
- HRESULT hr = S_OK;
-
- hr = g_main_player->HandleEvent(event);
- if (FAILED(hr))
- NotifyError(window_handle, L"An error occurred.", hr);
- UpdateUI(window_handle, g_main_player->state());
-}
-
-LRESULT CALLBACK CallbackProc(HWND window_handle, UINT message, WPARAM w_param,
- LPARAM l_param) {
- switch (message) {
- case WM_CREATE:
- return OnCreateWindow(window_handle);
- case WM_PAINT:
- OnPaint(window_handle);
- break;
- case WM_SIZE:
- g_main_player->ResizeVideo(LOWORD(l_param), HIWORD(l_param));
- break;
- case WM_ERASEBKGND:
- // Suppress window erasing, to reduce flickering while the video is
- // playing.
- return 1;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- case WM_CHAR:
- OnKeyPress(w_param);
- break;
- case MFPlayer::WM_APP_PLAYER_EVENT:
- OnPlayerEvent(window_handle, w_param);
- break;
- default:
- return DefWindowProc(window_handle, message, w_param, l_param);
- }
- return 0;
-}
-
-// Creates a window for doing playback.
-bool InitInstance() {
- HWND window_handle;
- WNDCLASSEX window_class_info;
-
- // Register the window class.
- ZeroMemory(&window_class_info, sizeof(WNDCLASSEX));
- window_class_info.cbSize = sizeof(WNDCLASSEX);
- window_class_info.style = CS_HREDRAW | CS_VREDRAW;
- window_class_info.lpfnWndProc = CallbackProc;
- window_class_info.hInstance = NULL;
- window_class_info.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
- window_class_info.lpszMenuName = NULL;
- window_class_info.lpszClassName = g_window_class;
-
- if (RegisterClassEx(&window_class_info) == 0)
- return false;
-
- // Create the application window.
- window_handle = CreateWindow(g_window_class, g_window_title,
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
- CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL);
- if (window_handle == 0) {
- fprintf(stderr, "Cannot create window\n");
- return false;
- }
-
- ShowWindow(window_handle, SW_SHOW);
- UpdateWindow(window_handle);
- return true;
-}
-
-int RunRendererApp() {
- if (!InitInstance()) {
- fprintf(stderr, "Could not initialize the application\n");
- return 1;
- }
- MSG message;
- ZeroMemory(&message, sizeof(message));
- // Main message loop.
- while (GetMessage(&message, NULL, 0, 0)) {
- TranslateMessage(&message);
- DispatchMessage(&message);
- }
- return 0;
-}
-
-int RunTranscoderApp(const char* output_file_name) {
- HRESULT hr;
- int ret = 0;
-
- // In here, we do not use any windows - just use the media player as a
- // transcoder.
- hr = MFPlayer::CreateInstance(NULL, NULL, false, &g_main_player);
- if (FAILED(hr)) {
- fprintf(stderr, "Transcoder app: Could not create player\n");
- return 1;
- }
- wchar_t* output_file_name_wchar = NULL;
- if (ConvertANSIStringToUnicode(output_file_name,
- &output_file_name_wchar) != 0) {
- fprintf(stderr, "Fatal error while converting output_file_name\n");
- return 1;
- }
- hr = g_main_player->OpenURL(g_input_file_name, output_file_name_wchar);
- if (FAILED(hr)) {
- fprintf(stderr, "Failed to open URL and configure transcoder profile\n");
- ret = 1;
- goto cleanup;
- }
- fprintf(stderr, "Transcode starting now, writing to %s\n", output_file_name);
- hr = g_main_player->Transcode();
- if (FAILED(hr)) {
- fprintf(stderr, "Transcode failed\n");
- ret = 1;
- goto cleanup;
- }
- if (SUCCEEDED(hr))
- fprintf(stderr, "Transcode successful\n");
- cleanup:
- delete[] output_file_name_wchar;
- return ret;
-}
-
-int main2(int argc, char** argv) {
- bool use_renderer_sink;
- bool enable_dxva2;
- if (argc < 4) {
- Usage();
- return 1;
- }
- if (strcmp(argv[1], "-r") == 0) {
- use_renderer_sink = true;
- } else if (strcmp(argv[1], "-f") == 0) {
- use_renderer_sink = false;
- if (argc < 5) {
- fprintf(stderr, "Archive sink specified but out-file missing\n");
- Usage();
- return 1;
- }
- } else {
- fprintf(stderr, "Unknown option '%s'\n", argv[1]);
- Usage();
- return 1;
- }
- if (strcmp(argv[2], "-h") == 0) {
- enable_dxva2 = true;
- } else if (strcmp(argv[2], "-s") == 0) {
- enable_dxva2 = false;
- } else {
- fprintf(stderr, "Unknown option '%s'\n", argv[2]);
- Usage();
- return 1;
- }
-
- // TODO(imcheng): implement the option for hardware acceleration
- fprintf(stderr, "use_renderer_sink: %s\n",
- use_renderer_sink ? "TRUE" : "FALSE");
- fprintf(stderr, "enable_dxva2: %s\n", enable_dxva2 ? "TRUE" : "FALSE");
-
- HRESULT hr;
- // Startup is moved from object creation to main method.
- hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
- if (FAILED(hr)) {
- fprintf(stderr, "MFStartup failed: %#X", hr);
- return 1;
- }
-
- // Note: This function allocates space for g_input_file_name on the heap, so
- // remember to free it at the end.
- if (ConvertANSIStringToUnicode(argv[3], &g_input_file_name) != 0) {
- fprintf(stderr, "Fatal error while converting g_input_file_name\n");
- return 1;
- }
- _fwprintf_p(stderr, L"Input file: %s\n", g_input_file_name);
- int retval;
- if (use_renderer_sink)
- retval = RunRendererApp();
- else
- retval = RunTranscoderApp(argv[4]);
-
- // Clean up.
- if (g_main_player) {
- g_main_player->Shutdown();
- g_main_player->Release();
- }
- MFShutdown();
- delete[] g_input_file_name;
-
- printf("Terminated\n");
- return retval;
-}
-
-} // namespace mfplayer
-
-
-int main(int argc, char** argv) {
- return mfplayer::main2(argc, argv);
-}
diff --git a/media/tools/mfplayer/mfplayer.cc b/media/tools/mfplayer/mfplayer.cc
deleted file mode 100644
index 7ef51e1..0000000
--- a/media/tools/mfplayer/mfplayer.cc
+++ /dev/null
@@ -1,823 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/tools/mfplayer/mfplayer.h"
-
-#include <mfapi.h>
-#include <mferror.h>
-#include <shlwapi.h>
-
-#include <cassert>
-#include <cstdio>
-
-template <class T>
-static void SafeRelease(T** pptr) {
- if (pptr && *pptr) {
- (*pptr)->Release();
- *pptr = NULL;
- }
-}
-
-static HRESULT ProbeTopology(IMFMediaEvent* event,
- IMFTopology** topology_ptr) {
- HRESULT hr = S_OK;
- PROPVARIANT var;
- PropVariantInit(&var);
- hr = event->GetValue(&var);
- if (SUCCEEDED(hr)) {
- if (var.vt != VT_UNKNOWN)
- hr = E_UNEXPECTED;
- }
- if (SUCCEEDED(hr))
- hr = var.punkVal->QueryInterface(IID_PPV_ARGS(topology_ptr));
- PropVariantClear(&var);
- return hr;
-}
-
-namespace mfplayer {
-
-// Public methods
-
-bool MFPlayer::CreateInstance(HWND video_window, HWND event_window,
- bool render_to_window, MFPlayer** player) {
- if (!player)
- return false;
-
- HRESULT hr = S_OK;
- MFPlayer* temp_player = new MFPlayer(video_window, event_window,
- render_to_window);
- if (!temp_player)
- return false;
-
- hr = temp_player->Initialize();
- if (SUCCEEDED(hr)) {
- *player = temp_player;
- (*player)->AddRef();
- }
- // If above succeeded, then ref count is now 2, so SafeRelease won't delete
- // the object.
- SafeRelease(&temp_player);
- return SUCCEEDED(hr);
-}
-
-// Override IUnknown
-HRESULT MFPlayer::QueryInterface(REFIID id, void** object_ptr) {
- static const QITAB qit[] = { QITABENT(MFPlayer, IMFAsyncCallback), {0}};
- return QISearch(this, qit, id, object_ptr);
-}
-
-ULONG MFPlayer::AddRef() {
- return InterlockedIncrement(&ref_count_);
-}
-
-ULONG MFPlayer::Release() {
- ULONG count = InterlockedDecrement(&ref_count_);
- if (count == 0)
- delete this;
- return count;
-}
-
-// IMFAsyncCallback implementation
-// Callback for asynchronous BeginGetEvent method.
-HRESULT MFPlayer::Invoke(IMFAsyncResult* result) {
- IMFMediaEvent* event = NULL;
- MediaEventType event_type = MEUnknown;
-
- HRESULT hr = session_->EndGetEvent(result, &event);
- if (FAILED(hr))
- goto done;
- hr = event->GetType(&event_type);
- if (FAILED(hr))
- goto done;
-
- // |session_|->Close() queues an event of this type.
- // If the session is closed, the application is waiting on the event
- // handle. Also, do not request any more events from the session.
- if (event_type == MESessionClosed) {
- SetEvent(close_event_);
- } else {
- // For all other events, ask the media session for the
- // next event in the queue.
- hr = session_->BeginGetEvent(this, NULL);
- if (FAILED(hr))
- goto done;
- }
- // For most events, post the event as a private window message to the
- // application. This lets the application process the event on its main
- // thread.
-
- // However, if a call to IMFMediaSession::Close is pending, it means the
- // application is waiting on the m_hCloseEvent event handle. (Blocking
- // call.) In that case, we simply discard the event.
-
- // When IMFMediaSession::Close is called, MESessionClosed is NOT
- // necessarily the next event that we will receive. We may receive any
- // number of other events before receiving MESessionClosed.
- if (state_ != CLOSING) {
- event->AddRef();
- // Post this event onto the event_window_'s queue. When an event is
- // received, the app calls MFPlayer::HandleEvent() to handle the event.
- PostMessage(event_window_, WM_APP_PLAYER_EVENT, (WPARAM)event, NULL);
- }
- done:
- return S_OK;
-}
-
-// This method does the following:
-// 1. Create a new media session.
-// 2. Create the media source.
-// 3. Create the topology.
-// 4. Queue the topology [asynchronous]
-// 5. Start playback [asynchronous - does not happen in this method.]
-bool MFPlayer::OpenURL(const WCHAR* in_url, const WCHAR* out_url) {
- IMFTopology* topology = NULL;
- HRESULT hr;
-
- // Initializes |session_|.
- hr = CreateSession();
- if (FAILED(hr))
- goto done;
- // Initializes |source_|.
- hr = CreateMediaSource(in_url);
- if (FAILED(hr))
- goto done;
- if (render_to_window_) {
- // Create a partial topology.
- hr = CreateTopologyFromSource(&topology);
- if (FAILED(hr))
- goto done;
- } else {
- // Creating topology for a transcoder requires a somewhat different setup.
- fprintf(stderr, "OpenURL: using archive sink\n");
- hr = MFCreateTranscodeProfile(&transcode_profile_);
- if (FAILED(hr))
- goto done;
- /*
- hr = ConfigureTranscodeAudioOutput();
- if (FAILED(hr))
- goto done;
- fprintf(stderr, "OpenURL: Configured audio output\n");
- */
- hr = ConfigureTranscodeVideoOutput();
- if (FAILED(hr))
- goto done;
- fprintf(stderr, "OpenURL: Configured video output\n");
- hr = ConfigureContainer();
- if (FAILED(hr))
- goto done;
- fprintf(stderr, "OpenURL: Configured container\n");
- hr = MFCreateTranscodeTopology(source_, out_url, transcode_profile_,
- &topology);
- if (FAILED(hr))
- goto done;
- fprintf(stderr, "OpenURL: Created transcode topology\n");
- }
- // First argument is flags (which is none).
- hr = session_->SetTopology(0, topology);
- if (FAILED(hr))
- goto done;
- fprintf(stderr, "Added topology to session\n");
- // SetTopology() is an asynchronous method. If it succeeds, the media
- // session will queue an MESessionTopologySet event.
- // SetTopology() without MFSESSION_SETTOPOLOGY_NORESOLUTION means the
- // topology is to be resolved.
- state_ = OPEN_PENDING;
- done:
- if (FAILED(hr))
- state_ = CLOSED;
- SafeRelease(&topology);
- return SUCCEEDED(hr);
-}
-
-bool MFPlayer::Play() {
- if (state_ != PAUSED && state_ != STOPPED)
- return false;
- if (!session_ || !source_)
- return false;
- HRESULT hr = StartPlayback();
- return SUCCEEDED(hr);
-}
-
-bool MFPlayer::Pause() {
- if (state_ != STARTED)
- return false;
- if (!session_ || !source_)
- return false;
- HRESULT hr = session_->Pause();
- if (SUCCEEDED(hr))
- state_ = PAUSED;
- return SUCCEEDED(hr);
-}
-
-bool MFPlayer::Shutdown() {
- HRESULT hr = CloseSession();
- if (close_event_) {
- CloseHandle(close_event_);
- close_event_ = NULL;
- }
- return SUCCEEDED(hr);
-}
-
-// Callback from application upon receiving an WM_APP_PLAYER event.
-// This method is used to process media session events on the
-// application's main thread.
-HRESULT MFPlayer::HandleEvent(UINT_PTR event_ptr) {
- IUnknown* unknown_ptr = reinterpret_cast<IUnknown*>(event_ptr);
- IMFMediaEvent* event = NULL;
-
- if (!unknown_ptr)
- return E_POINTER;
- // Incremented ref count.
- HRESULT hr = unknown_ptr->QueryInterface(IID_PPV_ARGS(&event));
- if (FAILED(hr))
- goto done;
- MediaEventType event_type;
- HRESULT event_status = S_OK;
- hr = event->GetType(&event_type);
- if (FAILED(hr))
- goto done;
- hr = event->GetStatus(&event_status);
- if (FAILED(hr))
- goto done;
- // Check if the async operation succeeded.
- if (FAILED(event_status)) {
- hr = event_status;
- goto done;
- }
-
- // Handle the event according to its type.
- MF_TOPOSTATUS topology_status = MF_TOPOSTATUS_INVALID;
- switch (event_type) {
- case MESessionTopologySet:
- hr = OnTopologyReady(event);
- break;
- case MEEndOfPresentation:
- hr = OnPresentationEnded(event);
- break;
- // The MENewPresentation event signals the start of a new presentation.
- // However, in many cases, you will not receive this event at all.
- // It seems like there is no need to handle other events, but if there
- // is a need in the future they can be added here.
- }
-
- done:
- SafeRelease(&event);
- SafeRelease(&unknown_ptr);
- return hr;
-}
-
-// Video functionality implementation
-// Called by OnPaint() in application, when it receives a WM_PAINT message.
-// The EVR (video_display_) must be notified, i.e. repaint.
-bool MFPlayer::Repaint() {
- if (video_display_)
- return SUCCEEDED(video_display_->RepaintVideo());
- else
- return true;
-}
-
-// Called when application receives a WM_SIZE message.
-bool MFPlayer::ResizeVideo(WORD Width, WORD Height) {
- if (video_display_) {
- // Fields are: Left (x), Top (y), Right (x), Bottom (y)
- RECT DestRect = { 0, 0, Width, Height };
- // First parameter is the "source rectangle" - NULL means show
- // the entire portion of the original rectangle. Default is
- // {0, 0, 1, 1}.
- return SUCCEEDED(video_display_->SetVideoPosition(NULL, &DestRect));
- } else {
- return true;
- }
-}
-
-// Private methods
-
-MFPlayer::MFPlayer(HWND video_window, HWND event_window,
- bool render_to_window)
- : ref_count_(1),
- state_(CLOSED),
- session_(NULL),
- source_(NULL),
- video_display_(NULL),
- video_window_(video_window),
- event_window_(event_window),
- close_event_(NULL),
- render_to_window_(render_to_window),
- transcode_profile_(NULL) {
-}
-
-MFPlayer::~MFPlayer() {
- // If false, app did not call Shutdown().
- assert(!session_);
-
- // When MFPlayer calls IMediaEventGenerator::BeginGetEvent on the
- // media session, it causes the media session to hold a reference
- // count on the MFPlayer.
- // This creates a circular reference count between MFPlayer and the
- // media session. Calling Shutdown breaks the circular reference
- // count.
- // If CreateInstance fails, the application will not call
- // Shutdown. To handle that case, call Shutdown in the destructor.
- Shutdown();
-}
-
-// This method only creates the close event. This method is called from
-// CreateInstance().
-HRESULT MFPlayer::Initialize() {
- if (close_event_)
- return MF_E_ALREADY_INITIALIZED;
- HRESULT hr = S_OK;
- close_event_ = CreateEvent(NULL, // Not inheritable by child process, if any
- FALSE, // Auto-reset
- FALSE, // Not signaled initially
- NULL); // No name
- if (!close_event_)
- hr = HRESULT_FROM_WIN32(GetLastError());
- return hr;
-}
-
-HRESULT MFPlayer::CreateSession() {
- // Close previous section, if any.
- HRESULT hr = CloseSession();
- if (FAILED(hr))
- goto done;
-
- assert(state_ == CLOSED);
-
- // First argument is optional configurations. (Which is none)
- hr = MFCreateMediaSession(NULL, &session_);
- if (FAILED(hr))
- goto done;
-
- state_ = READY;
- if (render_to_window_) {
- // Start pulling events from the media session. It calls back the object's
- // Invoke method when there is a new event available.
- hr = session_->BeginGetEvent(this, NULL);
- if (FAILED(hr))
- goto done;
- }
- done:
- return hr;
-}
-
-// Closes the media session. Called from either Shutdown() or CreateSession().
-// The IMFMediaSession::Close method is asynchronous, but the CloseSession
-// method waits on the MESessionClosed event. The MESessionClosed event is
-// guaranteed to be the last event that the media session fires.
-HRESULT MFPlayer::CloseSession() {
- HRESULT hr = S_OK;
-
- SafeRelease(&video_display_);
- if (session_) {
- state_ = CLOSING;
- hr = session_->Close();
- if (FAILED(hr))
- goto done;
- // Wait 5 seconds for the close operation to complete, i.e. the close event
- // to be signaled. close_event_ only exists for playback mode.
- if (render_to_window_)
- WaitForSingleObject(close_event_, 5000);
- // Now there will (or should) be no more events from this session.
- }
- // Complete shutdown operations.
- // Note: Shutdown()s are synchronous.
- if (source_)
- source_->Shutdown();
- if (session_)
- session_->Shutdown();
- SafeRelease(&source_);
- SafeRelease(&session_);
- SafeRelease(&transcode_profile_);
- state_ = CLOSED;
-
- done:
- return hr;
-}
-
-// Starts the session. In the context of playback, it means starting the
-// playback. In the context of writing to file, it means starting the encoding
-// operation.
-HRESULT MFPlayer::StartPlayback() {
- assert(session_);
- PROPVARIANT var_start;
- PropVariantInit(&var_start);
- var_start.vt = VT_EMPTY;
- HRESULT hr = session_->Start(&GUID_NULL, &var_start);
- if (SUCCEEDED(hr)) {
- // Start is an asynchronous operation. However, we can treat our state
- // as being already started.
- state_ = STARTED;
- }
- PropVariantClear(&var_start);
- return hr;
-}
-
-HRESULT MFPlayer::CreateMediaSource(const WCHAR* url) {
- MF_OBJECT_TYPE object_type = MF_OBJECT_INVALID;
- IMFSourceResolver* resolver = NULL;
- IUnknown* source = NULL;
-
- // Release the old source.
- SafeRelease(&source_);
-
- HRESULT hr = MFCreateSourceResolver(&resolver);
- if (FAILED(hr))
- goto done;
-
- // Use resolver to create media source.
- // Synchronous method, use BeginCreateObjectFromUrl for asynchronous.
- hr = resolver->CreateObjectFromURL(url,
- MF_RESOLUTION_MEDIASOURCE,
- NULL, // Not passing in properties.
- &object_type,
- &source); // Receives created source.
- if (FAILED(hr))
- goto done;
-
- // Get the IMFMediaSource interface from the media source, i.e. initializes
- // source_.
- // This call increments the ref count of returned interface.
- hr = source->QueryInterface(IID_PPV_ARGS(&source_));
-
- done:
- // Free up resources, if any were acquired.
- SafeRelease(&resolver);
- SafeRelease(&source);
- return hr;
-}
-
-HRESULT MFPlayer::CreateTopologyFromSource(IMFTopology** topology) {
- assert(session_);
- assert(source_);
-
- IMFTopology* temp_topology = NULL;
- IMFPresentationDescriptor* presentation_desc = NULL;
- DWORD num_streams = 0;
-
- HRESULT hr = MFCreateTopology(&temp_topology);
- if (FAILED(hr))
- goto done;
- hr = source_->CreatePresentationDescriptor(&presentation_desc);
- if (FAILED(hr))
- goto done;
- hr = presentation_desc->GetStreamDescriptorCount(&num_streams);
- if (FAILED(hr))
- goto done;
- // For each stream, create the topology nodes and add them to the topology.
- for (DWORD i = 0; i < num_streams; i++) {
- hr = AddBranchToPartialTopology(temp_topology, presentation_desc, i);
- if (FAILED(hr))
- goto done;
- }
- *topology = temp_topology;
- (*topology)->AddRef();
-
- done:
- SafeRelease(&temp_topology);
- SafeRelease(&presentation_desc);
- return hr;
-}
-
-// Creates a topology node with stream of given index and adds the node to the
-// topology.
-// Add a topology branch for one stream.
-// For each stream, this function does the following:
-// 1. Creates a source node associated with the stream.
-// 2. Creates an output node for the renderer.
-// 3. Connects the two nodes.
-// The media session will add any decoders that are needed.
-HRESULT MFPlayer::AddBranchToPartialTopology(
- IMFTopology* topology, IMFPresentationDescriptor* presentation_desc,
- DWORD index) {
- assert(topology);
-
- IMFStreamDescriptor* stream_desc = NULL;
- IMFMediaTypeHandler* handler = NULL;
- GUID major_type_id = GUID_NULL;
- IMFTopologyNode* source_node = NULL;
- IMFTopologyNode* output_node = NULL;
- BOOL stream_selected = FALSE;
-
- HRESULT hr = presentation_desc->GetStreamDescriptorByIndex(index,
- &stream_selected,
- &stream_desc);
- if (FAILED(hr))
- goto done;
- // Create topology branch only if stream is selected.
- if (stream_selected) {
- hr = stream_desc->GetMediaTypeHandler(&handler);
- if (FAILED(hr))
- goto done;
- hr = handler->GetMajorType(&major_type_id);
- if (FAILED(hr))
- goto done;
- if (major_type_id != MFMediaType_Video)
- goto done;
- hr = CreateSourceStreamNode(presentation_desc, stream_desc, &source_node);
- if (FAILED(hr))
- goto done;
- hr = CreateOutputNode(stream_desc, &output_node);
- if (FAILED(hr))
- goto done;
- // Add both nodes to the topology.
- hr = topology->AddNode(source_node);
- if (FAILED(hr))
- goto done;
- hr = topology->AddNode(output_node);
- if (FAILED(hr))
- goto done;
- // Connect the 0-th output stream of source node to the 0-th input stream of
- // the output node.
- hr = source_node->ConnectOutput(0, output_node, 0);
- }
-
- done:
- SafeRelease(&stream_desc);
- SafeRelease(&source_node);
- SafeRelease(&output_node);
- SafeRelease(&handler);
- return hr;
-}
-
-HRESULT MFPlayer::CreateSourceStreamNode(
- IMFPresentationDescriptor* presentation_desc,
- IMFStreamDescriptor* stream_desc, IMFTopologyNode** node_ptr) {
- if (!source_ || !presentation_desc || !stream_desc || !node_ptr)
- return E_POINTER;
- IMFTopologyNode* temp_node = NULL;
- HRESULT hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &temp_node);
- if (FAILED(hr))
- goto done;
- // Set attribute of top node source to source_.
- hr = temp_node->SetUnknown(MF_TOPONODE_SOURCE, source_);
- if (FAILED(hr))
- goto done;
- // Set attribute of presentation descriptor.
- hr = temp_node->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR,
- presentation_desc);
- if (FAILED(hr))
- goto done;
- // Set attribute of stream descriptor.
- hr = temp_node->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, stream_desc);
- if (FAILED(hr))
- goto done;
- *node_ptr = temp_node;
- (*node_ptr)->AddRef();
-
- done:
- SafeRelease(&temp_node);
- return hr;
-}
-
-// This function does the following:
-// 1. Chooses a renderer based on the media type of the stream.
-// 2. Creates an IActivate object for the renderer. IActivate objects allow the
-// application to defer its creation.
-// 3. Creates an output topology node.
-// 4. Sets the IActivate pointer on the node.
-HRESULT MFPlayer::CreateOutputNode(IMFStreamDescriptor* stream_desc,
- IMFTopologyNode** node_ptr) {
- IMFTopologyNode* temp_node = NULL;
- IMFMediaTypeHandler* handler = NULL;
- IMFActivate* renderer_activate = NULL;
- GUID major_type_id = GUID_NULL;
-
- HRESULT hr = stream_desc->GetMediaTypeHandler(&handler);
- if (FAILED(hr))
- goto done;
-
- // Get the type of the stream (video, audio, etc.)
- hr = handler->GetMajorType(&major_type_id);
- if (FAILED(hr))
- goto done;
-
- // Is it a video stream, audio stream, etc.?
- // Create an IMFActivate object for the renderer, based on the media type
- if (major_type_id == MFMediaType_Video) {
- assert(video_window_);
- hr = MFCreateVideoRendererActivate(video_window_, &renderer_activate);
- } else {
- hr = E_FAIL;
- }
- if (FAILED(hr))
- goto done;
-
- hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &temp_node);
- if (FAILED(hr))
- goto done;
-
- // Associate the activate object with the node.
- hr = temp_node->SetObject(renderer_activate);
- if (FAILED(hr))
- goto done;
-
- *node_ptr = temp_node;
- (*node_ptr)->AddRef();
-
- done:
- SafeRelease(&temp_node);
- SafeRelease(&handler);
- SafeRelease(&renderer_activate);
- return hr;
-}
-
-// Handler for MESessionTopologySet.
-// This situation means the new topology is ready for playback. After this
-// event is received, any calls to IMFGetService will get service interfaces
-// from the new topology.
-HRESULT MFPlayer::OnTopologyReady(IMFMediaEvent* event) {
-//////////
- IMFTopology* full_topology = NULL;
- HRESULT hr;
- hr = ProbeTopology(event, &full_topology);
- if (FAILED(hr))
- fprintf(stderr, "Failed to probe topology\n");
- fprintf(stderr, "Probed topology\n");
-
- WORD num_nodes_in_topology;
- hr = full_topology->GetNodeCount(&num_nodes_in_topology);
- if (FAILED(hr)) {
- fprintf(stderr, "GetNodeCount failed\n");
- goto release_topology;
- }
- fprintf(stderr, "There are %d nodes in topology\n", num_nodes_in_topology);
-
- for (WORD i = 0; i < num_nodes_in_topology; i++) {
- IMFTopologyNode* node = NULL;
- hr = full_topology->GetNode(i, &node);
- if (FAILED(hr)) {
- fprintf(stderr, "failed to get node %d\n", i);
- } else {
- fprintf(stderr, "got node %d\n", i);
- }
- SafeRelease(&node);
- }
-
- release_topology:
- SafeRelease(&full_topology);
- if (render_to_window_) {
- // Release the old IMFVideoDisplayControl.
- SafeRelease(&video_display_);
- // Ask for the IMFVideoDisplayControl interface. This interface is
- // implemented by the EVR and is exposed by the media session as a service.
- // Note: This call is expected to fail if the source does not have video.
- MFGetService(session_, MR_VIDEO_RENDER_SERVICE,
- IID_PPV_ARGS(&video_display_));
- // Note: Audio, Video acceleration are also services that can be obtained.
- }
- hr = StartPlayback();
- return hr;
-}
-
-// Handler for MEEndOfPresentation event.
-HRESULT MFPlayer::OnPresentationEnded(IMFMediaEvent* event) {
- state_ = STOPPED;
- return S_OK;
-}
-
-HRESULT MFPlayer::ConfigureTranscodeAudioOutput() {
- assert(transcode_profile_);
-
- HRESULT hr = S_OK;
- DWORD num_available_formats;
- IMFCollection* available_types = NULL;
- IUnknown* unknown_audio_type = NULL;
- IMFMediaType* audio_type = NULL;
- IMFAttributes* audio_attributes = NULL;
- const GUID OUTPUT_AUDIO_SUBTYPE = MFAudioFormat_AAC;
- // Get all available types of output formats.
- hr = MFTranscodeGetAudioOutputAvailableTypes(OUTPUT_AUDIO_SUBTYPE,
- MFT_ENUM_FLAG_ALL,
- NULL,
- &available_types);
- if (SUCCEEDED(hr)) {
- hr = available_types->GetElementCount(&num_available_formats);
- if (num_available_formats == 0)
- hr = E_UNEXPECTED;
- }
- if (SUCCEEDED(hr)) {
- // Just pick the first available format.
- hr = available_types->GetElement(0, &unknown_audio_type);
- }
- if (SUCCEEDED(hr))
- hr = unknown_audio_type->QueryInterface(IID_PPV_ARGS(&audio_type));
- if (SUCCEEDED(hr))
- hr = MFCreateAttributes(&audio_attributes, 0);
- if (SUCCEEDED(hr))
- hr = audio_type->CopyAllItems(audio_attributes);
- if (SUCCEEDED(hr))
- hr = audio_attributes->SetGUID(MF_MT_SUBTYPE, OUTPUT_AUDIO_SUBTYPE);
-
- if (SUCCEEDED(hr))
- hr = transcode_profile_->SetAudioAttributes(audio_attributes);
-
- SafeRelease(&available_types);
- SafeRelease(&unknown_audio_type);
- SafeRelease(&audio_type);
- SafeRelease(&audio_attributes);
- return hr;
-}
-
-HRESULT MFPlayer::ConfigureTranscodeVideoOutput() {
- assert(transcode_profile_);
-
- HRESULT hr = S_OK;
- IMFAttributes* video_attributes = NULL;
- // We set 5 attributes for our video output:
- // 1. Output subtype
- // 2. Frame rate
- // 3. Frame Size
- // 4. Aspect ratio
- // 5. Bit rate
- hr = MFCreateAttributes(&video_attributes, 5);
- if (SUCCEEDED(hr))
- hr = video_attributes->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
- if (SUCCEEDED(hr))
- hr = MFSetAttributeRatio(video_attributes, MF_MT_FRAME_RATE, 30, 1);
- if (SUCCEEDED(hr))
- hr = MFSetAttributeSize(video_attributes, MF_MT_FRAME_SIZE, 320, 240);
- if (SUCCEEDED(hr))
- hr = MFSetAttributeRatio(video_attributes, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
- if (SUCCEEDED(hr))
- hr = video_attributes->SetUINT32(MF_MT_AVG_BITRATE, 300000);
-
- if (SUCCEEDED(hr))
- hr = transcode_profile_->SetVideoAttributes(video_attributes);
-
- SafeRelease(&video_attributes);
- return hr;
-}
-
-HRESULT MFPlayer::ConfigureContainer() {
- assert(transcode_profile_);
-
- HRESULT hr = S_OK;
- IMFAttributes* container_attributes = NULL;
-
- hr = MFCreateAttributes(&container_attributes, 2);
- // Make the container of MP4 type.
- if (SUCCEEDED(hr))
- hr = container_attributes->SetGUID(MF_TRANSCODE_CONTAINERTYPE,
- MFTranscodeContainerType_MPEG4);
- // Use the default setting. Media Foundation will use the stream
- // settings set in ConfigureAudioOutput and ConfigureVideoOutput.
- if (SUCCEEDED(hr))
- hr = container_attributes->SetUINT32(MF_TRANSCODE_ADJUST_PROFILE,
- MF_TRANSCODE_ADJUST_PROFILE_DEFAULT);
-
- if (SUCCEEDED(hr))
- hr = transcode_profile_->SetContainerAttributes(container_attributes);
-
- SafeRelease(&container_attributes);
- return hr;
-}
-
-// This method will start getting media session events synchronously.
-bool MFPlayer::Transcode() {
- assert(session_);
-
- IMFMediaEvent* event = NULL;
- MediaEventType event_type = MEUnknown;
- HRESULT hr = S_OK;
- HRESULT event_status = S_OK;
-
- while (event_type != MESessionClosed) {
- hr = session_->GetEvent(0, &event);
- if (FAILED(hr))
- break;
- hr = event->GetType(&event_type);
- if (FAILED(hr))
- break;
- hr = event->GetStatus(&event_status);
- if (FAILED(hr))
- break;
- if (FAILED(event_status)) {
- hr = event_status;
- break;
- }
- switch (event_type) {
- case MESessionTopologySet:
- hr = OnTopologyReady(event);
- break;
- case MESessionStarted:
- break;
- case MESessionEnded:
- hr = session_->Close();
- // Finished encoding.
- break;
- case MESessionClosed:
- // Output file has been created - exit on next iteration.
- break;
- }
- if (FAILED(hr))
- break;
- SafeRelease(&event);
- }
- // Release the last MESessionClosed event.
- SafeRelease(&event);
- return SUCCEEDED(hr);
-}
-
-} // namespace mfplayer
diff --git a/media/tools/mfplayer/mfplayer.h b/media/tools/mfplayer/mfplayer.h
deleted file mode 100644
index 6daead1..0000000
--- a/media/tools/mfplayer/mfplayer.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_TOOLS_MFPLAYER_MFPLAYER_H_
-#define MEDIA_TOOLS_MFPLAYER_MFPLAYER_H_
-
-#ifdef _WIN32_WINNT
-#undef _WIN32_WINNT
-#endif
-#ifdef WIN32
-#undef WIN32
-#endif
-#ifdef WINVER
-#undef WINVER
-#endif
-
-#include <evr.h> // Subclass IMFAsyncCallback
-
-#include <cassert>
-
-#include "base/basictypes.h"
-
-#pragma comment(lib, "d3d9.lib")
-#pragma comment(lib, "dwmapi.lib")
-#pragma comment(lib, "dxva2.lib")
-#pragma comment(lib, "mf.lib")
-#pragma comment(lib, "mfplat.lib")
-#pragma comment(lib, "mfuuid.lib")
-#pragma comment(lib, "shlwapi.lib")
-#pragma comment(lib, "strmiids.lib")
-#pragma comment(lib, "winmm.lib")
-
-struct IMFAsyncResult;
-struct IMFMediaEvent;
-struct IMFMediaSession;
-struct IMFMediaSource;
-struct IMFPresentationDescriptor;
-struct IMFStreamDescriptor;
-struct IMFTopology;
-struct IMFTopologyNode;
-struct IMFTranscodeProfile;
-struct IMFVideoDisplayControl;
-
-namespace mfplayer {
-
-class MFPlayer : public IMFAsyncCallback {
- public:
- enum PlayerState {
- CLOSED = 0, // No session.
- READY, // Session was created, ready to open a file.
- OPEN_PENDING, // Session is opening a file.
- STARTED, // Session is playing a file.
- PAUSED, // Session is paused.
- STOPPED, // Session is stopped (ready to play).
- CLOSING // Application has closed the session, but is waiting for
- // MESessionClosed.
- };
-
- // This is used to represent a type of event posted to the event_window_.
- static const UINT WM_APP_PLAYER_EVENT = WM_APP + 1;
-
- // Use this to construct a MFPlayer instead of constructor.
- static bool CreateInstance(HWND video_window, HWND event_window,
- bool render_to_window, MFPlayer** player);
-
- // Override IUnknown. STDMETHODCALLTYPE, which expands to __stdcall, is
- // necessary for overriding the parent class's method.
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, void** object_ptr);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- // Implement IMFAsyncCallback.
- HRESULT STDMETHODCALLTYPE GetParameters(DWORD* flags, DWORD* queue) {
- // Implementation of this method is optional, assume default behavior.
- return E_NOTIMPL;
- }
- HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult* result);
-
- // Opens the file specified in url and sends a message to start playback,
- // once topology has been completed. For archive sinks, out_url is the
- // destination at which the encoded file will be saved.
- bool OpenURL(const WCHAR* in_url, const WCHAR* out_url);
-
- // Starts playback.
- bool Play();
-
- // Pauses playback.
- bool Pause();
-
- // Shuts down the media player. Called by the destructor.
- bool Shutdown();
-
- // Handles messages in the message queue.
- HRESULT HandleEvent(UINT_PTR event_ptr);
- inline PlayerState state() const { return state_; }
-
- // Video functionality
- bool Repaint();
- bool ResizeVideo(WORD width, WORD height);
- inline bool HasVideo() const { return (video_display_ != NULL); }
-
- // The following methods are used for archive sink.
- // Begins the encoding operation. Call this after OpenURL() only.
- bool Transcode();
-
- private:
- // Private constructor: Call CreateInstance() instead.
- MFPlayer(HWND video_window, HWND event_window,
- bool render_to_window);
-
- // Caller should use Release() instead, which keeps track of ref count.
- ~MFPlayer();
-
- // Initializes the media player. This actually only creates an Event object
- // to signal closing the media player.
- HRESULT Initialize();
-
- // Creates the media session object of the player, and starts pulling events
- // from it.
- HRESULT CreateSession();
-
- // The meat of Shutdown(). Releases the source and the session.
- HRESULT CloseSession();
- HRESULT StartPlayback();
- HRESULT CreateMediaSource(const WCHAR* url);
-
- // Creates the partial topology of the player.
- HRESULT CreateTopologyFromSource(IMFTopology** topology);
-
- // Called by CreateTopologyFromSource() to add nodes to the topology, if the
- // stream is either video or audio stream.
- HRESULT AddBranchToPartialTopology(
- IMFTopology* topology,
- IMFPresentationDescriptor* presentation_desc,
- DWORD index);
- HRESULT CreateSourceStreamNode(IMFPresentationDescriptor* presentation_desc,
- IMFStreamDescriptor* stream_desc,
- IMFTopologyNode** node_ptr);
- HRESULT CreateOutputNode(IMFStreamDescriptor* stream_desc,
- IMFTopologyNode** node_ptr);
-
- // Media event handlers
- HRESULT OnTopologyReady(IMFMediaEvent* event);
- HRESULT OnPresentationEnded(IMFMediaEvent* event);
-
- // These methods are used for archive sink.
- HRESULT ConfigureTranscodeAudioOutput();
- HRESULT ConfigureTranscodeVideoOutput();
- HRESULT ConfigureContainer();
-
- LONG ref_count_;
- PlayerState state_;
- IMFMediaSession* session_;
- IMFMediaSource* source_;
- IMFVideoDisplayControl* video_display_;
- HWND video_window_;
- HWND event_window_;
- HANDLE close_event_;
- bool render_to_window_;
- IMFTranscodeProfile* transcode_profile_;
-
- DISALLOW_COPY_AND_ASSIGN(MFPlayer);
-};
-
-} // namespace mfplayer
-
-#endif // MEDIA_TOOLS_MFPLAYER_MFPLAYER_H_