[Reform] Apply Coding Style
[platform/core/multimedia/esplusplayer.git] / src / esplusplayer / src / esplusplayer_capi.cpp
1 #include "esplusplayer_capi/esplusplayer_capi.h"
2
3 #include "esplusplayer/esplusplayer.h"
4
5 using esplusplayer::EsPlusPlayer;
6 using esplusplayer::Geometry;
7
8 #include <inttypes.h>
9 #include <tbm_surface.h>
10
11 #include <filesystem>
12 #include <fstream>
13 #include <functional>
14 #include <iostream>
15 #include <mutex>
16 #include <unordered_map>
17
18 #include "core/utils/plusplayer_log.h"
19 #include "esplayer/decoded_pkt_list.h"
20 #include "esplusplayer_capi/esplusplayer_internal.h"
21 #if defined(USE_MIXER) && !defined(IS_TOMATO)
22 #include "mixer_capi/mixer_capi.h"
23 #endif  // defined(USE_MIXER) && !defined(IS_TOMATO)
24 #include "esplusplayer/appinfo.h"
25 #include "esplusplayer/audioeasinginfo.h"
26 #include "esplusplayer/drm.h"
27 #include "esplusplayer/elementary_stream.h"
28 #include "esplusplayer/espacket.h"
29 #include "esplusplayer/esplusplayer.h"
30 #include "esplusplayer/track.h"
31 #include "esplusplayer/types/buffer.h"
32 #include "esplusplayer/types/display.h"
33 #include "esplusplayer/types/error.h"
34 #include "esplusplayer/types/latency.h"
35 #include "esplusplayer/types/picturequality.h"
36 #include "esplusplayer/types/resource.h"
37 #include "esplusplayer/types/stream.h"
38
39 using esplusplayer::AdvPictureQualityType;
40 using esplusplayer::AudioEasingInfo;
41 using esplusplayer::AudioEasingType;
42 using esplusplayer::AudioMimeType;
43 using esplusplayer::AudioStream;
44 using esplusplayer::AudioStreamPtr;
45 using esplusplayer::BufferStatus;
46 using esplusplayer::CatchUpSpeed;
47 using esplusplayer::CropArea;
48 using esplusplayer::DecodedPacketManagerInterface;
49 using esplusplayer::DecoderBufferTime;
50 using esplusplayer::DisplayMode;
51 using esplusplayer::DisplayRotation;
52 using esplusplayer::DisplayType;
53 using esplusplayer::ErrorType;
54 using esplusplayer::EsPacket;
55 using esplusplayer::EsPacketPtr;
56 using esplusplayer::EsState;
57 using esplusplayer::LatencyStatus;
58 using esplusplayer::MatroskaColor;
59 using esplusplayer::PlayerAdaptiveInfo;
60 using esplusplayer::PlayerAppInfo;
61 using esplusplayer::PlayerAppInfoEx;
62 using esplusplayer::PlayerAudioCodecType;
63 using esplusplayer::PlayerAudioResourceType;
64 using esplusplayer::PlayerLowLatencyMode;
65 using esplusplayer::PlayerSimpleMixOutBufferLevel;
66 using esplusplayer::PlayerTimeUnitType;
67 using esplusplayer::PlayerVideoCodecType;
68 using esplusplayer::PlayerVideoScanType;
69 using esplusplayer::Rational;
70 using esplusplayer::RenderRect;
71 using esplusplayer::RscAllocPolicy;
72 using esplusplayer::RscType;
73 using esplusplayer::StreamType;
74 using esplusplayer::SubmitDataType;
75 using esplusplayer::Track;
76 using esplusplayer::TrackType;
77 using esplusplayer::VideoMimeType;
78 using esplusplayer::VideoRotation;
79 using esplusplayer::VideoStream;
80 using esplusplayer::VideoStreamPtr;
81 using esplusplayer::drm::EsPlayerEncryptedInfo;
82 using esplusplayer::drm::Type;
83 using std::filesystem::exists;
84
85 namespace util {
86 const std::unordered_map<esplusplayer_error_type, std::string> kErrorStringMap =
87     {{ESPLUSPLAYER_ERROR_TYPE_NONE, "ESPLUSPLAYER_ERROR_TYPE_NONE"},
88      {ESPLUSPLAYER_ERROR_TYPE_OUT_OF_MEMORY,
89       "ESPLUSPLAYER_ERROR_TYPE_OUT_OF_MEMORY"},
90      {ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER,
91       "ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER"},
92      {ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION,
93       "ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION"},
94      {ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE,
95       "ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE"},
96      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_AUDIO_CODEC,
97       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_AUDIO_CODEC"},
98      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_VIDEO_CODEC,
99       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_VIDEO_CODEC"},
100      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FILE,
101       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FILE"},
102      {ESPLUSPLAYER_ERROR_TYPE_CONNECTION_FAILED,
103       "ESPLUSPLAYER_ERROR_TYPE_CONNECTION_FAILED"},
104      {ESPLUSPLAYER_ERROR_TYPE_DRM_EXPIRED,
105       "ESPLUSPLAYER_ERROR_TYPE_DRM_EXPIRED"},
106      {ESPLUSPLAYER_ERROR_TYPE_DRM_NO_LICENSE,
107       "ESPLUSPLAYER_ERROR_TYPE_DRM_NO_LICENSE"},
108      {ESPLUSPLAYER_ERROR_TYPE_DRM_FUTURE_USE,
109       "ESPLUSPLAYER_ERROR_TYPE_DRM_FUTURE_USE"},
110      {ESPLUSPLAYER_ERROR_TYPE_NOT_PERMITTED,
111       "ESPLUSPLAYER_ERROR_TYPE_NOT_PERMITTED"},
112      {ESPLUSPLAYER_ERROR_TYPE_DRM_DECRYPTION_FAILED,
113       "ESPLUSPLAYER_ERROR_TYPE_DRM_DECRYPTION_FAILED"},
114      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FORMAT,
115       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FORMAT"},
116      {ESPLUSPLAYER_ERROR_TYPE_UNKNOWN, "ESPLUSPLAYER_ERROR_TYPE_UNKNOWN"}};
117
118 const std::string kUnhandledErrorString = "Unhandled Error Type";
119 static const std::string& ConvertErrorTypeToString(
120     esplusplayer_error_type type) {
121   return kErrorStringMap.count(type) > 0 ? kErrorStringMap.at(type)
122                                          : kUnhandledErrorString;
123 }
124
125 // LCOV_EXCL_START
126 esplusplayer_error_type ConvertErrorCode(const ErrorType& error_code) {
127   esplusplayer_error_type type = ESPLUSPLAYER_ERROR_TYPE_NONE;
128   switch (error_code) {
129     case ErrorType::kOutOfMemory:
130       type = ESPLUSPLAYER_ERROR_TYPE_OUT_OF_MEMORY;
131       break;
132     case ErrorType::kInvalidParameter:
133       type = ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
134       break;
135     case ErrorType::kInvalidOperation:
136       type = ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
137       break;
138     case ErrorType::kInvalidState:
139       type = ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE;
140       break;
141     case ErrorType::kNotSupportedAudioCodec:
142       type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_AUDIO_CODEC;
143       break;
144     case ErrorType::kNotSupportedVideoCodec:
145       type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_VIDEO_CODEC;
146       break;
147     case ErrorType::kNotSupportedFile:
148       type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FILE;
149       break;
150     case ErrorType::kConnectionFailed:
151       type = ESPLUSPLAYER_ERROR_TYPE_CONNECTION_FAILED;
152       break;
153     case ErrorType::kDrmExpired:
154       type = ESPLUSPLAYER_ERROR_TYPE_DRM_EXPIRED;
155       break;
156     case ErrorType::kDrmNoLicense:
157       type = ESPLUSPLAYER_ERROR_TYPE_DRM_NO_LICENSE;
158       break;
159     case ErrorType::kDrmFutureUse:
160       type = ESPLUSPLAYER_ERROR_TYPE_DRM_FUTURE_USE;
161       break;
162     case ErrorType::kDrmNotPermitted:
163       type = ESPLUSPLAYER_ERROR_TYPE_NOT_PERMITTED;
164       break;
165     case ErrorType::kDrmInfo:
166       type = ESPLUSPLAYER_ERROR_TYPE_DRM_DECRYPTION_FAILED;
167       break;
168     case ErrorType::kNotSupportedFormat:
169       type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FORMAT;
170       break;
171     case ErrorType::kNone:
172       type = ESPLUSPLAYER_ERROR_TYPE_NONE;
173       break;
174     default:
175       LOG_ERROR("not defined error %x", static_cast<int>(error_code));
176       type = ESPLUSPLAYER_ERROR_TYPE_UNKNOWN;
177       break;
178   }
179   return type;
180 }
181 // LCOV_EXCL_STOP
182
183 }  // namespace util
184
185 struct EsPlusPlayerPriv;
186
187 class listener_bridge : public esplusplayer::EsEventListener {
188  public:
189   listener_bridge() { LOG_ENTER }
190   ~listener_bridge() { LOG_ENTER }
191
192   void ResetPacketList() {
193     if (decoded_pkt_mgr_) decoded_pkt_mgr_->Clear();
194   }
195
196   void ResetMultiSeekControl() {
197     std::unique_lock<std::mutex> lock(multi_seek_control.lock);
198     multi_seek_control.is_offset_valid = false;
199     multi_seek_control.offset = 0;
200   }
201
202   void Reset() {
203     LOG_ENTER
204     ResetPacketList();
205     ResetMultiSeekControl();
206     LOG_LEAVE
207   }
208
209   virtual void OnError(const ErrorType& error_code, UserData userdata) {
210     LOG_ENTER
211     LOG_INFO("error code : %x", static_cast<int>(error_code));
212     if (this->error_cb_)
213       this->error_cb_(util::ConvertErrorCode(error_code), error_cb_userdata_);
214   }
215
216   virtual void OnBufferStatus(const StreamType& type,
217                               const BufferStatus& status,
218                               const uint64_t byte_size,
219                               const uint64_t time_size, UserData userdata) {
220     // LOG_ENTER
221     // LOG_INFO("stream type : %d, buffer status : %d", static_cast<int>(type),
222     //          static_cast<int>(status));
223
224     if (this->buffer_status_cb_)
225       this->buffer_status_cb_(static_cast<esplusplayer_stream_type>(type),
226                               static_cast<esplusplayer_buffer_status>(status),
227                               buffer_status_cb_userdata_);
228     if (this->buffer_byte_status_cb_)
229       this->buffer_byte_status_cb_(
230           static_cast<esplusplayer_stream_type>(type),
231           static_cast<esplusplayer_buffer_status>(status), byte_size,
232           buffer_byte_status_cb_userdata_);
233     if (this->buffer_time_status_cb_)
234       this->buffer_time_status_cb_(
235           static_cast<esplusplayer_stream_type>(type),
236           static_cast<esplusplayer_buffer_status>(status), time_size,
237           buffer_time_status_cb_userdata_);
238   }
239
240   virtual void OnResourceConflicted(UserData userdata) {
241     LOG_ENTER
242     this->Reset();
243     if (this->resource_conflicted_cb_)
244       this->resource_conflicted_cb_(resource_conflicted_cb_userdata_);
245   }
246
247   virtual void OnEos(UserData userdata) {
248     LOG_ENTER
249     if (this->eos_cb_) this->eos_cb_(eos_cb_userdata_);
250   }
251
252   virtual void OnPrepareDone(bool result, UserData userdata) {
253     LOG_ENTER
254     LOG_INFO("prepare done. result : %s", result ? "true" : "false");
255     if (this->prepare_async_done_cb_)
256       this->prepare_async_done_cb_(result, prepare_async_done_cb_userdata_);
257   }
258
259   virtual void OnReadyToPrepare(const StreamType& type, UserData userdata) {
260     LOG_ENTER
261     LOG_INFO("stream type : %d", static_cast<int>(type));
262     if (this->ready_to_prepare_cb_)
263       this->ready_to_prepare_cb_(static_cast<esplusplayer_stream_type>(type),
264                                  ready_to_prepare_cb_userdata_);
265   }
266
267   virtual void OnSeekDone(UserData userdata) {
268     LOG_ENTER
269     if (this->seek_done_cb_) this->seek_done_cb_(seek_done_cb_userdata_);
270   }
271
272   virtual void OnReadyToSeek(const StreamType& type, const uint64_t offset,
273                              UserData userdata) {
274     LOG_ENTER
275     LOG_INFO("offset : %" PRId64 "", offset);
276     std::unique_lock<std::mutex> lock(this->multi_seek_control.lock);
277     if (this->multi_seek_control.is_offset_valid == false ||
278         this->multi_seek_control.offset != offset) {
279       LOG_ERROR("Invalid offset:%" PRId64 "", this->multi_seek_control.offset);
280       return;
281     }
282     if (this->ready_to_seek_cb_)
283       this->ready_to_seek_cb_(static_cast<esplusplayer_stream_type>(type),
284                               offset, ready_to_seek_cb_userdata_);
285   }
286
287   void SetDecodedPacketManager(
288       std::shared_ptr<DecodedPacketManagerInterface>& mgr) {
289     decoded_pkt_mgr_ = mgr;
290   }
291
292   virtual void OnMediaPacketGetTbmBufPtr(void** ptr, bool is_scale_change) {
293     // get one free point in current tbm list, send to trackrender, if can't
294     // find, set null
295     void* ptr1 = nullptr;
296     if (decoded_pkt_mgr_)
297       decoded_pkt_mgr_->GetFreeTbmSurface(&ptr1, is_scale_change);
298     *ptr = ptr1;
299   }
300
301   // LCOV_EXCL_START
302   virtual void OnMediaPacketVideoDecoded(
303       const esplusplayer::DecodedVideoPacket& packet) {
304     if (this->media_packet_video_decoded_cb_ == nullptr) return;
305
306     auto* _pkt = new esplusplayer_decoded_video_packet();
307     _pkt->pts = packet.pts;
308     _pkt->duration = packet.duration;
309     _pkt->surface_data = static_cast<void*>(packet.surface_data);
310     _pkt->private_data = packet.scaler_index;
311     if (decoded_pkt_mgr_ && decoded_pkt_mgr_->TryToAdd(_pkt)) {
312       this->media_packet_video_decoded_cb_(
313           _pkt, media_packet_video_decoded_cb_userdata_);
314     } else {
315       LOG_ERROR("Too many buffers are not released. packet(%p) will be drop.",
316                 _pkt);
317     }
318   }
319
320   virtual void OnClosedCaptionData(std::unique_ptr<char[]> data, const int size,
321                                    UserData userdata) {
322     LOG_ENTER
323     if (this->closed_caption_cb_) {
324       this->closed_caption_cb_(data.get(), size, closed_caption_cb_userdata_);
325     }
326   }
327
328   virtual void OnFlushDone(UserData userdata) {
329     LOG_ENTER
330     if (this->flush_done_cb_) this->flush_done_cb_(flush_done_cb_userdata_);
331   }
332
333   virtual void OnEvent(const esplusplayer::EventType& event,
334                        const esplusplayer::EventMsg& msg_data,
335                        UserData userdata) {
336     LOG_INFO("event type [%d]", static_cast<int>(event));
337     esplusplayer_event_msg event_msg;
338     event_msg.data = const_cast<char*>(msg_data.data.c_str());
339     event_msg.len = msg_data.len;
340     if (this->event_cb_)
341       this->event_cb_(static_cast<esplusplayer_event_type>(event), event_msg,
342                       event_cb_userdata_);
343   }
344   // LCOV_EXCL_STOP
345
346   virtual void OnFirstDecodingDone(UserData userdata) {
347     LOG_ENTER
348     if (this->first_video_decoding_done_cb_) {
349       this->first_video_decoding_done_cb_(
350           first_video_decoding_done_cb_userdata_);
351     }
352   }
353
354   virtual void OnVideoDecoderUnderrun(UserData userdata) {
355     LOG_ENTER
356     if (this->video_decoder_underrun_cb_)
357       this->video_decoder_underrun_cb_(video_decoder_underrun_cb_userdata_);
358   }
359
360   virtual void OnVideoLatencyStatus(const LatencyStatus& latency_status,
361                                     UserData userdata) {
362     LOG_ENTER
363     if (this->video_latency_status_cb_)
364       this->video_latency_status_cb_(
365           static_cast<esplusplayer_latency_status>(latency_status),
366           video_latency_status_cb_userdata_);
367   }
368
369   virtual void OnAudioLatencyStatus(const LatencyStatus& latency_status,
370                                     UserData userdata) {
371     LOG_ENTER
372     if (this->audio_latency_status_cb_)
373       this->audio_latency_status_cb_(
374           static_cast<esplusplayer_latency_status>(latency_status),
375           audio_latency_status_cb_userdata_);
376   }
377
378   virtual void OnVideoHighLatency(UserData userdata) {
379     LOG_ENTER
380     if (this->video_high_latency_cb_)
381       this->video_high_latency_cb_(video_high_latency_cb_userdata_);
382   }
383
384   virtual void OnAudioHighLatency(UserData userdata) {
385     LOG_ENTER
386     if (this->audio_high_latency_cb_)
387       this->audio_high_latency_cb_(audio_high_latency_cb_userdata_);
388   }
389
390   virtual void OnVideoFrameDropped(const uint64_t& count, UserData userdata) {
391     LOG_ERROR("count: %" PRId64 "", count);
392     if (this->video_frame_dropped_cb_)
393       this->video_frame_dropped_cb_(count, video_frame_dropped_cb_userdata_);
394   }
395
396   virtual void OnDecoderInputBufferTime(const StreamType& type,
397                                         const DecoderBufferTime& time) {
398     if (this->decoder_input_buffer_time_cb_) {
399       esplusplayer_decoder_buffer_time decoder_buffer_time;
400       decoder_buffer_time.pts = time.pts;
401       decoder_buffer_time.system_time = time.system_time;
402       this->decoder_input_buffer_time_cb_(
403           static_cast<esplusplayer_stream_type>(type), decoder_buffer_time,
404           decoder_input_buffer_time_cb_userdata_);
405     }
406   }
407
408   virtual void OnDecoderOutputBufferTime(const StreamType& type,
409                                          const DecoderBufferTime& time) {
410     if (this->decoder_output_buffer_time_cb_) {
411       esplusplayer_decoder_buffer_time decoder_buffer_time;
412       decoder_buffer_time.pts = time.pts;
413       decoder_buffer_time.system_time = time.system_time;
414       this->decoder_output_buffer_time_cb_(
415           static_cast<esplusplayer_stream_type>(type), decoder_buffer_time,
416           decoder_output_buffer_time_cb_userdata_);
417     }
418   }
419
420  private:
421   static void DecodedPacketDeleter(esplusplayer_decoded_video_packet* packet) {
422     if (packet->surface_data != nullptr) {
423       tbm_surface_destroy(static_cast<tbm_surface_h>(packet->surface_data));
424       packet->surface_data = NULL;
425     }
426     delete packet;
427   }
428
429  private:
430   esplusplayer_error_cb error_cb_ = nullptr;
431   void* error_cb_userdata_ = nullptr;
432   esplusplayer_buffer_status_cb buffer_status_cb_ = nullptr;
433   void* buffer_status_cb_userdata_ = nullptr;
434   esplusplayer_buffer_byte_status_cb buffer_byte_status_cb_ = nullptr;
435   void* buffer_byte_status_cb_userdata_ = nullptr;
436   esplusplayer_buffer_time_status_cb buffer_time_status_cb_ = nullptr;
437   void* buffer_time_status_cb_userdata_ = nullptr;
438   esplusplayer_resource_conflicted_cb resource_conflicted_cb_ = nullptr;
439   void* resource_conflicted_cb_userdata_ = nullptr;
440   esplusplayer_eos_cb eos_cb_ = nullptr;
441   void* eos_cb_userdata_ = nullptr;
442   esplusplayer_ready_to_prepare_cb ready_to_prepare_cb_ = nullptr;
443   void* ready_to_prepare_cb_userdata_ = nullptr;
444   esplusplayer_prepare_async_done_cb prepare_async_done_cb_ = nullptr;
445   void* prepare_async_done_cb_userdata_ = nullptr;
446   esplusplayer_seek_done_cb seek_done_cb_ = nullptr;
447   void* seek_done_cb_userdata_ = nullptr;
448   esplusplayer_ready_to_seek_cb ready_to_seek_cb_ = nullptr;
449   void* ready_to_seek_cb_userdata_ = nullptr;
450   esplusplayer_media_packet_video_decoded_cb media_packet_video_decoded_cb_ =
451       nullptr;
452   void* media_packet_video_decoded_cb_userdata_ = nullptr;
453   esplusplayer_closed_caption_cb closed_caption_cb_ = nullptr;
454   void* closed_caption_cb_userdata_ = nullptr;
455   esplusplayer_flush_done_cb flush_done_cb_ = nullptr;
456   void* flush_done_cb_userdata_ = nullptr;
457   esplusplayer_event_cb event_cb_ = nullptr;
458   void* event_cb_userdata_ = nullptr;
459   esplusplayer_first_video_decoding_done_cb first_video_decoding_done_cb_ =
460       nullptr;
461   void* first_video_decoding_done_cb_userdata_ = nullptr;
462   esplusplayer_decoder_underrun_cb video_decoder_underrun_cb_ = nullptr;
463   void* video_decoder_underrun_cb_userdata_ = nullptr;
464   esplusplayer_video_latency_status_cb video_latency_status_cb_ = nullptr;
465   esplusplayer_audio_latency_status_cb audio_latency_status_cb_ = nullptr;
466   void* video_latency_status_cb_userdata_ = nullptr;
467   void* audio_latency_status_cb_userdata_ = nullptr;
468   esplusplayer_video_high_latency_cb video_high_latency_cb_ = nullptr;
469   esplusplayer_audio_high_latency_cb audio_high_latency_cb_ = nullptr;
470   void* video_high_latency_cb_userdata_ = nullptr;
471   void* audio_high_latency_cb_userdata_ = nullptr;
472   esplusplayer_video_frame_dropped_cb video_frame_dropped_cb_ = nullptr;
473   void* video_frame_dropped_cb_userdata_ = nullptr;
474   esplusplayer_decoder_buffer_time_cb decoder_input_buffer_time_cb_ = nullptr;
475   esplusplayer_decoder_buffer_time_cb decoder_output_buffer_time_cb_ = nullptr;
476   void* decoder_input_buffer_time_cb_userdata_ = nullptr;
477   void* decoder_output_buffer_time_cb_userdata_ = nullptr;
478
479   std::shared_ptr<DecodedPacketManagerInterface> decoded_pkt_mgr_;
480
481   struct MultiSeekControl {
482     std::mutex lock;
483     bool is_offset_valid = false;
484     uint64_t offset = 0;
485   };
486   friend void update_ready_to_seek_callback(
487       esplusplayer_handle pp, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
488       void* userdata);
489   friend void update_ready_to_seek_offset(esplusplayer_handle pp,
490                                           const uint64_t offset);
491   MultiSeekControl multi_seek_control;
492
493   friend int esplusplayer_set_error_cb(esplusplayer_handle pp,
494                                        esplusplayer_error_cb error_cb,
495                                        void* userdata);
496   friend int esplusplayer_set_buffer_status_cb(
497       esplusplayer_handle pp, esplusplayer_buffer_status_cb buffer_status_cb,
498       void* userdata);
499   friend int esplusplayer_set_buffer_byte_status_cb(
500       esplusplayer_handle pp,
501       esplusplayer_buffer_byte_status_cb buffer_status_cb, void* userdata);
502   friend int esplusplayer_set_buffer_time_status_cb(
503       esplusplayer_handle pp,
504       esplusplayer_buffer_time_status_cb buffer_status_cb, void* userdata);
505   friend int esplusplayer_set_resource_conflicted_cb(
506       esplusplayer_handle pp,
507       esplusplayer_resource_conflicted_cb resource_conflicted_cb,
508       void* userdata);
509   friend int esplusplayer_set_eos_cb(esplusplayer_handle pp,
510                                      esplusplayer_eos_cb eos_cb,
511                                      void* userdata);
512   friend int esplusplayer_set_ready_to_prepare_cb(
513       esplusplayer_handle pp,
514       esplusplayer_ready_to_prepare_cb ready_to_prepare_cb, void* userdata);
515   friend int esplusplayer_set_prepare_async_done_cb(
516       esplusplayer_handle pp,
517       esplusplayer_prepare_async_done_cb prepare_async_done_cb, void* userdata);
518   friend int esplusplayer_set_seek_done_cb(
519       esplusplayer_handle pp, esplusplayer_seek_done_cb seek_done_cb,
520       void* userdata);
521   friend int esplusplayer_set_ready_to_seek_cb(
522       esplusplayer_handle pp, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
523       void* userdata);
524   friend int esplusplayer_set_media_packet_video_decoded_cb(
525       esplusplayer_handle pp,
526       esplusplayer_media_packet_video_decoded_cb media_packet_video_decoded_cb,
527       void* userdata);
528   friend int esplusplayer_set_closed_caption_cb(
529       esplusplayer_handle handle,
530       esplusplayer_closed_caption_cb closed_caption_cb, void* userdata);
531   friend int esplusplayer_set_flush_done_cb(
532       esplusplayer_handle pp, esplusplayer_flush_done_cb flush_done_cb,
533       void* userdata);
534   friend int esplusplayer_set_event_cb(esplusplayer_handle pp,
535                                        esplusplayer_event_cb event_cb,
536                                        void* userdata);
537   friend int esplusplayer_set_first_video_decoding_done_cb(
538       esplusplayer_handle handle,
539       esplusplayer_first_video_decoding_done_cb first_video_decoding_done_cb,
540       void* userdata);
541   friend int esplusplayer_set_video_decoder_underrun_cb(
542       esplusplayer_handle handle,
543       esplusplayer_decoder_underrun_cb video_decoder_underrun_cb,
544       void* userdata);
545   friend int esplusplayer_set_video_latency_status_cb(
546       esplusplayer_handle pp,
547       esplusplayer_video_latency_status_cb video_latency_status_cb,
548       void* userdata);
549   friend int esplusplayer_set_audio_latency_status_cb(
550       esplusplayer_handle pp,
551       esplusplayer_audio_latency_status_cb audio_latency_status_cb,
552       void* userdata);
553   friend int esplusplayer_set_video_high_latency_cb(
554       esplusplayer_handle pp,
555       esplusplayer_video_high_latency_cb video_high_latency_cb, void* userdata);
556   friend int esplusplayer_set_audio_high_latency_cb(
557       esplusplayer_handle pp,
558       esplusplayer_audio_high_latency_cb audio_high_latency_cb, void* userdata);
559   friend int esplusplayer_set_video_frame_dropped_cb(
560       esplusplayer_handle pp,
561       esplusplayer_video_frame_dropped_cb video_frame_dropped_cb,
562       void* userdata);
563   friend int esplusplayer_set_decoder_input_buffer_time_cb(
564       esplusplayer_handle handle,
565       esplusplayer_decoder_buffer_time_cb decoder_buffer_time_cb,
566       void* userdata);
567   friend int esplusplayer_set_decoder_output_buffer_time_cb(
568       esplusplayer_handle handle,
569       esplusplayer_decoder_buffer_time_cb decoder_buffer_time_cb,
570       void* userdata);
571 };
572
573 #define ES_DUMP 0
574 struct EsPlusPlayerPriv {
575   std::unique_ptr<EsPlusPlayer> player;
576   std::unique_ptr<listener_bridge> listener{new listener_bridge()};
577   std::shared_ptr<DecodedPacketManagerInterface> decoded_pkt_mgr;
578
579   friend EsPlusPlayerPriv* EsPrivCreate();
580   friend void EsPrivDestroy(EsPlusPlayerPriv*& instance);
581
582 #ifdef ES_DUMP
583   std::ofstream video_stream_;
584   std::ofstream audio_stream_;
585 #endif
586
587  private:
588   EsPlusPlayerPriv() {}
589   ~EsPlusPlayerPriv() {}
590 };
591
592 EsPlusPlayerPriv* EsPrivCreate() {
593   EsPlusPlayerPriv* instance = new EsPlusPlayerPriv();
594   instance->player = EsPlusPlayer::Create();
595   instance->player->RegisterListener(instance->listener.get(),
596                                      instance->player.get());
597   return instance;
598 }
599
600 void EsPrivDestroy(EsPlusPlayerPriv*& instance) {
601   if (instance) delete instance;
602   instance = nullptr;
603 }
604
605 inline bool is_null_(void* object) { return object == nullptr; }
606
607 inline EsPlusPlayer* cast_(esplusplayer_handle pp) {
608   auto priv = static_cast<EsPlusPlayerPriv*>(pp);
609   return priv ? priv->player.get() : nullptr;
610 }
611
612 inline listener_bridge* listener_cast_(esplusplayer_handle pp) {
613   auto priv = static_cast<EsPlusPlayerPriv*>(pp);
614   return priv->listener.get();
615 }
616
617 void update_ready_to_seek_callback(
618     esplusplayer_handle handle, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
619     void* userdata) {
620   LOG_ENTER
621   listener_bridge* listener = nullptr;
622   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
623     LOG_ERROR("ESPlayer or Listener object is nil.");
624     return;
625   }
626   std::unique_lock<std::mutex> lock(listener->multi_seek_control.lock);
627   listener->ready_to_seek_cb_ = ready_to_seek_cb;
628   listener->ready_to_seek_cb_userdata_ = userdata;
629   listener->multi_seek_control.is_offset_valid = false;
630 }
631 void update_ready_to_seek_offset(esplusplayer_handle handle,
632                                  const uint64_t offset) {
633   LOG_ENTER
634   listener_bridge* listener = nullptr;
635   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
636     LOG_ERROR("ESPlayer or Listener object is nil.");
637     return;
638   }
639   std::unique_lock<std::mutex> lock(listener->multi_seek_control.lock);
640   listener->multi_seek_control.offset = offset;
641   listener->multi_seek_control.is_offset_valid = true;
642 }
643
644 // LCOV_EXCL_START
645 inline void convert_matroska_color_info_(
646     const esplusplayer_matroska_color* from, MatroskaColor* to) {
647   to->matrix_coefficients = from->matrix_coefficients;
648   to->bits_per_channel = from->bits_per_channel;
649   to->chroma_subsampling_horizontal = from->chroma_subsampling_horizontal;
650   to->chroma_subsampling_vertical = from->chroma_subsampling_vertical;
651   to->cb_subsampling_horizontal = from->cb_subsampling_horizontal;
652   to->cb_subsampling_vertical = from->cb_subsampling_vertical;
653   to->chroma_siting_horizontal = from->chroma_siting_horizontal;
654   to->chroma_siting_vertical = from->chroma_siting_vertical;
655   to->range = from->range;
656   to->transfer_characteristics = from->transfer_characteristics;
657   to->primaries = from->primaries;
658   to->max_cll = from->max_cll;
659   to->max_fall = from->max_fall;
660   to->is_hdr_10p = from->isHDR10p;
661   to->metadata.primary_r_chromaticity_x =
662       from->metadata.primary_r_chromaticity_x;
663   to->metadata.primary_r_chromaticity_y =
664       from->metadata.primary_r_chromaticity_y;
665   to->metadata.primary_g_chromaticity_x =
666       from->metadata.primary_g_chromaticity_x;
667   to->metadata.primary_g_chromaticity_y =
668       from->metadata.primary_g_chromaticity_y;
669   to->metadata.primary_b_chromaticity_x =
670       from->metadata.primary_b_chromaticity_x;
671   to->metadata.primary_b_chromaticity_y =
672       from->metadata.primary_b_chromaticity_y;
673   to->metadata.white_point_chromaticity_x =
674       from->metadata.white_point_chromaticity_x;
675   to->metadata.white_point_chromaticity_y =
676       from->metadata.white_point_chromaticity_y;
677   to->metadata.luminance_max = from->metadata.luminance_max;
678   to->metadata.luminance_min = from->metadata.luminance_min;
679 }
680 // LCOV_EXCL_STOP
681
682 inline EsPacketPtr convert_espacket_(esplusplayer_es_packet* from) {
683   std::shared_ptr<char> buffer = nullptr;
684   std::shared_ptr<char> hdr10p_metadata = nullptr;
685   if (from->buffer_size != 0 && from->buffer) {
686     buffer = std::shared_ptr<char>(new char[from->buffer_size],
687                                    std::default_delete<char[]>());
688     memcpy(buffer.get(), from->buffer, from->buffer_size);
689   }
690   if (from->hdr10p_metadata_size != 0 && from->hdr10p_metadata) {
691     hdr10p_metadata = std::shared_ptr<char>(
692         new char[from->hdr10p_metadata_size], std::default_delete<char[]>());
693     memcpy(hdr10p_metadata.get(), from->hdr10p_metadata,
694            from->hdr10p_metadata_size);
695   }
696   auto espacket = EsPacket::Create(static_cast<StreamType>(from->type), buffer,
697                                    from->buffer_size, from->pts, from->duration,
698                                    from->hdr10p_metadata_size, hdr10p_metadata);
699
700   if (from->matroska_color_info != nullptr) {
701     MatroskaColor color_info;
702     convert_matroska_color_info_(from->matroska_color_info, &color_info);
703     bool ret = espacket->SetMatroskaColorInfo(color_info);
704     if (ret == false) return nullptr;
705   }
706   return std::move(espacket);
707 }
708
709 // LCOV_EXCL_START
710 using EncryptedInfoPtr =
711     std::unique_ptr<EsPlayerEncryptedInfo,
712                     std::function<void(EsPlayerEncryptedInfo*)>>;
713 #ifdef DRM_MAPI_AARCH_64
714 inline EncryptedInfoPtr convert_es_drm_info_(
715     esplusplayer_drm_info_64bit* from) {
716 #else
717 inline EncryptedInfoPtr convert_es_drm_info_(esplusplayer_drm_info* from) {
718 #endif
719   auto custom_deleter = [](EsPlayerEncryptedInfo* drm_info) {
720     if (drm_info == nullptr) return;
721     if (drm_info->sub_data != nullptr) {
722       delete reinterpret_cast<esplusplayer::drm::DrmbEsFragmentedMp4Data*>(
723           drm_info->sub_data);
724       drm_info->sub_data = nullptr;
725     }
726     delete drm_info;
727   };
728
729   if (from == nullptr) return EncryptedInfoPtr(nullptr, custom_deleter);
730
731   EncryptedInfoPtr drm_info =
732       EncryptedInfoPtr(new EsPlayerEncryptedInfo(), custom_deleter);
733
734   drm_info->handle = from->handle;
735   drm_info->algorithm =
736       static_cast<esplusplayer::drm::DrmbEsCipherAlgorithm>(from->algorithm);
737   drm_info->format =
738       static_cast<esplusplayer::drm::DrmbEsMediaFormat>(from->format);
739   drm_info->phase =
740       static_cast<esplusplayer::drm::DrmbEsCipherPhase>(from->phase);
741
742   // kid
743   if (from->kid && from->kid_length > 0) {
744     drm_info->kid = std::move(
745         std::vector<unsigned char>(from->kid, from->kid + from->kid_length));
746   }
747
748   // initialization_vector
749   if (from->iv && from->iv_length > 0) {
750     drm_info->initialization_vector = std::move(
751         std::vector<unsigned char>(from->iv, from->iv + from->iv_length));
752   }
753
754   // sub_data
755   auto* from_sub_data =
756       reinterpret_cast<esplusplayer_drmb_es_fmp4_data*>(from->sub_data);
757   if (from_sub_data && from_sub_data->subsample_count > 0) {
758     drm_info->sub_data = new esplusplayer::drm::DrmbEsFragmentedMp4Data;
759     auto* sub_data =
760         reinterpret_cast<esplusplayer::drm::DrmbEsFragmentedMp4Data*>(
761             drm_info->sub_data);
762     for (uint32_t i = 0; i < from_sub_data->subsample_count; i++) {
763       auto& subsample_info = from_sub_data->subsample_infos[i];
764       sub_data->sub_sample_info_vector.emplace_back(
765           subsample_info.bytes_of_clear_data,
766           subsample_info.bytes_of_encrypted_data);
767     }
768   }
769
770   // split_offsets
771   if (from->split_offsets) {
772     const std::size_t kSplitOffsetMaxSize = 15 * sizeof(int);
773     std::memcpy(drm_info->split_offsets.data(), from->split_offsets,
774                 kSplitOffsetMaxSize);
775   }
776
777   drm_info->use_out_buffer = from->use_out_buffer;
778   drm_info->use_pattern = from->use_pattern;
779   drm_info->crypt_byte_block = from->crypt_byte_block;
780   drm_info->skip_byte_block = from->skip_byte_block;
781
782   return std::move(drm_info);
783 }
784 // LCOV_EXCL_STOP
785
786 inline AudioStreamPtr convert_stream_ptr_(
787     esplusplayer_audio_stream_info* from) {
788   LOG_INFO("mime type : %d", static_cast<int>(from->mime_type));
789   LOG_INFO("from->bitrate : %d", from->bitrate);
790   LOG_INFO("from->channels : %d", from->channels);
791   LOG_INFO("from->sample_rate : %d", from->sample_rate);
792   LOG_INFO("from->codec_data_length : %d", from->codec_data_length);
793
794   auto stream = AudioStream::Create();
795   std::shared_ptr<char> codec_data = nullptr;
796
797   if (from->codec_data_length != 0) {
798     codec_data = std::shared_ptr<char>(new char[from->codec_data_length],
799                                        std::default_delete<char[]>());
800     memcpy(codec_data.get(), from->codec_data, from->codec_data_length);
801   }
802
803   stream->SetCodecData(codec_data, from->codec_data_length);
804   stream->SetMimeType(
805       static_cast<esplusplayer::AudioMimeType>(from->mime_type));
806   stream->SetBitrate(from->bitrate);
807   stream->SetChannels(from->channels);
808   stream->SetSamplerate(from->sample_rate);
809
810   return std::move(stream);
811 }
812
813 inline int convert_return_type_(bool ret) {
814   return ret ? ESPLUSPLAYER_ERROR_TYPE_NONE
815              : ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
816 }
817
818 inline esplusplayer_get_decoded_video_frame_status_type
819 convert_get_decoded_video_frame_status_(
820     const esplusplayer::GetDecodedVideoFrameStatus status) {
821   switch (status) {
822     case esplusplayer::GetDecodedVideoFrameStatus::kSuccess: {
823       return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_SUCCESS;
824     }
825     case esplusplayer::GetDecodedVideoFrameStatus::kNoRemainingBuffer: {
826       return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_REMAINING_BUFFER;
827     }
828     case esplusplayer::GetDecodedVideoFrameStatus::kNoFilledBuffer: {
829       return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_NO_FILLED_BUFFER;
830     }
831     case esplusplayer::GetDecodedVideoFrameStatus::kUnknown: {
832       return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN;
833     }
834     default: {
835       return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN;
836     }
837   }
838   return ESPLUSPLAYER_GET_DECVIDEOFRAME_STATUS_UNKNOWN;
839 }
840
841 inline VideoStreamPtr convert_stream_ptr_(
842     esplusplayer_video_stream_info* from) {
843   LOG_INFO("mime type : %u", static_cast<int>(from->mime_type));
844   LOG_INFO("from->width : %u", from->width);
845   LOG_INFO("from->height : %u", from->height);
846   LOG_INFO("from->max_width : %u", from->max_width);
847   LOG_INFO("from->max_height : %u", from->max_height);
848   LOG_INFO("from->framerate_num : %u", from->framerate_num);
849   LOG_INFO("from->framerate_den : %u", from->framerate_den);
850   LOG_INFO("from->codec_data_length : %u", from->codec_data_length);
851
852   auto stream = VideoStream::Create();
853   std::shared_ptr<char> codec_data = nullptr;
854
855   if (from->codec_data_length != 0) {
856     codec_data = std::shared_ptr<char>(new char[from->codec_data_length],
857                                        std::default_delete<char[]>());
858     memcpy(codec_data.get(), from->codec_data, from->codec_data_length);
859   }
860
861   stream->SetCodecData(codec_data, from->codec_data_length);
862   stream->SetMimeType(
863       static_cast<esplusplayer::VideoMimeType>(from->mime_type));
864   stream->SetWidth(from->width);
865   stream->SetHeight(from->height);
866   stream->SetMaxWidth(from->max_width);
867   stream->SetMaxHeight(from->max_height);
868   stream->SetFramerate(from->framerate_num, from->framerate_den);
869
870   return std::move(stream);
871 }
872
873 esplusplayer_handle esplusplayer_create() {
874   esplusplayer_handle player = static_cast<esplusplayer_handle>(EsPrivCreate());
875   LOG_INFO("capi handle > [%p], cpp handle > [%p]", player, cast_(player));
876   return player;
877 }
878
879 int esplusplayer_open(esplusplayer_handle handle) {
880   LOG_ENTER_P(cast_(handle))
881   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
882   return convert_return_type_(cast_(handle)->Open());
883 }
884
885 int esplusplayer_close(esplusplayer_handle handle) {
886   LOG_ENTER_P(cast_(handle))
887   listener_bridge* listener = nullptr;
888   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
889     LOG_ERROR("ESPlayer or Listener object is nil.");
890     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
891   }
892
893 #ifdef ES_DUMP
894   std::ofstream& vstream =
895       static_cast<EsPlusPlayerPriv*>(handle)->video_stream_;
896   if (vstream.is_open()) {
897     vstream.close();
898     LOG_DEBUG("Close video_stream_");
899   }
900   std::ofstream& astream =
901       static_cast<EsPlusPlayerPriv*>(handle)->audio_stream_;
902   if (astream.is_open()) {
903     astream.close();
904     LOG_DEBUG("Close audio_stream_");
905   }
906 #endif
907
908   bool ret = cast_(handle)->Close();
909   listener->Reset();
910   return convert_return_type_(ret);
911 }
912
913 int esplusplayer_destroy(esplusplayer_handle handle) {
914   LOG_ENTER_P(cast_(handle))
915   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
916
917   esplusplayer_state state = esplusplayer_get_state(handle);
918   if (ESPLUSPLAYER_STATE_NONE != state) {
919     LOG_ERROR("state must be ESPLUSPLAYER_STATE_NONE, but %d now", state);
920     return ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE;
921   }
922
923   auto priv = static_cast<EsPlusPlayerPriv*>(handle);
924   EsPrivDestroy(priv);
925
926   return ESPLUSPLAYER_ERROR_TYPE_NONE;
927 }
928
929 int esplusplayer_deactivate(esplusplayer_handle handle,
930                             esplusplayer_stream_type type) {
931   LOG_ENTER_P(cast_(handle))
932   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
933
934   return convert_return_type_(
935       cast_(handle)->Deactivate(static_cast<StreamType>(type)));
936 }
937
938 int esplusplayer_activate(esplusplayer_handle handle,
939                           esplusplayer_stream_type type) {
940   LOG_ENTER_P(cast_(handle))
941   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
942
943   return convert_return_type_(
944       cast_(handle)->Activate(static_cast<StreamType>(type)));
945 }
946
947 int esplusplayer_deactivate_audio(esplusplayer_handle handle) {
948   LOG_ENTER_P(cast_(handle))
949   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
950
951   return convert_return_type_(cast_(handle)->DeactivateAudio());
952 }
953
954 int esplusplayer_activate_audio(esplusplayer_handle handle) {
955   LOG_ENTER_P(cast_(handle))
956   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
957
958   return convert_return_type_(cast_(handle)->ActivateAudio());
959 }
960
961 int esplusplayer_prepare_async(esplusplayer_handle handle) {
962   LOG_ENTER_P(cast_(handle))
963   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
964
965   return convert_return_type_(cast_(handle)->PrepareAsync());
966 }
967
968 int esplusplayer_start(esplusplayer_handle handle) {
969   LOG_ENTER_P(cast_(handle))
970   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
971
972   return convert_return_type_(cast_(handle)->Start());
973 }
974
975 int esplusplayer_stop(esplusplayer_handle handle) {
976   LOG_ENTER_P(cast_(handle))
977   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
978
979   return convert_return_type_(cast_(handle)->Stop());
980 }
981
982 int esplusplayer_pause(esplusplayer_handle handle) {
983   LOG_ENTER_P(cast_(handle))
984   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
985
986   return convert_return_type_(cast_(handle)->Pause());
987 }
988
989 int esplusplayer_resume(esplusplayer_handle handle) {
990   LOG_ENTER_P(cast_(handle))
991   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
992
993   return convert_return_type_(cast_(handle)->Resume());
994 }
995
996 int esplusplayer_set_playback_rate(esplusplayer_handle handle,
997                                    const double playback_rate,
998                                    const bool audio_mute) {
999   LOG_ENTER_P(cast_(handle))
1000   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1001   LOG_INFO_P(cast_(handle), "playback rate : %lf, audio mute : %d",
1002              playback_rate, audio_mute);
1003   return convert_return_type_(
1004       cast_(handle)->SetPlaybackRate(playback_rate, audio_mute));
1005 }
1006
1007 int esplusplayer_seek(esplusplayer_handle handle, uint64_t time) {
1008   LOG_ENTER_P(cast_(handle))
1009   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1010   LOG_INFO("%p time : %" PRId64 "", cast_(handle), time);
1011   update_ready_to_seek_offset(handle, time);
1012
1013   return convert_return_type_(cast_(handle)->Seek(time));
1014 }
1015
1016 int esplusplayer_set_app_info(esplusplayer_handle handle,
1017                               const esplusplayer_app_info* app_info) {
1018   LOG_ENTER_P(cast_(handle))
1019   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1020   if (app_info == nullptr) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1021
1022   LOG_INFO_P(cast_(handle), "app id : %s ", app_info->id);
1023   LOG_INFO_P(cast_(handle), "app version : %s ", app_info->version);
1024   LOG_INFO_P(cast_(handle), "app type : %s", app_info->type);
1025
1026   PlayerAppInfo info;
1027   info.id = app_info->id;
1028   info.version = app_info->version;
1029   info.type = app_info->type;
1030   cast_(handle)->SetAppInfo(info);
1031   return convert_return_type_(true);
1032 }
1033
1034 int esplusplayer_set_app_info_ex(esplusplayer_handle handle,
1035                                  const esplusplayer_app_info_ex* app_info) {
1036   LOG_ENTER_P(cast_(handle))
1037   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1038   if (app_info == nullptr) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1039
1040   LOG_INFO_P(cast_(handle), "app id : %s ", app_info->id);
1041   LOG_INFO_P(cast_(handle), "app version : %s ", app_info->version);
1042   LOG_INFO_P(cast_(handle), "app type : %s", app_info->type);
1043   LOG_INFO_P(cast_(handle), "app runtitle : %s", app_info->runtitle);
1044
1045   PlayerAppInfoEx info;
1046   info.id = app_info->id;
1047   info.version = app_info->version;
1048   info.type = app_info->type;
1049   info.runtitle = app_info->runtitle;
1050   cast_(handle)->SetAppInfoEx(info);
1051   return convert_return_type_(true);
1052 }
1053
1054 int esplusplayer_set_display(esplusplayer_handle handle,
1055                              esplusplayer_display_type type, void* window) {
1056   LOG_ENTER_P(cast_(handle))
1057   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1058   LOG_INFO_P(cast_(handle), "display type : %d, object : %p",
1059              static_cast<int>(type), window);
1060
1061 #if defined(USE_MIXER) && !defined(IS_TOMATO)
1062   if (type == ESPLUSPLAYER_DISPLAY_TYPE_MIXER) {
1063     mixer_handle mixer_h = window;
1064     esplusplayer::MixerTicket* ticket =
1065         (esplusplayer::MixerTicket*)mixer_create_ticket(mixer_h, handle);
1066     if (is_null_(ticket)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1067     return convert_return_type_(
1068         cast_(handle)->SetDisplay(static_cast<DisplayType>(type), ticket));
1069   }
1070 #endif  // defined(USE_MIXER) && !defined(IS_TOMATO)
1071   return convert_return_type_(
1072       cast_(handle)->SetDisplay(static_cast<DisplayType>(type), window));
1073 }
1074
1075 int esplusplayer_set_ecore_display(esplusplayer_handle handle,
1076                                    esplusplayer_display_type type, void* window,
1077                                    int x, int y, int width, int height) {
1078   LOG_ENTER_P(cast_(handle))
1079   if (is_null_(handle) || is_null_(window))
1080     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1081   LOG_INFO_P(cast_(handle), "display type : %d, object : %p",
1082              static_cast<int>(type), window);
1083
1084   return convert_return_type_(cast_(handle)->SetDisplay(
1085       static_cast<DisplayType>(type), window, x, y, width, height));
1086 }
1087
1088 int esplusplayer_set_display_ecore_subsurface(esplusplayer_handle handle,
1089                                               esplusplayer_display_type type,
1090                                               void* subsurface, int x, int y,
1091                                               int width, int height) {
1092   LOG_ENTER_P(cast_(handle))
1093   if (is_null_(handle) || is_null_(subsurface))
1094     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1095   LOG_INFO_P(cast_(handle), "display type : %d, object : %p",
1096              static_cast<int>(type), subsurface);
1097
1098   return convert_return_type_(cast_(handle)->SetDisplaySubsurface(
1099       static_cast<DisplayType>(type), subsurface, x, y, width, height));
1100 }
1101
1102 int esplusplayer_set_surface_display(esplusplayer_handle handle,
1103                                      esplusplayer_display_type type,
1104                                      unsigned int surface_id, int x, int y,
1105                                      int width, int height) {
1106   LOG_ENTER_P(cast_(handle))
1107   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1108   LOG_INFO_P(cast_(handle), "display type : %d, object : %u",
1109              static_cast<int>(type), surface_id);
1110
1111   return convert_return_type_(cast_(handle)->SetDisplay(
1112       static_cast<DisplayType>(type), surface_id, x, y, width, height));
1113 }
1114
1115 int esplusplayer_set_display_mode(esplusplayer_handle handle,
1116                                   esplusplayer_display_mode mode) {
1117   LOG_ENTER_P(cast_(handle))
1118   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1119   LOG_INFO_P(cast_(handle), "display mode : %d", static_cast<int>(mode));
1120
1121   return convert_return_type_(
1122       cast_(handle)->SetDisplayMode(static_cast<DisplayMode>(mode)));
1123 }
1124
1125 int esplusplayer_set_display_roi(esplusplayer_handle handle, int x, int y,
1126                                  int width, int height) {
1127   LOG_ENTER_P(cast_(handle))
1128   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1129   LOG_INFO_P(cast_(handle), "x : %d, y: %d, width : %d, height : %d", x, y,
1130              width, height);
1131
1132   Geometry roi;
1133   roi.x = x;
1134   roi.y = y;
1135   roi.w = width;
1136   roi.h = height;
1137
1138   return convert_return_type_(cast_(handle)->SetDisplayRoi(roi));
1139 }
1140
1141 int esplusplayer_set_stretch_mode(esplusplayer_handle handle, int mode) {
1142   LOG_ENTER_P(cast_(handle))
1143   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1144   LOG_INFO_P(cast_(handle), "stretch mode : %d", static_cast<int>(mode));
1145
1146   return convert_return_type_(cast_(handle)->SetStretchMode(mode));
1147 }
1148
1149 int esplusplayer_set_video_roi(esplusplayer_handle handle, double scale_x,
1150                                double scale_y, double scale_w, double scale_h) {
1151   LOG_ENTER_P(cast_(handle))
1152   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1153   LOG_INFO_P(cast_(handle),
1154              "scale-x : %lf, scale-y: %lf, scale-w : %lf, scale-h : %lf",
1155              scale_x, scale_y, scale_w, scale_h);
1156
1157   CropArea rio_area;
1158   rio_area.scale_x = scale_x;
1159   rio_area.scale_y = scale_y;
1160   rio_area.scale_w = scale_w;
1161   rio_area.scale_h = scale_h;
1162
1163   return convert_return_type_(cast_(handle)->SetVideoRoi(rio_area));
1164 }
1165
1166 int esplusplayer_resize_render_rect(esplusplayer_handle handle, int x, int y,
1167                                     int width, int height) {
1168   LOG_ENTER_P(cast_(handle))
1169   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1170   LOG_INFO_P(cast_(handle), "x : %d, y: %d, width : %d, height : %d", x, y,
1171              width, height);
1172
1173   RenderRect rect;
1174   rect.x = x;
1175   rect.y = y;
1176   rect.w = width;
1177   rect.h = height;
1178
1179   return convert_return_type_(cast_(handle)->ResizeRenderRect(rect));
1180 }
1181
1182 int esplusplayer_set_display_rotation(
1183     esplusplayer_handle handle, esplusplayer_display_rotation_type rotation) {
1184   LOG_ENTER_P(cast_(handle))
1185   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1186   LOG_INFO_P(cast_(handle), "display rotate angle : %d",
1187              static_cast<int>(rotation));
1188   return convert_return_type_(
1189       cast_(handle)->SetDisplayRotate(static_cast<DisplayRotation>(rotation)));
1190 }
1191
1192 int esplusplayer_get_display_rotation(
1193     esplusplayer_handle handle, esplusplayer_display_rotation_type* rotation) {
1194   LOG_ENTER_P(cast_(handle))
1195   if (is_null_(handle) || is_null_(rotation))
1196     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1197   return convert_return_type_(cast_(handle)->GetDisplayRotate(
1198       reinterpret_cast<DisplayRotation*>(rotation)));
1199 }
1200
1201 int esplusplayer_set_display_visible(esplusplayer_handle handle, bool visible) {
1202   LOG_ENTER_P(cast_(handle))
1203   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1204   LOG_INFO_P(cast_(handle), "visible : %s", visible ? "true" : "false");
1205   return convert_return_type_(cast_(handle)->SetDisplayVisible(visible));
1206 }
1207
1208 int esplusplayer_set_tz_use(esplusplayer_handle handle, bool using_tz) {
1209   LOG_ENTER_P(cast_(handle))
1210   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1211   LOG_INFO_P(cast_(handle), "using_tz : %s", using_tz ? "true" : "false");
1212   return convert_return_type_(cast_(handle)->SetTrustZoneUse(using_tz));
1213 }
1214
1215 int esplusplayer_set_submit_data_type(esplusplayer_handle handle,
1216                                       esplusplayer_submit_data_type type) {
1217   LOG_ENTER_P(cast_(handle))
1218   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1219   LOG_INFO_P(cast_(handle), "type : %d", type);
1220   return convert_return_type_(
1221       cast_(handle)->SetSubmitDataType(static_cast<SubmitDataType>(type)));
1222 }
1223
1224 int esplusplayer_set_audio_mute(esplusplayer_handle handle, bool mute) {
1225   LOG_ENTER_P(cast_(handle))
1226   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1227   LOG_INFO_P(cast_(handle), "mute : %s", mute ? "true" : "false");
1228   return convert_return_type_(cast_(handle)->SetAudioMute(mute));
1229 }
1230
1231 esplusplayer_state esplusplayer_get_state(esplusplayer_handle handle) {
1232   // LOG_ENTER_P(cast_(handle))
1233   if (is_null_(handle)) return esplusplayer_state::ESPLUSPLAYER_STATE_NONE;
1234   auto current_state =
1235       static_cast<esplusplayer_state>(cast_(handle)->GetState());
1236   // LOG_INFO_P(cast_(handle), "state : %d", static_cast<int>(current_state));
1237
1238   return current_state;
1239 }
1240
1241 #ifdef ES_DUMP
1242 static void esdump(esplusplayer_handle handle, esplusplayer_es_packet* packet) {
1243   std::ofstream& ostream =
1244       (packet->type == ESPLUSPLAYER_STREAM_TYPE_AUDIO
1245            ? static_cast<EsPlusPlayerPriv*>(handle)->audio_stream_
1246            : static_cast<EsPlusPlayerPriv*>(handle)->video_stream_);
1247
1248   if (ostream.is_open() == false) return;
1249
1250   uint64_t tmp = packet->pts * 1000000;
1251   ostream.write(reinterpret_cast<char*>(&tmp), sizeof(uint64_t));
1252   tmp = packet->duration * 1000000;
1253   ostream.write(reinterpret_cast<char*>(&tmp), sizeof(uint64_t));
1254   std::uint64_t size = (std::uint64_t)packet->buffer_size;
1255   ostream.write(reinterpret_cast<char*>(&size), sizeof(size));
1256   ostream.write(reinterpret_cast<char*>(packet->buffer), packet->buffer_size);
1257   LOG_DEBUG("DUMP type:%d pkt pts: %" PRId64 "duration: %" PRId64 "size: %d",
1258             packet->type, packet->pts, packet->duration, packet->buffer_size);
1259 }
1260 #endif
1261
1262 esplusplayer_submit_status esplusplayer_submit_packet(
1263     esplusplayer_handle handle, esplusplayer_es_packet* packet) {
1264   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
1265   auto packetptr = convert_espacket_(packet);
1266   if (packetptr == nullptr) {
1267     LOG_ERROR("packet converting failed");
1268     return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
1269   }
1270
1271 #ifdef ES_DUMP
1272   esdump(handle, packet);
1273 #endif
1274
1275   auto status = cast_(handle)->SubmitPacket(packetptr);
1276   if (status != esplusplayer::PacketSubmitStatus::kSuccess) {
1277     LOG_ERROR("SubmitPacket status isn't SUCCESS [%d]",
1278               static_cast<int>(status));
1279   }
1280   return static_cast<esplusplayer_submit_status>(status);
1281 }
1282 // LCOV_EXCL_START
1283 esplusplayer_submit_status esplusplayer_submit_trust_zone_packet(
1284     esplusplayer_handle handle, esplusplayer_es_packet* packet,
1285     uint32_t tz_handle) {
1286   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
1287   auto packetptr = convert_espacket_(packet);
1288   if (packetptr == nullptr) {
1289     LOG_ERROR("packet converting failed");
1290     return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
1291   }
1292   auto status = cast_(handle)->SubmitTrustZonePacket(packetptr, tz_handle);
1293   if (status != esplusplayer::PacketSubmitStatus::kSuccess) {
1294     LOG_ERROR("SubmitPacket status isn't SUCCESS [%d]",
1295               static_cast<int>(status));
1296   }
1297   return static_cast<esplusplayer_submit_status>(status);
1298 }
1299
1300 esplusplayer_submit_status esplusplayer_submit_encrypted_packet_64bit(
1301     esplusplayer_handle handle, esplusplayer_es_packet* packet,
1302     esplusplayer_drm_info_64bit* drm_info) {
1303 #if DRM_MAPI_AARCH_64
1304   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
1305   auto packetptr = convert_espacket_(packet);
1306   if (packetptr == nullptr) {
1307     LOG_ERROR("packet converting failed");
1308     return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
1309   }
1310   auto status = esplusplayer::PacketSubmitStatus::kSuccess;
1311   if (drm_info == nullptr) {
1312     status = cast_(handle)->SubmitPacket(packetptr);
1313   } else {
1314     auto encrypted_info = convert_es_drm_info_(drm_info);
1315     status = cast_(handle)->SubmitEncryptedPacket(packetptr, *encrypted_info);
1316   }
1317   if (status != esplusplayer::PacketSubmitStatus::kSuccess) {
1318     LOG_ERROR("SubmitPacket status isn't SUCCESS [%d]",
1319               static_cast<int>(status));
1320   }
1321   return static_cast<esplusplayer_submit_status>(status);
1322 #else
1323   return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
1324 #endif
1325 }
1326
1327 esplusplayer_submit_status esplusplayer_submit_encrypted_packet(
1328     esplusplayer_handle handle, esplusplayer_es_packet* packet,
1329     esplusplayer_drm_info* drm_info) {
1330 #if DRM_MAPI_AARCH_64
1331   return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
1332 #else
1333   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
1334   auto packetptr = convert_espacket_(packet);
1335   if (packetptr == nullptr) {
1336     LOG_ERROR("packet converting failed");
1337     return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
1338   }
1339   auto status = esplusplayer::PacketSubmitStatus::kSuccess;
1340   if (drm_info == nullptr) {
1341     status = cast_(handle)->SubmitPacket(packetptr);
1342   } else {
1343     auto encrypted_info = convert_es_drm_info_(drm_info);
1344     status = cast_(handle)->SubmitEncryptedPacket(packetptr, *encrypted_info);
1345   }
1346   if (status != esplusplayer::PacketSubmitStatus::kSuccess) {
1347     LOG_ERROR("SubmitPacket status isn't SUCCESS [%d]",
1348               static_cast<int>(status));
1349   }
1350   return static_cast<esplusplayer_submit_status>(status);
1351 #endif
1352 }
1353
1354 esplusplayer_submit_status esplusplayer_submit_eos_packet(
1355     esplusplayer_handle handle, esplusplayer_stream_type type) {
1356   LOG_ENTER_P(cast_(handle))
1357   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
1358
1359   auto status = cast_(handle)->SubmitPacket(
1360       std::move(EsPacket::CreateEos(static_cast<StreamType>(type))));
1361   return static_cast<esplusplayer_submit_status>(status);
1362 }
1363 // LCOV_EXCL_STOP
1364
1365 #ifdef ES_DUMP
1366 static void audio_es_dump(esplusplayer_handle handle,
1367                           esplusplayer_audio_stream_info* info) {
1368   if (!exists("/tmp/asdump")) return;
1369   if (!exists("/etc/debug") && !exists("/etc/perf")) return;
1370
1371   std::ofstream& ostream =
1372       static_cast<EsPlusPlayerPriv*>(handle)->audio_stream_;
1373   if (ostream.is_open()) ostream.close();
1374   std::string dumppath = "/tmp/audiodump.ESP";
1375   ostream.open(dumppath + ".es", std::ofstream::binary | std::ofstream::trunc);
1376   if (ostream.is_open() == false) {
1377     LOG_ERROR("Fail to open %s.es", dumppath.c_str());
1378     return;
1379   }
1380   std::ofstream info_stream;
1381   info_stream.open(dumppath + ".info", std::ofstream::trunc);
1382   if (info_stream.is_open() == false) {
1383     LOG_ERROR("Fail to open %s.info", dumppath.c_str());
1384     return;
1385   }
1386   info_stream << static_cast<int>(info->mime_type) << std::endl;
1387   info_stream << info->sample_rate << std::endl << info->channels << std::endl;
1388   info_stream.close();
1389   if (info->codec_data_length == 0) return;
1390   std::ofstream codec_extradata_stream;
1391   codec_extradata_stream.open(dumppath + ".codec_extradata",
1392                               std::ofstream::binary | std::ofstream::trunc);
1393   if (codec_extradata_stream.is_open() == false) {
1394     LOG_ERROR("Fail to open %s.codec_extradata", dumppath.c_str());
1395     return;
1396   }
1397   codec_extradata_stream.write(
1398       reinterpret_cast<char*>(&info->codec_data_length),
1399       sizeof(info->codec_data_length));
1400   codec_extradata_stream.write(info->codec_data, info->codec_data_length);
1401   codec_extradata_stream.close();
1402 }
1403
1404 static void video_es_dump(esplusplayer_handle handle,
1405                           esplusplayer_video_stream_info* info) {
1406   // It requires to do "chsmack -a '_' /tmp/vsdump"
1407   // after touch /tmp/vsdump on the shell
1408   if (!exists("/tmp/vsdump")) return;
1409   if (!exists("/etc/debug") && !exists("/etc/perf")) return;
1410
1411   std::ofstream& ostream =
1412       static_cast<EsPlusPlayerPriv*>(handle)->video_stream_;
1413   if (ostream.is_open()) ostream.close();
1414   std::string dumppath = "/tmp/videodump.ESP";
1415   ostream.open(dumppath + ".es", std::ofstream::binary | std::ofstream::trunc);
1416   if (ostream.is_open() == false) {
1417     LOG_ERROR("Fail to open %s.es", dumppath.c_str());
1418     return;
1419   }
1420   std::ofstream info_stream;
1421   info_stream.open(dumppath + ".info", std::ofstream::trunc);
1422   if (info_stream.is_open() == false) {
1423     LOG_ERROR("Fail to open %s.info", dumppath.c_str());
1424     return;
1425   }
1426   info_stream << static_cast<int>(info->mime_type) << std::endl;
1427   info_stream << info->width << std::endl << info->height << std::endl;
1428   info_stream << info->max_width << std::endl << info->max_height << std::endl;
1429   info_stream << info->framerate_num << std::endl
1430               << info->framerate_den << std::endl;
1431   info_stream.close();
1432   if (info->codec_data_length == 0) return;
1433   std::ofstream codec_extradata_stream;
1434   codec_extradata_stream.open(dumppath + ".codec_extradata",
1435                               std::ofstream::binary | std::ofstream::trunc);
1436   if (codec_extradata_stream.is_open() == false) {
1437     LOG_ERROR("Fail to open %s.codec_extradata", dumppath.c_str());
1438     return;
1439   }
1440   codec_extradata_stream.write(
1441       reinterpret_cast<char*>(&info->codec_data_length),
1442       sizeof(info->codec_data_length));
1443   codec_extradata_stream.write(info->codec_data, info->codec_data_length);
1444   codec_extradata_stream.close();
1445 }
1446 #endif
1447
1448 int esplusplayer_set_audio_stream_info(esplusplayer_handle handle,
1449                                        esplusplayer_audio_stream_info* info) {
1450   LOG_ENTER_P(cast_(handle))
1451   if (is_null_(handle) || is_null_(info))
1452     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1453
1454 #ifdef ES_DUMP
1455   audio_es_dump(handle, info);
1456 #endif
1457
1458   auto stream = convert_stream_ptr_(info);
1459   return convert_return_type_(cast_(handle)->SetStream(std::move(stream)));
1460 }
1461
1462 int esplusplayer_set_video_stream_info(esplusplayer_handle handle,
1463                                        esplusplayer_video_stream_info* info) {
1464   LOG_ENTER_P(cast_(handle))
1465   if (is_null_(handle) || is_null_(info))
1466     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1467
1468 #ifdef ES_DUMP
1469   video_es_dump(handle, info);
1470 #endif
1471
1472   auto stream = convert_stream_ptr_(info);
1473   return convert_return_type_(cast_(handle)->SetStream(std::move(stream)));
1474 }
1475
1476 int esplusplayer_get_playing_time(esplusplayer_handle handle,
1477                                   uint64_t* cur_time) {
1478   if (is_null_(handle) || is_null_(cur_time))
1479     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1480
1481   auto ret = cast_(handle)->GetPlayingTime(cur_time);
1482   // LOG_INFO_P(cast_(handle), "playing time : %llu", *ms);
1483   return convert_return_type_(ret);
1484 }
1485
1486 namespace {
1487 std::shared_ptr<DecodedPacketManagerInterface> CreateDecodedPacketManager(
1488     esplusplayer_handle handle,
1489     esplusplayer_decoded_video_frame_buffer_type type) {
1490   std::shared_ptr<DecodedPacketManagerInterface> mgr = nullptr;
1491   if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_COPY)
1492     mgr = std::make_shared<esplusplayer::DecodedCopiedPacketList>();
1493   else if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_REFERENCE)
1494     mgr = std::make_shared<esplusplayer::DecodedReferencePacketList>();
1495   else if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE)
1496     mgr = std::make_shared<esplusplayer::DecodedScaledPacketList>();
1497   else if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_MANUAL_COPY)
1498     mgr = std::make_shared<esplusplayer::ManualDecodedCopiedPacketList>(
1499         [handle](esplusplayer_decoded_video_packet* pkt) {
1500           esplusplayer::DecodedVideoPacket _pkt;
1501           _pkt.pts = pkt->pts;
1502           _pkt.duration = pkt->duration;
1503           _pkt.surface_data = static_cast<tbm_surface_h>(pkt->surface_data);
1504           _pkt.scaler_index = pkt->private_data;
1505           return cast_(handle)->ReturnDecodedPacket(_pkt);
1506         });
1507   return mgr;
1508 }
1509 }  // namespace
1510
1511 int esplusplayer_set_video_frame_buffer_type(
1512     esplusplayer_handle handle,
1513     esplusplayer_decoded_video_frame_buffer_type type) {
1514   LOG_ENTER_P(cast_(handle))
1515   if (is_null_(handle) || is_null_(listener_cast_(handle)))
1516     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1517   LOG_INFO_P(cast_(handle), "decoded buffer type : %d", static_cast<int>(type));
1518
1519   auto priv = static_cast<EsPlusPlayerPriv*>(handle);
1520   priv->decoded_pkt_mgr = ::CreateDecodedPacketManager(handle, type);
1521   priv->listener->SetDecodedPacketManager(priv->decoded_pkt_mgr);
1522
1523   auto ret = cast_(handle)->SetVideoFrameBufferType(
1524       static_cast<esplusplayer::DecodedVideoFrameBufferType>(type));
1525   return convert_return_type_(ret);
1526 }
1527
1528 int esplusplayer_set_video_frame_buffer_scale_resolution(
1529     esplusplayer_handle handle, uint32_t target_width, uint32_t target_height) {
1530   LOG_ENTER_P(cast_(handle))
1531   if (is_null_(handle) || !target_width || !target_height)
1532     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1533
1534   LOG_INFO_P(cast_(handle), "target_width : %d, target_height: %d",
1535              target_width, target_height);
1536   return convert_return_type_(cast_(handle)->SetVideoFrameBufferScaleResolution(
1537       target_width, target_height));
1538 }
1539
1540 int esplusplayer_set_decoded_video_frame_rate(
1541     esplusplayer_handle handle, esplusplayer_rational request_framerate) {
1542   LOG_ENTER_P(cast_(handle))
1543   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1544   LOG_INFO("request decoded video frame rate : %d/%d", request_framerate.num,
1545            request_framerate.den);
1546
1547   Rational request_fps;
1548   request_fps.num = request_framerate.num;
1549   request_fps.den = request_framerate.den;
1550   return convert_return_type_(
1551       cast_(handle)->SetDecodedVideoFrameRate(request_fps));
1552 }
1553
1554 int esplusplayer_get_adaptive_info(
1555     esplusplayer_handle handle, void* padaptive_info,
1556     esplusplayer_adaptive_info_type adaptive_type) {
1557   // LOG_ENTER_P(cast_(handle))
1558   if (is_null_(handle) || is_null_(padaptive_info))
1559     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1560
1561   auto ret = cast_(handle)->GetAdaptiveInfo(
1562       padaptive_info, static_cast<PlayerAdaptiveInfo>(adaptive_type));
1563   return convert_return_type_(ret);
1564 }
1565
1566 int esplusplayer_set_volume(esplusplayer_handle handle, const int volume) {
1567   LOG_ENTER_P(cast_(handle))
1568   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1569
1570   auto ret = cast_(handle)->SetVolume(volume);
1571   return convert_return_type_(ret);
1572 }
1573
1574 int esplusplayer_get_volume(esplusplayer_handle handle, int* volume) {
1575   LOG_ENTER_P(cast_(handle))
1576   if (is_null_(handle) || is_null_(volume))
1577     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1578
1579   auto ret = cast_(handle)->GetVolume(volume);
1580   return convert_return_type_(ret);
1581 }
1582
1583 int esplusplayer_flush(esplusplayer_handle handle,
1584                        esplusplayer_stream_type type) {
1585   LOG_ENTER_P(cast_(handle))
1586   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1587   auto ret = cast_(handle)->Flush(static_cast<StreamType>(type));
1588   return convert_return_type_(ret);
1589 }
1590
1591 const char* esplusplayer_get_error_string(esplusplayer_error_type type) {
1592   LOG_ENTER
1593   return util::ConvertErrorTypeToString(type).c_str();
1594 }
1595
1596 int esplusplayer_set_error_cb(esplusplayer_handle handle,
1597                               esplusplayer_error_cb error_cb, void* userdata) {
1598   LOG_ENTER_P(cast_(handle))
1599   listener_bridge* listener = nullptr;
1600   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1601     LOG_ERROR("ESPlayer or Listener object is nil.");
1602     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1603   }
1604
1605   listener->error_cb_ = error_cb;
1606   listener->error_cb_userdata_ = userdata;
1607   return convert_return_type_(true);
1608 }
1609
1610 int esplusplayer_set_buffer_status_cb(
1611     esplusplayer_handle handle, esplusplayer_buffer_status_cb buffer_status_cb,
1612     void* userdata) {
1613   LOG_ENTER_P(cast_(handle))
1614   listener_bridge* listener = nullptr;
1615   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1616     LOG_ERROR("ESPlayer or Listener object is nil.");
1617     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1618   }
1619
1620   listener->buffer_status_cb_ = buffer_status_cb;
1621   listener->buffer_status_cb_userdata_ = userdata;
1622   return convert_return_type_(true);
1623 }
1624
1625 int esplusplayer_set_buffer_byte_status_cb(
1626     esplusplayer_handle handle,
1627     esplusplayer_buffer_byte_status_cb buffer_status_cb, void* userdata) {
1628   LOG_ENTER_P(cast_(handle))
1629   listener_bridge* listener = nullptr;
1630   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1631     LOG_ERROR("ESPlayer or Listener object is nil.");
1632     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1633   }
1634
1635   listener->buffer_byte_status_cb_ = buffer_status_cb;
1636   listener->buffer_byte_status_cb_userdata_ = userdata;
1637   return convert_return_type_(true);
1638 }
1639
1640 int esplusplayer_set_buffer_time_status_cb(
1641     esplusplayer_handle handle,
1642     esplusplayer_buffer_time_status_cb buffer_status_cb, void* userdata) {
1643   LOG_ENTER_P(cast_(handle))
1644   listener_bridge* listener = nullptr;
1645   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1646     LOG_ERROR("ESPlayer or Listener object is nil.");
1647     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1648   }
1649
1650   listener->buffer_time_status_cb_ = buffer_status_cb;
1651   listener->buffer_time_status_cb_userdata_ = userdata;
1652   return convert_return_type_(true);
1653 }
1654
1655 int esplusplayer_set_buffer_size(esplusplayer_handle handle,
1656                                  esplusplayer_buffer_option option,
1657                                  uint64_t size) {
1658   LOG_ENTER_P(cast_(handle))
1659   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1660   LOG_INFO("%p option: %d, size: %" PRId64 "", cast_(handle),
1661            static_cast<int>(option), size);
1662   auto ret = cast_(handle)->SetBufferSize(
1663       static_cast<esplusplayer::BufferOption>(option), size);
1664   return convert_return_type_(ret);
1665 }
1666
1667 int esplusplayer_set_resource_conflicted_cb(
1668     esplusplayer_handle handle,
1669     esplusplayer_resource_conflicted_cb resource_conflicted_cb,
1670     void* userdata) {
1671   LOG_ENTER_P(cast_(handle))
1672   listener_bridge* listener = nullptr;
1673   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1674     LOG_ERROR("ESPlayer or Listener object is nil.");
1675     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1676   }
1677
1678   listener->resource_conflicted_cb_ = resource_conflicted_cb;
1679   listener->resource_conflicted_cb_userdata_ = userdata;
1680   return convert_return_type_(true);
1681 }
1682
1683 int esplusplayer_set_eos_cb(esplusplayer_handle handle,
1684                             esplusplayer_eos_cb eos_cb, void* userdata) {
1685   LOG_ENTER_P(cast_(handle))
1686   listener_bridge* listener = nullptr;
1687   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1688     LOG_ERROR("ESPlayer or Listener object is nil.");
1689     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1690   }
1691
1692   listener->eos_cb_ = eos_cb;
1693   listener->eos_cb_userdata_ = userdata;
1694   return convert_return_type_(true);
1695 }
1696
1697 int esplusplayer_set_ready_to_prepare_cb(
1698     esplusplayer_handle handle,
1699     esplusplayer_ready_to_prepare_cb ready_to_prepare_cb, void* userdata) {
1700   LOG_ENTER_P(cast_(handle))
1701   listener_bridge* listener = nullptr;
1702   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1703     LOG_ERROR("ESPlayer or Listener object is nil.");
1704     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1705   }
1706
1707   listener->ready_to_prepare_cb_ = ready_to_prepare_cb;
1708   listener->ready_to_prepare_cb_userdata_ = userdata;
1709   return convert_return_type_(true);
1710 }
1711
1712 int esplusplayer_set_prepare_async_done_cb(
1713     esplusplayer_handle handle,
1714     esplusplayer_prepare_async_done_cb prepare_async_done_cb, void* userdata) {
1715   LOG_ENTER_P(cast_(handle))
1716   listener_bridge* listener = nullptr;
1717   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1718     LOG_ERROR("ESPlayer or Listener object is nil.");
1719     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1720   }
1721
1722   listener->prepare_async_done_cb_ = prepare_async_done_cb;
1723   listener->prepare_async_done_cb_userdata_ = userdata;
1724   return convert_return_type_(true);
1725 }
1726
1727 int esplusplayer_set_seek_done_cb(esplusplayer_handle handle,
1728                                   esplusplayer_seek_done_cb seek_done_cb,
1729                                   void* userdata) {
1730   LOG_ENTER_P(cast_(handle))
1731   listener_bridge* listener = nullptr;
1732   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1733     LOG_ERROR("ESPlayer or Listener object is nil.");
1734     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1735   }
1736
1737   listener->seek_done_cb_ = seek_done_cb;
1738   listener->seek_done_cb_userdata_ = userdata;
1739   return convert_return_type_(true);
1740 }
1741
1742 int esplusplayer_set_ready_to_seek_cb(
1743     esplusplayer_handle handle, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
1744     void* userdata) {
1745   LOG_ENTER_P(cast_(handle))
1746   listener_bridge* listener = nullptr;
1747   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1748     LOG_ERROR("ESPlayer or Listener object is nil.");
1749     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1750   }
1751   update_ready_to_seek_callback(handle, ready_to_seek_cb, userdata);
1752   return convert_return_type_(true);
1753 }
1754
1755 int esplusplayer_set_media_packet_video_decoded_cb(
1756     esplusplayer_handle handle,
1757     esplusplayer_media_packet_video_decoded_cb media_packet_video_decoded_cb,
1758     void* userdata) {
1759   LOG_ENTER_P(cast_(handle))
1760   listener_bridge* listener = nullptr;
1761   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1762     LOG_ERROR("ESPlayer or Listener object is nil.");
1763     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1764   }
1765
1766   listener->media_packet_video_decoded_cb_ = media_packet_video_decoded_cb;
1767   listener->media_packet_video_decoded_cb_userdata_ = userdata;
1768   return convert_return_type_(true);
1769 }
1770
1771 int esplusplayer_set_closed_caption_cb(
1772     esplusplayer_handle handle,
1773     esplusplayer_closed_caption_cb closed_caption_cb, void* userdata) {
1774   LOG_ENTER_P(cast_(handle))
1775   listener_bridge* listener = nullptr;
1776   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1777     LOG_ERROR("ESPlayer or Listener object is nil.");
1778     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1779   }
1780
1781   listener->closed_caption_cb_ = closed_caption_cb;
1782   listener->closed_caption_cb_userdata_ = userdata;
1783   return convert_return_type_(true);
1784 }
1785
1786 int esplusplayer_set_flush_done_cb(esplusplayer_handle handle,
1787                                    esplusplayer_flush_done_cb flush_done_cb,
1788                                    void* userdata) {
1789   LOG_ENTER_P(cast_(handle))
1790   listener_bridge* listener = nullptr;
1791   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1792     LOG_ERROR("ESPlayer or Listener object is nil.");
1793     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1794   }
1795
1796   listener->flush_done_cb_ = flush_done_cb;
1797   listener->flush_done_cb_userdata_ = userdata;
1798   return convert_return_type_(true);
1799 }
1800
1801 int esplusplayer_set_event_cb(esplusplayer_handle handle,
1802                               esplusplayer_event_cb event_cb, void* userdata) {
1803   LOG_ENTER_P(cast_(handle))
1804   listener_bridge* listener = nullptr;
1805   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1806     LOG_ERROR("ESPlayer or Listener object is nil.");
1807     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1808   }
1809   listener->event_cb_ = event_cb;
1810   listener->event_cb_userdata_ = userdata;
1811
1812   return convert_return_type_(true);
1813 }
1814
1815 // LCOV_EXCL_START
1816 int esplusplayer_set_first_video_decoding_done_cb(
1817     esplusplayer_handle handle,
1818     esplusplayer_first_video_decoding_done_cb first_video_decoding_done_cb,
1819     void* userdata) {
1820   LOG_ENTER_P(cast_(handle))
1821   listener_bridge* listener = nullptr;
1822   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1823     LOG_ERROR("ESPlayer or Listener object is nil.");
1824     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1825   }
1826   listener->first_video_decoding_done_cb_ = first_video_decoding_done_cb;
1827   listener->first_video_decoding_done_cb_userdata_ = userdata;
1828   return convert_return_type_(true);
1829 }
1830
1831 int esplusplayer_set_video_decoder_underrun_cb(
1832     esplusplayer_handle handle,
1833     esplusplayer_decoder_underrun_cb video_decoder_underrun_cb,
1834     void* userdata) {
1835   LOG_ENTER_P(cast_(handle))
1836   listener_bridge* listener = nullptr;
1837   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1838     LOG_ERROR("ESPlayer or Listener object is nil.");
1839     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1840   }
1841   listener->video_decoder_underrun_cb_ = video_decoder_underrun_cb;
1842   listener->video_decoder_underrun_cb_userdata_ = userdata;
1843
1844   return convert_return_type_(true);
1845 }
1846 // LCOV_EXCL_STOP
1847
1848 int esplusplayer_set_video_latency_status_cb(
1849     esplusplayer_handle handle,
1850     esplusplayer_video_latency_status_cb video_latency_status_cb,
1851     void* userdata) {
1852   LOG_ENTER_P(cast_(handle))
1853   listener_bridge* listener = nullptr;
1854   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1855     LOG_ERROR("ESPlayer or Listener object is nil.");
1856     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1857   }
1858
1859   listener->video_latency_status_cb_ = video_latency_status_cb;
1860   listener->video_latency_status_cb_userdata_ = userdata;
1861   return convert_return_type_(true);
1862 }
1863
1864 int esplusplayer_set_audio_latency_status_cb(
1865     esplusplayer_handle handle,
1866     esplusplayer_audio_latency_status_cb audio_latency_status_cb,
1867     void* userdata) {
1868   LOG_ENTER_P(cast_(handle))
1869   listener_bridge* listener = nullptr;
1870   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1871     LOG_ERROR("ESPlayer or Listener object is nil.");
1872     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1873   }
1874
1875   listener->audio_latency_status_cb_ = audio_latency_status_cb;
1876   listener->audio_latency_status_cb_userdata_ = userdata;
1877   return convert_return_type_(true);
1878 }
1879
1880 int esplusplayer_set_video_high_latency_cb(
1881     esplusplayer_handle handle,
1882     esplusplayer_video_high_latency_cb video_high_latency_cb, void* userdata) {
1883   LOG_ENTER_P(cast_(handle))
1884   listener_bridge* listener = nullptr;
1885   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1886     LOG_ERROR("ESPlayer or Listener object is nil.");
1887     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1888   }
1889
1890   listener->video_high_latency_cb_ = video_high_latency_cb;
1891   listener->video_high_latency_cb_userdata_ = userdata;
1892   return convert_return_type_(true);
1893 }
1894
1895 int esplusplayer_set_audio_high_latency_cb(
1896     esplusplayer_handle handle,
1897     esplusplayer_audio_high_latency_cb audio_high_latency_cb, void* userdata) {
1898   LOG_ENTER_P(cast_(handle))
1899   listener_bridge* listener = nullptr;
1900   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1901     LOG_ERROR("ESPlayer or Listener object is nil.");
1902     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1903   }
1904
1905   listener->audio_high_latency_cb_ = audio_high_latency_cb;
1906   listener->audio_high_latency_cb_userdata_ = userdata;
1907   return convert_return_type_(true);
1908 }
1909
1910 int esplusplayer_get_decoded_video_packet(
1911     esplusplayer_handle handle, esplusplayer_decoded_video_packet* packet,
1912     esplusplayer_get_decoded_video_frame_status_type* state) {
1913   if (is_null_(handle) || is_null_(packet)) {
1914     LOG_ERROR("handle[%p] or packet[%p] is nil.", handle, packet);
1915     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1916   }
1917   esplusplayer::DecodedVideoPacket _packet;
1918   bool ret = false;
1919   auto _state = cast_(handle)->GetDecodedPacket(_packet);
1920   if (_state != esplusplayer::GetDecodedVideoFrameStatus::kUnknown) {
1921     ret = true;
1922   }
1923   if (_state == esplusplayer::GetDecodedVideoFrameStatus::kSuccess) {
1924     packet->pts = _packet.pts;
1925     packet->duration = _packet.duration;
1926     packet->surface_data = static_cast<void*>(_packet.surface_data);
1927     packet->private_data = _packet.scaler_index;
1928   }
1929   if (state) {
1930     *state = convert_get_decoded_video_frame_status_(_state);
1931   }
1932   return convert_return_type_(ret);
1933 }
1934
1935 int esplusplayer_decoded_buffer_destroy(
1936     esplusplayer_handle handle, esplusplayer_decoded_video_packet* packet) {
1937   if (is_null_(handle)) {
1938     LOG_ERROR("ESPlayer object is nil.");
1939     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1940   }
1941   auto priv = static_cast<EsPlusPlayerPriv*>(handle);
1942   auto& mgr = priv->decoded_pkt_mgr;
1943   if (mgr == nullptr) {
1944     LOG_ERROR("DecodedPacketManager object is nil.");
1945     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1946   }
1947   mgr->Remove(packet);
1948   return convert_return_type_(true);
1949 }
1950
1951 int esplusplayer_set_low_latency_mode(esplusplayer_handle handle,
1952                                       esplusplayer_low_latency_mode mode) {
1953   LOG_ENTER_P(cast_(handle))
1954   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1955   auto ret =
1956       cast_(handle)->SetLowLatencyMode(static_cast<PlayerLowLatencyMode>(mode));
1957   return convert_return_type_(ret);
1958 }
1959
1960 int esplusplayer_set_video_frame_peek_mode(esplusplayer_handle handle) {
1961   LOG_ENTER_P(cast_(handle))
1962   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1963   auto ret = cast_(handle)->SetVideoFramePeekMode();
1964   return convert_return_type_(ret);
1965 }
1966
1967 int esplusplayer_render_video_frame(esplusplayer_handle handle) {
1968   LOG_ENTER_P(cast_(handle))
1969   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1970   auto ret = cast_(handle)->RenderVideoFrame();
1971   return convert_return_type_(ret);
1972 }
1973
1974 int esplusplayer_set_unlimited_max_buffer_mode(esplusplayer_handle handle) {
1975   LOG_ENTER_P(cast_(handle))
1976   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1977   auto ret = cast_(handle)->SetUnlimitedMaxBufferMode();
1978   return convert_return_type_(ret);
1979 }
1980
1981 int esplusplayer_set_fmm_mode(esplusplayer_handle handle) {
1982   LOG_ENTER_P(cast_(handle))
1983   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1984   auto ret = cast_(handle)->SetFmmMode();
1985   return util::ConvertErrorCode(ret);
1986 }
1987
1988 int esplusplayer_set_audio_codec_type(esplusplayer_handle handle,
1989                                       esplusplayer_audio_codec_type type) {
1990   LOG_ENTER_P(cast_(handle))
1991   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1992   auto ret =
1993       cast_(handle)->SetAudioCodecType(static_cast<PlayerAudioCodecType>(type));
1994   return convert_return_type_(ret);
1995 }
1996
1997 int esplusplayer_set_aifilter(esplusplayer_handle handle, void* aifilter) {
1998   LOG_ENTER_P(cast_(handle))
1999   if (is_null_(handle) || is_null_(aifilter))
2000     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2001   auto ret = cast_(handle)->SetAiFilter(aifilter);
2002   return convert_return_type_(ret);
2003 }
2004
2005 int esplusplayer_set_video_codec_type(esplusplayer_handle handle,
2006                                       esplusplayer_video_codec_type type) {
2007   LOG_ENTER_P(cast_(handle))
2008   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2009   auto ret =
2010       cast_(handle)->SetVideoCodecType(static_cast<PlayerVideoCodecType>(type));
2011   return convert_return_type_(ret);
2012 }
2013
2014 int esplusplayer_set_alternative_video_resource(esplusplayer_handle handle,
2015                                                 unsigned int rsc_type) {
2016   LOG_ENTER_P(cast_(handle))
2017   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2018   auto ret = cast_(handle)->SetAlternativeVideoResource(rsc_type);
2019   return convert_return_type_(ret);
2020 }
2021
2022 int esplusplayer_set_alternative_audio_resource(
2023     esplusplayer_handle handle, esplusplayer_audio_resource_type rsc_type) {
2024   LOG_ENTER_P(cast_(handle))
2025   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2026   auto ret = cast_(handle)->SetAlternativeAudioResource(
2027       static_cast<PlayerAudioResourceType>(rsc_type));
2028   return convert_return_type_(ret);
2029 }
2030
2031 int esplusplayer_set_render_time_offset(esplusplayer_handle handle,
2032                                         esplusplayer_stream_type type,
2033                                         int64_t offset) {
2034   LOG_ENTER_P(cast_(handle))
2035   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2036   auto ret =
2037       cast_(handle)->SetRenderTimeOffset(static_cast<StreamType>(type), offset);
2038   return convert_return_type_(ret);
2039 }
2040
2041 int esplusplayer_get_render_time_offset(esplusplayer_handle handle,
2042                                         esplusplayer_stream_type type,
2043                                         int64_t* offset) {
2044   LOG_ENTER_P(cast_(handle))
2045   if (is_null_(handle) || is_null_(offset))
2046     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2047   auto ret =
2048       cast_(handle)->GetRenderTimeOffset(static_cast<StreamType>(type), offset);
2049   return convert_return_type_(ret);
2050 }
2051
2052 int esplusplayer_switch_audio_stream_onthefly(
2053     esplusplayer_handle handle, esplusplayer_audio_stream_info* info) {
2054   LOG_ENTER_P(cast_(handle))
2055   if (is_null_(handle) || is_null_(info))
2056     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2057
2058   auto stream = convert_stream_ptr_(info);
2059   auto ret = cast_(handle)->SwitchAudioStreamOnTheFly(std::move(stream));
2060   return convert_return_type_(ret);
2061 }
2062
2063 int esplusplayer_init_audio_easing_info(
2064     esplusplayer_handle handle, uint32_t init_volume, uint32_t elapsed_time,
2065     const esplusplayer_target_audio_easing_info* easing_info) {
2066   LOG_ENTER_P(cast_(handle))
2067   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2068   if (easing_info == nullptr) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2069
2070   AudioEasingInfo info;
2071   info.target_volume = easing_info->volume;
2072   info.duration = easing_info->duration;
2073   info.type = static_cast<AudioEasingType>(easing_info->type);
2074   auto ret =
2075       cast_(handle)->InitAudioEasingInfo(init_volume, elapsed_time, info);
2076   return convert_return_type_(ret);
2077 }
2078
2079 int esplusplayer_update_audio_easing_info(
2080     esplusplayer_handle handle,
2081     const esplusplayer_target_audio_easing_info* easing_info) {
2082   LOG_ENTER_P(cast_(handle))
2083   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2084   if (easing_info == nullptr) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2085
2086   AudioEasingInfo info;
2087   info.target_volume = easing_info->volume;
2088   info.duration = easing_info->duration;
2089   info.type = static_cast<AudioEasingType>(easing_info->type);
2090
2091   auto ret = cast_(handle)->UpdateAudioEasingInfo(info);
2092   return convert_return_type_(ret);
2093 }
2094
2095 int esplusplayer_get_audio_easing_info(
2096     esplusplayer_handle handle, uint32_t* current_volume,
2097     uint32_t* elapsed_time,
2098     esplusplayer_target_audio_easing_info* easing_info) {
2099   LOG_ENTER_P(cast_(handle))
2100   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2101   if (is_null_(current_volume) || is_null_(elapsed_time) ||
2102       is_null_(easing_info))
2103     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2104
2105   AudioEasingInfo info;
2106   auto ret =
2107       cast_(handle)->GetAudioEasingInfo(current_volume, elapsed_time, &info);
2108   easing_info->volume = info.target_volume;
2109   easing_info->duration = info.duration;
2110   easing_info->type = static_cast<esplusplayer_audio_easing_type>(info.type);
2111
2112   return convert_return_type_(ret);
2113 }
2114
2115 int esplusplayer_start_audio_easing(esplusplayer_handle handle) {
2116   LOG_ENTER_P(cast_(handle))
2117   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2118   auto ret = cast_(handle)->StartAudioEasing();
2119   return convert_return_type_(ret);
2120 }
2121
2122 int esplusplayer_stop_audio_easing(esplusplayer_handle handle) {
2123   LOG_ENTER_P(cast_(handle))
2124   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2125   auto ret = cast_(handle)->StopAudioEasing();
2126   return convert_return_type_(ret);
2127 }
2128
2129 // LCOV_EXCL_START
2130 int get_size_of_esplusplayer_app_info(void) {
2131   return sizeof(esplusplayer_app_info);
2132 }
2133
2134 int get_size_of_esplusplayer_es_packet(void) {
2135   return sizeof(esplusplayer_es_packet);
2136 }
2137
2138 int get_size_of_esplusplayer_es_tz_packet(void) {
2139   return sizeof(esplusplayer_es_tz_packet);
2140 }
2141
2142 int get_size_of_esplusplayer_audio_stream_info(void) {
2143   return sizeof(esplusplayer_audio_stream_info);
2144 }
2145
2146 int get_size_of_esplusplayer_video_stream_info(void) {
2147   return sizeof(esplusplayer_video_stream_info);
2148 }
2149
2150 int get_size_of_esplusplayer_drm_info(void) {
2151 #ifdef DRM_MAPI_AARCH_64
2152   return sizeof(esplusplayer_drm_info_64bit);
2153 #else
2154   return sizeof(esplusplayer_drm_info);
2155 #endif
2156 }
2157 // LCOV_EXCL_STOP
2158
2159 int esplusplayer_set_catch_up_speed(esplusplayer_handle handle,
2160                                     esplusplayer_catch_up_speed level) {
2161   LOG_ENTER_P(cast_(handle))
2162   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2163   if (level < ESPLUSPLAYER_CATCH_UP_SPEED_NONE ||
2164       level > ESPLUSPLAYER_CATCH_UP_SPEED_FAST) {
2165     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2166   }
2167   auto ret = cast_(handle)->SetCatchUpSpeed(static_cast<CatchUpSpeed>(level));
2168   return convert_return_type_(ret);
2169 }
2170
2171 int esplusplayer_get_video_latency_status(esplusplayer_handle handle,
2172                                           esplusplayer_latency_status* status) {
2173   LOG_ENTER_P(cast_(handle))
2174   if (is_null_(handle) || is_null_(status))
2175     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2176
2177   LatencyStatus current_status = LatencyStatus::kLow;
2178   auto ret = cast_(handle)->GetVideoLatencyStatus(&current_status);
2179   *status = static_cast<esplusplayer_latency_status>(current_status);
2180
2181   return convert_return_type_(ret);
2182 }
2183
2184 int esplusplayer_get_audio_latency_status(esplusplayer_handle handle,
2185                                           esplusplayer_latency_status* status) {
2186   LOG_ENTER_P(cast_(handle))
2187   if (is_null_(handle) || is_null_(status))
2188     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2189
2190   LatencyStatus current_status = LatencyStatus::kLow;
2191   auto ret = cast_(handle)->GetAudioLatencyStatus(&current_status);
2192   *status = static_cast<esplusplayer_latency_status>(current_status);
2193
2194   return convert_return_type_(ret);
2195 }
2196
2197 int esplusplayer_set_video_mid_latency_threshold(esplusplayer_handle handle,
2198                                                  const unsigned int threshold) {
2199   LOG_ENTER_P(cast_(handle))
2200   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2201
2202   auto ret = cast_(handle)->SetVideoMidLatencyThreshold(threshold);
2203   return convert_return_type_(ret);
2204 }
2205
2206 int esplusplayer_set_audio_mid_latency_threshold(esplusplayer_handle handle,
2207                                                  const unsigned int threshold) {
2208   LOG_ENTER_P(cast_(handle))
2209   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2210
2211   auto ret = cast_(handle)->SetAudioMidLatencyThreshold(threshold);
2212   return convert_return_type_(ret);
2213 }
2214
2215 int esplusplayer_set_video_high_latency_threshold(
2216     esplusplayer_handle handle, const unsigned int threshold,
2217     esplusplayer_video_high_latency_cb video_high_latency_cb, void* userdata) {
2218   LOG_ENTER_P(cast_(handle))
2219   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2220
2221   esplusplayer_set_video_high_latency_cb(handle, video_high_latency_cb,
2222                                          userdata);
2223
2224   auto ret = cast_(handle)->SetVideoHighLatencyThreshold(threshold);
2225   return convert_return_type_(ret);
2226 }
2227
2228 int esplusplayer_set_audio_high_latency_threshold(
2229     esplusplayer_handle handle, const unsigned int threshold,
2230     esplusplayer_audio_high_latency_cb audio_high_latency_cb, void* userdata) {
2231   LOG_ENTER_P(cast_(handle))
2232   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2233
2234   esplusplayer_set_audio_high_latency_cb(handle, audio_high_latency_cb,
2235                                          userdata);
2236
2237   auto ret = cast_(handle)->SetAudioHighLatencyThreshold(threshold);
2238   return convert_return_type_(ret);
2239 }
2240
2241 int esplusplayer_get_low_latency_pcm_buffer_size(esplusplayer_handle handle,
2242                                                  uint64_t* frame_count) {
2243   LOG_ENTER_P(cast_(handle))
2244   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2245
2246   auto ret = cast_(handle)->GetLowLatencyPcmBufferSize(frame_count);
2247   return convert_return_type_(ret);
2248 }
2249
2250 int esplusplayer_get_low_latency_pcm_current_buffer_level(
2251     esplusplayer_handle handle, uint64_t* frame_count) {
2252   LOG_ENTER_P(cast_(handle))
2253   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2254
2255   auto ret = cast_(handle)->GetLowLatencyPcmCurrentBufferLevel(frame_count);
2256   return convert_return_type_(ret);
2257 }
2258
2259 int esplusplayer_get_low_latency_pcm_underrun_count(esplusplayer_handle handle,
2260                                                     uint64_t* underrun_count) {
2261   LOG_ENTER_P(cast_(handle))
2262   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2263
2264   auto ret = cast_(handle)->GetLowLatencyPcmUnderrunCount(underrun_count);
2265   return convert_return_type_(ret);
2266 }
2267
2268 int esplusplayer_get_virtual_rsc_id(esplusplayer_handle handle,
2269                                     const esplusplayer_rsc_type type,
2270                                     int* virtual_id) {
2271   LOG_ENTER_P(cast_(handle))
2272   if (is_null_(handle) || is_null_(virtual_id))
2273     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2274
2275   auto ret =
2276       cast_(handle)->GetVirtualRscId(static_cast<RscType>(type), virtual_id);
2277   return convert_return_type_(ret);
2278 }
2279
2280 int esplusplayer_set_advanced_picture_quality_type(
2281     esplusplayer_handle handle,
2282     esplusplayer_advanced_picture_quality_type type) {
2283   LOG_ENTER_P(cast_(handle))
2284   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2285
2286   auto ret = cast_(handle)->SetAdvancedPictureQualityType(
2287       static_cast<AdvPictureQualityType>(type));
2288   return convert_return_type_(ret);
2289 }
2290
2291 int esplusplayer_set_resource_allocate_policy(
2292     esplusplayer_handle handle, esplusplayer_rsc_alloc_policy policy) {
2293   LOG_ENTER_P(cast_(handle))
2294   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2295   LOG_INFO("policy: %d", static_cast<int>(policy));
2296   if (policy == ESPLUSPLAYER_RSC_ALLOC_INAPP_MULTIVIEW) {
2297     LOG_INFO(
2298         "change policy ESPLUSPLAYER_RSC_ALLOC_INAPP_MULTIVIEW to "
2299         "ESPLUSPLAYER_RSC_ALLOC_EXCLUSIVE_NO_EXPLICIT");
2300     policy = ESPLUSPLAYER_RSC_ALLOC_EXCLUSIVE_NO_EXPLICIT;
2301   }
2302   auto ret = cast_(handle)->SetResourceAllocatePolicy(
2303       static_cast<RscAllocPolicy>(policy));
2304   return convert_return_type_(ret);
2305 }
2306
2307 int esplusplayer_set_audio_preloading(esplusplayer_handle handle) {
2308   LOG_ENTER_P(cast_(handle))
2309   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2310   return convert_return_type_(cast_(handle)->SetAudioPreloading());
2311 }
2312
2313 int esplusplayer_set_video_frame_dropped_cb(
2314     esplusplayer_handle handle,
2315     esplusplayer_video_frame_dropped_cb video_frame_dropped_cb,
2316     void* userdata) {
2317   LOG_ENTER_P(cast_(handle))
2318   listener_bridge* listener = nullptr;
2319   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
2320     LOG_ERROR("ESPlayer or Listener object is nil.");
2321     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2322   }
2323
2324   listener->video_frame_dropped_cb_ = video_frame_dropped_cb;
2325   listener->video_frame_dropped_cb_userdata_ = userdata;
2326   return convert_return_type_(true);
2327 }
2328
2329 int esplusplayer_set_decoder_input_buffer_time_cb(
2330     esplusplayer_handle handle,
2331     esplusplayer_decoder_buffer_time_cb decoder_buffer_time_cb,
2332     void* userdata) {
2333   LOG_ENTER_P(cast_(handle))
2334   listener_bridge* listener = nullptr;
2335   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
2336     LOG_ERROR("ESPlayer or Listener object is nil.");
2337     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2338   }
2339
2340   listener->decoder_input_buffer_time_cb_ = decoder_buffer_time_cb;
2341   listener->decoder_input_buffer_time_cb_userdata_ = userdata;
2342   return convert_return_type_(true);
2343 }
2344
2345 int esplusplayer_set_decoder_output_buffer_time_cb(
2346     esplusplayer_handle handle,
2347     esplusplayer_decoder_buffer_time_cb decoder_buffer_time_cb,
2348     void* userdata) {
2349   LOG_ENTER_P(cast_(handle))
2350   listener_bridge* listener = nullptr;
2351   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
2352     LOG_ERROR("ESPlayer or Listener object is nil.");
2353     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2354   }
2355
2356   listener->decoder_output_buffer_time_cb_ = decoder_buffer_time_cb;
2357   listener->decoder_output_buffer_time_cb_userdata_ = userdata;
2358   return convert_return_type_(true);
2359 }
2360
2361 int esplusplayer_set_video_scan_type(esplusplayer_handle handle,
2362                                      esplusplayer_video_scan_type type) {
2363   LOG_ENTER_P(cast_(handle))
2364   if (is_null_(handle) || is_null_(listener_cast_(handle)))
2365     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2366   LOG_INFO("scan type: %d", static_cast<int>(type));
2367
2368   auto ret =
2369       cast_(handle)->SetVideoScanType(static_cast<PlayerVideoScanType>(type));
2370   return convert_return_type_(ret);
2371 }
2372
2373 int esplusplayer_get_decoding_time(esplusplayer_handle handle,
2374                                    esplusplayer_stream_type type,
2375                                    int32_t* time_in_milliseconds) {
2376   if (is_null_(handle) || is_null_(time_in_milliseconds))
2377     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2378
2379   StreamType stream_type = static_cast<StreamType>(type);
2380
2381   auto ret = cast_(handle)->GetDecodingTime(stream_type, time_in_milliseconds);
2382   LOG_INFO_I("decoding_time = %d", *time_in_milliseconds);
2383   return convert_return_type_(ret);
2384 }
2385 int esplusplayer_set_timeunit_type(esplusplayer_handle handle,
2386                                    esplusplayer_time_unit_type type) {
2387   LOG_ENTER_P(cast_(handle))
2388   if (is_null_(handle) || is_null_(listener_cast_(handle)))
2389     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2390   LOG_INFO("time unit type: %d", static_cast<int>(type));
2391   auto ret =
2392       cast_(handle)->SetTimeUnitType(static_cast<PlayerTimeUnitType>(type));
2393   return convert_return_type_(ret);
2394 }
2395
2396 int esplusplayer_set_video_stream_rotation_info(
2397     esplusplayer_handle handle,
2398     const esplusplayer_video_stream_rotation_type rotation) {
2399   LOG_ENTER_P(cast_(handle))
2400   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2401   LOG_INFO_P(cast_(handle), "video stream rotation type : %d",
2402              static_cast<int>(rotation));
2403   return convert_return_type_(cast_(handle)->SetVideoStreamRotationInfo(
2404       static_cast<VideoRotation>(rotation)));
2405 }
2406
2407 int esplusplayer_get_video_stream_rotation_info(
2408     esplusplayer_handle handle,
2409     esplusplayer_video_stream_rotation_type* rotation) {
2410   LOG_ENTER_P(cast_(handle))
2411   if (is_null_(handle) || is_null_(rotation))
2412     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2413   return convert_return_type_(cast_(handle)->GetVideoStreamRotationInfo(
2414       reinterpret_cast<VideoRotation*>(rotation)));
2415 }
2416
2417 int esplusplayer_set_simple_mix_out_buffer_level(
2418     esplusplayer_handle handle,
2419     esplusplayer_simple_mix_out_buffer_level level) {
2420   LOG_ENTER_P(cast_(handle))
2421   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
2422   LOG_INFO_P(cast_(handle), "buffer level : %d", static_cast<int>((level)));
2423
2424   return convert_return_type_(cast_(handle)->SetSimpleMixOutBufferLevel(
2425       static_cast<PlayerSimpleMixOutBufferLevel>(level)));
2426 }