1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "player_server.h"
17 #include "media_info.h"
18 #include "media_log.h"
19 #include "format.h"
20 #include "player_type.h"
21 #include "source.h"
22 #include "surface.h"
23 #include "surface_impl.h"
24 #include "player_factory.h"
25 #include "rpc_errno.h"
26 extern "C"
27 {
28 #include "codec_interface.h"
29 #include "pthread.h"
30 #include <sys/prctl.h>
31 #include "securec.h"
32 }
33 
34 #define READ_LEN  (1024)
35 
36 typedef struct TagIdleBuffer {
37     size_t idx;
38     size_t offset;
39     size_t size;
40 } IdleBuffer;
41 
42 namespace OHOS {
43 namespace Media {
PlayerServerRequestHandle(int funcId,void * origin,IpcIo * req,IpcIo * reply)44 void PlayerServer::PlayerServerRequestHandle(int funcId, void *origin, IpcIo *req, IpcIo *reply)
45 {
46     switch (funcId) {
47         case PLAYER_SERVER_SET_SOURCE:
48             PlayerServer::GetInstance()->SetSource(req, reply);
49             break;
50         case PLAYER_SERVER_PREPARE:
51             PlayerServer::GetInstance()->Prepare(req, reply);
52             break;
53         case PLAYER_SERVER_PLAY:
54             PlayerServer::GetInstance()->Play(req, reply);
55             break;
56         case PLAYER_SERVER_IS_PLAYING:
57             PlayerServer::GetInstance()->IsPlaying(req, reply);
58             break;
59         case PLAYER_SERVER_PAUSE:
60             PlayerServer::GetInstance()->Pause(req, reply);
61             break;
62         case PLAYER_SERVER_STOP:
63             PlayerServer::GetInstance()->Stop(req, reply);
64             break;
65         case PLAYER_SERVER_REWIND:
66             PlayerServer::GetInstance()->Rewind(req, reply);
67             break;
68         case PLAYER_SERVER_SET_VOLUME:
69             PlayerServer::GetInstance()->SetVolume(req, reply);
70             break;
71         case PLAYER_SERVER_SET_VIDEO_SURFACE:
72             PlayerServer::GetInstance()->SetSurface(req, reply);
73             break;
74         case PLAYER_SERVER_ENABLE_SINGLE_LOOPING:
75             PlayerServer::GetInstance()->SetLoop(req, reply);
76             break;
77         case PLAYER_SERVER_IS_SINGLE_LOOPING:
78             PlayerServer::GetInstance()->IsSingleLooping(req, reply);
79             break;
80         case PLAYER_SERVER_GET_CURRENT_TIME:
81             PlayerServer::GetInstance()->GetCurrentPosition(req, reply);
82             break;
83         case PLAYER_SERVER_GET_DURATION:
84             PlayerServer::GetInstance()->GetDuration(req, reply);
85             break;
86         case PLAYER_SERVER_GET_VIDEO_WIDTH:
87             PlayerServer::GetInstance()->GetVideoWidth(req, reply);
88             break;
89         case PLAYER_SERVER_GET_VIDEO_HEIGHT:
90             PlayerServer::GetInstance()->GetVideoHeight(req, reply);
91             break;
92         case PLAYER_SERVER_RESET:
93             PlayerServer::GetInstance()->Reset(req, reply);
94             break;
95         case PLAYER_SERVER_RELEASE:
96             PlayerServer::GetInstance()->Release(req, reply);
97             break;
98         case PLAYER_SERVER_SET_PLAYER_CALLBACK:
99             PlayerServer::GetInstance()->SetPlayerCallback(req, reply);
100             break;
101         case PLAYER_SERVER_GET_STATE:
102             PlayerServer::GetInstance()->GetPlayerState(req, reply);
103             break;
104         case PLAYER_SERVER_SET_SPEED:
105             PlayerServer::GetInstance()->SetPlaybackSpeed(req, reply);
106             break;
107         case PLAYER_SERVER_GET_SPEED:
108             PlayerServer::GetInstance()->GetPlaybackSpeed(req, reply);
109             break;
110         case PLAYER_SERVER_SET_PARAMETER:
111             PlayerServer::GetInstance()->SetParameter(req, reply);
112             break;
113         case PLAYER_SERVER_SET_AUDIO_STREAM_TYPE:
114             PlayerServer::GetInstance()->SetAudioStreamType(req, reply);
115             break;
116         case PLAYER_SERVER_GET_AUDIO_STREAM_TYPE:
117             PlayerServer::GetInstance()->GetAudioStreamType(req, reply);
118             break;
119         default:
120             MEDIA_ERR_LOG("code not support: %d", funcId);
121             break;
122     }
123 }
124 
PlayerServerInit()125 int32_t PlayerServer::PlayerServerInit()
126 {
127     return 0;
128 }
129 
130 class ServerStreamSource : public StreamSource {
131 public:
132     ServerStreamSource(void);
133     virtual ~ServerStreamSource(void);
134     void OnBufferAvailable(size_t index, size_t offset, size_t size);
135     void SetStreamCallback(const std::shared_ptr<StreamCallback> &callback);
136     uint8_t *GetBufferAddress(size_t idx);
137     void QueueBuffer(size_t index, size_t offset, size_t size, int64_t timestampUs, uint32_t flags);
138     int GetAvailableBuffer(IdleBuffer* buffer);
139     bool threadRuning;
140 
141 private:
142     std::weak_ptr<StreamCallback> m_callBack;
143     std::vector<IdleBuffer> availableBuffer;
144     pthread_mutex_t m_mutex;
145 };
146 
147 struct StreamThreadControl {
148     pthread_t process;
149     pthread_mutex_t mutex;
150 };
151 StreamThreadControl g_streamThreadControl;
152 
ServerStreamSource(void)153 ServerStreamSource::ServerStreamSource(void)
154 {
155     availableBuffer.clear();
156     pthread_mutex_init(&m_mutex, nullptr);
157 }
158 
~ServerStreamSource(void)159 ServerStreamSource::~ServerStreamSource(void)
160 {
161     availableBuffer.clear();
162     pthread_mutex_destroy(&m_mutex);
163 }
164 
SetStreamCallback(const std::shared_ptr<StreamCallback> & callback)165 void ServerStreamSource::SetStreamCallback(const std::shared_ptr<StreamCallback> &callback)
166 {
167     m_callBack = callback;
168 }
169 
GetBufferAddress(size_t idx)170 uint8_t *ServerStreamSource::GetBufferAddress(size_t idx)
171 {
172     std::shared_ptr<StreamCallback> callback = m_callBack.lock();
173     if (callback == nullptr) {
174         return nullptr;
175     }
176     return callback->GetBuffer(idx);
177 }
178 
QueueBuffer(size_t index,size_t offset,size_t size,int64_t timestampUs,uint32_t flags)179 void ServerStreamSource::QueueBuffer(size_t index, size_t offset, size_t size, int64_t timestampUs, uint32_t flags)
180 {
181     std::shared_ptr<StreamCallback> callback = m_callBack.lock();
182     if (callback == nullptr) {
183         return;
184     }
185     callback->QueueBuffer(index, offset, size, timestampUs, flags);
186 }
187 
OnBufferAvailable(size_t index,size_t offset,size_t size)188 void ServerStreamSource::OnBufferAvailable(size_t index, size_t offset, size_t size)
189 {
190     IdleBuffer buffer;
191     pthread_mutex_lock(&m_mutex);
192     buffer.idx = index;
193     buffer.offset = offset;
194     buffer.size = size;
195     availableBuffer.push_back(buffer);
196     pthread_mutex_unlock(&m_mutex);
197 }
198 
GetAvailableBuffer(IdleBuffer * buffer)199 int ServerStreamSource::GetAvailableBuffer(IdleBuffer* buffer)
200 {
201     pthread_mutex_lock(&m_mutex);
202     if (availableBuffer.empty()) {
203         pthread_mutex_unlock(&m_mutex);
204         return -1;
205     }
206     *buffer = availableBuffer[0];
207     availableBuffer.erase(availableBuffer.begin());
208     pthread_mutex_unlock(&m_mutex);
209     return 0;
210 }
211 
streamProcess(void * arg)212 static void* streamProcess(void* arg)
213 {
214     IdleBuffer buffer;
215     int ret;
216     uint8_t *data = nullptr;
217     int32_t readLen;
218     ServerStreamSource *stream = (ServerStreamSource *)arg;
219     SurfaceBuffer* acquireBuffer = nullptr;
220     prctl(PR_SET_NAME, "StreamProc_server", 0, 0, 0);
221     MEDIA_INFO_LOG("[%s %d]", __func__, __LINE__);
222     int sleepTime = 20000;
223     while (true) {
224         pthread_mutex_lock(&g_streamThreadControl.mutex);
225         if (!(stream->threadRuning)) {
226             pthread_mutex_unlock(&g_streamThreadControl.mutex);
227             break;
228         }
229         pthread_mutex_unlock(&g_streamThreadControl.mutex);
230         ret = stream->GetAvailableBuffer(&buffer);
231         if (ret != 0) {
232             usleep(sleepTime);
233             continue;
234         }
235         data = stream->GetBufferAddress(buffer.idx);
236         if (data == nullptr) {
237             break;
238         }
239         while (true) {
240             pthread_mutex_lock(&g_streamThreadControl.mutex);
241             if (!(stream->threadRuning)) {
242                 pthread_mutex_unlock(&g_streamThreadControl.mutex);
243                 break;
244             }
245             pthread_mutex_unlock(&g_streamThreadControl.mutex);
246             acquireBuffer = stream->GetSurface()->AcquireBuffer();
247             if (acquireBuffer != nullptr) {
248                 ret = acquireBuffer->GetInt32(0, readLen);
249                 if (ret != 0) {
250                     MEDIA_ERR_LOG("[%s,%d] acquireBuffer GetInt32 failed", __func__, __LINE__);
251                     readLen = 0;
252                 }
253                 if (readLen != 0) {
254                     void* acquireBufVirAddr = acquireBuffer->GetVirAddr();
255                     if (acquireBufVirAddr != nullptr) {
256                         if (buffer.size < static_cast<uint32_t>(readLen)) {
257                             MEDIA_ERR_LOG("[%s,%d] error:buffer.size < readLen", __func__, __LINE__);
258                         }
259                         if (memcpy_s(data + buffer.offset, buffer.size, acquireBufVirAddr, readLen) != EOK) {
260                             MEDIA_ERR_LOG("memcpy_s error!");
261                         }
262                     } else {
263                         MEDIA_ERR_LOG("[%s,%d]", __func__, __LINE__);
264                     }
265                 }
266                 stream->GetSurface()->ReleaseBuffer(acquireBuffer);
267                 break;
268             } else {
269                 usleep(sleepTime);
270                 continue;
271             }
272         }
273         if (readLen > 0) {
274             int flags = 8;
275             stream->QueueBuffer(buffer.idx, buffer.offset, readLen, 0, flags);
276         } else {
277             int flags = 4;
278             stream->QueueBuffer(buffer.idx, buffer.offset, readLen, 0, flags);
279             break;
280         }
281     }
282     return nullptr;
283 }
284 
SurfaceRequestHandler(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)285 int32_t SurfaceRequestHandler(uint32_t code, IpcIo* data, IpcIo* reply, MessageOption option)
286 {
287     Surface* surface =  reinterpret_cast<Surface*>(option.args);
288     SurfaceImpl* liteSurface = reinterpret_cast<SurfaceImpl*>(surface);
289     liteSurface->DoIpcMsg(code, data, reply, option);
290     return 0;
291 }
292 
SetStreamSource(IpcIo * reply)293 void PlayerServer::SetStreamSource(IpcIo *reply)
294 {
295     MEDIA_INFO_LOG("process in");
296     stream_ = std::make_shared<ServerStreamSource>();
297     Format formats;
298     formats.PutStringValue(CODEC_MIME, MIME_AUDIO_AAC);
299     Source streamSource(stream_, formats);
300     int32_t ret = player_->SetSource(streamSource);
301     WriteInt32(reply, ret);
302     if (ret == 0) {
303         Surface* surface = Surface::CreateSurface();
304         surface->SetUsage(BUFFER_CONSUMER_USAGE_HARDWARE);
305         surface->SetSize(READ_LEN);
306         if (sid_ == nullptr) {
307             sid_ = new SvcIdentity();
308         }
309         objectStub_.func = SurfaceRequestHandler;
310         objectStub_.args = surface;
311         objectStub_.isRemote = false;
312         sid_->handle = IPC_INVALID_HANDLE;
313         sid_->token = SERVICE_TYPE_ANONYMOUS;
314         sid_->cookie = reinterpret_cast<uintptr_t>(&objectStub_);
315         stream_->SetSurface(surface);
316         bool writeRemote = WriteRemoteObject(reply, sid_);
317         if (!writeRemote) {
318             MEDIA_ERR_LOG("WriteRemoteObject failed.");
319         }
320         pthread_attr_t attr;
321         pthread_mutex_init(&g_streamThreadControl.mutex, nullptr);
322         ServerStreamSource* serverStream = reinterpret_cast<ServerStreamSource*>(stream_.get());
323         serverStream->threadRuning = true;
324         pthread_attr_init(&attr);
325         pthread_create(&g_streamThreadControl.process, &attr, streamProcess, stream_.get());
326     }
327 }
328 
SetSource(IpcIo * req,IpcIo * reply)329 void PlayerServer::SetSource(IpcIo *req, IpcIo *reply)
330 {
331     MEDIA_INFO_LOG("process in");
332     int32_t sourceType;
333     ReadInt32(req, &sourceType);
334     if (player_ == nullptr) {
335         MEDIA_INFO_LOG("player nullptr");
336         player_ = PlayerFactory::CreatePlayer();
337     }
338 
339     int32_t state = 0;
340     /* only support set source at state idle */
341     if (player_ == nullptr || player_->GetPlayerState(state) != 0 || state != static_cast<int32_t> (PLAYER_IDLE)) {
342         WriteInt32(reply, -1);
343         return;
344     }
345     switch ((SourceType)sourceType) {
346         case SourceType::SOURCE_TYPE_URI: {
347             size_t size;
348             char* str = (char*)ReadString(req, &size);
349             if (str != nullptr) {
350                 std::string uri(str);
351                 Source sourceUri(uri);
352                 WriteInt32(reply, player_->SetSource(sourceUri));
353             }
354             break;
355         }
356         case SourceType::SOURCE_TYPE_FD:
357             MEDIA_ERR_LOG("unsupported now: SOURCE_TYPE_FD");
358             WriteInt32(reply, -1);
359             break;
360         case SourceType::SOURCE_TYPE_STREAM: {
361             SetStreamSource(reply);
362             break;
363         }
364         default:
365             break;
366     }
367     MEDIA_INFO_LOG("PlayerServer::SetSource out");
368 }
369 
Prepare(IpcIo * req,IpcIo * reply)370 void PlayerServer::Prepare(IpcIo *req, IpcIo *reply)
371 {
372     MEDIA_INFO_LOG("process in");
373     if (player_ != nullptr) {
374         WriteInt32(reply, player_->Prepare());
375         return;
376     }
377     WriteInt32(reply, -1);
378 }
379 
Play(IpcIo * req,IpcIo * reply)380 void PlayerServer::Play(IpcIo *req, IpcIo *reply)
381 {
382     MEDIA_INFO_LOG("process in");
383     if (player_ != nullptr) {
384         WriteInt32(reply, player_->Play());
385         return;
386     }
387     WriteInt32(reply, -1);
388 }
389 
IsPlaying(IpcIo * req,IpcIo * reply)390 void PlayerServer::IsPlaying(IpcIo *req, IpcIo *reply)
391 {
392     MEDIA_INFO_LOG("process in");
393     if (player_ != nullptr) {
394         WriteBool(reply, player_->IsPlaying());
395         return;
396     }
397     WriteBool(reply, false);
398 }
399 
Pause(IpcIo * req,IpcIo * reply)400 void PlayerServer::Pause(IpcIo *req, IpcIo *reply)
401 {
402     MEDIA_INFO_LOG("process in");
403     if (player_ != nullptr) {
404         WriteInt32(reply, player_->Pause());
405         return;
406     }
407     WriteInt32(reply, -1);
408 }
409 
Stop(IpcIo * req,IpcIo * reply)410 void PlayerServer::Stop(IpcIo *req, IpcIo *reply)
411 {
412     MEDIA_INFO_LOG("process in");
413     if (player_ != nullptr) {
414         int32_t ret = player_->Stop();
415         if (stream_.get() != nullptr) {
416             ServerStreamSource* serverStream = reinterpret_cast<ServerStreamSource*>(stream_.get());
417             pthread_mutex_lock(&g_streamThreadControl.mutex);
418             serverStream->threadRuning = false;
419             pthread_mutex_unlock(&g_streamThreadControl.mutex);
420         }
421         WriteInt32(reply, ret);
422         return;
423     }
424     WriteInt32(reply, -1);
425 }
426 
Rewind(IpcIo * req,IpcIo * reply)427 void PlayerServer::Rewind(IpcIo *req, IpcIo *reply)
428 {
429     MEDIA_INFO_LOG("process in");
430     int64_t mSecond;
431     ReadInt64(req, &mSecond);
432     int32_t mode;
433     ReadInt32(req, &mode);
434     if (player_ != nullptr) {
435         WriteInt32(reply, player_->Rewind(mSecond, mode));
436         return;
437     }
438     WriteInt32(reply, -1);
439 }
440 
SetVolume(IpcIo * req,IpcIo * reply)441 void PlayerServer::SetVolume(IpcIo *req, IpcIo *reply)
442 {
443     MEDIA_INFO_LOG("process in");
444     float *leftVolume = static_cast<float *>(ReadRawData(req, sizeof(float)));
445     float *rightVolume = static_cast<float *>(ReadRawData(req, sizeof(float)));
446     if (player_ != nullptr) {
447         WriteInt32(reply, player_->SetVolume(*leftVolume, *rightVolume));
448         return;
449     }
450     WriteInt32(reply, -1);
451 }
452 
SetSurface(IpcIo * req,IpcIo * reply)453 void PlayerServer::SetSurface(IpcIo *req, IpcIo *reply)
454 {
455     MEDIA_INFO_LOG("process in");
456     size_t size;
457     char* str_x = (char*)ReadString(req, &size);
458     char* str_y = (char*)ReadString(req, &size);
459     char* str_width = (char*)ReadString(req, &size);
460     char* str_height = (char*)ReadString(req, &size);
461     Surface* surface = Surface::CreateSurface();
462     if (surface != nullptr) {
463         surface->SetUserData("region_position_x", std::string(str_x));
464         surface->SetUserData("region_position_y", std::string(str_y));
465         surface->SetUserData("region_width", std::string(str_width));
466         surface->SetUserData("region_height", std::string(str_height));
467         if (player_ != nullptr) {
468             WriteInt32(reply, player_->SetSurface(surface));
469             return;
470         }
471     }
472     WriteInt32(reply, -1);
473 }
474 
SetLoop(IpcIo * req,IpcIo * reply)475 void PlayerServer::SetLoop(IpcIo *req, IpcIo *reply)
476 {
477     MEDIA_INFO_LOG("process in");
478     bool loop;
479     ReadBool(req, &loop);
480     if (player_ != nullptr) {
481         WriteBool(reply, player_->SetLoop(loop));
482         return;
483     }
484     WriteInt32(reply, -1);
485 }
486 
IsSingleLooping(IpcIo * req,IpcIo * reply)487 void PlayerServer::IsSingleLooping(IpcIo *req, IpcIo *reply)
488 {
489     MEDIA_INFO_LOG("process in");
490     if (player_ != nullptr) {
491         WriteBool(reply, player_->IsSingleLooping());
492         return;
493     }
494     WriteBool(reply, false);
495 }
496 
GetCurrentPosition(IpcIo * req,IpcIo * reply)497 void PlayerServer::GetCurrentPosition(IpcIo *req, IpcIo *reply)
498 {
499     int64_t time = 0;
500     if (player_ != nullptr) {
501         WriteInt32(reply, player_->GetCurrentPosition(time));
502         WriteInt64(reply, time);
503         return;
504     }
505     WriteInt32(reply, -1);
506     WriteInt64(reply, time);
507 }
508 
GetDuration(IpcIo * req,IpcIo * reply)509 void PlayerServer::GetDuration(IpcIo *req, IpcIo *reply)
510 {
511     MEDIA_INFO_LOG("process in");
512     int64_t duration = 0;
513     if (player_ != nullptr) {
514         WriteInt32(reply, player_->GetDuration(duration));
515         WriteInt64(reply, duration);
516         return;
517     }
518     WriteInt32(reply, -1);
519     WriteInt64(reply, duration);
520 }
521 
GetVideoWidth(IpcIo * req,IpcIo * reply)522 void PlayerServer::GetVideoWidth(IpcIo *req, IpcIo *reply)
523 {
524     MEDIA_INFO_LOG("process in");
525     int32_t width = 0;
526     if (player_ != nullptr) {
527         WriteInt32(reply, player_->GetVideoWidth(width));
528         WriteInt32(reply, width);
529         return;
530     }
531     WriteInt32(reply, -1);
532     WriteInt32(reply, width);
533 }
534 
GetVideoHeight(IpcIo * req,IpcIo * reply)535 void PlayerServer::GetVideoHeight(IpcIo *req, IpcIo *reply)
536 {
537     MEDIA_INFO_LOG("process in");
538     int32_t hight = 0;
539     if (player_ != nullptr) {
540         WriteInt32(reply, player_->GetVideoHeight(hight));
541         WriteInt32(reply, hight);
542         return;
543     }
544     WriteInt32(reply, -1);
545     WriteInt32(reply, hight);
546 }
547 
Reset(IpcIo * req,IpcIo * reply)548 void PlayerServer::Reset(IpcIo *req, IpcIo *reply)
549 {
550     MEDIA_INFO_LOG("process in");
551     if (player_ != nullptr) {
552         WriteInt32(reply, player_->Reset());
553         return;
554     }
555     WriteInt32(reply, -1);
556 }
557 
Release(IpcIo * req,IpcIo * reply)558 void PlayerServer::Release(IpcIo *req, IpcIo *reply)
559 {
560     MEDIA_INFO_LOG("process in");
561     if (player_ != nullptr) {
562         int32_t ret = player_->Release();
563         if (stream_ != nullptr) {
564             ServerStreamSource* serverStream = reinterpret_cast<ServerStreamSource*>(stream_.get());
565             pthread_mutex_lock(&g_streamThreadControl.mutex);
566             serverStream->threadRuning = false;
567             pthread_mutex_unlock(&g_streamThreadControl.mutex);
568             pthread_join(g_streamThreadControl.process, nullptr);
569             pthread_mutex_destroy(&g_streamThreadControl.mutex);
570             stream_.reset();
571             stream_ = nullptr;
572         }
573         if (sid_ != nullptr) {
574             delete sid_;
575             sid_ = nullptr;
576         }
577         playerCallback_.reset();
578         player_ = nullptr;
579         WriteInt32(reply, ret);
580         return;
581     }
582     WriteInt32(reply, -1);
583 }
584 
SetPlayerCallback(IpcIo * req,IpcIo * reply)585 void PlayerServer::SetPlayerCallback(IpcIo *req, IpcIo *reply)
586 {
587     MEDIA_INFO_LOG("process in");
588     SvcIdentity sid;
589     if (ReadRemoteObject(req, &sid)) {
590         playerCallback_ = std::make_shared<PalyerCallbackImpl>(sid);
591         if (player_ != nullptr) {
592             player_->SetPlayerCallback(playerCallback_);
593             return;
594         }
595     }
596 }
597 
GetPlayerState(IpcIo * req,IpcIo * reply)598 void PlayerServer::GetPlayerState(IpcIo *req, IpcIo *reply)
599 {
600     MEDIA_INFO_LOG("process in");
601     int32_t state = 0;
602     if (player_ != nullptr) {
603         WriteInt32(reply, player_->GetPlayerState(state));
604         WriteInt32(reply, state);
605         return;
606     }
607     WriteInt32(reply, -1);
608     WriteInt32(reply, state);
609 }
610 
SetPlaybackSpeed(IpcIo * req,IpcIo * reply)611 void PlayerServer::SetPlaybackSpeed(IpcIo *req, IpcIo *reply)
612 {
613     MEDIA_INFO_LOG("process in");
614     float speed;
615     ReadFloat(req, &speed);
616     if (player_ != nullptr) {
617         WriteInt32(reply, player_->SetPlaybackSpeed(speed));
618         return;
619     }
620     WriteInt32(reply, -1);
621 }
622 
GetPlaybackSpeed(IpcIo * req,IpcIo * reply)623 void PlayerServer::GetPlaybackSpeed(IpcIo *req, IpcIo *reply)
624 {
625     MEDIA_INFO_LOG("process in");
626     float speed = 1.0;
627     if (player_ != nullptr) {
628         WriteInt32(reply, player_->GetPlaybackSpeed(speed));
629         WriteFloat(reply, speed);
630         return;
631     }
632     WriteInt32(reply, -1);
633     WriteFloat(reply, 1.0);
634 }
635 
SetParameter(IpcIo * req,IpcIo * reply)636 void PlayerServer::SetParameter(IpcIo *req, IpcIo *reply)
637 {
638     MEDIA_INFO_LOG("process in");
639     Format formats;
640     if (player_ == nullptr) {
641         WriteInt32(reply, -1);
642         return;
643     }
644 
645     int32_t count;
646     ReadInt32(req, &count);
647     for (int32_t i = 0; i < count; i++) {
648         uint32_t size;
649         char *key = (char *)ReadString(req, &size);
650         FormatDataType type;
651         ReadInt32(req, (int32_t *)&type);
652         if (type == FORMAT_TYPE_INT32) {
653             int32_t value;
654             ReadInt32(req, &value);
655             formats.PutIntValue(key, value);
656         } else if (type == FORMAT_TYPE_INT64) {
657             int64_t value;
658             ReadInt64(req, &value);
659             formats.PutLongValue(key, value);
660         } else if (type == FORMAT_TYPE_FLOAT) {
661             float value;
662             ReadFloat(req, &value);
663             formats.PutFloatValue(key, value);
664         } else if (type == FORMAT_TYPE_DOUBLE) {
665             double value;
666             ReadDouble(req, &value);
667             formats.PutDoubleValue(key, value);
668         } else if (type == FORMAT_TYPE_STRING) {
669             char *value = (char *)ReadString(req, &size);
670             formats.PutStringValue(key, value);
671         } else {
672             MEDIA_ERR_LOG("SetParameter failed, type:%d\n", type);
673             WriteInt32(reply, -1);
674             return;
675         }
676     }
677 
678     WriteInt32(reply, player_->SetParameter(formats));
679 }
680 
SetAudioStreamType(IpcIo * req,IpcIo * reply)681 void PlayerServer::SetAudioStreamType(IpcIo *req, IpcIo *reply)
682 {
683     MEDIA_INFO_LOG("process in");
684     int32_t type;
685     ReadInt32(req, &type);
686     if (player_ != nullptr) {
687         WriteInt32(reply, player_->SetAudioStreamType(type));
688         return;
689     }
690     WriteInt32(reply, -1);
691 }
692 
GetAudioStreamType(IpcIo * req,IpcIo * reply)693 void PlayerServer::GetAudioStreamType(IpcIo *req, IpcIo *reply)
694 {
695     MEDIA_INFO_LOG("process in");
696     int32_t type = TYPE_MEDIA;
697     if (player_ != nullptr) {
698         player_->GetAudioStreamType(type);
699         WriteInt32(reply, 0);
700         WriteFloat(reply, type);
701         return;
702     }
703     WriteInt32(reply, -1);
704     WriteFloat(reply, type);
705 }
706 
OnPlaybackComplete()707 void PalyerCallbackImpl::OnPlaybackComplete()
708 {
709     IpcIo io;
710     uint8_t tmpData[DEFAULT_IPC_SIZE];
711     IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
712     MessageOption option;
713     MessageOptionInit(&option);
714     option.flags = TF_OP_ASYNC;
715     int32_t ret = SendRequest(sid_, ON_PLAYBACK_COMPLETE, &io, nullptr, option, nullptr);
716     if (ret != ERR_NONE) {
717         MEDIA_ERR_LOG("PalyerCallbackImpl::OnPlaybackComplete failed\n");
718     }
719 }
720 
OnError(int32_t errorType,int32_t errorCode)721 void PalyerCallbackImpl::OnError(int32_t errorType, int32_t errorCode)
722 {
723     IpcIo io;
724     uint8_t tmpData[DEFAULT_IPC_SIZE];
725     IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
726     WriteInt32(&io, errorType);
727     WriteInt32(&io, errorCode);
728     MessageOption option;
729     MessageOptionInit(&option);
730     option.flags = TF_OP_ASYNC;
731     int32_t ret = SendRequest(sid_, ON_ERROR, &io, nullptr, option, nullptr);
732     if (ret != ERR_NONE) {
733         MEDIA_ERR_LOG("PalyerCallbackImpl::OnError failed\n");
734     }
735 }
736 
OnInfo(int type,int extra)737 void PalyerCallbackImpl::OnInfo(int type, int extra)
738 {
739     IpcIo io;
740     uint8_t tmpData[DEFAULT_IPC_SIZE];
741     IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
742     WriteInt32(&io, (int32_t)type);
743     WriteInt32(&io, (int32_t)extra);
744     MessageOption option;
745     MessageOptionInit(&option);
746     option.flags = TF_OP_ASYNC;
747     int32_t ret = SendRequest(sid_, ON_INFO, &io, nullptr, option, nullptr);
748     if (ret != ERR_NONE) {
749         MEDIA_ERR_LOG("PalyerCallbackImpl::OnInfo failed\n");
750     }
751 }
752 
OnVideoSizeChanged(int width,int height)753 void PalyerCallbackImpl::OnVideoSizeChanged(int width, int height)
754 {
755     IpcIo io;
756     uint8_t tmpData[DEFAULT_IPC_SIZE];
757     IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
758     WriteInt32(&io, (int32_t)width);
759     WriteInt32(&io, (int32_t)height);
760     MessageOption option;
761     MessageOptionInit(&option);
762     option.flags = TF_OP_ASYNC;
763     int32_t ret = SendRequest(sid_, ON_INFO, &io, nullptr, option, nullptr);
764     if (ret != ERR_NONE) {
765         MEDIA_ERR_LOG("PalyerCallbackImpl::OnInfo failed\n");
766     }
767 }
768 
OnRewindToComplete()769 void PalyerCallbackImpl::OnRewindToComplete()
770 {
771     IpcIo io;
772     uint8_t tmpData[DEFAULT_IPC_SIZE];
773     IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
774     MessageOption option;
775     MessageOptionInit(&option);
776     option.flags = TF_OP_ASYNC;
777     int32_t ret = SendRequest(sid_, ON_REWIND_TO_COMPLETE, &io, nullptr, option, nullptr);
778     if (ret != ERR_NONE) {
779         MEDIA_ERR_LOG("PalyerCallbackImpl::OnRewindToComplete failed\n");
780     }
781 }
782 }
783 }
784