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