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

Last change on this file since 39881 was 39881, checked in by obi, 5 years ago

test

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