1b95cb9c2173c585db8136feab88e9bc5d0382a3
[platform/core/multimedia/esplusplayer.git] / src / esplusplayer / src / esplusplayer_capi.cpp
1 #include "esplusplayer_capi/esplusplayer_capi.h"
2
3 #include "plusplayer/esplusplayer.h"
4
5 using plusplayer::EsPlusPlayer;
6 using plusplayer::Geometry;
7
8 #include <inttypes.h>
9 #include <tbm_surface.h>
10
11 #include <functional>
12 #include <iostream>
13 #include <mutex>
14 #include <unordered_map>
15
16 #include "core/utils/plusplayer_log.h"
17 #include "esplayer/decoded_pkt_list.h"
18 #include "esplusplayer_capi/esplusplayer_internal.h"
19 #include "plusplayer/drm.h"
20 #include "plusplayer/elementary_stream.h"
21 #include "plusplayer/espacket.h"
22 #include "plusplayer/esplusplayer.h"
23 #include "plusplayer/track.h"
24 #include "plusplayer/types/buffer.h"
25 #include "plusplayer/types/display.h"
26 #include "plusplayer/types/error.h"
27 #include "plusplayer/types/stream.h"
28
29 using plusplayer::AudioMimeType;
30 using plusplayer::AudioStream;
31 using plusplayer::AudioStreamPtr;
32 using plusplayer::BufferStatus;
33 using plusplayer::CropArea;
34 using plusplayer::DecodedPacketManagerInterface;
35 using plusplayer::DisplayMode;
36 using plusplayer::DisplayRotation;
37 using plusplayer::DisplayType;
38 using plusplayer::ErrorType;
39 using plusplayer::EsPacket;
40 using plusplayer::EsPacketPtr;
41 using plusplayer::EsState;
42 using plusplayer::MatroskaColor;
43 using plusplayer::PlayerAdaptiveInfo;
44 using plusplayer::PlayerLowLatencyMode;
45 using plusplayer::StreamType;
46 using plusplayer::SubmitDataType;
47 using plusplayer::Track;
48 using plusplayer::TrackType;
49 using plusplayer::VideoMimeType;
50 using plusplayer::VideoStream;
51 using plusplayer::VideoStreamPtr;
52 using plusplayer::drm::EsPlayerEncryptedInfo;
53 using plusplayer::drm::Type;
54 using plusplayer::PlayerAudioCodecType;
55 using plusplayer::PlayerVideoCodecType;
56
57 namespace util {
58 const std::unordered_map<esplusplayer_error_type, std::string> kErrorStringMap =
59     {{ESPLUSPLAYER_ERROR_TYPE_NONE, "ESPLUSPLAYER_ERROR_TYPE_NONE"},
60      {ESPLUSPLAYER_ERROR_TYPE_OUT_OF_MEMORY,
61       "ESPLUSPLAYER_ERROR_TYPE_OUT_OF_MEMORY"},
62      {ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER,
63       "ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER"},
64      {ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION,
65       "ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION"},
66      {ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE,
67       "ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE"},
68      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_AUDIO_CODEC,
69       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_AUDIO_CODEC"},
70      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_VIDEO_CODEC,
71       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_VIDEO_CODEC"},
72      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FILE,
73       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FILE"},
74      {ESPLUSPLAYER_ERROR_TYPE_CONNECTION_FAILED,
75       "ESPLUSPLAYER_ERROR_TYPE_CONNECTION_FAILED"},
76      {ESPLUSPLAYER_ERROR_TYPE_DRM_EXPIRED,
77       "ESPLUSPLAYER_ERROR_TYPE_DRM_EXPIRED"},
78      {ESPLUSPLAYER_ERROR_TYPE_DRM_NO_LICENSE,
79       "ESPLUSPLAYER_ERROR_TYPE_DRM_NO_LICENSE"},
80      {ESPLUSPLAYER_ERROR_TYPE_DRM_FUTURE_USE,
81       "ESPLUSPLAYER_ERROR_TYPE_DRM_FUTURE_USE"},
82      {ESPLUSPLAYER_ERROR_TYPE_NOT_PERMITTED,
83       "ESPLUSPLAYER_ERROR_TYPE_NOT_PERMITTED"},
84      {ESPLUSPLAYER_ERROR_TYPE_DRM_DECRYPTION_FAILED,
85       "ESPLUSPLAYER_ERROR_TYPE_DRM_DECRYPTION_FAILED"},
86      {ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FORMAT,
87       "ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FORMAT"},
88      {ESPLUSPLAYER_ERROR_TYPE_UNKNOWN, "ESPLUSPLAYER_ERROR_TYPE_UNKNOWN"}};
89
90 const std::string kUnhandledErrorString = "Unhandled Error Type";
91 static const std::string& ConvertErrorTypeToString(
92     esplusplayer_error_type type) {
93   return kErrorStringMap.count(type) > 0 ? kErrorStringMap.at(type)
94                                          : kUnhandledErrorString;
95 }
96 }  // namespace util
97
98 struct EsPlusPlayerPriv;
99
100 class listener_bridge : public plusplayer::EsEventListener {
101  public:
102   listener_bridge() { LOG_ENTER }
103   ~listener_bridge() { LOG_ENTER }
104
105   void ResetPacketList() {
106     if (decoded_pkt_mgr_) decoded_pkt_mgr_->Clear();
107   }
108
109   void ResetMultiSeekControl() {
110     std::unique_lock<std::mutex> lock(multi_seek_control.lock);
111     multi_seek_control.is_offset_valid = false;
112     multi_seek_control.offset = 0;
113   }
114
115   void Reset() {
116     LOG_ENTER
117     ResetPacketList();
118     ResetMultiSeekControl();
119     LOG_LEAVE
120   }
121
122   esplusplayer_error_type ConvertErrorCode(const ErrorType& error_code) {
123     esplusplayer_error_type type = ESPLUSPLAYER_ERROR_TYPE_NONE;
124     switch (error_code) {
125       case ErrorType::kOutOfMemory:
126         type = ESPLUSPLAYER_ERROR_TYPE_OUT_OF_MEMORY;
127         break;
128       case ErrorType::kInvalidParameter:
129         type = ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
130         break;
131       case ErrorType::kInvalidOperation:
132         type = ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
133         break;
134       case ErrorType::kInvalidState:
135         type = ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE;
136         break;
137       case ErrorType::kNotSupportedAudioCodec:
138         type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_AUDIO_CODEC;
139         break;
140       case ErrorType::kNotSupportedVideoCodec:
141         type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_VIDEO_CODEC;
142         break;
143       case ErrorType::kNotSupportedFile:
144         type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FILE;
145         break;
146       case ErrorType::kConnectionFailed:
147         type = ESPLUSPLAYER_ERROR_TYPE_CONNECTION_FAILED;
148         break;
149       case ErrorType::kDrmExpired:
150         type = ESPLUSPLAYER_ERROR_TYPE_DRM_EXPIRED;
151         break;
152       case ErrorType::kDrmNoLicense:
153         type = ESPLUSPLAYER_ERROR_TYPE_DRM_NO_LICENSE;
154         break;
155       case ErrorType::kDrmFutureUse:
156         type = ESPLUSPLAYER_ERROR_TYPE_DRM_FUTURE_USE;
157         break;
158       case ErrorType::kDrmNotPermitted:
159         type = ESPLUSPLAYER_ERROR_TYPE_NOT_PERMITTED;
160         break;
161       case ErrorType::kDrmInfo:
162         type = ESPLUSPLAYER_ERROR_TYPE_DRM_DECRYPTION_FAILED;
163         break;
164       case ErrorType::kNotSupportedFormat:
165         type = ESPLUSPLAYER_ERROR_TYPE_NOT_SUPPORTED_FORMAT;
166         break;
167       default:
168         LOG_ERROR("not defined error %x", static_cast<int>(error_code));
169         type = ESPLUSPLAYER_ERROR_TYPE_UNKNOWN;
170         break;
171     }
172     return type;
173   }
174
175   virtual void OnError(const ErrorType& error_code, UserData userdata) {
176     LOG_ENTER
177     LOG_INFO("error code : %x", static_cast<int>(error_code));
178     if (this->error_cb_)
179       this->error_cb_(ConvertErrorCode(error_code), error_cb_userdata_);
180   }
181
182   virtual void OnBufferStatus(const StreamType& type,
183                               const BufferStatus& status,
184                               const uint64_t byte_size,
185                               const uint64_t time_size, UserData userdata) {
186     // LOG_ENTER
187     // LOG_INFO("stream type : %d, buffer status : %d", static_cast<int>(type),
188     //          static_cast<int>(status));
189
190     if (this->buffer_status_cb_)
191       this->buffer_status_cb_(static_cast<esplusplayer_stream_type>(type),
192                               static_cast<esplusplayer_buffer_status>(status),
193                               buffer_status_cb_userdata_);
194     if (this->buffer_byte_status_cb_)
195       this->buffer_byte_status_cb_(
196           static_cast<esplusplayer_stream_type>(type),
197           static_cast<esplusplayer_buffer_status>(status), byte_size,
198           buffer_byte_status_cb_userdata_);
199     if (this->buffer_time_status_cb_)
200       this->buffer_time_status_cb_(
201           static_cast<esplusplayer_stream_type>(type),
202           static_cast<esplusplayer_buffer_status>(status), time_size,
203           buffer_time_status_cb_userdata_);
204   }
205
206   virtual void OnResourceConflicted(UserData userdata) {
207     LOG_ENTER
208     this->Reset();
209     if (this->resource_conflicted_cb_)
210       this->resource_conflicted_cb_(resource_conflicted_cb_userdata_);
211   }
212
213   virtual void OnEos(UserData userdata) {
214     LOG_ENTER
215     if (this->eos_cb_) this->eos_cb_(eos_cb_userdata_);
216   }
217
218   virtual void OnPrepareDone(bool result, UserData userdata) {
219     LOG_ENTER
220     LOG_INFO("prepare done. result : %s", result ? "true" : "false");
221     if (this->prepare_async_done_cb_)
222       this->prepare_async_done_cb_(result, prepare_async_done_cb_userdata_);
223   }
224
225   virtual void OnReadyToPrepare(const StreamType& type, UserData userdata) {
226     LOG_ENTER
227     LOG_INFO("stream type : %d", static_cast<int>(type));
228     if (this->ready_to_prepare_cb_)
229       this->ready_to_prepare_cb_(static_cast<esplusplayer_stream_type>(type),
230                                  ready_to_prepare_cb_userdata_);
231   }
232
233   virtual void OnSeekDone(UserData userdata) {
234     LOG_ENTER
235     if (this->seek_done_cb_) this->seek_done_cb_(seek_done_cb_userdata_);
236   }
237
238   virtual void OnReadyToSeek(const StreamType& type, const uint64_t offset,
239                              UserData userdata) {
240     LOG_ENTER
241     LOG_INFO("offset : %" PRIu64, offset);
242     std::unique_lock<std::mutex> lock(this->multi_seek_control.lock);
243     if (this->multi_seek_control.is_offset_valid == false ||
244         this->multi_seek_control.offset != offset) {
245       LOG_ERROR("Invalid offset:%" PRIu64, this->multi_seek_control.offset);
246       return;
247     }
248     if (this->ready_to_seek_cb_)
249       this->ready_to_seek_cb_(static_cast<esplusplayer_stream_type>(type),
250                               offset, ready_to_seek_cb_userdata_);
251   }
252
253   void SetDecodedPacketManager(
254       std::shared_ptr<DecodedPacketManagerInterface>& mgr) {
255     decoded_pkt_mgr_ = mgr;
256   }
257
258   virtual void OnMediaPacketGetTbmBufPtr(void** ptr, bool is_scale_change) {
259     // get one free point in current tbm list, send to trackrender, if can't
260     // find, set null
261     void* ptr1 = nullptr;
262     if (decoded_pkt_mgr_)
263       decoded_pkt_mgr_->GetFreeTbmSurface(&ptr1, is_scale_change);
264     *ptr = ptr1;
265   }
266
267   virtual void OnMediaPacketVideoDecoded(
268       const plusplayer::DecodedVideoPacket& packet) {
269     if (this->media_packet_video_decoded_cb_ == nullptr) return;
270     if (!decoded_pkt_mgr_) return;
271
272     auto* _pkt = new esplusplayer_decoded_video_packet();
273     _pkt->pts = packet.pts;
274     _pkt->duration = packet.duration;
275     _pkt->surface_data = static_cast<void*>(packet.surface_data);
276     _pkt->private_data = packet.buffer_addr;
277
278     if (decoded_pkt_mgr_->TryToAdd(_pkt)) {
279       this->media_packet_video_decoded_cb_(
280           _pkt, media_packet_video_decoded_cb_userdata_);
281     } else {
282       LOG_ERROR("Too many buffers are not released. packet(%p) will be drop.",
283                 _pkt);
284     }
285   }
286
287   virtual void OnClosedCaptionData(std::unique_ptr<char[]> data, const int size,
288                                    UserData userdata) {
289     LOG_ENTER
290     if (this->closed_caption_cb_) {
291       this->closed_caption_cb_(data.get(), size, closed_caption_cb_userdata_);
292     }
293   }
294
295   virtual void OnFlushDone(UserData userdata) {
296     LOG_ENTER
297     if (this->flush_done_cb_) this->flush_done_cb_(flush_done_cb_userdata_);
298   }
299
300   virtual void OnEvent(const plusplayer::EventType& event,
301                        const plusplayer::EventMsg& msg_data,
302                        UserData userdata) {
303     LOG_ENTER
304     esplusplayer_event_msg event_msg;
305     event_msg.data = const_cast<char*>(msg_data.data.c_str());
306     event_msg.len = msg_data.len;
307     if (this->event_cb_)
308       this->event_cb_(static_cast<esplusplayer_event_type>(event), event_msg,
309                       event_cb_userdata_);
310   }
311
312   virtual void OnFirstDecodingDone(UserData userdata) {
313     LOG_ENTER
314     if (this->first_video_decoding_done_cb_) {
315       this->first_video_decoding_done_cb_(
316           first_video_decoding_done_cb_userdata_);
317     }
318   }
319
320  private:
321   static void DecodedPacketDeleter(esplusplayer_decoded_video_packet* packet) {
322     if (packet->surface_data != nullptr) {
323       tbm_surface_destroy(static_cast<tbm_surface_h>(packet->surface_data));
324       packet->surface_data = NULL;
325     }
326     delete packet;
327   }
328
329  private:
330   esplusplayer_error_cb error_cb_ = nullptr;
331   void* error_cb_userdata_ = nullptr;
332   esplusplayer_buffer_status_cb buffer_status_cb_ = nullptr;
333   void* buffer_status_cb_userdata_ = nullptr;
334   esplusplayer_buffer_byte_status_cb buffer_byte_status_cb_ = nullptr;
335   void* buffer_byte_status_cb_userdata_ = nullptr;
336   esplusplayer_buffer_time_status_cb buffer_time_status_cb_ = nullptr;
337   void* buffer_time_status_cb_userdata_ = nullptr;
338   esplusplayer_resource_conflicted_cb resource_conflicted_cb_ = nullptr;
339   void* resource_conflicted_cb_userdata_ = nullptr;
340   esplusplayer_eos_cb eos_cb_ = nullptr;
341   void* eos_cb_userdata_ = nullptr;
342   esplusplayer_ready_to_prepare_cb ready_to_prepare_cb_ = nullptr;
343   void* ready_to_prepare_cb_userdata_ = nullptr;
344   esplusplayer_prepare_async_done_cb prepare_async_done_cb_ = nullptr;
345   void* prepare_async_done_cb_userdata_ = nullptr;
346   esplusplayer_seek_done_cb seek_done_cb_ = nullptr;
347   void* seek_done_cb_userdata_ = nullptr;
348   esplusplayer_ready_to_seek_cb ready_to_seek_cb_ = nullptr;
349   void* ready_to_seek_cb_userdata_ = nullptr;
350   esplusplayer_media_packet_video_decoded_cb media_packet_video_decoded_cb_ =
351       nullptr;
352   void* media_packet_video_decoded_cb_userdata_ = nullptr;
353   esplusplayer_closed_caption_cb closed_caption_cb_ = nullptr;
354   void* closed_caption_cb_userdata_ = nullptr;
355   esplusplayer_flush_done_cb flush_done_cb_ = nullptr;
356   void* flush_done_cb_userdata_ = nullptr;
357   esplusplayer_event_cb event_cb_ = nullptr;
358   void* event_cb_userdata_ = nullptr;
359   esplusplayer_first_video_decoding_done_cb first_video_decoding_done_cb_ =
360       nullptr;
361   void* first_video_decoding_done_cb_userdata_ = nullptr;
362
363   std::shared_ptr<DecodedPacketManagerInterface> decoded_pkt_mgr_;
364
365   struct MultiSeekControl {
366     std::mutex lock;
367     bool is_offset_valid = false;
368     uint64_t offset = 0;
369   };
370   friend void update_ready_to_seek_callback(
371       esplusplayer_handle pp, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
372       void* userdata);
373   friend void update_ready_to_seek_offset(esplusplayer_handle pp,
374                                           const uint64_t offset);
375   MultiSeekControl multi_seek_control;
376
377   friend int esplusplayer_set_error_cb(esplusplayer_handle pp,
378                                        esplusplayer_error_cb error_cb,
379                                        void* userdata);
380   friend int esplusplayer_set_buffer_status_cb(
381       esplusplayer_handle pp, esplusplayer_buffer_status_cb buffer_status_cb,
382       void* userdata);
383   friend int esplusplayer_set_buffer_byte_status_cb(
384       esplusplayer_handle pp,
385       esplusplayer_buffer_byte_status_cb buffer_status_cb, void* userdata);
386   friend int esplusplayer_set_buffer_time_status_cb(
387       esplusplayer_handle pp,
388       esplusplayer_buffer_time_status_cb buffer_status_cb, void* userdata);
389   friend int esplusplayer_set_resource_conflicted_cb(
390       esplusplayer_handle pp,
391       esplusplayer_resource_conflicted_cb resource_conflicted_cb,
392       void* userdata);
393   friend int esplusplayer_set_eos_cb(esplusplayer_handle pp,
394                                      esplusplayer_eos_cb eos_cb,
395                                      void* userdata);
396   friend int esplusplayer_set_ready_to_prepare_cb(
397       esplusplayer_handle pp,
398       esplusplayer_ready_to_prepare_cb ready_to_prepare_cb, void* userdata);
399   friend int esplusplayer_set_prepare_async_done_cb(
400       esplusplayer_handle pp,
401       esplusplayer_prepare_async_done_cb prepare_async_done_cb, void* userdata);
402   friend int esplusplayer_set_seek_done_cb(
403       esplusplayer_handle pp, esplusplayer_seek_done_cb seek_done_cb,
404       void* userdata);
405   friend int esplusplayer_set_ready_to_seek_cb(
406       esplusplayer_handle pp, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
407       void* userdata);
408   friend int esplusplayer_set_media_packet_video_decoded_cb(
409       esplusplayer_handle pp,
410       esplusplayer_media_packet_video_decoded_cb media_packet_video_decoded_cb,
411       void* userdata);
412   friend int esplusplayer_set_closed_caption_cb(
413       esplusplayer_handle handle,
414       esplusplayer_closed_caption_cb closed_caption_cb, void* userdata);
415   friend int esplusplayer_set_flush_done_cb(
416       esplusplayer_handle pp, esplusplayer_flush_done_cb flush_done_cb,
417       void* userdata);
418   friend int esplusplayer_set_event_cb(esplusplayer_handle pp,
419                                        esplusplayer_event_cb event_cb,
420                                        void* userdata);
421   friend int esplusplayer_set_first_video_decoding_done_cb(
422       esplusplayer_handle handle,
423       esplusplayer_first_video_decoding_done_cb first_video_decoding_done_cb,
424       void* userdata);
425 };
426
427 struct EsPlusPlayerPriv {
428   std::unique_ptr<EsPlusPlayer> player;
429   std::unique_ptr<listener_bridge> listener{new listener_bridge()};
430   std::shared_ptr<DecodedPacketManagerInterface> decoded_pkt_mgr;
431
432   friend EsPlusPlayerPriv* EsPrivCreate();
433   friend void EsPrivDestroy(EsPlusPlayerPriv*& instance);
434
435  private:
436   EsPlusPlayerPriv() {}
437   ~EsPlusPlayerPriv() {}
438 };
439
440 EsPlusPlayerPriv* EsPrivCreate() {
441   EsPlusPlayerPriv* instance = new EsPlusPlayerPriv();
442   instance->player = EsPlusPlayer::Create();
443   instance->player->RegisterListener(instance->listener.get(),
444                                      instance->player.get());
445   return instance;
446 }
447
448 void EsPrivDestroy(EsPlusPlayerPriv*& instance) {
449   if (instance) delete instance;
450   instance = nullptr;
451 }
452
453 inline bool is_null_(void* object) { return object == nullptr; }
454
455 inline EsPlusPlayer* cast_(esplusplayer_handle pp) {
456   auto priv = static_cast<EsPlusPlayerPriv*>(pp);
457   return priv ? priv->player.get() : nullptr;
458 }
459
460 inline listener_bridge* listener_cast_(esplusplayer_handle pp) {
461   auto priv = static_cast<EsPlusPlayerPriv*>(pp);
462   return priv->listener.get();
463 }
464
465 void update_ready_to_seek_callback(
466     esplusplayer_handle handle, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
467     void* userdata) {
468   LOG_ENTER
469   listener_bridge* listener = nullptr;
470   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
471     LOG_ERROR("ESPlayer or Listener object is nil.");
472     return;
473   }
474   std::unique_lock<std::mutex> lock(listener->multi_seek_control.lock);
475   listener->ready_to_seek_cb_ = ready_to_seek_cb;
476   listener->ready_to_seek_cb_userdata_ = userdata;
477   listener->multi_seek_control.is_offset_valid = false;
478 }
479 void update_ready_to_seek_offset(esplusplayer_handle handle,
480                                  const uint64_t offset) {
481   LOG_ENTER
482   listener_bridge* listener = nullptr;
483   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
484     LOG_ERROR("ESPlayer or Listener object is nil.");
485     return;
486   }
487   std::unique_lock<std::mutex> lock(listener->multi_seek_control.lock);
488   listener->multi_seek_control.offset = offset;
489   listener->multi_seek_control.is_offset_valid = true;
490 }
491
492 inline void convert_matroska_color_info_(
493     const esplusplayer_matroska_color* from, MatroskaColor* to) {
494   to->matrix_coefficients = from->matrix_coefficients;
495   to->bits_per_channel = from->bits_per_channel;
496   to->chroma_subsampling_horizontal = from->chroma_subsampling_horizontal;
497   to->chroma_subsampling_vertical = from->chroma_subsampling_vertical;
498   to->cb_subsampling_horizontal = from->cb_subsampling_horizontal;
499   to->cb_subsampling_vertical = from->cb_subsampling_vertical;
500   to->chroma_siting_horizontal = from->chroma_siting_horizontal;
501   to->chroma_siting_vertical = from->chroma_siting_vertical;
502   to->range = from->range;
503   to->transfer_characteristics = from->transfer_characteristics;
504   to->primaries = from->primaries;
505   to->max_cll = from->max_cll;
506   to->max_fall = from->max_fall;
507   to->is_hdr_10p = from->isHDR10p;
508   to->metadata.primary_r_chromaticity_x =
509       from->metadata.primary_r_chromaticity_x;
510   to->metadata.primary_r_chromaticity_y =
511       from->metadata.primary_r_chromaticity_y;
512   to->metadata.primary_g_chromaticity_x =
513       from->metadata.primary_g_chromaticity_x;
514   to->metadata.primary_g_chromaticity_y =
515       from->metadata.primary_g_chromaticity_y;
516   to->metadata.primary_b_chromaticity_x =
517       from->metadata.primary_b_chromaticity_x;
518   to->metadata.primary_b_chromaticity_y =
519       from->metadata.primary_b_chromaticity_y;
520   to->metadata.white_point_chromaticity_x =
521       from->metadata.white_point_chromaticity_x;
522   to->metadata.white_point_chromaticity_y =
523       from->metadata.white_point_chromaticity_y;
524   to->metadata.luminance_max = from->metadata.luminance_max;
525   to->metadata.luminance_min = from->metadata.luminance_min;
526 }
527
528 inline EsPacketPtr convert_espacket_(esplusplayer_es_packet* from) {
529   std::shared_ptr<char> buffer = nullptr;
530   std::shared_ptr<char> hdr10p_metadata = nullptr;
531   if (from->buffer_size != 0 && from->buffer) {
532     buffer = std::shared_ptr<char>(new char[from->buffer_size],
533                                    std::default_delete<char[]>());
534     memcpy(buffer.get(), from->buffer, from->buffer_size);
535   }
536   if (from->hdr10p_metadata_size != 0 && from->hdr10p_metadata) {
537     hdr10p_metadata = std::shared_ptr<char>(
538         new char[from->hdr10p_metadata_size], std::default_delete<char[]>());
539     memcpy(hdr10p_metadata.get(), from->hdr10p_metadata,
540            from->hdr10p_metadata_size);
541   }
542   auto espacket = EsPacket::Create(static_cast<StreamType>(from->type), buffer,
543                                    from->buffer_size, from->pts, from->duration,
544                                    from->hdr10p_metadata_size, hdr10p_metadata);
545
546   if (from->matroska_color_info != nullptr) {
547     MatroskaColor color_info;
548     convert_matroska_color_info_(from->matroska_color_info, &color_info);
549     bool ret = espacket->SetMatroskaColorInfo(color_info);
550     if (ret == false) return nullptr;
551   }
552   return std::move(espacket);
553 }
554
555 using EncryptedInfoPtr =
556     std::unique_ptr<EsPlayerEncryptedInfo,
557                     std::function<void(EsPlayerEncryptedInfo*)>>;
558 inline EncryptedInfoPtr convert_es_drm_info_(esplusplayer_drm_info* from) {
559   auto custom_deleter = [](EsPlayerEncryptedInfo* drm_info) {
560     if (drm_info == nullptr) return;
561     if (drm_info->sub_data != nullptr) {
562       delete reinterpret_cast<plusplayer::drm::DrmbEsFragmentedMp4Data*>(
563           drm_info->sub_data);
564       drm_info->sub_data = nullptr;
565     }
566     delete drm_info;
567   };
568
569   if (from == nullptr) return EncryptedInfoPtr(nullptr, custom_deleter);
570
571   EncryptedInfoPtr drm_info =
572       EncryptedInfoPtr(new EsPlayerEncryptedInfo(), custom_deleter);
573
574   drm_info->handle = from->handle;
575   drm_info->algorithm =
576       static_cast<plusplayer::drm::DrmbEsCipherAlgorithm>(from->algorithm);
577   drm_info->format =
578       static_cast<plusplayer::drm::DrmbEsMediaFormat>(from->format);
579   drm_info->phase =
580       static_cast<plusplayer::drm::DrmbEsCipherPhase>(from->phase);
581
582   // kid
583   if (from->kid && from->kid_length > 0) {
584     drm_info->kid = std::move(
585         std::vector<unsigned char>(from->kid, from->kid + from->kid_length));
586   }
587
588   // initialization_vector
589   if (from->iv && from->iv_length > 0) {
590     drm_info->initialization_vector = std::move(
591         std::vector<unsigned char>(from->iv, from->iv + from->iv_length));
592   }
593
594   // sub_data
595   auto* from_sub_data =
596       reinterpret_cast<esplusplayer_drmb_es_fmp4_data*>(from->sub_data);
597   if (from_sub_data && from_sub_data->subsample_count > 0) {
598     drm_info->sub_data = new plusplayer::drm::DrmbEsFragmentedMp4Data;
599     auto* sub_data =
600         reinterpret_cast<plusplayer::drm::DrmbEsFragmentedMp4Data*>(
601             drm_info->sub_data);
602     for (uint32_t i = 0; i < from_sub_data->subsample_count; i++) {
603       auto& subsample_info = from_sub_data->subsample_infos[i];
604       sub_data->sub_sample_info_vector.emplace_back(
605           subsample_info.bytes_of_clear_data,
606           subsample_info.bytes_of_encrypted_data);
607     }
608   }
609
610   // split_offsets
611   if (from->split_offsets) {
612     const std::size_t kSplitOffsetMaxSize = 15 * sizeof(int);
613     std::memcpy(drm_info->split_offsets.data(), from->split_offsets,
614                 kSplitOffsetMaxSize);
615   }
616
617   drm_info->use_out_buffer = from->use_out_buffer;
618   drm_info->use_pattern = from->use_pattern;
619   drm_info->crypt_byte_block = from->crypt_byte_block;
620   drm_info->skip_byte_block = from->skip_byte_block;
621
622   return std::move(drm_info);
623 }
624
625 inline AudioStreamPtr convert_stream_ptr_(
626     esplusplayer_audio_stream_info* from) {
627   LOG_INFO("mime type : %d", static_cast<int>(from->mime_type));
628   LOG_INFO("from->bitrate : %d", from->bitrate);
629   LOG_INFO("from->channels : %d", from->channels);
630   LOG_INFO("from->sample_rate : %d", from->sample_rate);
631   LOG_INFO("from->codec_data_length : %d", from->codec_data_length);
632
633   auto stream = AudioStream::Create();
634   std::shared_ptr<char> codec_data = nullptr;
635
636   if (from->codec_data_length != 0) {
637     codec_data = std::shared_ptr<char>(new char[from->codec_data_length],
638                                        std::default_delete<char[]>());
639     memcpy(codec_data.get(), from->codec_data, from->codec_data_length);
640   }
641
642   stream->SetCodecData(codec_data, from->codec_data_length);
643   stream->SetMimeType(static_cast<plusplayer::AudioMimeType>(from->mime_type));
644   stream->SetBitrate(from->bitrate);
645   stream->SetChannels(from->channels);
646   stream->SetSamplerate(from->sample_rate);
647
648   return std::move(stream);
649 }
650
651 inline int convert_return_type_(bool ret) {
652   return ret ? ESPLUSPLAYER_ERROR_TYPE_NONE
653              : ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
654 }
655
656 inline VideoStreamPtr convert_stream_ptr_(
657     esplusplayer_video_stream_info* from) {
658   LOG_INFO("mime type : %u", static_cast<int>(from->mime_type));
659   LOG_INFO("from->width : %u", from->width);
660   LOG_INFO("from->height : %u", from->height);
661   LOG_INFO("from->max_width : %u", from->max_width);
662   LOG_INFO("from->max_height : %u", from->max_height);
663   LOG_INFO("from->framerate_num : %u", from->framerate_num);
664   LOG_INFO("from->framerate_den : %u", from->framerate_den);
665   LOG_INFO("from->codec_data_length : %u", from->codec_data_length);
666
667   auto stream = VideoStream::Create();
668   std::shared_ptr<char> codec_data = nullptr;
669
670   if (from->codec_data_length != 0) {
671     codec_data = std::shared_ptr<char>(new char[from->codec_data_length],
672                                        std::default_delete<char[]>());
673     memcpy(codec_data.get(), from->codec_data, from->codec_data_length);
674   }
675
676   stream->SetCodecData(codec_data, from->codec_data_length);
677   stream->SetMimeType(static_cast<plusplayer::VideoMimeType>(from->mime_type));
678   stream->SetWidth(from->width);
679   stream->SetHeight(from->height);
680   stream->SetMaxWidth(from->max_width);
681   stream->SetMaxHeight(from->max_height);
682   stream->SetFramerate(from->framerate_num, from->framerate_den);
683
684   return std::move(stream);
685 }
686
687 esplusplayer_handle esplusplayer_create() {
688   esplusplayer_handle player = static_cast<esplusplayer_handle>(EsPrivCreate());
689   LOG_INFO("capi handle > [%p], cpp handle > [%p]", player, cast_(player));
690   return player;
691 }
692
693 int esplusplayer_open(esplusplayer_handle handle) {
694   LOG_ENTER_P(cast_(handle))
695   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
696   return convert_return_type_(cast_(handle)->Open());
697 }
698
699 int esplusplayer_close(esplusplayer_handle handle) {
700   LOG_ENTER_P(cast_(handle))
701   listener_bridge* listener = nullptr;
702   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
703     LOG_ERROR("ESPlayer or Listener object is nil.");
704     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
705   }
706
707   bool ret = cast_(handle)->Close();
708   listener->Reset();
709   return convert_return_type_(ret);
710 }
711
712 int esplusplayer_destroy(esplusplayer_handle handle) {
713   LOG_ENTER_P(cast_(handle))
714   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
715
716   if (ESPLUSPLAYER_STATE_NONE != esplusplayer_get_state(handle))
717     return ESPLUSPLAYER_ERROR_TYPE_INVALID_STATE;
718
719   auto priv = static_cast<EsPlusPlayerPriv*>(handle);
720   EsPrivDestroy(priv);
721
722   return ESPLUSPLAYER_ERROR_TYPE_NONE;
723 }
724
725 int esplusplayer_deactivate(esplusplayer_handle handle,
726                             esplusplayer_stream_type type) {
727   LOG_ENTER_P(cast_(handle))
728   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
729
730   return convert_return_type_(
731       cast_(handle)->Deactivate(static_cast<StreamType>(type)));
732 }
733
734 int esplusplayer_activate(esplusplayer_handle handle,
735                           esplusplayer_stream_type type) {
736   LOG_ENTER_P(cast_(handle))
737   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
738
739   return convert_return_type_(
740       cast_(handle)->Activate(static_cast<StreamType>(type)));
741 }
742
743 int esplusplayer_prepare_async(esplusplayer_handle handle) {
744   LOG_ENTER_P(cast_(handle))
745   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
746
747   return convert_return_type_(cast_(handle)->PrepareAsync());
748 }
749
750 int esplusplayer_start(esplusplayer_handle handle) {
751   LOG_ENTER_P(cast_(handle))
752   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
753
754   return convert_return_type_(cast_(handle)->Start());
755 }
756
757 int esplusplayer_stop(esplusplayer_handle handle) {
758   LOG_ENTER_P(cast_(handle))
759   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
760
761   return convert_return_type_(cast_(handle)->Stop());
762 }
763
764 int esplusplayer_pause(esplusplayer_handle handle) {
765   LOG_ENTER_P(cast_(handle))
766   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
767
768   return convert_return_type_(cast_(handle)->Pause());
769 }
770
771 int esplusplayer_resume(esplusplayer_handle handle) {
772   LOG_ENTER_P(cast_(handle))
773   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
774
775   return convert_return_type_(cast_(handle)->Resume());
776 }
777
778 int esplusplayer_set_playback_rate(esplusplayer_handle handle,
779                                    const double playback_rate,
780                                    const bool audio_mute) {
781   LOG_ENTER_P(cast_(handle))
782   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
783   LOG_INFO_P(cast_(handle), "playback rate : %lf, audio mute : %d",
784              playback_rate, audio_mute);
785   return convert_return_type_(
786       cast_(handle)->SetPlaybackRate(playback_rate, audio_mute));
787 }
788
789 int esplusplayer_seek(esplusplayer_handle handle, uint64_t time_ms) {
790   LOG_ENTER_P(cast_(handle))
791   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
792   LOG_INFO("[%p] > time : %" PRIu64, cast_(handle), time_ms);
793   update_ready_to_seek_offset(handle, time_ms);
794
795   return convert_return_type_(cast_(handle)->Seek(time_ms));
796 }
797
798 int esplusplayer_set_display(esplusplayer_handle handle,
799                              esplusplayer_display_type type, void* window) {
800   LOG_ENTER_P(cast_(handle))
801   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
802   if (type < ESPLUSPLAYER_DISPLAY_TYPE_NONE ||
803     type >= ESPLUSPLAYER_DISPLAY_TYPE_MAX) return ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
804   LOG_INFO_P(cast_(handle), "display type : %d, object : %p",
805              static_cast<int>(type), window);
806
807   return convert_return_type_(
808       cast_(handle)->SetDisplay(static_cast<DisplayType>(type), window));
809 }
810
811 int esplusplayer_set_ecore_display(esplusplayer_handle handle,
812                                    esplusplayer_display_type type, void* window,
813                                    int x, int y, int width, int height) {
814   LOG_ENTER_P(cast_(handle))
815   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
816   if (type < ESPLUSPLAYER_DISPLAY_TYPE_NONE ||
817     type >= ESPLUSPLAYER_DISPLAY_TYPE_MAX) return ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
818   LOG_INFO_P(cast_(handle), "display type : %d, object : %p",
819              static_cast<int>(type), window);
820
821   return convert_return_type_(cast_(handle)->SetDisplay(
822       static_cast<DisplayType>(type), window, x, y, width, height));
823 }
824
825 int esplusplayer_set_surface_display(esplusplayer_handle handle,
826                                      esplusplayer_display_type type,
827                                      unsigned int surface_id, int x, int y,
828                                      int width, int height) {
829   LOG_ENTER_P(cast_(handle))
830   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
831   if (type < ESPLUSPLAYER_DISPLAY_TYPE_NONE ||
832     type >= ESPLUSPLAYER_DISPLAY_TYPE_MAX) return ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
833   if (width <= 0 || height <= 0) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
834   LOG_INFO_P(cast_(handle), "display type : %d, object : %u",
835              static_cast<int>(type), surface_id);
836
837   return convert_return_type_(cast_(handle)->SetDisplay(
838       static_cast<DisplayType>(type), surface_id, x, y, width, height));
839 }
840
841 int esplusplayer_set_display_mode(esplusplayer_handle handle,
842                                   esplusplayer_display_mode mode) {
843   LOG_ENTER_P(cast_(handle))
844   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
845   if (mode < ESPLUSPLAYER_DISPLAY_MODE_LETTER_BOX ||
846     mode >= ESPLUSPLAYER_DISPLAY_MODE_MAX) return ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
847   LOG_INFO_P(cast_(handle), "display mode : %d", static_cast<int>(mode));
848
849   return convert_return_type_(
850       cast_(handle)->SetDisplayMode(static_cast<DisplayMode>(mode)));
851 }
852
853 int esplusplayer_set_display_roi(esplusplayer_handle handle, int x, int y,
854                                  int width, int height) {
855   LOG_ENTER_P(cast_(handle))
856   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
857   if (width <= 0 || height <= 0) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
858   LOG_INFO_P(cast_(handle), "x : %d, y: %d, width : %d, height : %d", x, y,
859              width, height);
860
861   Geometry roi;
862   roi.x = x;
863   roi.y = y;
864   roi.w = width;
865   roi.h = height;
866
867   return convert_return_type_(cast_(handle)->SetDisplayRoi(roi));
868 }
869
870 int esplusplayer_set_video_roi(esplusplayer_handle handle, double scale_x,
871                                double scale_y, double scale_w, double scale_h) {
872   LOG_ENTER_P(cast_(handle))
873   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
874   LOG_INFO_P(cast_(handle),
875              "scale-x : %lf, scale-y: %lf, scale-w : %lf, scale-h : %lf",
876              scale_x, scale_y, scale_w, scale_h);
877
878   CropArea roi_area;
879   roi_area.scale_x = scale_x;
880   roi_area.scale_y = scale_y;
881   roi_area.scale_w = scale_w;
882   roi_area.scale_h = scale_h;
883
884   return convert_return_type_(cast_(handle)->SetVideoRoi(roi_area));
885 }
886
887 int esplusplayer_set_display_rotation(
888     esplusplayer_handle handle, esplusplayer_display_rotation_type rotation) {
889   LOG_ENTER_P(cast_(handle))
890   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
891   LOG_INFO_P(cast_(handle), "display rotate angle : %d",
892              static_cast<int>(rotation));
893   return convert_return_type_(
894       cast_(handle)->SetDisplayRotate(static_cast<DisplayRotation>(rotation)));
895 }
896
897 int esplusplayer_get_display_rotation(
898     esplusplayer_handle handle, esplusplayer_display_rotation_type* rotation) {
899   LOG_ENTER_P(cast_(handle))
900   if (is_null_(handle) || is_null_(rotation))
901     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
902   return convert_return_type_(cast_(handle)->GetDisplayRotate(
903       reinterpret_cast<DisplayRotation*>(rotation)));
904 }
905
906 int esplusplayer_set_display_visible(esplusplayer_handle handle, bool visible) {
907   LOG_ENTER_P(cast_(handle))
908   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
909   LOG_INFO_P(cast_(handle), "visible : %s", visible ? "true" : "false");
910   return convert_return_type_(cast_(handle)->SetDisplayVisible(visible));
911 }
912
913 int esplusplayer_set_submit_data_type(esplusplayer_handle handle,
914                                       esplusplayer_submit_data_type type) {
915   LOG_ENTER_P(cast_(handle))
916   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
917   if (type < ESPLUSPLAYER_SUBMIT_DATA_TYPE_CLEAN_DATA ||
918     type >= ESPLUSPLAYER_SUBMIT_DATA_TYPE_MAX) return ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
919   LOG_INFO_P(cast_(handle), "type : %d", type);
920   return convert_return_type_(
921       cast_(handle)->SetSubmitDataType(static_cast<SubmitDataType>(type)));
922 }
923
924 int esplusplayer_set_audio_mute(esplusplayer_handle handle, bool mute) {
925   LOG_ENTER_P(cast_(handle))
926   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
927   LOG_INFO_P(cast_(handle), "mute : %s", mute ? "true" : "false");
928   return convert_return_type_(cast_(handle)->SetAudioMute(mute));
929 }
930
931 esplusplayer_state esplusplayer_get_state(esplusplayer_handle handle) {
932   // LOG_ENTER_P(cast_(handle))
933   if (is_null_(handle)) return esplusplayer_state::ESPLUSPLAYER_STATE_NONE;
934   auto current_state =
935       static_cast<esplusplayer_state>(cast_(handle)->GetState());
936   // LOG_INFO_P(cast_(handle), "state : %d", static_cast<int>(current_state));
937
938   return current_state;
939 }
940
941 esplusplayer_submit_status esplusplayer_submit_packet(
942     esplusplayer_handle handle, esplusplayer_es_packet* packet) {
943   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
944   auto packetptr = convert_espacket_(packet);
945   if (packetptr == nullptr) {
946     LOG_ERROR("packet converting failed");
947     return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
948   }
949   auto status = cast_(handle)->SubmitPacket(packetptr);
950   if (status != plusplayer::PacketSubmitStatus::kSuccess) {
951     LOG_ERROR("SubmitPacket status isn't SUCCESS [%d]",
952               static_cast<int>(status));
953   }
954   return static_cast<esplusplayer_submit_status>(status);
955 }
956
957 esplusplayer_submit_status esplusplayer_submit_encrypted_packet(
958     esplusplayer_handle handle, esplusplayer_es_packet* packet,
959     esplusplayer_drm_info* drm_info) {
960   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
961   auto packetptr = convert_espacket_(packet);
962   if (packetptr == nullptr) {
963     LOG_ERROR("packet converting failed");
964     return ESPLUSPLAYER_SUBMIT_STATUS_INVALID_PACKET;
965   }
966   auto status = plusplayer::PacketSubmitStatus::kSuccess;
967   if (drm_info == nullptr) {
968     status = cast_(handle)->SubmitPacket(packetptr);
969   } else {
970     auto encrypted_info = convert_es_drm_info_(drm_info);
971     status = cast_(handle)->SubmitEncryptedPacket(packetptr, *encrypted_info);
972   }
973   if (status != plusplayer::PacketSubmitStatus::kSuccess) {
974     LOG_ERROR("SubmitPacket status isn't SUCCESS [%d]",
975               static_cast<int>(status));
976   }
977   return static_cast<esplusplayer_submit_status>(status);
978 }
979
980 esplusplayer_submit_status esplusplayer_submit_eos_packet(
981     esplusplayer_handle handle, esplusplayer_stream_type type) {
982   LOG_ENTER_P(cast_(handle))
983   if (is_null_(handle)) return ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED;
984
985   auto status = cast_(handle)->SubmitPacket(
986       std::move(EsPacket::CreateEos(static_cast<StreamType>(type))));
987   return static_cast<esplusplayer_submit_status>(status);
988 }
989
990 int esplusplayer_set_audio_stream_info(esplusplayer_handle handle,
991                                        esplusplayer_audio_stream_info* info) {
992   LOG_ENTER_P(cast_(handle))
993   if (is_null_(handle) || is_null_(info))
994     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
995
996   auto stream = convert_stream_ptr_(info);
997   return convert_return_type_(cast_(handle)->SetStream(std::move(stream)));
998 }
999
1000 int esplusplayer_set_video_stream_info(esplusplayer_handle handle,
1001                                        esplusplayer_video_stream_info* info) {
1002   LOG_ENTER_P(cast_(handle))
1003   if (is_null_(handle) || is_null_(info))
1004     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1005
1006   auto stream = convert_stream_ptr_(info);
1007   return convert_return_type_(cast_(handle)->SetStream(std::move(stream)));
1008 }
1009
1010 int esplusplayer_get_playing_time(esplusplayer_handle handle, uint64_t* ms) {
1011   // LOG_ENTER_P(cast_(handle))
1012   if (is_null_(handle) || is_null_(ms))
1013     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1014
1015   auto ret = cast_(handle)->GetPlayingTime(ms);
1016   // LOG_INFO("[%p] > playing time : %" PRIu64, cast_(handle), *ms);
1017   return convert_return_type_(ret);
1018 }
1019
1020 namespace {
1021 std::shared_ptr<DecodedPacketManagerInterface> CreateDecodedPacketManager(
1022     esplusplayer_decoded_video_frame_buffer_type type) {
1023   std::shared_ptr<DecodedPacketManagerInterface> mgr = nullptr;
1024   if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_COPY)
1025     mgr = std::make_shared<plusplayer::DecodedCopiedPacketList>();
1026   else if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_REFERENCE)
1027     mgr = std::make_shared<plusplayer::DecodedReferencePacketList>();
1028   else if (type == ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_SCALE)
1029     mgr = std::make_shared<plusplayer::DecodedScaledPacketList>();
1030   return mgr;
1031 }
1032 }  // namespace
1033
1034 int esplusplayer_set_video_frame_buffer_type(
1035     esplusplayer_handle handle,
1036     esplusplayer_decoded_video_frame_buffer_type type) {
1037   LOG_ENTER_P(cast_(handle))
1038   if (is_null_(handle) || is_null_(listener_cast_(handle)))
1039     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1040
1041   auto priv = static_cast<EsPlusPlayerPriv*>(handle);
1042   priv->decoded_pkt_mgr = ::CreateDecodedPacketManager(type);
1043   priv->listener->SetDecodedPacketManager(priv->decoded_pkt_mgr);
1044
1045   auto ret = cast_(handle)->SetVideoFrameBufferType(
1046       static_cast<plusplayer::DecodedVideoFrameBufferType>(type));
1047   return convert_return_type_(ret);
1048 }
1049
1050 int esplusplayer_get_adaptive_info(
1051     esplusplayer_handle handle, void* padaptive_info,
1052     esplusplayer_adaptive_info_type adaptive_type) {
1053   // LOG_ENTER_P(cast_(handle))
1054   if (is_null_(handle) || is_null_(padaptive_info))
1055     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1056
1057   auto ret = cast_(handle)->GetAdaptiveInfo(
1058       padaptive_info, static_cast<PlayerAdaptiveInfo>(adaptive_type));
1059   return convert_return_type_(ret);
1060 }
1061
1062 int esplusplayer_set_volume(esplusplayer_handle handle, const int volume) {
1063   LOG_ENTER_P(cast_(handle))
1064   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1065
1066   auto ret = cast_(handle)->SetVolume(volume);
1067   return convert_return_type_(ret);
1068 }
1069
1070 int esplusplayer_get_volume(esplusplayer_handle handle, int* volume) {
1071   LOG_ENTER_P(cast_(handle))
1072   if (is_null_(handle) || is_null_(volume))
1073     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1074
1075   auto ret = cast_(handle)->GetVolume(volume);
1076   return convert_return_type_(ret);
1077 }
1078
1079 int esplusplayer_flush(esplusplayer_handle handle,
1080                        esplusplayer_stream_type type) {
1081   LOG_ENTER_P(cast_(handle))
1082   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1083   auto ret = cast_(handle)->Flush(static_cast<StreamType>(type));
1084   return convert_return_type_(ret);
1085 }
1086
1087 const char* esplusplayer_get_error_string(esplusplayer_error_type type) {
1088   LOG_ENTER
1089   return util::ConvertErrorTypeToString(type).c_str();
1090 }
1091
1092 int esplusplayer_set_error_cb(esplusplayer_handle handle,
1093                               esplusplayer_error_cb error_cb, void* userdata) {
1094   LOG_ENTER_P(cast_(handle))
1095   listener_bridge* listener = nullptr;
1096   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1097     LOG_ERROR("ESPlayer or Listener object is nil.");
1098     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1099   }
1100
1101   listener->error_cb_ = error_cb;
1102   listener->error_cb_userdata_ = userdata;
1103   return convert_return_type_(true);
1104 }
1105
1106 int esplusplayer_set_buffer_status_cb(
1107     esplusplayer_handle handle, esplusplayer_buffer_status_cb buffer_status_cb,
1108     void* userdata) {
1109   LOG_ENTER_P(cast_(handle))
1110   listener_bridge* listener = nullptr;
1111   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1112     LOG_ERROR("ESPlayer or Listener object is nil.");
1113     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1114   }
1115
1116   listener->buffer_status_cb_ = buffer_status_cb;
1117   listener->buffer_status_cb_userdata_ = userdata;
1118   return convert_return_type_(true);
1119 }
1120
1121 int esplusplayer_set_buffer_byte_status_cb(
1122     esplusplayer_handle handle,
1123     esplusplayer_buffer_byte_status_cb buffer_status_cb, void* userdata) {
1124   LOG_ENTER_P(cast_(handle))
1125   listener_bridge* listener = nullptr;
1126   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1127     LOG_ERROR("ESPlayer or Listener object is nil.");
1128     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1129   }
1130
1131   listener->buffer_byte_status_cb_ = buffer_status_cb;
1132   listener->buffer_byte_status_cb_userdata_ = userdata;
1133   return convert_return_type_(true);
1134 }
1135
1136 int esplusplayer_set_buffer_time_status_cb(
1137     esplusplayer_handle handle,
1138     esplusplayer_buffer_time_status_cb buffer_status_cb, void* userdata) {
1139   LOG_ENTER_P(cast_(handle))
1140   listener_bridge* listener = nullptr;
1141   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1142     LOG_ERROR("ESPlayer or Listener object is nil.");
1143     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1144   }
1145
1146   listener->buffer_time_status_cb_ = buffer_status_cb;
1147   listener->buffer_time_status_cb_userdata_ = userdata;
1148   return convert_return_type_(true);
1149 }
1150
1151 int esplusplayer_set_buffer_size(esplusplayer_handle handle,
1152                                  esplusplayer_buffer_option option,
1153                                  uint64_t size) {
1154   LOG_ENTER_P(cast_(handle))
1155   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1156   LOG_INFO("[%p] > option: %d, size: %" PRId64, cast_(handle),
1157              static_cast<int>(option), size);
1158   cast_(handle)->SetBufferSize(static_cast<plusplayer::BufferOption>(option),
1159                                size);
1160   return convert_return_type_(true);
1161 }
1162
1163 int esplusplayer_enable_video_hole(esplusplayer_handle handle, const bool value) {
1164   LOG_ENTER_P(cast_(handle))
1165   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1166
1167   auto ret = cast_(handle)->EnableVideoHole(value);
1168   return convert_return_type_(ret);
1169 }
1170
1171 int esplusplayer_set_resource_conflicted_cb(
1172     esplusplayer_handle handle,
1173     esplusplayer_resource_conflicted_cb resource_conflicted_cb,
1174     void* userdata) {
1175   LOG_ENTER_P(cast_(handle))
1176   listener_bridge* listener = nullptr;
1177   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1178     LOG_ERROR("ESPlayer or Listener object is nil.");
1179     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1180   }
1181
1182   listener->resource_conflicted_cb_ = resource_conflicted_cb;
1183   listener->resource_conflicted_cb_userdata_ = userdata;
1184   return convert_return_type_(true);
1185 }
1186
1187 int esplusplayer_set_eos_cb(esplusplayer_handle handle,
1188                             esplusplayer_eos_cb eos_cb, void* userdata) {
1189   LOG_ENTER_P(cast_(handle))
1190   listener_bridge* listener = nullptr;
1191   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1192     LOG_ERROR("ESPlayer or Listener object is nil.");
1193     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1194   }
1195
1196   listener->eos_cb_ = eos_cb;
1197   listener->eos_cb_userdata_ = userdata;
1198   return convert_return_type_(true);
1199 }
1200
1201 int esplusplayer_set_ready_to_prepare_cb(
1202     esplusplayer_handle handle,
1203     esplusplayer_ready_to_prepare_cb ready_to_prepare_cb, void* userdata) {
1204   LOG_ENTER_P(cast_(handle))
1205   listener_bridge* listener = nullptr;
1206   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1207     LOG_ERROR("ESPlayer or Listener object is nil.");
1208     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1209   }
1210
1211   listener->ready_to_prepare_cb_ = ready_to_prepare_cb;
1212   listener->ready_to_prepare_cb_userdata_ = userdata;
1213   return convert_return_type_(true);
1214 }
1215
1216 int esplusplayer_set_prepare_async_done_cb(
1217     esplusplayer_handle handle,
1218     esplusplayer_prepare_async_done_cb prepare_async_done_cb, void* userdata) {
1219   LOG_ENTER_P(cast_(handle))
1220   listener_bridge* listener = nullptr;
1221   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1222     LOG_ERROR("ESPlayer or Listener object is nil.");
1223     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1224   }
1225
1226   listener->prepare_async_done_cb_ = prepare_async_done_cb;
1227   listener->prepare_async_done_cb_userdata_ = userdata;
1228   return convert_return_type_(true);
1229 }
1230
1231 int esplusplayer_set_seek_done_cb(esplusplayer_handle handle,
1232                                   esplusplayer_seek_done_cb seek_done_cb,
1233                                   void* userdata) {
1234   LOG_ENTER_P(cast_(handle))
1235   listener_bridge* listener = nullptr;
1236   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1237     LOG_ERROR("ESPlayer or Listener object is nil.");
1238     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1239   }
1240
1241   listener->seek_done_cb_ = seek_done_cb;
1242   listener->seek_done_cb_userdata_ = userdata;
1243   return convert_return_type_(true);
1244 }
1245
1246 int esplusplayer_set_ready_to_seek_cb(
1247     esplusplayer_handle handle, esplusplayer_ready_to_seek_cb ready_to_seek_cb,
1248     void* userdata) {
1249   LOG_ENTER_P(cast_(handle))
1250   listener_bridge* listener = nullptr;
1251   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1252     LOG_ERROR("ESPlayer or Listener object is nil.");
1253     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1254   }
1255   update_ready_to_seek_callback(handle, ready_to_seek_cb, userdata);
1256   return convert_return_type_(true);
1257 }
1258
1259 int esplusplayer_set_media_packet_video_decoded_cb(
1260     esplusplayer_handle handle,
1261     esplusplayer_media_packet_video_decoded_cb media_packet_video_decoded_cb,
1262     void* userdata) {
1263   LOG_ENTER_P(cast_(handle))
1264   listener_bridge* listener = nullptr;
1265   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1266     LOG_ERROR("ESPlayer or Listener object is nil.");
1267     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1268   }
1269
1270   listener->media_packet_video_decoded_cb_ = media_packet_video_decoded_cb;
1271   listener->media_packet_video_decoded_cb_userdata_ = userdata;
1272
1273   return convert_return_type_(true);
1274 }
1275
1276 int esplusplayer_set_closed_caption_cb(
1277     esplusplayer_handle handle,
1278     esplusplayer_closed_caption_cb closed_caption_cb, void* userdata) {
1279   LOG_ENTER_P(cast_(handle))
1280   listener_bridge* listener = nullptr;
1281   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1282     LOG_ERROR("ESPlayer or Listener object is nil.");
1283     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1284   }
1285
1286   listener->closed_caption_cb_ = closed_caption_cb;
1287   listener->closed_caption_cb_userdata_ = userdata;
1288   return convert_return_type_(true);
1289 }
1290
1291 int esplusplayer_set_flush_done_cb(esplusplayer_handle handle,
1292                                    esplusplayer_flush_done_cb flush_done_cb,
1293                                    void* userdata) {
1294   LOG_ENTER_P(cast_(handle))
1295   listener_bridge* listener = nullptr;
1296   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1297     LOG_ERROR("ESPlayer or Listener object is nil.");
1298     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1299   }
1300
1301   listener->flush_done_cb_ = flush_done_cb;
1302   listener->flush_done_cb_userdata_ = userdata;
1303   return convert_return_type_(true);
1304 }
1305
1306 int esplusplayer_set_event_cb(esplusplayer_handle handle,
1307                               esplusplayer_event_cb event_cb, void* userdata) {
1308   LOG_ENTER_P(cast_(handle))
1309   listener_bridge* listener = nullptr;
1310   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1311     LOG_ERROR("ESPlayer or Listener object is nil.");
1312     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1313   }
1314   listener->event_cb_ = event_cb;
1315   listener->event_cb_userdata_ = userdata;
1316
1317   return convert_return_type_(true);
1318 }
1319
1320 int esplusplayer_set_first_video_decoding_done_cb(
1321     esplusplayer_handle handle,
1322     esplusplayer_first_video_decoding_done_cb first_video_decoding_done_cb,
1323     void* userdata) {
1324   LOG_ENTER_P(cast_(handle))
1325   listener_bridge* listener = nullptr;
1326   if (is_null_(handle) || is_null_(listener = listener_cast_(handle))) {
1327     LOG_ERROR("ESPlayer or Listener object is nil.");
1328     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1329   }
1330   listener->first_video_decoding_done_cb_ = first_video_decoding_done_cb;
1331   listener->first_video_decoding_done_cb_userdata_ = userdata;
1332   return convert_return_type_(true);
1333 }
1334
1335 int esplusplayer_decoded_buffer_destroy(
1336     esplusplayer_handle handle, esplusplayer_decoded_video_packet* packet) {
1337   if (is_null_(handle)) {
1338     LOG_ERROR("ESPlayer object is nil.");
1339     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1340   }
1341   auto priv = static_cast<EsPlusPlayerPriv*>(handle);
1342   auto& mgr = priv->decoded_pkt_mgr;
1343   if (mgr == nullptr) {
1344     LOG_ERROR("DecodedPacketManager object is nil.");
1345     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1346   }
1347   mgr->Remove(packet);
1348   return convert_return_type_(true);
1349 }
1350
1351 int esplusplayer_set_low_latency_mode(esplusplayer_handle handle,
1352                                       esplusplayer_low_latency_mode mode) {
1353   LOG_ENTER_P(cast_(handle))
1354   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1355   if (mode != ESPLUSPLAYER_LOW_LATENCY_MODE_NONE &&
1356       mode != ESPLUSPLAYER_LOW_LATENCY_MODE_DISABLE_PREROLL) {
1357     LOG_WARN("Not supported latency mode 0x%x", static_cast<std::uint32_t>(mode));
1358     return ESPLUSPLAYER_ERROR_TYPE_NONE;
1359   }
1360   auto ret =
1361       cast_(handle)->SetLowLatencyMode(static_cast<PlayerLowLatencyMode>(mode));
1362   return convert_return_type_(ret);
1363 }
1364
1365 int esplusplayer_set_unlimited_max_buffer_mode(esplusplayer_handle handle) {
1366   LOG_ENTER_P(cast_(handle))
1367   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1368   auto ret = cast_(handle)->SetUnlimitedMaxBufferMode();
1369   return convert_return_type_(ret);
1370 }
1371
1372 int esplusplayer_set_audio_codec_type(esplusplayer_handle handle,
1373                                       esplusplayer_audio_codec_type type) {
1374   LOG_ENTER_P(cast_(handle))
1375   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1376   if (type < ESPLUSPLAYER_AUDIO_CODEC_TYPE_HW ||
1377     type >= ESPLUSPLAYER_AUDIO_CODEC_TYPE_MAX) return ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
1378   auto ret =
1379       cast_(handle)->SetAudioCodecType(static_cast<PlayerAudioCodecType>(type));
1380   return convert_return_type_(ret);
1381 }
1382
1383 int esplusplayer_set_video_codec_type(esplusplayer_handle handle,
1384                                       esplusplayer_video_codec_type type) {
1385   LOG_ENTER_P(cast_(handle))
1386   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1387   if (type < ESPLUSPLAYER_VIDEO_CODEC_TYPE_HW ||
1388     type >= ESPLUSPLAYER_VIDEO_CODEC_TYPE_MAX) return ESPLUSPLAYER_ERROR_TYPE_INVALID_OPERATION;
1389   auto ret =
1390       cast_(handle)->SetVideoCodecType(static_cast<PlayerVideoCodecType>(type));
1391   return convert_return_type_(ret);
1392 }
1393
1394 int esplusplayer_set_render_time_offset(esplusplayer_handle handle,
1395                                         esplusplayer_stream_type type,
1396                                         int64_t offset) {
1397   LOG_ENTER_P(cast_(handle))
1398   if (is_null_(handle)) return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1399   auto ret =
1400       cast_(handle)->SetRenderTimeOffset(static_cast<StreamType>(type), offset);
1401   return convert_return_type_(ret);
1402 }
1403
1404 int esplusplayer_get_render_time_offset(esplusplayer_handle handle,
1405                                         esplusplayer_stream_type type,
1406                                         int64_t* offset) {
1407   LOG_ENTER_P(cast_(handle))
1408   if (is_null_(handle) || is_null_(offset))
1409     return ESPLUSPLAYER_ERROR_TYPE_INVALID_PARAMETER;
1410   auto ret =
1411       cast_(handle)->GetRenderTimeOffset(static_cast<StreamType>(type), offset);
1412   return convert_return_type_(ret);
1413 }