blob: 994ef1b39f518d579bc006ff76444830dd25f4ec [file] [log] [blame]
zhipeng.he60bbc802021-09-13 16:12:40 +08001/*
2 * Copyright (c) 2020 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 */
9#include <stdio.h>
10#include <string.h>
11#include <signal.h>
12#include <fstream>
13#include <unistd.h>
14#include <sys/time.h>
15#include <cstdlib>
16#include <time.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
20#include <thread>
21#include <atomic>
22#include <map>
23#include <mutex>
24#include <queue>
25#include <thread>
26#include <condition_variable>
27#include <chrono>
28#include <sys/time.h>
29#include <memory>
30#include <getopt.h>
31#include <chrono>
32#include <AmTsPlayer.h>
33#include <termios.h>
34
35#include <sys/select.h>
36#include <termios.h>
37#include <sys/ioctl.h>
38
39#include <iostream>
40
41using namespace std;
42
43#define ONLY_ONE_VIDEO 0
44
45#if ONLY_ONE_VIDEO
46const int changNum = 1;
47#else
48const int changNum = 2;
49#endif
50
51am_tsplayer_handle g_session[changNum] = {0};
52
53typedef struct {
54 char tsFilePatch[50];
55 am_tsplayer_video_codec videoFmt;
56 am_tsplayer_audio_codec audioFmt;
57 int vpid;
58 int apid;
59 am_tsplayer_input_source_type inPutTsType;
60 am_tsplayer_input_buffer_type drmmode;
61 int index;
62 bool run;
63 bool mute;
64 bool setAudio;
65 pthread_t mThread;
66} TsParams;
67
68void video_callback(void *user_data, am_tsplayer_event *event)
69{
70 //UNUSED(user_data);
71 TsParams* mTsParams = (TsParams*)user_data;
72 //printf("video_callback type %d\n", event? event->type : 0);
73 switch (event->type) {
74 case AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED:
75 {
76 printf("index:%d [evt] AM_TSPLAYER_EVENT_TYPE_VIDEO_CHANGED: %d x %d @%d [%d]\n",
77 mTsParams->index,
78 event->event.video_format.frame_width,
79 event->event.video_format.frame_height,
80 event->event.video_format.frame_rate,
81 event->event.video_format.frame_aspectratio);
82 break;
83 }
84 case AM_TSPLAYER_EVENT_TYPE_USERDATA_AFD:
85 case AM_TSPLAYER_EVENT_TYPE_USERDATA_CC:
86 {
87 uint8_t* pbuf = event->event.mpeg_user_data.data;
88 uint32_t size = event->event.mpeg_user_data.len;
89 printf("index:%d [evt] USERDATA [%d] : %x-%x-%x-%x %x-%x-%x-%x ,size %d\n",
90 mTsParams->index,event->type, pbuf[0], pbuf[1], pbuf[2], pbuf[3],
91 pbuf[4], pbuf[5], pbuf[6], pbuf[7], size);
92 //UNUSED(pbuf);
93 //UNUSED(size);
94 break;
95 }
96 case AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME:
97 {
98 printf("index:%d [evt] AM_TSPLAYER_EVENT_TYPE_FIRST_FRAME\n",mTsParams->index);
99 break;
100 }
101 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_VIDEO:
102 {
103 printf("index:%d [evt] AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_VIDEO\n",mTsParams->index);
104 break;
105 }
106 case AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO:
107 {
108 printf("index:%d [evt] AM_TSPLAYER_EVENT_TYPE_DECODE_FIRST_FRAME_AUDIO\n",mTsParams->index);
109 break;
110 }
111 case AM_TSPLAYER_EVENT_TYPE_AV_SYNC_DONE:
112 {
113 printf("index:%d [evt] AM_TSPLAYER_EVENT_TYPE_AV_SYNC_DONE\n",mTsParams->index);
114 break;
115 }
116 case AM_TSPLAYER_EVENT_TYPE_INPUT_VIDEO_BUFFER_DONE:
117 {
118 // printf("[evt] AM_TSPLAYER_EVENT_TYPE_INPUT_VIDEO_BUFFER_DONE,%p\n",event->event.ptr);
119 break;
120 }
121 case AM_TSPLAYER_EVENT_TYPE_INPUT_AUDIO_BUFFER_DONE:
122 {
123 // printf("[evt] AM_TSPLAYER_EVENT_TYPE_INPUT_AUDIO_BUFFER_DONE\n");
124 break;
125 }
126 default:
127 break;
128 }
129}
130
131void* TsPlayerThread(void *arg) {
132 TsParams* mTsParams = (TsParams*)arg;
133 mTsParams->run = true;
134 std::string inputTsName(mTsParams->tsFilePatch);
135 am_tsplayer_handle session;
136 am_tsplayer_avsync_mode avsyncMode= TS_SYNC_AMASTER;
137 am_tsplayer_video_trick_mode vTrickMode = AV_VIDEO_TRICK_MODE_NONE;
138 int kRwSize = 188*300;
139 int kRwTimeout = 30000;
140 char buf[kRwSize];
141 uint64_t fsize = 0;
142 ifstream file(inputTsName.c_str(), ifstream::binary);
143 if (mTsParams->inPutTsType == TS_MEMORY) {
144 file.seekg(0, file.end);
145 fsize = file.tellg();
146 if (fsize <= 0) {
147 printf("file %s size %lld return\n", inputTsName.c_str(), fsize);
148 return 0;
149 }
150 file.seekg(0, file.beg);
151 }
152 printf("inde:%d file name = %s is_open %d, size %lld, inPutTsType %d drmmode:%d \n",
153 mTsParams->index,
154 inputTsName.c_str(),
155 file.is_open(),
156 fsize,
157 mTsParams->inPutTsType,
158 mTsParams->drmmode);
159 int x = 0, y = 0, w = 0, h = 0;
160 int tunnelid = 0;
161 switch (mTsParams->index) {
162 case 0:
163 tunnelid = 0;
164 x = 0;
165 y = 0;
166 w = 960;
167 h = 540;
168 break;
169 case 1:
170 tunnelid = 1;
171 x = 960;
172 y = 0;
173 w = 960;
174 h = 540;
175 break;
176 case 2:
177 tunnelid = 2;
178 x = 0;
179 y = 540;
180 w = 960;
181 h = 540;
182 break;
183 case 3:
184 tunnelid = 3;
185 x = 960;
186 y = 540;
187 w = 960;
188 h = 540;
189 break;
190 default:
191 break;
192 }
193
194
195 am_tsplayer_init_params parm = {mTsParams->inPutTsType, mTsParams->drmmode, mTsParams->index, 0};
196 AmTsPlayer_create(parm, &session);
197 g_session[mTsParams->index] = session;
198 AmTsPlayer_setSurface(session,(void*)&tunnelid);
199 AmTsPlayer_setVideoWindow(session, x, y, w, h);
200
201
202 uint32_t versionM, versionL;
203 AmTsPlayer_getVersion(&versionM, &versionL);
204 uint32_t instanceno;
205 AmTsPlayer_getInstansNo(session, &instanceno);
206 AmTsPlayer_setWorkMode(session, TS_PLAYER_MODE_NORMAL);
207 AmTsPlayer_registerCb(session, video_callback, (void*)mTsParams);
208 AmTsPlayer_setSyncMode(session, avsyncMode);
209
210 am_tsplayer_video_params vparm;
211 vparm.codectype = mTsParams->videoFmt;
212 vparm.pid = mTsParams->vpid;
213 AmTsPlayer_setVideoParams(session, &vparm);
214 AmTsPlayer_startVideoDecoding(session);
215
216 am_tsplayer_audio_params aparm;
217 aparm.codectype = mTsParams->audioFmt;
218 aparm.pid = mTsParams->apid;
219 AmTsPlayer_setAudioMute(session,false,mTsParams->mute);
220 AmTsPlayer_setAudioParams(session, &aparm);
221 AmTsPlayer_startAudioDecoding(session);
222
223 AmTsPlayer_showVideo(session);
224 AmTsPlayer_setTrickMode(session, vTrickMode);
225
226 am_tsplayer_input_buffer ibuf = {TS_INPUT_BUFFER_TYPE_NORMAL, (char*)buf, 0};
227 am_tsplayer_result res;
228 while (mTsParams->inPutTsType)
229 {
230 if (file.eof()) {
231 printf("file read eof index:%d\n",mTsParams->index);
232 break;
233 }
234
235 file.read(buf, (int)kRwSize);
236 ibuf.buf_size = kRwSize;
237
238 int retry = 100;
239 do {
240 if (!mTsParams->run) {
241 printf("break by quit******index:%d \n",mTsParams->index);
242 break;
243 }
244 res = AmTsPlayer_writeData(session, &ibuf, kRwTimeout);
245 if (res == AM_TSPLAYER_ERROR_RETRY ) {
246 usleep(300000);
247 } else {
248 break;
249 }
250 } while(res || retry-- > 0);
251
252 if (!mTsParams->run) {
253 break;
254 }
255 }
256 while (mTsParams->inPutTsType == TS_DEMOD &&
257 mTsParams->run) {
258 usleep(1000000);
259 }
260 mTsParams->run = false;
261
262 printf("AmTsPlayer_stopVideoDecoding index:%d\n",mTsParams->index);
263 AmTsPlayer_stopVideoDecoding(session);
264 AmTsPlayer_stopAudioDecoding(session);
265 printf("AmTsPlayer_release index:%d\n",mTsParams->index);
266 AmTsPlayer_release(session);
267 printf("AmTsPlayer_release ok index:%d\n",mTsParams->index);
268 return NULL;
269}
270
271void signHandler(int iSignNo) {
272 (void) iSignNo;
273 return;
274}
275
276int _kbhit() {
277 static const int STDIN = 0;
278 static bool initialized = false;
279
280 if (!initialized) {
281 // Use termios to turn off line buffering
282 termios term;
283 tcgetattr(STDIN, &term);
284 term.c_lflag &= ~ICANON;
285 tcsetattr(STDIN, TCSANOW, &term);
286 setbuf(stdin, NULL);
287 initialized = true;
288 }
289
290 int bytesWaiting;
291 ioctl(STDIN, FIONREAD, &bytesWaiting);
292 return bytesWaiting;
293}
294
295#if ONLY_ONE_VIDEO
296void changAudio(TsParams* mTsParams,int number) {
297 bool bSetMute = false;
298 bSetMute = (number == 0) ? false : true;
299 if (mTsParams[0].mute != bSetMute) {
300 mTsParams[0].mute = bSetMute;
301 mTsParams[0].setAudio = true;
302 AmTsPlayer_setAudioMute(g_session[0],false,mTsParams[0].mute);
303 printf("AmTsPlayer_setAudioMute : %d \n",mTsParams[0].mute);
304 }
305 return;
306}
307#else
308void changAudio(TsParams* mTsParams,int number) {
309 for (int i = 0 ; i < changNum;i++) {
310 if (mTsParams[i].mute == false) {
311 if (i == number) {
312 return;
313 } else {
314 mTsParams[i].mute = true;
315 mTsParams[i].setAudio = true;
316 AmTsPlayer_setAudioMute(g_session[i],false,mTsParams[i].mute);
317 printf("index:%d AmTsPlayer_setAudioMute : %d \n",i,mTsParams[i].mute);
318 break;
319 }
320 }
321 }
322 // usleep(200000);
323 mTsParams[number].mute = false;
324 mTsParams[number].setAudio = true;
325 AmTsPlayer_setAudioMute(g_session[number],false,mTsParams[number].mute);
326 printf("index:%d AmTsPlayer_setAudioMute : %d \n",number,mTsParams[number].mute);
327 return;
328}
329#endif
330
331void stopVideo(TsParams* mTsParams,int number) {
332 printf("index:%d AmTsPlayer_stopVideoDecoding g_session:0x%x \n",number,g_session[number]);
333 AmTsPlayer_stopVideoDecoding(g_session[number]);
334 return;
335}
336
337void startVideo(TsParams* mTsParams,int number) {
338 am_tsplayer_video_params vparm;
339 vparm.codectype = mTsParams->videoFmt;
340 vparm.pid = mTsParams->vpid;
341 printf("index:%d AmTsPlayer_startVideoDecoding g_session:0x%x \n",number,g_session[number]);
342 AmTsPlayer_setVideoParams(g_session[number], &vparm);
343 AmTsPlayer_startVideoDecoding(g_session[number]);
344
345 return;
346}
347
zhipeng.he92870d82022-03-15 18:06:20 +0800348void hideVideo(TsParams* mTsParams,int number) {
349 printf("index:%d AmTsPlayer_hideVideo g_session:0x%x \n",number,g_session[number]);
350 AmTsPlayer_hideVideo(g_session[number]);
351 return;
352}
353
354void showVideo(TsParams* mTsParams,int number) {
355 printf("index:%d AmTsPlayer_showVideo g_session:0x%x \n",number,g_session[number]);
356 AmTsPlayer_showVideo(g_session[number]);
357 return;
358}
359
360
zhipeng.he60bbc802021-09-13 16:12:40 +0800361
362void printfStatus(TsParams* mTsParams,char ch) {
363 int i = 0;
364 printf("\n");
365 printf("******************************\n");
366 printf("******* key input : %c ********\n",ch);
367 printf("******** q:quit ***********\n");
368 for (i = 0 ; i < changNum;i++) {
369 printf("*******%d:%d channel sound******\n",i,i);
370 }
371 for (i = 0 ; i < changNum;i++) {
372 printf("*** number:%d audioMute:%d ***\n",i,mTsParams[i].mute);
373 }
374 printf("******************************\n");
375
376}
377int main(int argc, char **argv)
378{
379 (void)argc;
380 (void)argv;
381 signal(SIGINT, signHandler);
382 TsParams mTsParams[changNum];
383 char const* file0 = "/data/1.ts";
384 int file0_len = strlen(file0);
385 memcpy(mTsParams[0].tsFilePatch,file0,file0_len);
386 mTsParams[0].tsFilePatch[file0_len] = '\0';
387 printf("file0:%s file0_len:%d\n",file0,file0_len);
388 mTsParams[0].videoFmt = AV_VIDEO_CODEC_H264;
389 mTsParams[0].audioFmt = AV_AUDIO_CODEC_AAC;
390 mTsParams[0].vpid = 0x100;
391 mTsParams[0].apid = 0x101;
392 mTsParams[0].inPutTsType = TS_MEMORY;
393 mTsParams[0].drmmode = TS_INPUT_BUFFER_TYPE_NORMAL;
394 mTsParams[0].index = 0;
395 mTsParams[0].mThread = 0;
396 mTsParams[0].run = true;
397 mTsParams[0].mute = false;
398 mTsParams[0].setAudio = false;
399
400
401#if !ONLY_ONE_VIDEO
402 char const* file1 = "/data/2.ts";
403 int file1_len = strlen(file1);
404 memcpy(mTsParams[1].tsFilePatch,file1,file1_len);
405 mTsParams[1].tsFilePatch[file1_len] = '\0';
406 mTsParams[1].videoFmt = AV_VIDEO_CODEC_H264;
407 mTsParams[1].audioFmt = AV_AUDIO_CODEC_MP3;
408 mTsParams[1].vpid = 0xc8;
409 mTsParams[1].apid = 0xc9;
410 mTsParams[1].inPutTsType = TS_MEMORY;
411 mTsParams[1].drmmode = TS_INPUT_BUFFER_TYPE_NORMAL;
412 mTsParams[1].index = 1;
413 mTsParams[1].mThread = 0;
414 mTsParams[1].run = true;
415 mTsParams[1].mute = true;
416 mTsParams[1].setAudio = false;
417#endif
418#if 0
419
420 char const* file2 = "/data/2.ts";
421 memcpy(mTsParams[2].tsFilePatch,file2,strlen(file2));
422 mTsParams[2].videoFmt = AV_VIDEO_CODEC_H264;
423 mTsParams[2].audioFmt = AV_AUDIO_CODEC_MP3;
424 mTsParams[2].vpid = 0xc8;
425 mTsParams[2].apid = 0xc9;
426 mTsParams[2].inPutTsType = TS_MEMORY;
427 mTsParams[2].drmmode = TS_INPUT_BUFFER_TYPE_NORMAL;
428 mTsParams[2].index = 2;
429 mTsParams[2].mThread = 0;
430 mTsParams[2].mute = true;
431 mTsParams[2].setAudio = false;
432
433 char const* file3 = "/data/2.ts";
434 memcpy(mTsParams[3].tsFilePatch,file3,strlen(file3));
435 mTsParams[3].videoFmt = AV_VIDEO_CODEC_H264;
436 mTsParams[3].audioFmt = AV_AUDIO_CODEC_MP3;
437 mTsParams[3].vpid = 0xc8;
438 mTsParams[3].apid = 0xc9;
439 mTsParams[3].inPutTsType = TS_MEMORY;
440 mTsParams[3].drmmode = TS_INPUT_BUFFER_TYPE_NORMAL;
441 mTsParams[3].index = 3;
442 mTsParams[3].mThread = 0;
443 mTsParams[3].run = true;
444 mTsParams[3].mute = true;
445 mTsParams[3].setAudio = false;
446#endif
447
448 int i = 0;
449 for (i = 0 ; i < changNum;i++) {
450 if (pthread_create(&(mTsParams[i].mThread), NULL, TsPlayerThread, &mTsParams[i]) == 0) {
451 printf("pthread_create %d ok %ld\n",i,mTsParams[i].mThread);
452 } else {
453 mTsParams[i].mThread = 0;
454 printf("pthread_create %d errno:%d (%s) \n",i,errno,strerror(errno));
455 }
456 usleep(5000);
457 }
458
459 char ch = 0;
460 bool isExit = false;
461 int run_false_index_count = 0;
462 while (1) {
463 if (_kbhit()) {
464 ch = getchar();
465 printfStatus(mTsParams,ch);
466 switch (ch) {
467 case 'q':
468 printf("----break\n");
469 for (i = 0 ; i < 4;i++) {
470 mTsParams[i].run = false;
471 }
472 isExit = true;
473 break;
474 case '0':
475 changAudio(mTsParams, 0);
476 break;
477 case '1':
478 changAudio(mTsParams, 1);
479 break;
480 case '2':
481 changAudio(mTsParams, 2);
482 break;
483 case '3':
484 changAudio(mTsParams, 3);
485 break;
486 case 'p':
487 //stop video 2 decoding,test
488 stopVideo(mTsParams,changNum-1);
489 break;
490 case 'r':
491 //start video 2 decoding,test
492 startVideo(mTsParams,changNum-1);
493 break;
zhipeng.he92870d82022-03-15 18:06:20 +0800494 case 'h':
495 printf("----hide the video 1\n");
496 hideVideo(mTsParams,changNum-1);
497 break;
498 case 's':
499 printf("----show the video 1\n");
500 showVideo(mTsParams,changNum-1);
501 break;
zhipeng.he60bbc802021-09-13 16:12:40 +0800502 default:
503 break;
504 }
505 ch = 0;
506 }
zhipeng.hef31a5c82021-11-17 20:50:31 +0800507 run_false_index_count = 0;
zhipeng.he60bbc802021-09-13 16:12:40 +0800508 for (i = 0 ; i < changNum;i++) {
509 if (mTsParams[i].run == false) {
510 run_false_index_count++;
511 }
512 }
513 if (run_false_index_count == changNum) {
514 isExit = true;
515 printf("---->all channel exit changNum:%d \n",changNum);
516 }
517 if (isExit) {
518 break;
519 }
520 usleep(200000);
521 }
522
523 for (i = 0 ; i < changNum;i++) {
524 printf("---->pthread_join %d \n",i);
525 mTsParams[i].run = false;
526 if (mTsParams[i].mThread != 0) {
527 pthread_join(mTsParams[i].mThread, NULL);
528 mTsParams[i].mThread = 0;
529 }
530 }
531
532 printf("---->pthread_join end\n");
533 return 0;
534}