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

Last change on this file since 42162 was 42162, checked in by obi, 4 years ago

update libeplayer3 to v47

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