source: titan/libeplayer3/output/linuxdvb_mipsel.c @ 42227

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

reset libeplayer3 to v36

File size: 39.2 KB
Line 
1/*
2 * LinuxDVB Output handling.
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
20/* ***************************** */
21/* Includes                      */
22/* ***************************** */
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <fcntl.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/ioctl.h>
32#include <linux/dvb/video.h>
33#include <linux/dvb/audio.h>
34#include <memory.h>
35#include <asm/types.h>
36#include <pthread.h>
37#include <errno.h>
38#include <poll.h>
39
40#include "bcm_ioctls.h"
41
42#include "common.h"
43#include "output.h"
44#include "writer.h"
45#include "misc.h"
46#include "pes.h"
47
48/* ***************************** */
49/* Makros/Constants              */
50/* ***************************** */
51
52//#define LINUXDVB_DEBUG
53#define LINUXDVB_SILENT
54
55static unsigned short debug_level = 0;
56
57static const char FILENAME[] = __FILE__;
58
59#ifdef LINUXDVB_DEBUG
60#define linuxdvb_printf(level, fmt, x...) do { \
61if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x ); } while (0)
62#else
63#define linuxdvb_printf(x...)
64#endif
65
66#ifndef LINUXDVB_SILENT
67#define linuxdvb_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
68#else
69#define linuxdvb_err(x...)
70#endif
71
72#define cERR_LINUXDVB_NO_ERROR      0
73#define cERR_LINUXDVB_ERROR        -1
74
75static const char VIDEODEV[]    = "/dev/dvb/adapter0/video0";
76static const char AUDIODEV[]    = "/dev/dvb/adapter0/audio0";
77
78static int videofd      = -1;
79static int audiofd      = -1;
80
81struct DVBApiVideoInfo_s
82{
83    int aspect_ratio;
84    int progressive;
85    int frame_rate;
86    int width, height;
87};
88static struct DVBApiVideoInfo_s videoInfo = {-1,-1,-1,-1,-1};
89
90unsigned long long int sCURRENT_PTS = 0;
91
92pthread_mutex_t LinuxDVBmutex;
93
94/* ***************************** */
95/* Prototypes                    */
96/* ***************************** */
97int LinuxDvbStop(Context_t  *context, char * type);
98
99/* ***************************** */
100/* MISC Functions                */
101/* ***************************** */
102
103void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
104
105    linuxdvb_printf(250, "requesting mutex\n");
106
107    pthread_mutex_lock(&LinuxDVBmutex);
108
109    linuxdvb_printf(250, "received mutex\n");
110}
111
112void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) {
113    pthread_mutex_unlock(&LinuxDVBmutex);
114
115    linuxdvb_printf(250, "released mutex\n");
116
117}
118
119static int LinuxDvbMapBypassMode(int bypass)
120{
121    if( 0x30 == bypass && IsDreambox() )
122    {
123        return 0x0f;
124    }
125    return bypass;
126}
127
128int LinuxDvbOpen(Context_t  *context __attribute__((unused)), char * type) {
129    unsigned char video = !strcmp("video", type);
130    unsigned char audio = !strcmp("audio", type);
131
132    linuxdvb_printf(10, "v%d a%d\n", video, audio);
133
134    if (video && videofd < 0)
135    {
136        videofd = open(VIDEODEV, O_RDWR | O_NONBLOCK);
137
138        if (videofd < 0)
139        {
140            linuxdvb_err("failed to open %s - errno %d\n", VIDEODEV, errno);
141            linuxdvb_err("%s\n", strerror(errno));
142            return cERR_LINUXDVB_ERROR;
143        }
144 
145        if (ioctl( videofd, VIDEO_CLEAR_BUFFER) == -1)
146        {
147            linuxdvb_err("ioctl failed with errno %d\n", errno);
148            linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
149        }
150
151        if (ioctl( videofd, VIDEO_SELECT_SOURCE, (void*)VIDEO_SOURCE_MEMORY) == -1)
152        {
153            linuxdvb_err("ioctl failed with errno %d\n", errno);
154            linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno));
155        }
156       
157        if (ioctl(videofd, VIDEO_FREEZE) == -1)
158        {
159            linuxdvb_err("ioctl failed with errno %d\n", errno);
160            linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno));
161        }
162
163    }
164    if (audio && audiofd < 0)
165    {
166        audiofd = open(AUDIODEV, O_RDWR | O_NONBLOCK);
167
168        if (audiofd < 0)
169        {
170            linuxdvb_err("failed to open %s - errno %d\n", AUDIODEV, errno);
171            linuxdvb_err("%s\n", strerror(errno));
172           
173            return cERR_LINUXDVB_ERROR;
174        }
175
176        if (ioctl( audiofd, AUDIO_CLEAR_BUFFER) == -1)
177        {
178            linuxdvb_err("ioctl failed with errno %d\n", errno);
179            linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
180        }
181
182        if (ioctl( audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) == -1)
183        {
184            linuxdvb_err("ioctl failed with errno %d\n", errno);
185            linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno));
186        }
187       
188        if (ioctl( audiofd, AUDIO_PAUSE) == -1)
189        {
190            linuxdvb_err("ioctl failed with errno %d\n", errno);
191            linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno));
192        }
193       
194    }
195
196    return cERR_LINUXDVB_NO_ERROR;
197}
198
199int LinuxDvbClose(Context_t  *context, char * type)
200{
201    unsigned char video = !strcmp("video", type);
202    unsigned char audio = !strcmp("audio", type);
203
204    linuxdvb_printf(10, "v%d a%d\n", video, audio);
205
206    /* closing stand alone is not allowed, so prevent
207     * user from closing and don't call stop. stop will
208     * set default values for us (speed and so on).
209     */
210    LinuxDvbStop(context, type);
211
212    getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
213
214    if (video && videofd != -1)
215    {
216        close(videofd);
217        videofd = -1;
218    }
219    if (audio && audiofd != -1)
220    {
221        close(audiofd);
222        audiofd = -1;
223    }
224
225    releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
226    return cERR_LINUXDVB_NO_ERROR;
227}
228
229int LinuxDvbPlay(Context_t  *context, char * type) {
230    int ret = cERR_LINUXDVB_NO_ERROR;
231    Writer_t* writer;
232
233    unsigned char video = !strcmp("video", type);
234    unsigned char audio = !strcmp("audio", type);
235
236    linuxdvb_printf(10, "v%d a%d\n", video, audio);
237
238    if (video && videofd != -1) {
239        char * Encoding = NULL;
240        context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
241
242        linuxdvb_printf(10, "V %s\n", Encoding);
243
244        writer = getWriter(Encoding);
245       
246        // SULGE VU 4K dont like this
247        /*
248        if (0 != ioctl(videofd, VIDEO_STOP))
249        {
250            linuxdvb_err("ioctl failed with errno %d\n", errno);
251            linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
252            ret = cERR_LINUXDVB_ERROR;
253        }
254        */
255
256        if (writer == NULL)
257        {
258            linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
259            ret = cERR_LINUXDVB_ERROR;
260        }
261        else
262        {
263            linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
264            if (ioctl( videofd, VIDEO_SET_STREAMTYPE, (void*) writer->caps->dvbStreamType) == -1)
265            {
266                linuxdvb_err("ioctl failed with errno %d\n", errno);
267                linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
268                ret = cERR_LINUXDVB_ERROR;
269            }
270        }
271        free(Encoding);
272       
273        if (0 != ioctl(videofd, VIDEO_PLAY))
274        {
275            linuxdvb_err("ioctl failed with errno %d\n", errno);
276            linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno));
277            ret = cERR_LINUXDVB_ERROR;
278        }
279       
280        if (ioctl(videofd, VIDEO_CONTINUE) == -1)
281        {
282            linuxdvb_err("ioctl failed with errno %d\n", errno);
283            linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno));
284        }
285       
286        if (ioctl( videofd, VIDEO_CLEAR_BUFFER) == -1)
287        {
288            linuxdvb_err("ioctl failed with errno %d\n", errno);
289            linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
290        }
291    }
292    if (audio && audiofd != -1) {
293        char * Encoding = NULL;
294        context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
295
296        linuxdvb_printf(20, "0 A %s\n", Encoding);
297
298        writer = getWriter(Encoding);
299       
300        // SULGE VU 4K dont like this
301        /*
302        if (0 != ioctl(audiofd, AUDIO_STOP))
303        {
304            linuxdvb_err("ioctl failed with errno %d\n", errno);
305            linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
306            ret = cERR_LINUXDVB_ERROR;
307        }
308        */
309
310        if (writer == NULL)
311        {
312            linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
313            ret = cERR_LINUXDVB_ERROR;
314        }
315        else
316        {
317            linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
318            if (ioctl( audiofd, AUDIO_SET_BYPASS_MODE, (void*) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) < 0)
319            {
320                linuxdvb_err("ioctl failed with errno %d\n", errno);
321                linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
322                ret = cERR_LINUXDVB_ERROR;
323            }
324        }
325
326        if (ioctl(audiofd, AUDIO_PLAY) < 0)
327        {
328            linuxdvb_err("ioctl failed with errno %d\n", errno);
329            linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
330            ret = cERR_LINUXDVB_ERROR;
331        }
332       
333        if (ioctl(audiofd, AUDIO_CONTINUE) < 0)
334        {
335            linuxdvb_err("ioctl failed with errno %d\n", errno);
336            linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno));
337            ret = cERR_LINUXDVB_ERROR;
338        }
339        free(Encoding);
340    }
341
342    //return ret;
343    return 0;
344}
345
346int LinuxDvbStop(Context_t  *context __attribute__((unused)), char * type)
347{
348    int ret = cERR_LINUXDVB_NO_ERROR;
349    unsigned char video = !strcmp("video", type);
350    unsigned char audio = !strcmp("audio", type);
351
352    linuxdvb_printf(10, "v%d a%d\n", video, audio);
353
354    getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
355
356    if (video && videofd != -1)
357    {
358        if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
359        {
360            linuxdvb_err("ioctl failed with errno %d\n", errno);
361            linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
362        }
363       
364        if (ioctl(videofd, VIDEO_STOP) == -1)
365        {
366            linuxdvb_err("ioctl failed with errno %d\n", errno);
367            linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
368            ret = cERR_LINUXDVB_ERROR;
369        }
370
371        ioctl(videofd, VIDEO_SLOWMOTION, 0);
372        ioctl(videofd, VIDEO_FAST_FORWARD, 0);
373
374        ioctl(videofd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
375    }
376    if (audio && audiofd != -1) {
377        if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
378        {
379            linuxdvb_err("ioctl failed with errno %d\n", errno);
380            linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
381        }
382
383        /* set back to normal speed (end trickmodes) */
384        // if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1)
385        // {
386            // linuxdvb_err("ioctl failed with errno %d\n", errno);
387            // linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno));
388        // }
389        if (ioctl(audiofd, AUDIO_STOP) == -1)
390        {
391            linuxdvb_err("ioctl failed with errno %d\n", errno);
392            linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
393            ret = cERR_LINUXDVB_ERROR;
394        }
395        ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX);
396    }
397
398    releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
399
400    return ret;
401}
402
403int LinuxDvbPause(Context_t  *context __attribute__((unused)), char * type) {
404    int ret = cERR_LINUXDVB_NO_ERROR;
405    unsigned char video = !strcmp("video", type);
406    unsigned char audio = !strcmp("audio", type);
407
408    linuxdvb_printf(10, "v%d a%d\n", video, audio);
409
410    getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
411
412    if (video && videofd != -1) {
413        if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1)
414        {
415            linuxdvb_err("ioctl failed with errno %d\n", errno);
416            linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno));
417            ret = cERR_LINUXDVB_ERROR;
418        }
419    }
420    if (audio && audiofd != -1) {
421        if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1)
422        {
423            linuxdvb_err("ioctl failed with errno %d\n", errno);
424            linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno));
425            ret = cERR_LINUXDVB_ERROR;
426        }
427    }
428
429    releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
430
431    return ret;
432}
433
434int LinuxDvbContinue(Context_t  *context __attribute__((unused)), char * type) {
435    int ret = cERR_LINUXDVB_NO_ERROR;
436    unsigned char video = !strcmp("video", type);
437    unsigned char audio = !strcmp("audio", type);
438
439    linuxdvb_printf(10, "v%d a%d\n", video, audio);
440
441    if (video && videofd != -1) {
442        if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1)
443        {
444            linuxdvb_err("ioctl failed with errno %d\n", errno);
445            linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno));
446            ret = cERR_LINUXDVB_ERROR;
447        }
448    }
449    if (audio && audiofd != -1) {
450        if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1)
451        {
452            linuxdvb_err("ioctl failed with errno %d\n", errno);
453            linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno));
454            ret = cERR_LINUXDVB_ERROR;
455        }
456    }
457
458    linuxdvb_printf(10, "exiting\n");
459
460
461    return ret;
462}
463
464int LinuxDvbReverseDiscontinuity(Context_t  *context __attribute__((unused)), int* surplus) {
465    int ret = cERR_LINUXDVB_NO_ERROR;
466    // int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus;
467   
468    // linuxdvb_printf(50, "\n");
469
470    // if (ioctl( videofd, VIDEO_DISCONTINUITY, (void*) dis_type) == -1)
471    // {
472        // linuxdvb_err("ioctl failed with errno %d\n", errno);
473        // linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno));
474    // }
475
476    // linuxdvb_printf(50, "exiting\n");
477
478    return ret;
479}
480
481int LinuxDvbAudioMute(Context_t  *context __attribute__((unused)), char *flag) {
482    int ret = cERR_LINUXDVB_NO_ERROR;
483
484    linuxdvb_printf(10, "\n");
485
486    if (audiofd != -1) {
487        if(*flag == '1')
488        {
489            //AUDIO_SET_MUTE has no effect with new player
490            //if (ioctl(audiofd, AUDIO_SET_MUTE, 1) == -1)
491            if (ioctl(audiofd, AUDIO_STOP, NULL) == -1)
492            {
493                linuxdvb_err("ioctl failed with errno %d\n", errno);
494                //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno));
495                linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
496                ret = cERR_LINUXDVB_ERROR;
497            }
498        }
499        else
500        {
501            //AUDIO_SET_MUTE has no effect with new player
502            //if (ioctl(audiofd, AUDIO_SET_MUTE, 0) == -1)
503            if (ioctl(audiofd, AUDIO_PLAY) == -1)
504            {
505                linuxdvb_err("ioctl failed with errno %d\n", errno);
506                //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno));
507                linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
508                ret = cERR_LINUXDVB_ERROR;
509            }
510        }
511    }
512
513    linuxdvb_printf(10, "exiting\n");
514
515    return ret;
516}
517
518
519int LinuxDvbFlush(Context_t  *context __attribute__((unused)), char * type)
520{
521    // unsigned char video = !strcmp("video", type);
522    // unsigned char audio = !strcmp("audio", type);
523
524    // linuxdvb_printf(10, "v%d a%d\n", video, audio);
525
526    // if ( (video && videofd != -1) || (audio && audiofd != -1) ) {
527        // getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
528
529        // if (video && videofd != -1) {
530            // if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1)
531            // {
532                // linuxdvb_err("ioctl failed with errno %d\n", errno);
533                // linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno));
534            // }
535        // }
536
537        // if (audio && audiofd != -1) {
538            // if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1)
539            // {
540                // linuxdvb_err("ioctl failed with errno %d\n", errno);
541                // linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno));
542            // }
543        // }
544
545        // releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
546    // }
547
548    // linuxdvb_printf(10, "exiting\n");
549
550    return cERR_LINUXDVB_NO_ERROR;
551}
552
553#ifndef use_set_speed_instead_ff
554int LinuxDvbFastForward(Context_t  *context, char * type) {
555    int ret = cERR_LINUXDVB_NO_ERROR;
556
557    unsigned char video = !strcmp("video", type);
558    unsigned char audio = !strcmp("audio", type);
559
560    linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed);
561
562    if (video && videofd != -1) {
563
564        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
565
566        /* konfetti comment: speed is a value given in skipped frames */
567
568        if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == -1)
569        {
570            linuxdvb_err("ioctl failed with errno %d\n", errno);
571            linuxdvb_err("VIDEO_FAST_FORWARD: %s\n", strerror(errno));
572            ret = cERR_LINUXDVB_ERROR;
573        }
574
575        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
576    }
577
578    linuxdvb_printf(10, "exiting with value %d\n", ret);
579
580    return ret;
581}
582#else
583
584static unsigned int SpeedList[] =
585{
586    1000, 1100, 1200, 1300, 1500,
587    2000, 3000, 4000, 5000, 8000,
588    12000, 16000,
589    125, 250, 500, 700, 800, 900
590};
591
592int LinuxDvbFastForward(Context_t  *context, char * type) {
593    int ret = cERR_LINUXDVB_NO_ERROR;
594    int speedIndex;
595    unsigned char video = !strcmp("video", type);
596    unsigned char audio = !strcmp("audio", type);
597
598    linuxdvb_printf(10, "v%d a%d\n", video, audio);
599
600    if (video && videofd != -1) {
601
602        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
603
604        speedIndex = context->playback->Speed % (sizeof (SpeedList) / sizeof (int));
605
606        linuxdvb_printf(1, "speedIndex %d\n", speedIndex);
607
608        // if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1)
609        // {
610            // linuxdvb_err("ioctl failed with errno %d\n", errno);
611            // linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno));
612            // ret = cERR_LINUXDVB_ERROR;
613        // }
614
615        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
616    }
617
618    if (audio && audiofd != -1) {
619
620        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
621
622        speedIndex = context->playback->Speed % (sizeof (SpeedList) / sizeof (int));
623
624        linuxdvb_printf(1, "speedIndex %d\n", speedIndex);
625
626        // if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1)
627        // {
628            // linuxdvb_err("ioctl failed with errno %d\n", errno);
629            // linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno));
630            // ret = cERR_LINUXDVB_ERROR;
631        // }
632
633        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
634    }
635
636    linuxdvb_printf(10, "exiting with value %d\n", ret);
637
638    return ret;
639}
640#endif
641
642
643int LinuxDvbReverse(Context_t  *context __attribute__((unused)), char * type __attribute__((unused))) {
644    int ret = cERR_LINUXDVB_NO_ERROR;
645    return ret;
646}
647
648int LinuxDvbSlowMotion(Context_t  *context, char * type) {
649    int ret = cERR_LINUXDVB_NO_ERROR;
650
651    unsigned char video = !strcmp("video", type);
652    unsigned char audio = !strcmp("audio", type);
653
654    linuxdvb_printf(10, "v%d a%d\n", video, audio);
655
656    if ( (video && videofd != -1) || (audio && audiofd != -1) ) {
657        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
658
659        if (video && videofd != -1) {
660            if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1)
661            {
662                linuxdvb_err("ioctl failed with errno %d\n", errno);
663                linuxdvb_err("VIDEO_SLOWMOTION: %s\n", strerror(errno));
664                ret = cERR_LINUXDVB_ERROR;
665            }
666        }
667
668        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
669    }
670
671    linuxdvb_printf(10, "exiting with value %d\n", ret);
672
673    return ret;
674}
675
676int LinuxDvbAVSync(Context_t  *context, char * type __attribute__((unused))) {
677    int ret = cERR_LINUXDVB_NO_ERROR;
678    /* konfetti: this one is dedicated to audiofd so we
679     * are ignoring what is given by type! I think we should
680     * remove this param. Therefor we should add a variable
681     * setOn or something like that instead, this would remove
682     * using a variable inside the structure.
683     */
684    if (audiofd != -1) {
685        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
686
687        if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1)
688        {
689            linuxdvb_err("ioctl failed with errno %d\n", errno);
690            linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno));
691            ret = cERR_LINUXDVB_ERROR;
692        }
693
694        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
695    }
696
697    return ret;
698}
699
700int LinuxDvbClear(Context_t  *context __attribute__((unused)), char * type)
701{
702    int32_t ret = cERR_LINUXDVB_NO_ERROR;
703    uint8_t video = !strcmp("video", type);
704    uint8_t audio = !strcmp("audio", type);
705
706    linuxdvb_printf(10, ">>>>>>>>>>LinuxDvbClear v%d a%d\n", video, audio);
707
708    if ( (video && videofd != -1) || (audio && audiofd != -1) )
709    {
710        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
711
712        if (video && videofd != -1)
713        {
714            if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
715            {
716                linuxdvb_err("ioctl failed with errno %d\n", errno);
717                linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
718                ret = cERR_LINUXDVB_ERROR;
719            }
720        }
721        else if (audio && audiofd != -1)
722        {
723            if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
724            {
725                linuxdvb_err("ioctl failed with errno %d\n", errno);
726                linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
727                ret = cERR_LINUXDVB_ERROR;
728            }
729        }
730
731        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
732    }
733
734    linuxdvb_printf(10, "exiting\n");
735
736    return ret;
737}
738
739int LinuxDvbPts(Context_t  *context __attribute__((unused)), unsigned long long int* pts) {
740    int ret = cERR_LINUXDVB_ERROR;
741   
742    linuxdvb_printf(50, "\n");
743
744    // pts is a non writting requests and can be done in parallel to other requests
745    //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
746
747    if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void*)&sCURRENT_PTS))
748    {
749        ret = cERR_LINUXDVB_NO_ERROR;
750    }
751    else
752    {
753        linuxdvb_err("VIDEO_GET_PTS: %d (%s)\n", errno, strerror(errno));
754    }
755
756    if (ret != cERR_LINUXDVB_NO_ERROR)
757    {
758        if (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void*)&sCURRENT_PTS))
759        {
760            ret = cERR_LINUXDVB_NO_ERROR;
761        }
762        else
763        {
764            linuxdvb_err("AUDIO_GET_PTS: %d (%s)\n", errno, strerror(errno));
765        }
766    }
767
768    if (ret != cERR_LINUXDVB_NO_ERROR)
769    {
770        sCURRENT_PTS = 0;
771    }
772
773    *((unsigned long long int *)pts)=(unsigned long long int)sCURRENT_PTS;
774
775    //releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
776
777    return ret;
778}
779
780int LinuxDvbGetFrameCount(Context_t  *context __attribute__((unused)), unsigned long long int* frameCount)
781{
782    int ret = cERR_LINUXDVB_NO_ERROR;
783    return ret;
784}
785
786int LinuxDvbSwitch(Context_t  *context, char * type)
787{
788    unsigned char audio = !strcmp("audio", type);
789    unsigned char video = !strcmp("video", type);
790    Writer_t* writer;
791
792    linuxdvb_printf(10, "v%d a%d\n", video, audio);
793
794    if ( (video && videofd != -1) || (audio && audiofd != -1) ) {
795        getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
796
797        if (audio && audiofd != -1) {
798            char * Encoding = NULL;
799            if (context && context->manager && context->manager->audio) {
800                context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
801
802                linuxdvb_printf(10, "A %s\n", Encoding);
803
804                writer = getWriter(Encoding);
805
806                if (ioctl(audiofd, AUDIO_STOP ,NULL) == -1)
807                {
808                    linuxdvb_err("ioctl failed with errno %d\n", errno);
809                    linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
810
811                }
812
813                if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
814                {
815                    linuxdvb_err("ioctl failed with errno %d\n", errno);
816                    linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
817
818                }
819
820                if (writer == NULL)
821                {
822                    linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
823                    // if (ioctl( audiofd, AUDIO_SET_BYPASS_MODE, (void*) AUDIO_ENCODING_MP3) == -1)
824                    // {
825                        // linuxdvb_err("ioctl failed with errno %d\n", errno);
826                        // linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
827                    // }
828                } else
829                {
830                    linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
831                    if (ioctl( audiofd, AUDIO_SET_BYPASS_MODE, (void*) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) == -1)
832                    {
833                        linuxdvb_err("ioctl failed with errno %d\n", errno);
834                        linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
835                    }
836                }
837
838                if (ioctl(audiofd, AUDIO_PLAY) == -1)
839                {
840                    linuxdvb_err("ioctl failed with errno %d\n", errno);
841                    linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
842                }
843                free(Encoding);
844            }
845            else
846                linuxdvb_printf(20, "no context for Audio\n");
847        }
848
849        if (video && videofd != -1) {
850            char * Encoding = NULL;
851            if (context && context->manager && context->manager->video) {
852                context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
853
854                if (ioctl(videofd, VIDEO_STOP ,NULL) == -1)
855                {
856                    linuxdvb_err("ioctl failed with errno %d\n", errno);
857                    linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
858                }
859
860                if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
861                {
862                    linuxdvb_err("ioctl failed with errno %d\n", errno);
863                    linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
864                }
865
866                linuxdvb_printf(10, "V %s\n", Encoding);
867
868                writer = getWriter(Encoding);
869
870                if (writer == NULL)
871                {
872                    linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
873                    // if (ioctl( videofd, VIDEO_SET_STREAMTYPE, (void*) VIDEO_ENCODING_AUTO) == -1)
874                    // {
875                        // linuxdvb_err("ioctl failed with errno %d\n", errno);
876                        // linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
877                    // }
878                } else
879                {
880                    linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
881                    if (ioctl( videofd, VIDEO_SET_STREAMTYPE, (void*) writer->caps->dvbStreamType) == -1)
882                    {
883                        linuxdvb_err("ioctl failed with errno %d\n", errno);
884                        linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
885                    }
886                }
887
888                if (ioctl(videofd, VIDEO_PLAY) == -1)
889                {
890                    /* konfetti: fixme: think on this, I think we should
891                     * return an error here and stop the playback mode
892                     */
893                    linuxdvb_err("ioctl failed with errno %d\n", errno);
894                    linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno));
895                }
896                free(Encoding);
897            }
898            else
899                linuxdvb_printf(20, "no context for Video\n");
900        }
901
902        releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
903
904    }
905
906    linuxdvb_printf(10, "exiting\n");
907
908    return cERR_LINUXDVB_NO_ERROR;
909}
910
911static int Write(void  *_context, void* _out)
912{
913    Context_t          *context  = (Context_t  *) _context;
914    AudioVideoOut_t    *out      = (AudioVideoOut_t*) _out;
915    int                ret       = cERR_LINUXDVB_NO_ERROR;
916    int                res       = 0;
917    unsigned char      video     = 0;
918    unsigned char      audio     = 0;
919    Writer_t*          writer;
920    WriterAVCallData_t call;
921
922    if (out == NULL)
923    {
924       linuxdvb_err("null pointer passed\n");
925       return cERR_LINUXDVB_ERROR;
926    }
927   
928    video = !strcmp("video", out->type);
929    audio = !strcmp("audio", out->type);
930 
931    linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n",
932                                                    out->len, out->extralen, out->pts, out->frameRate);
933    linuxdvb_printf(20, "v%d a%d\n", video, audio);
934
935    if (video)
936    {
937        char * Encoding = NULL;
938        context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
939
940        linuxdvb_printf(20, "Encoding = %s\n", Encoding);
941
942        writer = getWriter(Encoding);
943
944        if (writer == NULL)
945        {
946            linuxdvb_printf(20, "searching default writer ... %s\n", Encoding);
947            writer = getDefaultVideoWriter();
948        }
949
950        if (writer == NULL)
951        {
952            linuxdvb_err("unknown video codec and no default writer %s\n",Encoding);
953            ret = cERR_LINUXDVB_ERROR;
954        }
955        else
956        {
957            struct pollfd pfd[1];
958            pfd[0].fd = videofd;
959            pfd[0].events = POLLPRI;
960            int pollret = poll(pfd, 1, 0);
961            if (pollret > 0 && pfd[0].revents & POLLPRI)
962            {
963                struct video_event evt;
964                if (ioctl(videofd, VIDEO_GET_EVENT, &evt) == -1)
965                {
966                    linuxdvb_err("ioctl failed with errno %d\n", errno);
967                    linuxdvb_err("VIDEO_GET_EVENT: %s\n", strerror(errno));
968                }
969                else
970                {
971                    if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
972                    {
973                        linuxdvb_printf(10, "VIDEO_EVENT_SIZE_CHANGED\n", evt.type);
974                        linuxdvb_printf(10, "width  : %d\n", evt.u.size.w);
975                        linuxdvb_printf(10, "height : %d\n", evt.u.size.h);
976                        linuxdvb_printf(10, "aspect : %d\n", evt.u.size.aspect_ratio);
977                        videoInfo.width = evt.u.size.w;
978                        videoInfo.height = evt.u.size.h;
979                        videoInfo.aspect_ratio = evt.u.size.aspect_ratio;
980                    }
981                    else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
982                    {
983                        linuxdvb_printf(10, "VIDEO_EVENT_FRAME_RATE_CHANGED\n", evt.type);
984                        linuxdvb_printf(10, "framerate : %d\n", evt.u.frame_rate);
985                        videoInfo.frame_rate = evt.u.frame_rate;
986                    }
987                    else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
988                    {
989                        linuxdvb_printf(10, "VIDEO_EVENT_PROGRESSIVE_CHANGED\n", evt.type);
990                        linuxdvb_printf(10, "progressive : %d\n", evt.u.frame_rate);
991                        videoInfo.progressive = evt.u.frame_rate;
992                        context->manager->video->Command(context, MANAGER_UPDATED_TRACK_INFO, NULL);
993                    }
994                    else
995                    {
996                        linuxdvb_err("unhandled DVBAPI Video Event %d\n", evt.type);
997                    }
998                }
999            }
1000
1001            call.fd           = videofd;
1002            call.data         = out->data;
1003            call.len          = out->len;
1004            call.Pts          = out->pts;
1005            call.Dts          = out->dts;
1006            call.private_data = out->extradata;
1007            call.private_size = out->extralen;
1008            call.FrameRate    = out->frameRate;
1009            call.FrameScale   = out->timeScale;
1010            call.Width        = out->width;
1011            call.Height       = out->height;
1012            call.InfoFlags    = out->infoFlags;
1013            call.Version      = 0; // is unsingned char
1014
1015            if (writer->writeData)
1016            {
1017                res = writer->writeData(&call);
1018            }
1019
1020            if (res < 0)
1021            {
1022                linuxdvb_err("failed to write data %d - %d\n", res, errno);
1023                linuxdvb_err("%s\n", strerror(errno));
1024                ret = cERR_LINUXDVB_ERROR;
1025            }
1026        }
1027
1028        free(Encoding);
1029    }
1030    else if (audio)
1031    {
1032        char * Encoding = NULL;
1033        context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
1034
1035        linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding);
1036
1037        writer = getWriter(Encoding);
1038
1039        if (writer == NULL)
1040        {
1041            linuxdvb_printf(20, "searching default writer ... %s\n", Encoding);
1042            writer = getDefaultAudioWriter();
1043        }
1044
1045        if (writer == NULL)
1046        {
1047            linuxdvb_err("unknown audio codec %s and no default writer\n",Encoding);
1048            ret = cERR_LINUXDVB_ERROR;
1049        }
1050        else
1051        {
1052            call.fd             = audiofd;
1053            call.data           = out->data;
1054            call.len            = out->len;
1055            call.Pts            = out->pts;
1056            call.Dts            = out->dts;
1057            call.private_data   = out->extradata;
1058            call.private_size   = out->extralen;
1059            call.FrameRate      = out->frameRate;
1060            call.FrameScale     = out->timeScale;
1061            call.InfoFlags      = out->infoFlags;
1062            call.Version        = 0; /* -1; unsigned char cannot be negative */
1063
1064            if (writer->writeData)
1065            {
1066                res = writer->writeData(&call);
1067            }
1068
1069            if (res < 0)
1070            {
1071                linuxdvb_err("failed to write data %d - %d\n", res, errno);
1072                linuxdvb_err("%s\n", strerror(errno));
1073                ret = cERR_LINUXDVB_ERROR;
1074            }
1075        }
1076
1077        free(Encoding);
1078    }
1079
1080    return ret;
1081}
1082
1083static int reset(Context_t  *context)
1084{
1085    int ret = cERR_LINUXDVB_NO_ERROR;
1086    Writer_t*   writer;
1087    char * Encoding = NULL;
1088
1089    context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
1090
1091    writer = getWriter(Encoding);
1092
1093    if (writer == NULL)
1094    {
1095        linuxdvb_err("unknown video codec %s\n",Encoding);
1096        ret = cERR_LINUXDVB_ERROR;
1097    } else
1098    {
1099        writer->reset();
1100    }
1101
1102    free(Encoding);
1103
1104    context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
1105
1106    writer = getWriter(Encoding);
1107
1108    if (writer == NULL)
1109    {
1110        linuxdvb_err("unknown video codec %s\n",Encoding);
1111        ret = cERR_LINUXDVB_ERROR;
1112    } else
1113    {
1114        writer->reset();
1115    }
1116
1117    free(Encoding);
1118
1119    return ret;
1120}
1121
1122static int Command(void  *_context, OutputCmd_t command, void * argument) {
1123    Context_t* context = (Context_t*) _context;
1124    int ret = cERR_LINUXDVB_NO_ERROR;
1125   
1126    linuxdvb_printf(50, "Command %d\n", command);
1127
1128    switch(command) {
1129    case OUTPUT_OPEN: {
1130        ret = LinuxDvbOpen(context, (char*)argument);
1131        break;
1132    }
1133    case OUTPUT_CLOSE: {
1134        ret = LinuxDvbClose(context, (char*)argument);
1135        reset(context);
1136        sCURRENT_PTS = 0;
1137        break;
1138    }
1139    case OUTPUT_PLAY: { // 4
1140        sCURRENT_PTS = 0;
1141        ret = LinuxDvbPlay(context, (char*)argument);
1142        break;
1143    }
1144    case OUTPUT_STOP: {
1145        reset(context);
1146        ret = LinuxDvbStop(context, (char*)argument);
1147        sCURRENT_PTS = 0;
1148        break;
1149    }
1150    case OUTPUT_FLUSH: {
1151        ret = LinuxDvbFlush(context, (char*)argument);
1152        reset(context);
1153        sCURRENT_PTS = 0;
1154        break;
1155    }
1156    case OUTPUT_PAUSE: {
1157        ret = LinuxDvbPause(context, (char*)argument);
1158        break;
1159    }
1160    case OUTPUT_CONTINUE: {
1161        ret = LinuxDvbContinue(context, (char*)argument);
1162        break;
1163    }
1164    case OUTPUT_FASTFORWARD: {
1165        return LinuxDvbFastForward(context, (char*)argument);
1166        break;
1167    }
1168    case OUTPUT_REVERSE: {
1169        return LinuxDvbReverse(context, (char*)argument);
1170        break;
1171    }
1172    case OUTPUT_AVSYNC: {
1173        ret = LinuxDvbAVSync(context, (char*)argument);
1174        break;
1175    }
1176    case OUTPUT_CLEAR: {
1177        ret = LinuxDvbClear(context, (char*)argument);
1178        reset(context);
1179        sCURRENT_PTS = 0;
1180        break;
1181    }
1182    case OUTPUT_PTS: {
1183        unsigned long long int pts = 0;
1184        ret = LinuxDvbPts(context, &pts);
1185        *((unsigned long long int*)argument) = (unsigned long long int)pts;
1186        break;
1187    }
1188    case OUTPUT_SWITCH: {
1189        ret = LinuxDvbSwitch(context, (char*)argument);
1190        break;
1191    }
1192    case OUTPUT_SLOWMOTION: {
1193        return LinuxDvbSlowMotion(context, (char*)argument);
1194        break;
1195    }
1196    case OUTPUT_AUDIOMUTE: {
1197        return LinuxDvbAudioMute(context, (char*)argument);
1198        break;
1199    }
1200    case OUTPUT_DISCONTINUITY_REVERSE: {
1201        return LinuxDvbReverseDiscontinuity(context, (int*)argument);
1202        break;
1203    }
1204    case OUTPUT_GET_FRAME_COUNT: {
1205        unsigned long long int frameCount = 0;
1206        ret = LinuxDvbGetFrameCount(context, &frameCount);
1207        *((unsigned long long int*)argument) = (unsigned long long int)frameCount;
1208        break;
1209    }
1210    case OUTPUT_GET_PROGRESSIVE: {
1211        ret = cERR_LINUXDVB_NO_ERROR;
1212        *((int*)argument) = videoInfo.progressive;
1213        break;
1214    }
1215    default:
1216        linuxdvb_err("ContainerCmd %d not supported!\n", command);
1217        ret = cERR_LINUXDVB_ERROR;
1218        break;
1219    }
1220
1221    linuxdvb_printf(50, "exiting with value %d\n", ret);
1222
1223    return ret;
1224}
1225
1226static char *LinuxDvbCapabilities[] = { "audio", "video", NULL };
1227
1228struct Output_s LinuxDvbOutput = {
1229    "LinuxDvb",
1230    &Command,
1231    &Write,
1232    LinuxDvbCapabilities
1233};
Note: See TracBrowser for help on using the repository browser.