source: titan/libeplayer3/main/exteplayer.c @ 40322

Last change on this file since 40322 was 40322, checked in by obi, 6 years ago

update libeplayer3 new version only buffer

File size: 27.5 KB
Line 
1/*
2 * eplayer3: command line playback using libeplayer3
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <sched.h>
25#include <signal.h>
26
27#include <sys/ioctl.h>
28#include <sys/prctl.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/time.h>
32#include <sys/resource.h>
33#include <sys/mman.h>
34
35#include "common.h"
36
37#define DUMP_BOOL(x) 0 == x ? "false"  : "true"
38#define IPTV_MAX_FILE_PATH 1024
39
40extern int ffmpeg_av_dict_set(const char *key, const char *value, int flags);
41extern void       aac_software_decoder_set(const int32_t val);
42extern void  aac_latm_software_decoder_set(const int32_t val);
43extern void       dts_software_decoder_set(const int32_t val);
44extern void       wma_software_decoder_set(const int32_t val);
45extern void       ac3_software_decoder_set(const int32_t val);
46extern void      eac3_software_decoder_set(const int32_t val);
47extern void       mp3_software_decoder_set(const int32_t val);
48extern void            rtmp_proto_impl_set(const int32_t val);
49extern void        flv2mpeg4_converter_set(const int32_t val);
50
51extern void pcm_resampling_set(int32_t val);
52extern void stereo_software_decoder_set(int32_t val);
53extern void insert_pcm_as_lpcm_set(int32_t val);
54extern void progressive_playback_set(int32_t val);
55
56extern OutputHandler_t         OutputHandler;
57extern PlaybackHandler_t       PlaybackHandler;
58extern ContainerHandler_t      ContainerHandler;
59extern ManagerHandler_t        ManagerHandler;
60
61static Context_t *g_player = NULL;
62
63static void map_inter_file_path(char *filename)
64{
65    if (0 == strncmp(filename, "iptv://", 7))
66    {
67        FILE *f = fopen(filename + 7, "r");
68        if (NULL != f)
69        {
70            size_t num = fread(filename, 1, IPTV_MAX_FILE_PATH-1, f);
71            fclose(f);
72            if (num > 0 && filename[num-1] == '\n')
73            {
74                filename[num-1] = '\0';
75            }
76            else
77            {
78                filename[num] = '\0';
79            }
80        }
81    }
82}
83
84static int kbhit(void)
85{
86        struct timeval tv;
87        fd_set read_fd;
88
89        tv.tv_sec=1;
90        tv.tv_usec=0;
91
92        FD_ZERO(&read_fd);
93        FD_SET(0,&read_fd);
94
95        if(-1 == select(1, &read_fd, NULL, NULL, &tv))
96        {
97            return 0;
98        }
99
100        if(FD_ISSET(0,&read_fd))
101        {
102            return 1;
103        }
104
105        return 0;
106}
107
108static void SetBuffering()
109{
110    static char buff[2048];
111    memset( buff, '\0', sizeof(buff));
112    if( setvbuf(stderr, buff, _IOLBF, sizeof(buff)) )
113    {
114        printf("SetBuffering: failed to change the buffer of stderr\n");
115    }
116   
117    // make fgets not blocking
118    int flags = fcntl(stdin->_fileno, F_GETFL, 0);
119    fcntl(stdin->_fileno, F_SETFL, flags | O_NONBLOCK);
120}
121
122static void SetNice(int prio)
123{
124#if 0
125    setpriority(PRIO_PROCESS, 0, -8);
126   
127    int prio = sched_get_priority_max(SCHED_RR) / 2;
128    struct sched_param param = {
129        .sched_priority = prio
130    };
131    sched_setscheduler(0, SCHED_RR, &param);
132#else
133    int prevPrio = getpriority(PRIO_PROCESS, 0);
134    if (-1 == setpriority(PRIO_PROCESS, 0, prio))
135    {
136        printf("setpriority - failed\n");
137    }
138#endif
139}
140
141static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff)
142{
143    int commandRetVal = 0;
144   
145    if (NULL == ptrManager || NULL == argvBuff || 2 != strnlen(argvBuff, 2))
146    {
147        return -1;
148    }
149   
150    switch (argvBuff[1])
151    {
152        case 'l':
153        {
154            TrackDescription_t *TrackList = NULL;
155            ptrManager->Command(g_player, MANAGER_LIST, &TrackList);
156            if( NULL != TrackList)
157            {
158                int i = 0;
159                fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]);
160                for (i = 0; TrackList[i].Id >= 0; ++i)
161                {
162                    if(0 < i)
163                    {
164                        fprintf(stderr, ", ");
165                    }
166                    fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", TrackList[i].Id , TrackList[i].Encoding, TrackList[i].Name);
167                    free(TrackList[i].Encoding);
168                    free(TrackList[i].Name);
169                }
170                fprintf(stderr, "]}\n");
171                free(TrackList);
172            }
173            else
174            {
175                // not tracks
176                fprintf(stderr, "{\"%c_%c\": []}\n", argvBuff[0], argvBuff[1]);
177            }
178            break;
179        }
180        case 'c':
181        {
182           
183            TrackDescription_t *track = NULL;
184            ptrManager->Command(g_player, MANAGER_GET_TRACK_DESC, &track);
185            if (NULL != track)
186            {
187                if ('a' == argvBuff[0] || 's' == argvBuff[0])
188                {
189                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], track->Id , track->Encoding, track->Name);
190                }
191                else // video
192                {
193                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \
194                    argvBuff[0], argvBuff[1], track->Id , track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den);
195                }
196                free(track->Encoding);
197                free(track->Name);
198                free(track);
199            }
200            else
201            {
202                // no tracks
203                if ('a' == argvBuff[0] || 's' == argvBuff[0])
204                {
205                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], -1, "", "");
206                }
207                else // video
208                {
209                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d}}\n", argvBuff[0], argvBuff[1], -1, "", "", -1, -1, 0, -1);
210                }
211            }
212            break;
213        }
214        default:
215        {
216            /* switch command available only for audio and subtitle tracks */
217            if ('a' == argvBuff[0] || 's' == argvBuff[0])
218            {
219                int ok = 0;
220                int id = -1;
221                if ('i' == argvBuff[1])
222                {
223                    int idx = -1;
224                    ok = sscanf(argvBuff+2, "%d", &idx);
225                    if (idx >= 0)
226                    {
227                        TrackDescription_t *TrackList = NULL;
228                        ptrManager->Command(g_player, MANAGER_LIST, &TrackList);
229                        if( NULL != TrackList)
230                        {
231                            int i = 0;
232                            for (i = 0; TrackList[i].Id >= 0; ++i)
233                            {
234                                if (idx == i)
235                                {
236                                    id = TrackList[i].Id;
237                                }
238                                free(TrackList[i].Encoding);
239                                free(TrackList[i].Name);
240                            }
241                            free(TrackList);
242                        }
243                    }
244                    else
245                    {
246                        id = idx;
247                    }
248                }
249                else
250                {
251                    ok = sscanf(argvBuff+1, "%d", &id);
252                }
253               
254                if(id >= 0 || (1 == ok && id == -1))
255                {
256                    commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void*)&id);
257                    fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"sts\":%d}}\n", argvBuff[0], 's', id, commandRetVal);
258                }
259            }
260            break;
261        }
262    }
263   
264    return commandRetVal;
265}
266
267static void UpdateVideoTrack()
268{
269    HandleTracks(g_player->manager->video, (PlaybackCmd_t)-1, "vc");
270}
271
272static int ParseParams(int argc,char* argv[], char *file, char *audioFile, int *pAudioTrackIdx, int *subtitleTrackIdx)
273{   
274    int ret = 0;
275    int c;
276    int digit_optind = 0;
277    int aopt = 0, bopt = 0;
278    char *copt = 0, *dopt = 0;
279    while ( (c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:t:9:0:1:4:f:")) != -1)
280    {
281        switch (c)
282        {
283        case 'a':
284        {
285            int flag = atoi(optarg);
286            printf("Software decoder will be used for AAC codec\n");
287            aac_software_decoder_set(flag & 0x01);
288            aac_latm_software_decoder_set(flag & 0x02);
289            break;
290        }
291        case 'e':
292            printf("Software decoder will be used for EAC3 codec\n");
293            eac3_software_decoder_set(1);
294            break;
295        case '3':
296            printf("Software decoder will be used for AC3 codec\n");
297            ac3_software_decoder_set(1);
298            break;
299        case 'd':
300            printf("Software decoder will be used for DTS codec\n");
301            dts_software_decoder_set(1);
302            break;
303        case 'm':
304            printf("Software decoder will be used for MP3 codec\n");
305            mp3_software_decoder_set(1);
306            break;
307        case 'w':
308            printf("Software decoder will be used for WMA codec\n");
309            wma_software_decoder_set(1);
310            break;
311        case 'l':
312            printf("Audio software decoding as LPCM\n");
313            insert_pcm_as_lpcm_set(1);
314            break;
315        case 's':
316            printf("Software decoder will decode to stereo\n");
317            stereo_software_decoder_set(1);
318            break;
319        case 'r':
320            printf("Software decoder do not use PCM resampling\n");
321            pcm_resampling_set(0);
322            break;
323        case 'o':
324            printf("Set progressive download to %d\n", atoi(optarg));
325            progressive_playback_set(atoi(optarg));
326            break;
327        case 'p':
328            SetNice(atoi(optarg));
329            break;
330        case 't':
331            *pAudioTrackIdx = atoi(optarg);
332            break;
333        case '9':
334            *subtitleTrackIdx = atoi(optarg);
335            break;
336        case 'x':
337            strncpy(audioFile, optarg, IPTV_MAX_FILE_PATH-1);
338            map_inter_file_path(audioFile);
339            break;
340        case 'h':
341            ffmpeg_av_dict_set("headers", optarg, 0);
342            break;
343        case 'u':
344            ffmpeg_av_dict_set("user-agent", optarg, 0);
345            break;
346        case 'c':
347            printf("For now cookies should be set via headers option!\n");
348            ffmpeg_av_dict_set("cookies", optarg, 0);
349            break;
350        case 'i':
351            printf("Play in (infinity) loop.\n");
352            PlaybackHandler.isLoopMode = 1;
353            break;
354        case 'v':
355            printf("Use live TS stream mode.\n");
356            PlaybackHandler.isTSLiveMode = 1;
357            break;
358        case 'n':
359            printf("Force rtmp protocol implementation\n");
360            rtmp_proto_impl_set(atoi(optarg));
361            break;
362        case '0':
363            ffmpeg_av_dict_set("video_rep_index", optarg, 0);
364            break;
365        case '1':
366            ffmpeg_av_dict_set("audio_rep_index", optarg, 0);
367            break;
368        case '4':
369#ifdef HAVE_FLV2MPEG4_CONVERTER
370            flv2mpeg4_converter_set(atoi(optarg));
371#endif
372            break;
373        case 'f':
374        {
375            char *ffopt = strdup(optarg);
376            char *ffval = strchr(ffopt, '=');
377            if (ffval)
378            {
379                *ffval = '\0';
380                ffval += 1;
381                ffmpeg_av_dict_set(ffopt, ffval, 0);
382            }
383            free(ffopt);
384            break;
385        }
386        default:
387            printf ("?? getopt returned character code 0%o ??\n", c);
388            ret = -1;
389        }
390    }
391   
392    if (0 == ret && optind < argc)
393    {
394        ret = 0;
395       
396        if(NULL == strstr(argv[optind], "://"))
397        {
398            strcpy(file, "file://");
399        }
400        strcat(file, argv[optind]);
401        map_inter_file_path(file);
402        printf("file: [%s]\n", file);
403        ++optind;
404    }
405    else
406    {
407        ret = -1;
408    }
409    return ret;
410}
411
412int main(int argc, char* argv[])
413{
414    char file[IPTV_MAX_FILE_PATH];
415    memset(file, '\0', sizeof(file));
416   
417    char audioFile[IPTV_MAX_FILE_PATH];
418    memset(audioFile, '\0', sizeof(audioFile));
419   
420    int audioTrackIdx = -1;
421    int subtitleTrackIdx = -1;
422   
423    char argvBuff[256];
424    memset(argvBuff, '\0', sizeof(argvBuff));
425    int commandRetVal = -1;
426    /* inform client that we can handle additional commands */
427    fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 34);
428
429    if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx))
430    {
431        printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n");
432        printf("[-a 0|1|2|3] AAC software decoding - 1 bit - AAC ADTS, 2 - bit AAC LATM\n");
433        printf("[-e] EAC3 software decoding\n");
434        printf("[-3] AC3 software decoding\n");
435        printf("[-d] DTS software decoding\n");
436        printf("[-m] MP3 software decoding\n");
437        printf("[-w] WMA1, WMA2, WMA/PRO software decoding\n");
438        printf("[-l] software decoder use LPCM for injection (otherwise wav PCM will be used)\n");
439        printf("[-s] software decoding as stereo [downmix]\n");
440#ifdef HAVE_FLV2MPEG4_CONVERTER
441        printf("[-4 0|1] - disable/enable flv2mpeg4 converter\n");
442#endif
443        printf("[-i] play in infinity loop\n");
444        printf("[-v] switch to live TS stream mode\n");
445        printf("[-n 0|1|2] rtmp force protocol implementation auto(0) native/ffmpeg(1) or librtmp(2)\n");       
446        printf("[-o 0|1] set progressive download\n");
447        printf("[-p value] nice value\n");
448        printf("[-t id] audio track ID switched on at start\n");
449        printf("[-9 id] subtitle track ID switched on at start\n");
450        printf("[-h headers] set custom HTTP headers \"Name: value\\r\\nName: value\\r\\n\"\n");
451        printf("[-u user-agent] set custom http User-Agent header\n");
452        printf("[-c cookies] set cookies - not working at now, please use -h instead\n");
453        printf("[-x separateAudioUri]\n");
454        printf("[-0 idx] video MPEG-DASH representation index\n");
455        printf("[-1 idx] audio MPEG-DASH representation index\n");
456        printf("[-f ffopt=ffval] any other ffmpeg option\n");
457       
458        exit(1);
459    }
460   
461    g_player = malloc(sizeof(Context_t));
462    if(NULL == g_player)
463    {
464        printf("g_player allocate error\n");
465        exit(1);
466    }
467
468    g_player->playback    = &PlaybackHandler;
469    g_player->output      = &OutputHandler;
470    g_player->container   = &ContainerHandler;
471    g_player->manager     = &ManagerHandler;
472
473    // make sure to kill myself when parent dies
474    prctl(PR_SET_PDEATHSIG, SIGKILL);
475
476    SetBuffering();
477   
478    //Registrating output devices
479    g_player->output->Command(g_player, OUTPUT_ADD, "audio");
480    g_player->output->Command(g_player, OUTPUT_ADD, "video");
481    g_player->output->Command(g_player, OUTPUT_ADD, "subtitle");
482
483    g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack);
484    if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4))
485    {
486        g_player->playback->noprobe = 1;
487    }
488
489    PlayFiles_t playbackFiles = {file, NULL};
490    if('\0' != audioFile[0])
491    {
492        playbackFiles.szSecondFile = audioFile;
493    }
494   
495    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_OPEN, &playbackFiles);
496    fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, file, commandRetVal);
497    if(commandRetVal < 0)
498    {
499        if(NULL != g_player)
500        {
501            free(g_player);
502        }
503        return 10;
504    }
505   
506    {
507        commandRetVal = g_player->output->Command(g_player, OUTPUT_OPEN, NULL);
508        fprintf(stderr, "{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal);
509        commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PLAY, NULL);
510        fprintf(stderr, "{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal);
511       
512        if (g_player->playback->isPlaying)
513        {
514            HandleTracks(g_player->manager->video, (PlaybackCmd_t)-1, "vc");
515            HandleTracks(g_player->manager->audio, (PlaybackCmd_t)-1, "al");
516            if (audioTrackIdx >= 0)
517            {
518                static char cmd[128] = ""; // static to not allocate on stack
519                sprintf(cmd, "ai%d\n", audioTrackIdx);
520                commandRetVal = HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, cmd);
521            }
522            HandleTracks(g_player->manager->audio, (PlaybackCmd_t)-1, "ac");
523           
524            HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t)-1, "sl");
525            if (subtitleTrackIdx >= 0)
526            {
527                static char cmd[128] = ""; // static to not allocate on stack
528                sprintf(cmd, "si%d\n", subtitleTrackIdx);
529                commandRetVal = HandleTracks(g_player->manager->subtitle, PLAYBACK_SWITCH_SUBTITLE, cmd);
530            }
531            HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t)-1, "sc");
532        }
533
534        while(g_player->playback->isPlaying)
535        {
536            /* we made fgets non blocking */
537            if( NULL == fgets(argvBuff, sizeof(argvBuff)-1 , stdin) )
538            {
539                /* wait for data - max 1s */
540                kbhit();
541                continue;
542            }
543
544            if(0 == argvBuff[0])
545            {
546                continue;
547            }
548           
549            switch(argvBuff[0])
550            {
551            case 'v':
552            {
553                HandleTracks(g_player->manager->video, (PlaybackCmd_t)-1, argvBuff);
554            break;
555            }
556            case 'a':
557            {
558                HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, argvBuff);
559            break;
560            }
561            case 's':
562            {
563                HandleTracks(g_player->manager->subtitle, PLAYBACK_SWITCH_SUBTITLE, argvBuff);
564            break;
565            }
566            case 'q':
567            {
568                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_STOP, NULL);
569                fprintf(stderr, "{\"PLAYBACK_STOP\":{\"sts\":%d}}\n", commandRetVal);
570                break;
571            }
572            case 'c':
573            {
574                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_CONTINUE, NULL);
575                fprintf(stderr, "{\"PLAYBACK_CONTINUE\":{\"sts\":%d}}\n", commandRetVal);
576                break;
577            }
578            case 'p':
579            {
580                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PAUSE, NULL);
581                fprintf(stderr, "{\"PLAYBACK_PAUSE\":{\"sts\":%d}}\n", commandRetVal);
582                break;
583            }
584            case 'm':
585            {
586                int speed = 0;
587                sscanf(argvBuff+1, "%d", &speed);
588
589                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SLOWMOTION, &speed);
590                fprintf(stderr, "{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
591                break;
592            }
593            case 'o':
594            {
595                int flags = 0;
596                if( 1 == sscanf(argvBuff+1, "%d", &flags) )
597                {
598                    progressive_playback_set(flags);
599                    fprintf(stderr, "{\"PROGRESSIVE_DOWNLOAD\":{\"flags\":%d, \"sts\":0}}\n", flags);
600                }
601                break;
602            }
603            case 'f':
604            {
605                int speed = 0;
606                sscanf(argvBuff+1, "%d", &speed);
607
608                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTFORWARD, &speed);
609                fprintf(stderr, "{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
610                break;
611            }
612            case 'b':
613            {
614                int speed = 0;
615                sscanf(argvBuff+1, "%d", &speed);
616
617                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTBACKWARD, &speed);
618                fprintf(stderr, "{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal);
619                break;
620            }
621            case 'g':
622            {
623                int32_t gotoPos = 0;
624                int64_t length = 0;
625                int32_t lengthInt = 0;
626                int64_t sec = 0;
627                int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check
628               
629                sscanf(argvBuff+2, "%d", &gotoPos);
630                if(0 <= gotoPos || force)
631                {
632                    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void*)&length);
633                    fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
634
635                    lengthInt = (int32_t)length;
636                    if(10 <= lengthInt || force)
637                    {
638                        sec = gotoPos;
639                        if(!force && gotoPos >= lengthInt)
640                        {
641                            sec = lengthInt - 10;
642                        }
643                       
644                        commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK_ABS, (void*)&sec);
645                        fprintf(stderr, "{\"PLAYBACK_SEEK_ABS\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal);
646                    }
647                }
648                break;
649            }
650            case 'k':
651            {
652                int32_t seek = 0;
653                int64_t length = 0;
654                int32_t lengthInt = 0;
655                int64_t sec = 0;
656                int64_t pts = 0;
657                int32_t CurrentSec = 0;
658                int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check
659               
660                sscanf(argvBuff+2, "%d", &seek);
661               
662                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts);
663                CurrentSec = (int32_t)(pts / 90000);
664                if (0 == commandRetVal)
665                {
666                    fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal);
667                }
668                if(0 == commandRetVal || force)
669                {                   
670                    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void*)&length);
671                    fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
672                   
673                    lengthInt = (int32_t)length;
674                    if(10 <= lengthInt || force )
675                    {
676                        int32_t ergSec = CurrentSec + seek;
677                        if(!force && 0 > ergSec)
678                        {
679                            sec = CurrentSec * -1; // jump to start position
680                        }
681                        else if(!force && ergSec >= lengthInt)
682                        {
683                            sec = (lengthInt - CurrentSec) - 5;
684                            if(0 < sec)
685                            {
686                                sec = 0; // no jump we are at the end
687                            }
688                        }
689                        else
690                        {
691                            sec = seek;
692                        }
693                    }
694                    commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK, (void*)&sec);
695                    fprintf(stderr, "{\"PLAYBACK_SEEK\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal);
696                }
697                break;
698            }
699            case 'l':
700            {
701                int64_t length = 0;
702                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void*)&length);
703                fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal);
704                break;
705            }
706            case 'j':
707            {
708                int64_t pts = 0;
709                commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts);
710                if (0 == commandRetVal)
711                {
712                    fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal);
713                }
714                break;
715            }
716            case 'i':
717            {
718                PlaybackHandler_t *ptrP = g_player->playback;
719                if(ptrP)
720                {
721                    fprintf(stderr, "{\"PLAYBACK_INFO\":{ \"isPlaying\":%s, \"isPaused\":%s, \"isForwarding\":%s, \"isSeeking\":%s, \"isCreationPhase\":%s,", \
722                    DUMP_BOOL(ptrP->isPlaying), DUMP_BOOL(ptrP->isPaused), DUMP_BOOL(ptrP->isForwarding), DUMP_BOOL(ptrP->isSeeking), DUMP_BOOL(ptrP->isCreationPhase) );
723                    fprintf(stderr, "\"BackWard\":%d, \"SlowMotion\":%d, \"Speed\":%d, \"AVSync\":%d,", ptrP->BackWard, ptrP->SlowMotion, ptrP->Speed, ptrP->AVSync);
724                    fprintf(stderr, " \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \
725                    DUMP_BOOL(ptrP->isVideo), DUMP_BOOL(ptrP->isAudio), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(ptrP->abortRequested) );
726                }
727               
728                break;
729            }
730            case 'n':
731            {
732                uint8_t loop = 0;
733                if( '1' == argvBuff[1] || '0' == argvBuff[1] )
734                {
735                    PlaybackHandler_t *ptrP = g_player->playback;
736                    if(ptrP)
737                    {
738                        ptrP->isLoopMode = '1' == argvBuff[1] ? 1 : 0;
739                        fprintf(stderr, "{\"N\":{ \"isLoop\":%s }}\n", DUMP_BOOL(ptrP->isLoopMode));
740                    }
741                }
742                break;
743            }
744           
745            default:
746            {
747                break;
748            }
749            }
750        }
751
752        g_player->output->Command(g_player, OUTPUT_CLOSE, NULL);
753    }
754   
755    if(NULL != g_player)
756    {
757        free(g_player);
758    }
759
760    //printOutputCapabilities();
761
762    exit(0);
763}
Note: See TracBrowser for help on using the repository browser.