Fix svace issue
[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 #include <mutex>
24 #include <condition_variable>
25
26 #include "esplusplayer_capi/esplusplayer_capi.h"
27 #include "ut/include/esplusplayer/esreader.hpp"
28
29 class EsPlayerEventCallback {
30  public:
31   EsPlayerEventCallback(esplusplayer_handle handle,
32                         EsStreamReader* video_reader,
33                         EsStreamReader* audio_reader)
34       : handle_(handle),
35         video_reader_(video_reader),
36         audio_reader_(audio_reader) {}
37   ~EsPlayerEventCallback() {
38     if (audio_feeding_task_.joinable()) audio_feeding_task_.join();
39     if (video_feeding_task_.joinable()) video_feeding_task_.join();
40   }
41   void SetCallback(void) {
42     esplusplayer_set_error_cb(handle_, OnError, this);
43     esplusplayer_set_buffer_status_cb(handle_, OnBufferStatus, this);
44     esplusplayer_set_buffer_byte_status_cb(handle_, OnBufferByteStatus, this);
45     esplusplayer_set_buffer_time_status_cb(handle_, OnBufferTimeStatus, this);
46     esplusplayer_set_resource_conflicted_cb(handle_, OnResourceConflicted,
47                                             this);
48     esplusplayer_set_eos_cb(handle_, OnEos, this);
49     esplusplayer_set_ready_to_prepare_cb(handle_, OnReadyToPrepare, this);
50     esplusplayer_set_prepare_async_done_cb(handle_, OnPrepareDone, this);
51     esplusplayer_set_seek_done_cb(handle_, OnSeekDone, this);
52     esplusplayer_set_ready_to_seek_cb(handle_, OnReadyToSeek, this);
53     esplusplayer_set_media_packet_video_decoded_cb(handle_, OnVideoDecoded,
54                                                    this);
55     esplusplayer_set_closed_caption_cb(handle_, OnClosedCaption, this);
56     esplusplayer_set_flush_done_cb(handle_, OnFlushDone, this);
57     esplusplayer_set_event_cb(handle_, OnEvent, this);
58   }
59
60   static void DataFeedingTask(EsStreamReader* stream,
61                               esplusplayer_handle esplayer) {
62     esplusplayer_es_packet pkt;
63     while (true) {
64       memset(&pkt, 0, sizeof(esplusplayer_es_packet));
65       if (!stream->ReadNextPacket(pkt)) break;
66       esplusplayer_submit_packet(esplayer, &pkt);
67       delete []pkt.buffer;
68     }
69   }
70   static void OnError(const esplusplayer_error_type err_code, void* userdata) {
71     std::cout << "OnError : " << esplusplayer_get_error_string(err_code) << std::endl;
72   }
73   static void OnResourceConflicted(void* userdata) {
74     std::cout << "OnResourceConflicted" << std::endl;
75   }
76   static void OnSeekDone(void* userdata) {
77     std::cout << "OnSeekDone" << std::endl;
78   }
79   static void OnBufferByteStatus(const esplusplayer_stream_type,
80                                  const esplusplayer_buffer_status, uint64_t,
81                                  void* userdata) {
82     // std::cout << "OnBufferByteStatus" << std::endl;
83   }
84   static void OnBufferTimeStatus(const esplusplayer_stream_type,
85                                  const esplusplayer_buffer_status, uint64_t,
86                                  void* userdata) {
87     // std::cout << "OnBufferTimeStatus" << std::endl;
88   }
89   static void OnVideoDecoded(const esplusplayer_decoded_video_packet * pkt,
90                              void* userdata) {
91     EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
92
93     std::cout << "OnVideoDecoded" << std::endl;
94     esplusplayer_decoded_buffer_destroy (cb->handle_, (esplusplayer_decoded_video_packet *)pkt);
95   }
96   static void OnClosedCaption(const char* data, const int size,
97                               void* userdata) {
98     std::cout << "OnClosedCaption" << std::endl;
99   }
100   static void OnFlushDone(void* userdata) {
101     std::cout << "OnFlushDone" << std::endl;
102   }
103   static void OnEvent(const esplusplayer_event_type,
104                       const esplusplayer_event_msg, void*) {
105     std::cout << "OnEvent" << std::endl;
106   }
107   static void OnEos(void* userdata) {
108     EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
109     std::unique_lock<std::mutex> lk(cb->eos_m_);
110     std::cout << "OnEos" << std::endl;
111     cb->eos_ = true;
112     lk.unlock();
113     cb->eos_cv_.notify_all();
114   }
115   static void OnPrepareDone(bool ret, void* userdata) {
116     EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
117     std::unique_lock<std::mutex> lk(cb->prepare_done_m_);
118     std::cout << "OnPrepareDone" << std::endl;
119     cb->prepare_done_ = true;
120     cb->prepare_done_result_ = ret;
121     lk.unlock();
122     cb->prepare_done_cv_.notify_all();
123   }
124   static void OnBufferStatus(const esplusplayer_stream_type type,
125                              const esplusplayer_buffer_status status,
126                              void* userdata) {
127     // auto buffer_status =
128     //    status == ESPLUSPLAYER_BUFFER_STATUS_UNDERRUN ? "underrun" :
129     //    "overrun";
130     // std::cout << "OnBufferStatus " << buffer_status << std::endl;
131   }
132   static void OnReadyToPrepare(const esplusplayer_stream_type type,
133                                void* userdata) {
134     EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
135     std::cout << "OnReadyToPrepare" << std::endl;
136     std::unique_lock<std::mutex> lk(cb->data_m_);
137     if (type == ESPLUSPLAYER_STREAM_TYPE_AUDIO) {
138       cb->ready_audio_data_ = true;
139       if (cb->audio_reader_ != nullptr) {
140         cb->audio_feeding_task_ =
141             std::thread(DataFeedingTask, std::ref(cb->audio_reader_),
142                         std::ref(cb->handle_));
143       }
144       std::cout << "Audio ready to prepare" << std::endl;
145     } else if (type == ESPLUSPLAYER_STREAM_TYPE_VIDEO) {
146       cb->ready_video_data_ = true;
147       if (cb->video_reader_ != nullptr) {
148         cb->video_feeding_task_ =
149             std::thread(DataFeedingTask, std::ref(cb->video_reader_),
150                         std::ref(cb->handle_));
151       }
152       std::cout << "Video ready to prepare" << std::endl;
153     }
154     lk.unlock();
155     cb->data_cv_.notify_all();
156   }
157   static void OnReadyToSeek(const esplusplayer_stream_type type,
158                             const uint64_t offset, void* userdata) {
159     EsPlayerEventCallback* cb = static_cast<EsPlayerEventCallback*>(userdata);
160     std::cout << "OnReadyToSeek" << std::endl;
161     std::unique_lock<std::mutex> lk(cb->data_m_);
162     if (type == ESPLUSPLAYER_STREAM_TYPE_AUDIO)
163       cb->ready_audio_data_ = true;
164     else if (type == ESPLUSPLAYER_STREAM_TYPE_VIDEO)
165       cb->ready_video_data_ = true;
166     lk.unlock();
167     cb->data_cv_.notify_all();
168   }
169   void WaitAllStreamData() {
170     std::unique_lock<std::mutex> lk(data_m_);
171     std::cout << "WaitAllStreamData start" << std::endl;
172     data_cv_.wait_for(lk, std::chrono::seconds(1), [this]() -> bool {
173       return ready_audio_data_ && ready_video_data_;
174     });
175     std::cout << "WaitAllStreamData stop" << std::endl;
176     lk.unlock();
177   }
178   void WaitAudioStreamData() {
179     std::unique_lock<std::mutex> lk(data_m_);
180     std::cout << "WaitAudioStreamData start" << std::endl;
181     data_cv_.wait_for(lk, std::chrono::seconds(1),
182                       [this]() -> bool { return ready_audio_data_; });
183     std::cout << "WaitAudioStreamData stop" << std::endl;
184     lk.unlock();
185   }
186   void WaitVideoStreamData() {
187     std::unique_lock<std::mutex> lk(data_m_);
188     std::cout << "WaitVideoStreamData start" << std::endl;
189     data_cv_.wait_for(lk, std::chrono::seconds(1),
190                       [this]() -> bool { return ready_audio_data_; });
191     std::cout << "WaitVideoStreamData stop" << std::endl;
192     lk.unlock();
193   }
194   void WaitForEos() {
195     std::cout << "WaitForEos start" << std::endl;
196     std::unique_lock<std::mutex> lk(eos_m_);
197     eos_cv_.wait_for(lk, std::chrono::minutes(1),
198                      [this]() -> bool { return eos_; });
199     std::cout << "WaitForEos stop" << std::endl;
200     lk.unlock();
201   }
202   bool WaitForPrepareDone() {
203     std::cout << "WaitForPrepareDone start" << std::endl;
204     std::unique_lock<std::mutex> lk(prepare_done_m_);
205     prepare_done_cv_.wait_for(lk, std::chrono::seconds(10),
206                               [this]() -> bool { return prepare_done_; });
207     std::cout << "WaitForPrepareDone stop" << std::endl;
208     lk.unlock();
209     return prepare_done_result_;
210   }
211
212  private:
213   esplusplayer_handle handle_ = nullptr;
214   EsStreamReader* video_reader_ = nullptr;
215   EsStreamReader* audio_reader_ = nullptr;
216   std::thread video_feeding_task_;
217   std::thread audio_feeding_task_;
218
219   bool eos_ = false;
220   std::mutex eos_m_;
221   std::condition_variable eos_cv_;
222   bool ready_audio_data_ = false;
223   bool ready_video_data_ = false;
224   std::mutex data_m_;
225   std::condition_variable data_cv_;
226   bool prepare_done_ = false;
227   bool prepare_done_result_ = false;
228   std::mutex prepare_done_m_;
229   std::condition_variable prepare_done_cv_;
230 };
231
232 #endif  // __PLUSPLAYER_UT_INCLUDE_ES_EVENT_LISTENER_H__