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