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