1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
media / renderers / win / media_engine_extension.cc [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/renderers/win/media_engine_extension.h"
#include <mferror.h>
#include "media/base/win/mf_helpers.h"
namespace media {
using Microsoft::WRL::ComPtr;
MediaEngineExtension::MediaEngineExtension() = default;
MediaEngineExtension::~MediaEngineExtension() = default;
HRESULT MediaEngineExtension::RuntimeClassInitialize() {
DVLOG_FUNC(1);
return S_OK;
}
HRESULT MediaEngineExtension::CanPlayType(BOOL is_audio_only,
BSTR mime_type,
MF_MEDIA_ENGINE_CANPLAY* result) {
// We use MF_MEDIA_ENGINE_EXTENSION to resolve as custom media source for
// MFMediaEngine, MIME types are not used.
*result = MF_MEDIA_ENGINE_CANPLAY_NOT_SUPPORTED;
return S_OK;
}
HRESULT MediaEngineExtension::BeginCreateObject(BSTR url_bstr,
IMFByteStream* byte_stream,
MF_OBJECT_TYPE type,
IUnknown** cancel_cookie,
IMFAsyncCallback* callback,
IUnknown* state) {
DVLOG_FUNC(1) << "type=" << type;
if (cancel_cookie) {
// We don't support a cancel cookie.
*cancel_cookie = nullptr;
}
ComPtr<IUnknown> local_source;
{
base::AutoLock lock(lock_);
if (has_shutdown_) {
return MF_E_SHUTDOWN;
}
local_source = mf_media_source_;
}
if (type == MF_OBJECT_MEDIASOURCE) {
DVLOG_FUNC(2) << "Begin to resolve |mf_media_source_|";
DCHECK(local_source) << "Media Source should have been set";
ComPtr<IMFAsyncResult> async_result;
RETURN_IF_FAILED(MFCreateAsyncResult(local_source.Get(), callback, state,
&async_result));
RETURN_IF_FAILED(async_result->SetStatus(S_OK));
pending_create_object_ = true;
// Invoke the callback synchronously since no outstanding work is required.
RETURN_IF_FAILED(callback->Invoke(async_result.Get()));
} else {
// MediaEngine will try to resolve with different |type|.
return MF_E_UNEXPECTED;
}
return S_OK;
}
HRESULT MediaEngineExtension::CancelObjectCreation(
__in IUnknown* cancel_cookie) {
DVLOG_FUNC(1);
return MF_E_UNEXPECTED;
}
HRESULT MediaEngineExtension::EndCreateObject(__in IMFAsyncResult* result,
__deref_out IUnknown** ret_obj) {
DVLOG_FUNC(1);
*ret_obj = nullptr;
if (!pending_create_object_)
return MF_E_UNEXPECTED;
DVLOG_FUNC(2) << "End to resolve |mf_media_source_|";
RETURN_IF_FAILED(result->GetStatus());
RETURN_IF_FAILED(result->GetObject(ret_obj));
pending_create_object_ = false;
return S_OK;
}
HRESULT MediaEngineExtension::SetMediaSource(IUnknown* mf_media_source) {
DVLOG_FUNC(1);
base::AutoLock lock(lock_);
if (has_shutdown_)
return MF_E_SHUTDOWN;
mf_media_source_ = mf_media_source;
return S_OK;
}
// Break cycles.
void MediaEngineExtension::Shutdown() {
DVLOG_FUNC(1);
base::AutoLock lock(lock_);
if (!has_shutdown_) {
mf_media_source_.Reset();
has_shutdown_ = true;
}
}
} // namespace media