media_engine_notify_impl.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. #include "media/renderers/win/media_engine_notify_impl.h"
  5. #include "media/base/win/mf_helpers.h"
  6. namespace media {
  7. namespace {
  8. #define ENUM_TO_STRING(enum) \
  9. case enum: \
  10. return #enum
  11. std::string MediaEngineEventToString(MF_MEDIA_ENGINE_EVENT event) {
  12. switch (event) {
  13. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_LOADSTART);
  14. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_PROGRESS);
  15. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_SUSPEND);
  16. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_ABORT);
  17. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_ERROR);
  18. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_EMPTIED);
  19. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_STALLED);
  20. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_PLAY);
  21. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_PAUSE);
  22. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_LOADEDMETADATA);
  23. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_LOADEDDATA);
  24. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_WAITING);
  25. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_PLAYING);
  26. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_CANPLAY);
  27. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_CANPLAYTHROUGH);
  28. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_SEEKING);
  29. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_SEEKED);
  30. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_TIMEUPDATE);
  31. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_ENDED);
  32. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_RATECHANGE);
  33. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE);
  34. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE);
  35. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_FORMATCHANGE);
  36. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_PURGEQUEUEDEVENTS);
  37. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_TIMELINE_MARKER);
  38. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_BALANCECHANGE);
  39. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_DOWNLOADCOMPLETE);
  40. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_BUFFERINGSTARTED);
  41. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_BUFFERINGENDED);
  42. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_FRAMESTEPCOMPLETED);
  43. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_NOTIFYSTABLESTATE);
  44. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_FIRSTFRAMEREADY);
  45. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_TRACKSCHANGE);
  46. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_OPMINFO);
  47. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_RESOURCELOST);
  48. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_DELAYLOADEVENT_CHANGED);
  49. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_STREAMRENDERINGERROR);
  50. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_SUPPORTEDRATES_CHANGED);
  51. ENUM_TO_STRING(MF_MEDIA_ENGINE_EVENT_AUDIOENDPOINTCHANGE);
  52. default:
  53. return "Unknown MF_MEDIA_ENGINE_EVENT";
  54. }
  55. }
  56. #undef ENUM_TO_STRING
  57. PipelineStatus MediaEngineErrorToPipelineStatus(
  58. MF_MEDIA_ENGINE_ERR media_engine_error) {
  59. switch (media_engine_error) {
  60. case MF_MEDIA_ENGINE_ERR_NOERROR:
  61. return PIPELINE_OK;
  62. case MF_MEDIA_ENGINE_ERR_ABORTED:
  63. return PIPELINE_ERROR_ABORT;
  64. case MF_MEDIA_ENGINE_ERR_NETWORK:
  65. return PIPELINE_ERROR_NETWORK;
  66. case MF_MEDIA_ENGINE_ERR_DECODE:
  67. [[fallthrough]];
  68. case MF_MEDIA_ENGINE_ERR_ENCRYPTED:
  69. return PIPELINE_ERROR_DECODE;
  70. case MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED:
  71. return DEMUXER_ERROR_COULD_NOT_OPEN;
  72. default:
  73. NOTREACHED();
  74. return PIPELINE_ERROR_INVALID_STATE;
  75. }
  76. }
  77. } // namespace
  78. MediaEngineNotifyImpl::MediaEngineNotifyImpl() = default;
  79. MediaEngineNotifyImpl::~MediaEngineNotifyImpl() = default;
  80. HRESULT MediaEngineNotifyImpl::RuntimeClassInitialize(
  81. ErrorCB error_cb,
  82. EndedCB ended_cb,
  83. FormatChangeCB format_change_cb,
  84. LoadedDataCB loaded_data_cb,
  85. PlayingCB playing_cb,
  86. WaitingCB waiting_cb,
  87. TimeUpdateCB time_update_cb) {
  88. DVLOG_FUNC(1);
  89. error_cb_ = std::move(error_cb);
  90. ended_cb_ = std::move(ended_cb);
  91. format_change_cb_ = std::move(format_change_cb);
  92. loaded_data_cb_ = std::move(loaded_data_cb);
  93. playing_cb_ = std::move(playing_cb);
  94. waiting_cb_ = std::move(waiting_cb);
  95. time_update_cb_ = std::move(time_update_cb);
  96. return S_OK;
  97. }
  98. // |param1| and |param2|'s meaning depends on the |event_code| from
  99. // https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/ne-mfmediaengine-mf_media_engine_event
  100. // This method always return S_OK. Even for error |event_code| because we
  101. // successfully handled the event.
  102. HRESULT MediaEngineNotifyImpl::EventNotify(DWORD event_code,
  103. DWORD_PTR param1,
  104. DWORD param2) {
  105. auto event = static_cast<MF_MEDIA_ENGINE_EVENT>(event_code);
  106. DVLOG_FUNC(3) << "event=" << MediaEngineEventToString(event);
  107. base::AutoLock lock(lock_);
  108. if (has_shutdown_)
  109. return S_OK;
  110. switch (event) {
  111. case MF_MEDIA_ENGINE_EVENT_ERROR: {
  112. // |param1| - A member of the MF_MEDIA_ENGINE_ERR enumeration.
  113. // |param2| - An HRESULT error code, or zero.
  114. MF_MEDIA_ENGINE_ERR error = static_cast<MF_MEDIA_ENGINE_ERR>(param1);
  115. HRESULT hr = param2;
  116. LOG(ERROR) << __func__ << ": error=" << error << ", hr=" << PrintHr(hr);
  117. error_cb_.Run(MediaEngineErrorToPipelineStatus(error), hr);
  118. break;
  119. }
  120. case MF_MEDIA_ENGINE_EVENT_ENDED:
  121. ended_cb_.Run();
  122. break;
  123. case MF_MEDIA_ENGINE_EVENT_FORMATCHANGE:
  124. format_change_cb_.Run();
  125. break;
  126. case MF_MEDIA_ENGINE_EVENT_LOADEDDATA:
  127. loaded_data_cb_.Run();
  128. break;
  129. case MF_MEDIA_ENGINE_EVENT_PLAYING:
  130. playing_cb_.Run();
  131. break;
  132. case MF_MEDIA_ENGINE_EVENT_WAITING:
  133. waiting_cb_.Run();
  134. break;
  135. case MF_MEDIA_ENGINE_EVENT_TIMEUPDATE:
  136. time_update_cb_.Run();
  137. break;
  138. default:
  139. DVLOG_FUNC(2) << "Unhandled event=" << MediaEngineEventToString(event);
  140. break;
  141. }
  142. return S_OK;
  143. }
  144. void MediaEngineNotifyImpl::Shutdown() {
  145. DVLOG_FUNC(1);
  146. base::AutoLock lock(lock_);
  147. has_shutdown_ = true;
  148. }
  149. } // namespace media