source: titan/libeplayer3/output/writer/mipsel/writer.c @ 44958

Last change on this file since 44958 was 44958, checked in by obi, 20 months ago

[libeplayer3] update to v68

File size: 7.6 KB
Line 
1/*
2 * linuxdvb output/writer handling.
3 *
4 * konfetti 2010
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22/* ***************************** */
23/* Includes                      */
24/* ***************************** */
25#include <stdlib.h>
26#include <string.h>
27#include <errno.h>
28#include <pthread.h>
29
30#include "misc.h"
31#include "writer.h"
32#include "common.h"
33#include "debug.h"
34
35/* ***************************** */
36/* Makros/Constants              */
37/* ***************************** */
38#define getDVBMutex(pmtx) do { if (pmtx) pthread_mutex_lock(pmtx);} while(false);
39#define releaseDVBMutex(pmtx) do { if (pmtx) pthread_mutex_unlock(pmtx);} while(false);
40
41/* ***************************** */
42/* Types                         */
43/* ***************************** */
44typedef enum {
45    DVB_STS_UNKNOWN,
46    DVB_STS_SEEK,
47    DVB_STS_PAUSE,
48    DVB_STS_EXIT
49} DVBState_t;
50
51/* ***************************** */
52/* Varaibles                     */
53/* ***************************** */
54
55static Writer_t * AvailableWriter[] = {
56    &WriterAudioAAC,
57    &WriterAudioAACLATM,
58    &WriterAudioAACPLUS,
59    &WriterAudioAC3,
60    &WriterAudioEAC3,
61    &WriterAudioMP3,
62    &WriterAudioMPEGL3,
63    &WriterAudioPCM,
64    &WriterAudioIPCM,
65    &WriterAudioLPCM,
66    &WriterAudioDTS,
67    &WriterAudioWMA,
68    &WriterAudioWMAPRO,
69    &WriterAudioOPUS,
70    &WriterAudioVORBIS,
71
72    &WriterVideoH264,
73    &WriterVideoH265,
74    &WriterVideoH263,
75    &WriterVideoMPEG4,
76    &WriterVideoMPEG2,
77    &WriterVideoMPEG1,
78    &WriterVideoVC1,
79    &WriterVideoDIVX3,
80    &WriterVideoVP6,
81    &WriterVideoVP8,
82    &WriterVideoVP9,
83    &WriterVideoFLV,
84    &WriterVideoWMV,
85    &WriterVideoMJPEG,
86    &WriterVideoRV40,
87    &WriterVideoRV30,
88    &WriterVideoAVS2,
89    NULL
90};
91
92/* ***************************** */
93/* Prototypes                    */
94/* ***************************** */
95
96/* ***************************** */
97/*  Functions                    */
98/* ***************************** */
99ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, const void *buf, int size)
100{
101    fd_set rfds;
102    fd_set wfds;
103
104    ssize_t ret;
105    int retval = -1;
106    int maxFd = pipefd > fd ? pipefd : fd;
107    struct timeval tv;
108
109    while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking)
110    {
111        FD_ZERO(&rfds);
112        FD_ZERO(&wfds);
113
114        FD_SET(pipefd, &rfds);
115        FD_SET(fd, &wfds);
116
117        /* When we PAUSE LINUX DVB outputs buffers, then audio/video buffers
118         * will continue to be filled. Unfortunately, in such case after resume
119         * select() will never return with fd set - bug in DVB drivers?
120         * There are to workarounds possible:
121         *   1. write to pipe at resume to return from select() immediately
122         *   2. make timeout select(), limit max time spend in the select()
123         *      to for example 0,1s
124         *   (at now first workaround is used)
125         */
126        //tv.tv_sec = 0;
127        //tv.tv_usec = 100000; // 100ms
128       
129        retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); //&tv);
130        if (retval < 0)
131        {
132            break;
133        }
134       
135        //if (retval == 0)
136        //{
137        //    //printf("RETURN FROM SELECT DUE TO TIMEOUT\n");
138        //    continue;
139        //}
140       
141        if(FD_ISSET(pipefd, &rfds))
142        {
143            FlushPipe(pipefd);
144            //printf("RETURN FROM SELECT DUE TO pipefd SET\n");
145            continue;
146        }
147       
148        if(FD_ISSET(fd, &wfds))
149        {
150            ret = write(fd, buf, size);
151            if (ret < 0)
152            {
153                switch(errno)
154                {
155                    case EINTR:
156                    case EAGAIN:
157                        continue;
158                    default:
159                        retval = -3;
160                        break;
161                }
162                if (retval < 0)
163                {
164                    break;
165                }
166               
167                return ret;
168            }
169            else if (ret == 0)
170            {
171                // printf("This should not happen. Select return fd ready to write, but write return 0, errno [%d]\n", errno);
172                // wait 10ms before next try
173                tv.tv_sec = 0;
174                tv.tv_usec = 10000; // 10ms
175                retval = select(pipefd + 1, &rfds, NULL, NULL, &tv);
176                if (retval)
177                    FlushPipe(pipefd);
178                continue;
179            }
180           
181            size -= ret;
182            buf += ret;
183        }
184    }
185    return 0;
186}
187
188ssize_t write_with_retry(int fd, const void *buf, int size)
189{
190    ssize_t ret;
191    int retval = 0;
192    while(size > 0 && 0 == PlaybackDieNow(0))
193    {
194        ret = write(fd, buf, size);
195        if (ret < 0)
196        {
197            switch(errno)
198            {
199                case EINTR:
200                case EAGAIN:
201                    usleep(1000);
202                    continue;
203                default:
204                    retval = -3;
205                    break;
206            }
207            if (retval < 0)
208            {
209                break;
210            }
211        }
212           
213        if (ret < 0)
214        {
215            return ret;
216        }
217       
218        size -= ret;
219        buf += ret;
220       
221        if(size > 0)
222        {
223            if( usleep(1000) )
224            {
225                writer_err("usleep error \n");
226            }
227        }
228    }
229    return 0;
230}
231
232ssize_t writev_with_retry(int fd, const struct iovec *iov, int ic)
233{
234    ssize_t len = 0;
235    int i = 0;
236    for(i=0; i<ic; ++i)
237    {
238        write_with_retry(fd, iov[i].iov_base, iov[i].iov_len);
239        len += iov[i].iov_len;
240        if(PlaybackDieNow(0))
241        {
242            return -1;
243        }
244    }
245    return len;
246}
247
248Writer_t* getWriter(char* encoding)
249{
250    int i;
251
252    for (i = 0; AvailableWriter[i] != NULL; i++)
253    {
254        if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0)
255        {
256            writer_printf(50, "%s: found writer \"%s\" for \"%s\"\n", __func__, AvailableWriter[i]->caps->name, encoding);
257            return AvailableWriter[i];
258        }
259    }
260
261    writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, encoding);
262
263    return NULL;
264}
265
266Writer_t* getDefaultVideoWriter()
267{
268    int i;
269
270    for (i = 0; AvailableWriter[i] != NULL; i++)
271    {
272        if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0)
273        {
274            writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
275            return AvailableWriter[i];
276        }
277    }
278
279    writer_printf(1, "%s: no writer found\n", __func__);
280
281    return NULL;
282}
283
284Writer_t* getDefaultAudioWriter()
285{
286    int i;
287
288    for (i = 0; AvailableWriter[i] != NULL; i++)
289    {
290        if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0)
291        {
292            writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
293            return AvailableWriter[i];
294        }
295    }
296
297    writer_printf(1, "%s: no writer found\n", __func__);
298
299    return NULL;
300}
301
Note: See TracBrowser for help on using the repository browser.