Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: media/mf/main.cc

Issue 3044019: This tool demonstrates the use of the Media Foundation H.264 decoder as a sta... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/mf/file_reader_util.cc ('k') | media/mf/mft_h264_decoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file.
4 //
5 // Demonstrates the use of MftH264Decoder.
6
7 #include <d3d9.h>
8 #include <dxva2api.h>
9 #include <mfapi.h>
10
11 #include "base/command_line.h"
12 #include "base/file_path.h"
13 #include "base/logging.h"
14 #include "base/scoped_comptr_win.h"
15 #include "base/scoped_ptr.h"
16 #include "base/time.h"
17 #include "media/base/media.h"
18 #include "media/base/video_frame.h"
19 #include "media/ffmpeg/ffmpeg_common.h"
20 #include "media/ffmpeg/file_protocol.h"
21 #include "media/mf/file_reader_util.h"
22 #include "media/mf/mft_h264_decoder.h"
23
24 using base::Time;
25 using base::TimeDelta;
26 using media::FFmpegFileReader;
27 using media::MftH264Decoder;
28 using media::VideoFrame;
29
30 namespace {
31
32 void usage() {
33 static char* usage_msg =
34 "Usage: MftH264Decoder [--enable-dxva] --input-file=FILE\n"
35 "enable-dxva: Enables hardware accelerated decoding\n"
36 "To display this message: MftH264Decoder --help";
37 fprintf(stderr, "%s\n", usage_msg);
38 }
39
40 static bool InitFFmpeg() {
41 if (!media::InitializeMediaLibrary(FilePath()))
42 return false;
43 avcodec_init();
44 av_register_all();
45 av_register_protocol(&kFFmpegFileProtocol);
46 return true;
47 }
48
49 bool InitComLibraries() {
50 HRESULT hr;
51 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
52 if (FAILED(hr)) {
53 LOG(ERROR) << "CoInit fail";
54 return false;
55 }
56 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
57 if (FAILED(hr)) {
58 LOG(ERROR) << "MFStartup fail";
59 CoUninitialize();
60 return false;
61 }
62 return true;
63 }
64
65 void ShutdownComLibraries() {
66 HRESULT hr;
67 hr = MFShutdown();
68 if (FAILED(hr)) {
69 LOG(WARNING) << "Warning: MF failed to shutdown";
70 }
71 CoUninitialize();
72 }
73
74 IDirect3DDeviceManager9* CreateD3DDevManager(HWND video_window,
75 int width,
76 int height,
77 IDirect3D9** direct3d,
78 IDirect3DDevice9** device) {
79 CHECK(video_window != NULL);
80 CHECK(direct3d != NULL);
81 CHECK(device != NULL);
82
83 ScopedComPtr<IDirect3DDeviceManager9> dev_manager;
84 ScopedComPtr<IDirect3D9> d3d;
85 d3d.Attach(Direct3DCreate9(D3D_SDK_VERSION));
86 if (d3d == NULL) {
87 LOG(ERROR) << "Failed to create D3D9";
88 return NULL;
89 }
90 D3DPRESENT_PARAMETERS present_params = {0};
91
92 present_params.BackBufferWidth = width;
93 present_params.BackBufferHeight = height;
94 present_params.BackBufferFormat = D3DFMT_UNKNOWN;
95 present_params.BackBufferCount = 1;
96 present_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
97 present_params.hDeviceWindow = video_window;
98 present_params.Windowed = TRUE;
99 present_params.Flags = D3DPRESENTFLAG_VIDEO;
100 present_params.FullScreen_RefreshRateInHz = 0;
101 present_params.PresentationInterval = 0;
102
103 ScopedComPtr<IDirect3DDevice9> temp_device;
104
105 // D3DCREATE_HARDWARE_VERTEXPROCESSING specifies hardware vertex processing.
106 // (Is it even needed for just video decoding?)
107 HRESULT hr = d3d->CreateDevice(D3DADAPTER_DEFAULT,
108 D3DDEVTYPE_HAL,
109 video_window,
110 D3DCREATE_HARDWARE_VERTEXPROCESSING,
111 &present_params,
112 temp_device.Receive());
113 if (FAILED(hr)) {
114 LOG(ERROR) << "Failed to create D3D Device";
115 return NULL;
116 }
117 UINT dev_manager_reset_token = 0;
118 hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token,
119 dev_manager.Receive());
120 if (FAILED(hr)) {
121 LOG(ERROR) << "Couldn't create D3D Device manager";
122 return NULL;
123 }
124 hr = dev_manager->ResetDevice(temp_device.get(), dev_manager_reset_token);
125 if (FAILED(hr)) {
126 LOG(ERROR) << "Failed to set device to device manager";
127 return NULL;
128 }
129 *direct3d = d3d.Detach();
130 *device = temp_device.Detach();
131 return dev_manager.Detach();
132 }
133
134 static void ReleaseOutputBuffer(VideoFrame* frame) {
135 if (frame == NULL)
136 return;
137 if (frame->type() == VideoFrame::TYPE_MFBUFFER ||
138 frame->type() == VideoFrame::TYPE_DIRECT3DSURFACE) {
139 static_cast<IMFMediaBuffer*>(frame->private_buffer())->Release();
140 } else {
141 return;
142 }
143 }
144
145 class FakeRenderer {
146 public:
147 FakeRenderer() {}
148 ~FakeRenderer() {}
149 void ProcessFrame(scoped_refptr<VideoFrame> frame) {
150 ReleaseOutputBuffer(frame);
151 }
152 };
153
154 int Run(bool use_dxva, const std::string& input_file) {
155 scoped_ptr<FFmpegFileReader> reader(new FFmpegFileReader(input_file));
156 if (reader.get() == NULL) {
157 LOG(ERROR) << "Failed to create reader";
158 return -1;
159 }
160 if (!reader->Initialize()) {
161 LOG(ERROR) << "Failed to initialize reader";
162 return -1;
163 }
164
165 // TODO(imcheng): The frame rate obtained from ffmpeg seems to be double
166 // of what is expected. Why?
167 int frame_rate_num = 0, frame_rate_denom = 0;
168 if (!reader->GetFrameRate(&frame_rate_num, &frame_rate_denom)) {
169 LOG(WARNING) << "Failed to get frame rate from reader";
170 }
171 int width = 0, height = 0;
172 if (!reader->GetWidth(&width) || !reader->GetHeight(&height)) {
173 LOG(WARNING) << "Failed to get width/height from reader";
174 }
175 int aspect_ratio_num = 0, aspect_ratio_denom = 0;
176 if (!reader->GetAspectRatio(&aspect_ratio_num, &aspect_ratio_denom)) {
177 LOG(WARNING) << "Failed to get aspect ratio from reader";
178 }
179 ScopedComPtr<IDirect3D9> d3d9;
180 ScopedComPtr<IDirect3DDevice9> device;
181 ScopedComPtr<IDirect3DDeviceManager9> dev_manager;
182 if (use_dxva) {
183 dev_manager.Attach(CreateD3DDevManager(GetDesktopWindow(),
184 width,
185 height,
186 d3d9.Receive(),
187 device.Receive()));
188 if (dev_manager.get() == NULL) {
189 LOG(ERROR) << "Cannot create D3D9 manager";
190 return -1;
191 }
192 }
193 scoped_ptr<FakeRenderer> renderer(new FakeRenderer());
194 scoped_ptr<MftH264Decoder> mft(new MftH264Decoder(use_dxva));
195 if (mft.get() == NULL) {
196 LOG(ERROR) << "Failed to create MFT";
197 return -1;
198 }
199 if (!mft->Init(dev_manager,
200 frame_rate_num, frame_rate_denom,
201 width, height,
202 aspect_ratio_num, aspect_ratio_denom,
203 NewCallback<FFmpegFileReader, uint8**, int*, int64*, int64*>(
204 reader.get(), &FFmpegFileReader::Read),
205 NewCallback<FakeRenderer, scoped_refptr<VideoFrame> >(
206 renderer.get(), &FakeRenderer::ProcessFrame))) {
207 LOG(ERROR) << "Failed to initialize mft";
208 return -1;
209 }
210 TimeDelta decode_time;
211 while (true) {
212 Time decode_start(Time::Now());
213 if (MftH264Decoder::kOutputOk != mft->GetOutput())
214 break;
215 decode_time += Time::Now() - decode_start;
216 }
217 printf("All done, frames read: %d, frames decoded: %d\n",
218 mft->frames_read(), mft->frames_decoded());
219 printf("Took %lldms\n", decode_time.InMilliseconds());
220 return 0;
221 }
222
223 } // namespace
224
225 int main(int argc, char** argv) {
226 CommandLine::Init(argc, argv);
227 if (argc == 1) {
228 fprintf(stderr, "Not enough arguments\n");
229 usage();
230 return -1;
231 }
232
233 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
234 if (cmd_line.HasSwitch("help")) {
235 usage();
236 return -1;
237 }
238 bool use_dxva = cmd_line.HasSwitch("enable-dxva");
239 std::string input_file = cmd_line.GetSwitchValueASCII("input-file");
240 if (input_file.empty()) {
241 fprintf(stderr, "No input file provided\n");
242 usage();
243 return -1;
244 }
245 printf("enable-dxva: %d\n", use_dxva);
246 printf("input-file: %s\n", input_file.c_str());
247
248 if (!InitFFmpeg()) {
249 LOG(ERROR) << "InitFFMpeg() failed";
250 return -1;
251 }
252 if (!InitComLibraries()) {
253 LOG(ERROR) << "InitComLibraries() failed";
254 return -1;
255 }
256 int ret = Run(use_dxva, input_file);
257 ShutdownComLibraries();
258 printf("Done\n");
259 return ret;
260 }
OLDNEW
« no previous file with comments | « media/mf/file_reader_util.cc ('k') | media/mf/mft_h264_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698