1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/renderers/win/media_engine_notify_impl.h"
6
7 namespace media {
8
9 namespace {
10
MediaEngineStatusToPipelineStatus(MF_MEDIA_ENGINE_ERR media_engine_status)11 PipelineStatus MediaEngineStatusToPipelineStatus(
12 MF_MEDIA_ENGINE_ERR media_engine_status) {
13 switch (media_engine_status) {
14 case MF_MEDIA_ENGINE_ERR_NOERROR:
15 return PipelineStatus::PIPELINE_OK;
16 case MF_MEDIA_ENGINE_ERR_ABORTED:
17 return PipelineStatus::PIPELINE_ERROR_ABORT;
18 case MF_MEDIA_ENGINE_ERR_NETWORK:
19 return PipelineStatus::PIPELINE_ERROR_NETWORK;
20 case MF_MEDIA_ENGINE_ERR_DECODE:
21 FALLTHROUGH;
22 case MF_MEDIA_ENGINE_ERR_ENCRYPTED:
23 return PipelineStatus::PIPELINE_ERROR_DECODE;
24 case MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED:
25 return PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN;
26 default:
27 NOTREACHED();
28 return PipelineStatus::PIPELINE_ERROR_INVALID_STATE;
29 }
30 }
31
32 } // namespace
33
34 MediaEngineNotifyImpl::MediaEngineNotifyImpl() = default;
35 MediaEngineNotifyImpl::~MediaEngineNotifyImpl() = default;
36
RuntimeClassInitialize(ErrorCB error_cb,EndedCB ended_cb,DurationChangedCB duration_changed_cb,BufferingStateChangedCB buffering_state_changed_cb,VideoNaturalSizeChangedCB video_natural_size_changed_cb)37 HRESULT MediaEngineNotifyImpl::RuntimeClassInitialize(
38 ErrorCB error_cb,
39 EndedCB ended_cb,
40 DurationChangedCB duration_changed_cb,
41 BufferingStateChangedCB buffering_state_changed_cb,
42 VideoNaturalSizeChangedCB video_natural_size_changed_cb) {
43 DVLOG(1) << __func__ << ": this=" << this;
44
45 error_cb_ = std::move(error_cb);
46 ended_cb_ = std::move(ended_cb);
47 duration_changed_cb_ = std::move(duration_changed_cb);
48 buffering_state_changed_cb_ = std::move(buffering_state_changed_cb);
49 video_natural_size_changed_cb_ = std::move(video_natural_size_changed_cb);
50 return S_OK;
51 }
52
53 // |param1| and |param2|'s meaning depends on the |event_code| from
54 // https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/ne-mfmediaengine-mf_media_engine_event
55 // This method always return S_OK. Even for error |event_code| because we
56 // successfully handled the event.
EventNotify(DWORD event_code,DWORD_PTR param1,DWORD param2)57 HRESULT MediaEngineNotifyImpl::EventNotify(DWORD event_code,
58 DWORD_PTR param1,
59 DWORD param2) {
60 DVLOG(3) << __func__ << ": this=" << this << ",eventCode=" << event_code
61 << ",param1=" << static_cast<unsigned>(param1)
62 << ",param2=" << static_cast<unsigned>(param2);
63
64 base::AutoLock lock(lock_);
65 if (has_shutdown_)
66 return S_OK;
67
68 switch (static_cast<MF_MEDIA_ENGINE_EVENT>(event_code)) {
69 case MF_MEDIA_ENGINE_EVENT_ERROR: {
70 // |param1| - A member of the MF_MEDIA_ENGINE_ERR enumeration.
71 // |param2| - An HRESULT error code, or zero.
72 MF_MEDIA_ENGINE_ERR error = static_cast<MF_MEDIA_ENGINE_ERR>(param1);
73 DLOG(ERROR) << __func__ << ": error=" << error << ",hr=" << param2;
74 error_cb_.Run(MediaEngineStatusToPipelineStatus(error));
75 break;
76 }
77 case MF_MEDIA_ENGINE_EVENT_ENDED:
78 ended_cb_.Run();
79 break;
80 case MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE:
81 duration_changed_cb_.Run();
82 break;
83 case MF_MEDIA_ENGINE_EVENT_FORMATCHANGE:
84 video_natural_size_changed_cb_.Run();
85 break;
86 case MF_MEDIA_ENGINE_EVENT_LOADEDDATA:
87 video_natural_size_changed_cb_.Run();
88 FALLTHROUGH;
89 case MF_MEDIA_ENGINE_EVENT_PLAYING:
90 buffering_state_changed_cb_.Run(
91 BufferingState::BUFFERING_HAVE_ENOUGH,
92 BufferingStateChangeReason::BUFFERING_CHANGE_REASON_UNKNOWN);
93 break;
94 case MF_MEDIA_ENGINE_EVENT_WAITING:
95 buffering_state_changed_cb_.Run(
96 BufferingState::BUFFERING_HAVE_NOTHING,
97 BufferingStateChangeReason::BUFFERING_CHANGE_REASON_UNKNOWN);
98 break;
99 default:
100 DVLOG(3) << __func__ << ": this=" << this
101 << ", unhandled event_code=" << event_code;
102 break;
103 }
104 return S_OK;
105 }
106
Shutdown()107 void MediaEngineNotifyImpl::Shutdown() {
108 DVLOG(1) << __func__ << ": this=" << this;
109
110 base::AutoLock lock(lock_);
111 has_shutdown_ = true;
112 }
113
114 } // namespace media
115