source: titan/libeplayer3/playback/playback.c @ 44555

Last change on this file since 44555 was 44555, checked in by obi, 3 years ago

fix slowmotion

File size: 24.5 KB
Line 
1/*
2 * GPL
3 * duckbox 2010
4 */
5
6/* ***************************** */
7/* Includes                      */
8/* ***************************** */
9
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <sys/socket.h>
16#include <netdb.h>
17#include <sys/types.h>
18#include <dirent.h>
19#include <errno.h>
20#include <poll.h>
21#include <stdint.h>
22
23#include "playback.h"
24#include "common.h"
25#include "misc.h"
26
27/* ***************************** */
28/* Makros/Constants              */
29/* ***************************** */
30// SULGE DEBUG
31//#define SAM_WITH_DEBUG
32
33#ifdef SAM_WITH_DEBUG
34#define PLAYBACK_DEBUG
35#else
36#define PLAYBACK_SILENT
37#endif
38
39static short debug_level = 20;
40
41#ifdef PLAYBACK_DEBUG
42#define playback_printf(level, fmt, x...) do { \
43if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
44#else
45#define playback_printf(level, fmt, x...)
46#endif
47
48#ifndef PLAYBACK_SILENT
49#define playback_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
50#else
51#define playback_err(fmt, x...)
52#endif
53
54#define cERR_PLAYBACK_NO_ERROR      0
55#define cERR_PLAYBACK_ERROR        -1
56
57#define cMaxSpeed_ff   128 /* fixme: revise */
58#define cMaxSpeed_fr   -320 /* fixme: revise */
59
60/* ***************************** */
61/* Varaibles                     */
62/* ***************************** */
63
64/* ***************************** */
65/* Prototypes                    */
66/* ***************************** */
67extern void set_pause_timeout(uint8_t pause);
68static int32_t PlaybackTerminate(Context_t  *context);
69
70/* ***************************** */
71/* MISC Functions                */
72/* ***************************** */
73int8_t PlaybackDieNow(int8_t val)
74{
75    static int8_t dieNow = 0;
76    if(val)
77    {
78        dieNow = 1;
79    }
80    return dieNow;
81}
82
83/* ***************************** */
84/* Functions                     */
85/* ***************************** */
86
87static int PlaybackStop(Context_t  *context);
88
89static int PlaybackOpen(Context_t  *context, PlayFiles_t *pFiles)
90{
91    if (context->playback->isPlaying)
92    {
93        PlaybackStop(context);
94    }
95   
96    char *uri = pFiles->szFirstFile;
97   
98    playback_printf(10, "URI=%s\n", uri);
99
100    if (context->playback->isPlaying)
101    { // shouldn't happen
102        playback_err("playback already running\n");
103        return cERR_PLAYBACK_ERROR;
104    }
105
106    char * extension = NULL;
107
108    context->playback->uri = strdup(uri);
109
110    context->playback->isFile = 0;
111    context->playback->isHttp = 0;
112
113    if (!strncmp("file://", uri, 7) || !strncmp("myts://", uri, 7))
114    {
115        context->playback->isFile = 1;
116        if (!strncmp("myts://", uri, 7))
117        {
118            memcpy(context->playback->uri, "file", 4);
119            context->playback->noprobe = 1;
120        }
121        else
122        {
123            context->playback->noprobe = 0;
124        }
125
126        extension = getExtension(context->playback->uri+7);
127        if(!extension)
128        {
129            playback_err("Wrong extension (%s)\n", context->playback->uri+7);
130            return cERR_PLAYBACK_ERROR;
131        }
132    }
133    else if (strstr(uri, "://"))
134    {
135        context->playback->isHttp = 1;
136        extension = "mp3";
137        if (!strncmp("mms://", uri, 6))
138        {
139            // mms is in reality called rtsp, and ffmpeg expects this
140            char * tUri = (char*)malloc(strlen(uri) + 2);
141            strncpy(tUri+1, uri, strlen(uri)+1);
142            strncpy(tUri, "rtsp", 4);
143            free(context->playback->uri);
144            context->playback->uri = tUri;
145        }
146    }
147    else
148    {
149        playback_err("Unknown stream (%s)\n", uri);
150        return cERR_PLAYBACK_ERROR;
151    }
152
153    pFiles->szFirstFile = context->playback->uri;
154    if ((context->container->Command(context, CONTAINER_ADD, extension) < 0)
155        ||  (!context->container->selectedContainer)
156        ||  (context->container->selectedContainer->Command(context, CONTAINER_INIT, pFiles) < 0))
157    {
158        playback_err("CONTAINER_ADD failed\n");
159        return cERR_PLAYBACK_ERROR;
160    }
161
162    playback_printf(10, "exiting with value 0\n");
163
164    return cERR_PLAYBACK_NO_ERROR;
165}
166
167static int PlaybackClose(Context_t  *context)
168{
169    int ret = cERR_PLAYBACK_NO_ERROR;
170
171    playback_printf(10, "\n");
172
173    if (context->container->Command(context, CONTAINER_DEL, NULL) < 0)
174    {
175        playback_err("container delete failed\n");
176    }
177
178    context->manager->audio->Command(context, MANAGER_DEL, NULL);
179    context->manager->video->Command(context, MANAGER_DEL, NULL);
180
181    context->playback->isPaused     = 0;
182    context->playback->isPlaying    = 0;
183    context->playback->isForwarding = 0;
184    context->playback->BackWard     = 0;
185    context->playback->SlowMotion   = 0;
186    context->playback->Speed        = 0;
187    if(context->playback->uri)
188    {
189        free(context->playback->uri);
190        context->playback->uri = NULL;
191    }
192
193    playback_printf(10, "exiting with value %d\n", ret);
194
195    return ret;
196}
197
198static int PlaybackPlay(Context_t  *context)
199{
200    pthread_attr_t attr;
201    int ret = cERR_PLAYBACK_NO_ERROR;
202
203    playback_printf(10, "\n");
204
205    if (!context->playback->isPlaying)
206    {
207        context->playback->AVSync = 1;
208        context->output->Command(context, OUTPUT_AVSYNC, NULL);
209
210        context->playback->isCreationPhase = 1; // allows the created thread to go into wait mode
211        ret = context->output->Command(context, OUTPUT_PLAY, NULL);
212
213        if (ret != 0)
214        {
215            playback_err("OUTPUT_PLAY failed!\n");
216            playback_err("clearing isCreationPhase!\n");
217            context->playback->isCreationPhase = 0;     // allow thread to go into next state
218            context->playback->isPlaying       = 0;
219            context->playback->isPaused        = 0;
220            context->playback->isForwarding    = 0;
221            context->playback->BackWard        = 0;
222            context->playback->SlowMotion      = 0;
223            context->playback->Speed           = 0;
224            context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
225        }
226        else
227        {
228            context->playback->isPlaying    = 1;
229            context->playback->isPaused     = 0;
230            context->playback->isForwarding = 0;
231            context->playback->BackWard     = 0;
232            context->playback->SlowMotion   = 0;
233            context->playback->Speed        = 1;
234
235            playback_printf(10, "clearing isCreationPhase!\n");
236
237            context->playback->isCreationPhase = 0;     // allow thread to go into next state
238
239            ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL);
240            if (ret != 0) {
241                playback_err("CONTAINER_PLAY failed!\n");
242            }
243
244        }
245    }
246    else
247    {
248        playback_err("playback already running\n");
249        ret = cERR_PLAYBACK_ERROR;
250    }
251
252    playback_printf(10, "exiting with value %d\n", ret);
253
254    return ret;
255}
256
257static int PlaybackPause(Context_t  *context)
258{
259    int ret = cERR_PLAYBACK_NO_ERROR;
260
261    playback_printf(10, "\n");
262
263    if (context->playback->isPlaying && !context->playback->isPaused)
264    {
265        set_pause_timeout(1);
266//obi     
267        if(context->playback->SlowMotion)
268             context->output->Command(context, OUTPUT_CLEAR, NULL);
269//obi (end)
270
271        context->output->Command(context, OUTPUT_PAUSE, NULL);
272
273        context->playback->isPaused     = 1;
274        //context->playback->isPlaying  = 1;
275        context->playback->isForwarding = 0;
276        context->playback->BackWard     = 0;
277        context->playback->SlowMotion   = 0;
278        context->playback->Speed        = 1;
279    }
280    else
281    {
282        playback_err("playback not playing or already in pause mode\n");
283        ret = cERR_PLAYBACK_ERROR;
284    }
285
286    playback_printf(10, "exiting with value %d\n", ret);
287    return ret;
288}
289
290static int32_t PlaybackContinue(Context_t  *context)
291{
292    int32_t ret = cERR_PLAYBACK_NO_ERROR;
293
294    playback_printf(10, "\n");
295
296    if (context->playback->isPlaying &&
297       (context->playback->isPaused || context->playback->isForwarding ||
298        context->playback->BackWard || context->playback->SlowMotion))
299    {
300
301        set_pause_timeout(0);
302
303//obi     
304        if(context->playback->SlowMotion)
305             context->output->Command(context, OUTPUT_CLEAR, NULL);
306
307//obi (end)
308        context->output->Command(context, OUTPUT_CONTINUE, NULL);
309
310        context->playback->isPaused     = 0;
311        //context->playback->isPlaying  = 1;
312        context->playback->isForwarding = 0;
313        context->playback->BackWard     = 0;
314        context->playback->SlowMotion   = 0;
315        context->playback->Speed        = 1;
316    }
317    else
318    {
319        playback_err("continue not possible\n");
320        ret = cERR_PLAYBACK_ERROR;
321    }
322
323    playback_printf(10, "exiting with value %d\n", ret);
324    return ret;
325}
326
327static int32_t PlaybackStop(Context_t  *context)
328{
329    int32_t ret = cERR_PLAYBACK_NO_ERROR;
330
331    playback_printf(10, "\n");
332   
333    PlaybackDieNow(1);
334
335    if (context && context->playback && context->playback->isPlaying)
336    {
337
338        context->playback->isPaused     = 0;
339        context->playback->isPlaying    = 0;
340        context->playback->isForwarding = 0;
341        context->playback->BackWard     = 0;
342        context->playback->SlowMotion   = 0;
343        context->playback->Speed        = 0;
344
345        context->output->Command(context, OUTPUT_STOP, NULL);
346        context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
347
348    }
349    else
350    {
351        playback_err("stop not possible\n");
352        ret = cERR_PLAYBACK_ERROR;
353    }
354
355    playback_printf(10, "exiting with value %d\n", ret);
356    return ret;
357}
358
359static int32_t PlaybackTerminate(Context_t  *context)
360{
361    int32_t ret = cERR_PLAYBACK_NO_ERROR;
362
363    playback_printf(20, "\n");
364   
365    PlaybackDieNow(1);
366
367    if ( context && context->playback && context->playback->isPlaying )
368    {
369        //First Flush and than delete container, else e2 cant read length of file anymore
370
371        if (context->output->Command(context, OUTPUT_FLUSH, NULL) < 0)
372        {
373            playback_err("failed to flush output.\n");
374        }
375
376        ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
377
378        context->playback->isPaused     = 0;
379        context->playback->isPlaying    = 0;
380        context->playback->isForwarding = 0;
381        context->playback->BackWard     = 0;
382        context->playback->SlowMotion   = 0;
383        context->playback->Speed        = 0;
384
385    }
386    else
387    {
388        playback_err("%p %p %d\n", context, context->playback, context->playback->isPlaying);
389
390        /* fixme: konfetti: we should return an error here but this seems to be a condition which
391         * can happen and is not a real error, which leads to a dead neutrino. should investigate
392         * here later.
393         */
394    }
395
396    playback_printf(20, "exiting with value %d\n", ret);
397    return ret;
398}
399
400//obi
401static int PlaybackFastForward(Context_t  *context, int* speed) {
402    int32_t ret = cERR_PLAYBACK_NO_ERROR;
403
404    playback_printf(10, "speed %d\n", *speed);
405
406    /* Audio only forwarding not supported */
407    if (context->playback->isVideo && !context->playback->isHttp && !context->playback->BackWard && (!context->playback->isPaused || context->playback->isPlaying)) {
408
409        if ((*speed <= 0) || (*speed > cMaxSpeed_ff))
410        {
411            playback_err("speed %d out of range (1 - %d) \n", *speed, cMaxSpeed_ff);
412            return cERR_PLAYBACK_ERROR;
413        }
414
415        context->playback->isForwarding = 1;
416        context->playback->Speed = *speed;
417
418        playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->Speed);
419
420        context->output->Command(context, OUTPUT_FASTFORWARD, NULL);
421    } else
422    {
423        playback_err("fast forward not possible\n");
424        ret = cERR_PLAYBACK_ERROR;
425    }
426
427    playback_printf(10, "exiting with value %d\n", ret);
428
429    return ret;
430}
431
432static int PlaybackFastBackward(Context_t  *context,int* speed) {
433    int32_t ret = cERR_PLAYBACK_NO_ERROR;
434
435    playback_printf(10, "speed = %d\n", *speed);
436
437    /* Audio only reverse play not supported */
438    if (context->playback->isVideo && !context->playback->isForwarding && (!context->playback->isPaused || context->playback->isPlaying)) {
439
440        if ((*speed > 0) || (*speed < cMaxSpeed_fr))
441        {
442            playback_err("speed %d out of range (0 - %d) \n", *speed, cMaxSpeed_fr);
443            return cERR_PLAYBACK_ERROR;
444        }
445
446        if (*speed == 0)
447        {
448            context->playback->BackWard = 0;
449            context->playback->Speed = 0;    /* reverse end */
450        } else
451        {
452            context->playback->isSeeking = 1;
453            context->playback->Speed = *speed;
454            context->playback->BackWard = 2^(*speed);
455         
456            playback_printf(1, "S %d B %f\n", context->playback->Speed, context->playback->BackWard);
457        }
458
459        context->output->Command(context, OUTPUT_AUDIOMUTE, "1");
460        context->output->Command(context, OUTPUT_CLEAR, NULL);
461        if (context->output->Command(context, OUTPUT_REVERSE, NULL) < 0)
462        {
463            playback_err("OUTPUT_REVERSE failed\n");
464            context->playback->BackWard = 0;
465            context->playback->Speed = 1;
466            context->playback->isSeeking = 0;
467            ret = cERR_PLAYBACK_ERROR;
468        }
469    } else
470    {
471        playback_err("fast backward not possible\n");
472        ret = cERR_PLAYBACK_ERROR;
473    }
474
475    context->playback->isSeeking = 0;
476    playback_printf(10, "exiting with value %d\n", ret);
477
478    return ret;
479}
480
481static int32_t PlaybackSlowMotion(Context_t  *context,int* speed) {
482    int32_t ret = cERR_PLAYBACK_NO_ERROR;
483
484    playback_printf(10, "\n");
485
486    //Audio only forwarding not supported
487    if (context->playback->isVideo && !context->playback->isHttp && context->playback->isPlaying) {
488        if(context->playback->isPaused)
489            PlaybackContinue(context);
490
491        switch(*speed) {
492        case 2:
493            context->playback->SlowMotion = 2;
494            break;
495        case 4:
496            context->playback->SlowMotion = 4;
497            break;
498        case 8:
499            context->playback->SlowMotion = 8;
500            break;
501        }
502
503        playback_printf(20, "SlowMotion: %d x {%d}\n", *speed, context->playback->SlowMotion);
504
505        context->output->Command(context, OUTPUT_SLOWMOTION, NULL);
506    } else
507    {
508        playback_err("slowmotion not possible\n");
509        ret = cERR_PLAYBACK_ERROR;
510    }
511
512    playback_printf(10, "exiting with value %d\n", ret);
513
514    return ret;
515}
516//obi (end)
517
518static int32_t PlaybackSeek(Context_t  *context, int64_t *pos, uint8_t absolute)
519{
520    int32_t ret = cERR_PLAYBACK_NO_ERROR;
521
522    playback_printf(10, "pos: %lldd\n", *pos);
523
524    if (context->playback->isPlaying && !context->playback->isForwarding && !context->playback->BackWard && !context->playback->SlowMotion && !context->playback->isPaused)
525    {
526        context->playback->isSeeking = 1;
527        context->output->Command(context, OUTPUT_CLEAR, NULL);
528        if (absolute)
529        {
530            context->container->selectedContainer->Command(context, CONTAINER_SEEK_ABS, pos);
531        }
532        else
533        {
534            context->container->selectedContainer->Command(context, CONTAINER_SEEK, pos);
535        }
536        context->playback->isSeeking = 0;
537    }
538    else
539    {
540        playback_err("not possible\n");
541        ret = cERR_PLAYBACK_ERROR;
542    }
543
544    playback_printf(10, "exiting with value %d\n", ret);
545
546    return ret;
547}
548
549static int32_t PlaybackPts(Context_t  *context, int64_t *pts)
550{
551    int32_t ret = cERR_PLAYBACK_NO_ERROR;
552
553    playback_printf(20, "\n");
554
555    *pts = 0;
556
557    if (context->playback->isPlaying)
558    {
559        ret = context->output->Command(context, OUTPUT_PTS, pts);
560    }
561    else
562    {
563        playback_err("not possible\n");
564        ret = cERR_PLAYBACK_ERROR;
565    }
566
567    playback_printf(20, "exiting with value %d\n", ret);
568
569    return ret;
570}
571
572static int32_t PlaybackGetFrameCount(Context_t  *context, int64_t *frameCount)
573{
574    int ret = cERR_PLAYBACK_NO_ERROR;
575
576    playback_printf(20, "\n");
577
578    *frameCount = 0;
579
580    if (context->playback->isPlaying)
581    {
582        ret = context->output->Command(context, OUTPUT_GET_FRAME_COUNT, frameCount);
583    } else
584    {
585        playback_err("not possible\n");
586        ret = cERR_PLAYBACK_ERROR;
587    }
588
589    playback_printf(20, "exiting with value %d\n", ret);
590
591    return ret;
592}
593
594static int32_t PlaybackLength(Context_t  *context, int64_t *length)
595{
596    int32_t ret = cERR_PLAYBACK_NO_ERROR;
597
598    playback_printf(20, "\n");
599
600    *length = -1;
601
602    if (context->playback->isPlaying)
603    {
604        if (context->container && context->container->selectedContainer)
605        {
606            context->container->selectedContainer->Command(context, CONTAINER_LENGTH, length);
607        }
608    }
609    else
610    {
611        playback_err("not possible\n");
612        ret = cERR_PLAYBACK_ERROR;
613    }
614
615    playback_printf(20, "exiting with value %d\n", ret);
616    return ret;
617}
618
619static int32_t PlaybackSwitchAudio(Context_t  *context, int32_t *track)
620{
621    int32_t ret = cERR_PLAYBACK_NO_ERROR;
622    int32_t curtrackid = 0;
623    int32_t nextrackid = 0;
624
625    playback_printf(10, "\n");
626
627    if (context && context->playback && context->playback->isPlaying)
628    {
629        if (context->manager && context->manager->audio)
630        {
631            context->manager->audio->Command(context, MANAGER_GET, &curtrackid);
632            context->manager->audio->Command(context, MANAGER_SET, track);
633            context->manager->audio->Command(context, MANAGER_GET, &nextrackid);
634        }
635        else
636        {
637            playback_err("switch audio not possible\n");
638            ret = cERR_PLAYBACK_ERROR;
639        }
640
641        if(nextrackid != curtrackid)
642        {
643
644            //PlaybackPause(context);
645            if (context->output && context->output->audio)
646            {
647                context->output->audio->Command(context, OUTPUT_SWITCH, (void*)"audio");
648            }
649
650            if (context->container && context->container->selectedContainer)
651            {
652                context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, &nextrackid);
653            }
654            //PlaybackContinue(context);
655        }
656    }
657    else
658    {
659        playback_err("switch audio not possible\n");
660        ret = cERR_PLAYBACK_ERROR;
661    }
662
663    playback_printf(10, "exiting with value %d\n", ret);
664    return ret;
665}
666
667static int32_t PlaybackSwitchSubtitle(Context_t  *context, int32_t *track)
668{
669    int32_t ret = cERR_PLAYBACK_NO_ERROR;
670    int32_t curtrackid = -1;
671    int32_t nextrackid = -1;
672
673    playback_printf(10, "Track: %d\n", *track);
674
675    if (context && context->playback && context->playback->isPlaying )
676    {
677        if (context->manager && context->manager->subtitle)
678        {
679            context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid);
680            context->manager->subtitle->Command(context, MANAGER_SET, track);
681            context->manager->subtitle->Command(context, MANAGER_GET, &nextrackid);
682         
683            if (curtrackid != nextrackid && nextrackid > -1)
684            {
685                if (context->output && context->output->subtitle)
686                {
687                    context->output->subtitle->Command(context, OUTPUT_SWITCH, (void*)"subtitle");
688                }
689
690                if (context->container && context->container->selectedContainer)
691                {
692                    context->container->selectedContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, &nextrackid);
693                }
694            }
695        }
696        else
697        {
698            ret = cERR_PLAYBACK_ERROR;
699            playback_err("no subtitle\n");
700        }
701    }
702    else
703    {
704        playback_err("not possible\n");
705        ret = cERR_PLAYBACK_ERROR;
706    }
707
708    playback_printf(10, "exiting with value %d\n", ret);
709
710    return ret;
711}
712
713static int32_t PlaybackInfo(Context_t  *context, char **infoString)
714{
715    int32_t ret = cERR_PLAYBACK_NO_ERROR;
716
717    playback_printf(10, "\n");
718
719    /* konfetti comment:
720     * removed if clause here (playback running) because its
721     * not necessary for all container. e.g. in case of ffmpeg
722     * container playback must not play to get the info.
723     */
724    if (context->container && context->container->selectedContainer)
725    {
726        context->container->selectedContainer->Command(context, CONTAINER_INFO, infoString);
727    }
728
729    playback_printf(10, "exiting with value %d\n", ret);
730
731    return ret;
732}
733
734static int32_t Command(void* _context, PlaybackCmd_t command, void *argument)
735{
736    Context_t* context = (Context_t*) _context; /* to satisfy compiler */
737    int32_t ret = cERR_PLAYBACK_NO_ERROR;
738
739    playback_printf(20, "Command %d\n", command);
740
741
742    switch(command)
743    {
744        case PLAYBACK_OPEN:
745        {
746            ret = PlaybackOpen(context, (PlayFiles_t*)argument);
747            break;
748        }
749        case PLAYBACK_CLOSE:
750        {
751            ret = PlaybackClose(context);
752            break;
753        }
754        case PLAYBACK_PLAY:
755        {
756            ret = PlaybackPlay(context);
757            break;
758        }
759        case PLAYBACK_STOP:
760        {
761            ret = PlaybackStop(context);
762            break;
763        }
764        case PLAYBACK_PAUSE:
765        {
766            ret = PlaybackPause(context);
767            break;
768        }
769        case PLAYBACK_CONTINUE:
770        {
771            ret = PlaybackContinue(context);
772            break;
773        }
774        case PLAYBACK_TERM:
775        {
776            ret = PlaybackTerminate(context);
777            break;
778        }
779        case PLAYBACK_SEEK:
780        {
781            ret = PlaybackSeek(context, (int64_t*)argument, 0);
782            break;
783        }
784        case PLAYBACK_SEEK_ABS:
785        {
786            ret = PlaybackSeek(context, (int64_t*)argument, -1);
787            break;
788        }
789        case PLAYBACK_PTS:
790        {
791            ret = PlaybackPts(context, (int64_t*)argument);
792            break;
793        }
794        case PLAYBACK_LENGTH:
795        {
796            ret = PlaybackLength(context, (int64_t*)argument);
797            break;
798        }
799        case PLAYBACK_SWITCH_AUDIO:
800        {
801            ret = PlaybackSwitchAudio(context, (int*)argument);
802            break;
803        }
804        case PLAYBACK_SWITCH_SUBTITLE:
805        {
806            ret = PlaybackSwitchSubtitle(context, (int*)argument);
807            break;
808        }
809        case PLAYBACK_INFO:
810        {
811            ret = PlaybackInfo(context, (char**)argument);
812            break;
813        }
814//obi
815        case PLAYBACK_SLOWMOTION:
816        {
817            ret = PlaybackSlowMotion(context,(int*)argument);
818            break;
819        }
820        case PLAYBACK_FASTBACKWARD:
821        {
822            ret = PlaybackFastBackward(context,(int*)argument);
823            break;
824        }
825        case PLAYBACK_FASTFORWARD:
826        {
827            ret = PlaybackFastForward(context,(int*)argument);
828            break;
829        }
830//obi (end)
831        case PLAYBACK_GET_FRAME_COUNT:
832        {
833            ret = PlaybackGetFrameCount(context, (uint64_t*)argument);
834            break;
835        }
836        default:
837            playback_err("PlaybackCmd %d not supported!\n", command);
838            ret = cERR_PLAYBACK_ERROR;
839            break;
840    }
841
842    playback_printf(20, "exiting with value %d\n", ret);
843
844    return ret;
845}
846
847/*
848 * This is very unreadable and must be changed
849 */
850PlaybackHandler_t PlaybackHandler = {
851    "Playback", //name
852    -1,         //fd
853    0,          //isFile
854    0,          //isHttp
855    0,          //isPlaying
856    0,          //isPaused
857    0,          //isForwarding
858    0,          //isSeeking
859    0,          //isCreationPhase
860    0,          //BackWard
861    0,          //SlowMotion
862    0,          //Speed
863    0,          //AVSync
864    0,          //isVideo
865    0,          //isAudio
866    0,          //isSubtitle
867    0,          //abortRequested
868    &Command,   //Command
869    "",         //uri
870    0,          //size
871    0,          //noprobe
872    0,          //isLoopMode
873    0,          //isTSLiveMode
874};
Note: See TracBrowser for help on using the repository browser.