49988684a97c54f58ada80c12723005c61a360c5
[platform/core/multimedia/esplusplayer.git] / ut / include / esplusplayer / eseventlistener.hpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #ifndef __PLUSPLAYER_UT_INCLUDE_ES_EVENT_LISTENER_H__
18 #define __PLUSPLAYER_UT_INCLUDE_ES_EVENT_LISTENER_H__
19
20 #include <chrono>
21 #include <string>
22 #include <thread>
23
24 #include "esplusplayer_capi/esplusplayer_capi.h"
25 #include "ut/include/esplusplayer/esreader.hpp"
26
27 class EsPlayerEventCallback {
28  public:
29   EsPlayerEventCallback(esplusplayer_handle handle,
30                         EsStreamReader* video_reader,
31                         EsStreamReader* audio_reader)
32       : handle_(handle),
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();
38   }
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,
45                                             this);
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,
52                                                    this);
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);
56   }
57
58   static void DataFeedingTask(EsStreamReader* stream,
59                               esplusplayer_handle esplayer) {
60     esplusplayer_es_packet pkt;
61     while (true) {
62       memset(&pkt, 0, sizeof(esplusplayer_es_packet));
63       if (!stream->ReadNextPacket(pkt)) break;
64       esplusplayer_submit_packet(esplayer, &pkt);
65       delete []pkt.buffer;
66     }
67   }
68   static void OnError(const esplusplayer_error_type err_code, void* userdata) {
69     std::cout << "OnError : " << esplusplayer_get_error_string(err_code) << std::endl;
70   }
71   static void OnResourceConflicted(void* userdata) {
72     std::cout << "OnResourceConflicted" << std::endl;
73   }
74   static void OnSeekDone(void* userdata) {
75     std::cout << "OnSeekDone" << std::endl;
76   }
77   static void OnBufferByteStatus(const esplusplayer_stream_type,
78                                  const esplusplayer_buffer_status, uint64_t,
79                                  void* userdata) {
80     // std::cout << "OnBufferByteStatus" << std::endl;
81   }
82   static void OnBufferTimeStatus(const esplusplayer_stream_type,
83                                  const esplusplayer_buffer_status, uint64_t,
84                                  void* userdata) {
85     // std::cout << "OnBufferTimeStatus" << std::endl;
86   }
87   static void OnVideoDecoded(const esplusplayer_decoded_video_packet * pkt,
88                              void* userdata) {
89     EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
90
91     std::cout << "OnVideoDecoded" << std::endl;
92     esplusplayer_decoded_buffer_destroy (cb->handle_, (esplusplayer_decoded_video_packet *)pkt);
93   }
94   static void OnClosedCaption(const char* data, const int size,
95                               void* userdata) {
96     std::cout << "OnClosedCaption" << std::endl;
97   }
98   static void OnFlushDone(void* userdata) {
99     std::cout << "OnFlushDone" << std::endl;
100   }
101   static void OnEvent(const esplusplayer_event_type,
102                       const esplusplayer_event_msg, void*) {
103     std::cout << "OnEvent" << std::endl;
104   }
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;
109     cb->eos_ = true;
110     lk.unlock();
111     cb->eos_cv_.notify_all();
112   }
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;
119     lk.unlock();
120     cb->prepare_done_cv_.notify_all();
121   }
122   static void OnBufferStatus(const esplusplayer_stream_type type,
123                              const esplusplayer_buffer_status status,
124                              void* userdata) {
125     // auto buffer_status =
126     //    status == ESPLUSPLAYER_BUFFER_STATUS_UNDERRUN ? "underrun" :
127     //    "overrun";
128     // std::cout << "OnBufferStatus " << buffer_status << std::endl;
129   }
130   static void OnReadyToPrepare(const esplusplayer_stream_type type,
131                                void* userdata) {
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_));
141       }
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_));
149       }
150       std::cout << "Video ready to prepare" << std::endl;
151     }
152     lk.unlock();
153     cb->data_cv_.notify_all();
154   }
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;
164     lk.unlock();
165     cb->data_cv_.notify_all();
166   }
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_;
172     });
173     std::cout << "WaitAllStreamData stop" << std::endl;
174     lk.unlock();
175   }
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;
182     lk.unlock();
183   }
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;
190     lk.unlock();
191   }
192   void WaitForEos() {
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;
198     lk.unlock();
199   }
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;
206     lk.unlock();
207     return prepare_done_result_;
208   }
209
210  private:
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_;
216
217   bool eos_ = false;
218   std::mutex eos_m_;
219   std::condition_variable eos_cv_;
220   bool ready_audio_data_ = false;
221   bool ready_video_data_ = false;
222   std::mutex data_m_;
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_;
228 };
229
230 #endif  // __PLUSPLAYER_UT_INCLUDE_ES_EVENT_LISTENER_H__