2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef __PLUSPLAYER_UT_INCLUDE_ES_EVENT_LISTENER_H__
18 #define __PLUSPLAYER_UT_INCLUDE_ES_EVENT_LISTENER_H__
24 #include "esplusplayer_capi/esplusplayer_capi.h"
25 #include "ut/include/esplusplayer/esreader.hpp"
27 class EsPlayerEventCallback {
29 EsPlayerEventCallback(esplusplayer_handle handle,
30 EsStreamReader* video_reader,
31 EsStreamReader* audio_reader)
33 video_reader_(video_reader),
34 audio_reader_(audio_reader) {}
35 ~EsPlayerEventCallback() {
36 if (audio_feeding_task_.joinable()) audio_feeding_task_.join();
37 if (video_feeding_task_.joinable()) video_feeding_task_.join();
39 void SetCallback(void) {
40 esplusplayer_set_error_cb(handle_, OnError, this);
41 esplusplayer_set_buffer_status_cb(handle_, OnBufferStatus, this);
42 esplusplayer_set_buffer_byte_status_cb(handle_, OnBufferByteStatus, this);
43 esplusplayer_set_buffer_time_status_cb(handle_, OnBufferTimeStatus, this);
44 esplusplayer_set_resource_conflicted_cb(handle_, OnResourceConflicted,
46 esplusplayer_set_eos_cb(handle_, OnEos, this);
47 esplusplayer_set_ready_to_prepare_cb(handle_, OnReadyToPrepare, this);
48 esplusplayer_set_prepare_async_done_cb(handle_, OnPrepareDone, this);
49 esplusplayer_set_seek_done_cb(handle_, OnSeekDone, this);
50 esplusplayer_set_ready_to_seek_cb(handle_, OnReadyToSeek, this);
51 esplusplayer_set_media_packet_video_decoded_cb(handle_, OnVideoDecoded,
53 esplusplayer_set_closed_caption_cb(handle_, OnClosedCaption, this);
54 esplusplayer_set_flush_done_cb(handle_, OnFlushDone, this);
55 esplusplayer_set_event_cb(handle_, OnEvent, this);
58 static void DataFeedingTask(EsStreamReader* stream,
59 esplusplayer_handle esplayer) {
60 esplusplayer_es_packet pkt;
62 memset(&pkt, 0, sizeof(esplusplayer_es_packet));
63 if (!stream->ReadNextPacket(pkt)) break;
64 esplusplayer_submit_packet(esplayer, &pkt);
68 static void OnError(const esplusplayer_error_type err_code, void* userdata) {
69 std::cout << "OnError : " << esplusplayer_get_error_string(err_code) << std::endl;
71 static void OnResourceConflicted(void* userdata) {
72 std::cout << "OnResourceConflicted" << std::endl;
74 static void OnSeekDone(void* userdata) {
75 std::cout << "OnSeekDone" << std::endl;
77 static void OnBufferByteStatus(const esplusplayer_stream_type,
78 const esplusplayer_buffer_status, uint64_t,
80 // std::cout << "OnBufferByteStatus" << std::endl;
82 static void OnBufferTimeStatus(const esplusplayer_stream_type,
83 const esplusplayer_buffer_status, uint64_t,
85 // std::cout << "OnBufferTimeStatus" << std::endl;
87 static void OnVideoDecoded(const esplusplayer_decoded_video_packet * pkt,
89 EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
91 std::cout << "OnVideoDecoded" << std::endl;
92 esplusplayer_decoded_buffer_destroy (cb->handle_, (esplusplayer_decoded_video_packet *)pkt);
94 static void OnClosedCaption(const char* data, const int size,
96 std::cout << "OnClosedCaption" << std::endl;
98 static void OnFlushDone(void* userdata) {
99 std::cout << "OnFlushDone" << std::endl;
101 static void OnEvent(const esplusplayer_event_type,
102 const esplusplayer_event_msg, void*) {
103 std::cout << "OnEvent" << std::endl;
105 static void OnEos(void* userdata) {
106 EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
107 std::unique_lock<std::mutex> lk(cb->eos_m_);
108 std::cout << "OnEos" << std::endl;
111 cb->eos_cv_.notify_all();
113 static void OnPrepareDone(bool ret, void* userdata) {
114 EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
115 std::unique_lock<std::mutex> lk(cb->prepare_done_m_);
116 std::cout << "OnPrepareDone" << std::endl;
117 cb->prepare_done_ = true;
118 cb->prepare_done_result_ = ret;
120 cb->prepare_done_cv_.notify_all();
122 static void OnBufferStatus(const esplusplayer_stream_type type,
123 const esplusplayer_buffer_status status,
125 // auto buffer_status =
126 // status == ESPLUSPLAYER_BUFFER_STATUS_UNDERRUN ? "underrun" :
128 // std::cout << "OnBufferStatus " << buffer_status << std::endl;
130 static void OnReadyToPrepare(const esplusplayer_stream_type type,
132 EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
133 std::cout << "OnReadyToPrepare" << std::endl;
134 std::unique_lock<std::mutex> lk(cb->data_m_);
135 if (type == ESPLUSPLAYER_STREAM_TYPE_AUDIO) {
136 cb->ready_audio_data_ = true;
137 if (cb->audio_reader_ != nullptr) {
138 cb->audio_feeding_task_ =
139 std::thread(DataFeedingTask, std::ref(cb->audio_reader_),
140 std::ref(cb->handle_));
142 std::cout << "Audio ready to prepare" << std::endl;
143 } else if (type == ESPLUSPLAYER_STREAM_TYPE_VIDEO) {
144 cb->ready_video_data_ = true;
145 if (cb->video_reader_ != nullptr) {
146 cb->video_feeding_task_ =
147 std::thread(DataFeedingTask, std::ref(cb->video_reader_),
148 std::ref(cb->handle_));
150 std::cout << "Video ready to prepare" << std::endl;
153 cb->data_cv_.notify_all();
155 static void OnReadyToSeek(const esplusplayer_stream_type type,
156 const uint64_t offset, void* userdata) {
157 EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
158 std::cout << "OnReadyToSeek" << std::endl;
159 std::unique_lock<std::mutex> lk(cb->data_m_);
160 if (type == ESPLUSPLAYER_STREAM_TYPE_AUDIO)
161 cb->ready_audio_data_ = true;
162 else if (type == ESPLUSPLAYER_STREAM_TYPE_VIDEO)
163 cb->ready_video_data_ = true;
165 cb->data_cv_.notify_all();
167 void WaitAllStreamData() {
168 std::unique_lock<std::mutex> lk(data_m_);
169 std::cout << "WaitAllStreamData start" << std::endl;
170 data_cv_.wait_for(lk, std::chrono::seconds(1), [this]() -> bool {
171 return ready_audio_data_ && ready_video_data_;
173 std::cout << "WaitAllStreamData stop" << std::endl;
176 void WaitAudioStreamData() {
177 std::unique_lock<std::mutex> lk(data_m_);
178 std::cout << "WaitAudioStreamData start" << std::endl;
179 data_cv_.wait_for(lk, std::chrono::seconds(1),
180 [this]() -> bool { return ready_audio_data_; });
181 std::cout << "WaitAudioStreamData stop" << std::endl;
184 void WaitVideoStreamData() {
185 std::unique_lock<std::mutex> lk(data_m_);
186 std::cout << "WaitVideoStreamData start" << std::endl;
187 data_cv_.wait_for(lk, std::chrono::seconds(1),
188 [this]() -> bool { return ready_audio_data_; });
189 std::cout << "WaitVideoStreamData stop" << std::endl;
193 std::cout << "WaitForEos start" << std::endl;
194 std::unique_lock<std::mutex> lk(eos_m_);
195 eos_cv_.wait_for(lk, std::chrono::minutes(1),
196 [this]() -> bool { return eos_; });
197 std::cout << "WaitForEos stop" << std::endl;
200 bool WaitForPrepareDone() {
201 std::cout << "WaitForPrepareDone start" << std::endl;
202 std::unique_lock<std::mutex> lk(prepare_done_m_);
203 prepare_done_cv_.wait_for(lk, std::chrono::seconds(10),
204 [this]() -> bool { return prepare_done_; });
205 std::cout << "WaitForPrepareDone stop" << std::endl;
207 return prepare_done_result_;
211 esplusplayer_handle handle_ = nullptr;
212 EsStreamReader* video_reader_ = nullptr;
213 EsStreamReader* audio_reader_ = nullptr;
214 std::thread video_feeding_task_;
215 std::thread audio_feeding_task_;
219 std::condition_variable eos_cv_;
220 bool ready_audio_data_ = false;
221 bool ready_video_data_ = false;
223 std::condition_variable data_cv_;
224 bool prepare_done_ = false;
225 bool prepare_done_result_ = false;
226 std::mutex prepare_done_m_;
227 std::condition_variable prepare_done_cv_;
230 #endif // __PLUSPLAYER_UT_INCLUDE_ES_EVENT_LISTENER_H__