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

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

update libeplayer3 to v47

File size: 7.9 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
29#include "misc.h"
30#include "writer.h"
31#include "common.h"
32
33/* ***************************** */
34/* Makros/Constants              */
35/* ***************************** */
36
37#define WRITER_DEBUG
38
39#ifdef WRITER_DEBUG
40
41static short debug_level = 0;
42
43#define writer_printf(level, x...) do { \
44if (debug_level >= level) printf(x); } while (0)
45#else
46#define writer_printf(level, x...)
47#endif
48
49#ifndef WRITER_SILENT
50#define writer_err(x...) do { printf(x); } while (0)
51#else
52#define writer_err(x...)
53#endif
54
55/* ***************************** */
56/* Types                         */
57/* ***************************** */
58
59/* ***************************** */
60/* Varaibles                     */
61/* ***************************** */
62
63static Writer_t * AvailableWriter[] = {
64    &WriterAudioAAC,
65    &WriterAudioAACLATM,
66    &WriterAudioAACPLUS,
67    &WriterAudioAC3,
68    &WriterAudioEAC3,
69    &WriterAudioMP3,
70    &WriterAudioMPEGL3,
71    &WriterAudioPCM,
72    &WriterAudioIPCM,
73    &WriterAudioLPCM,
74    &WriterAudioDTS,
75    &WriterAudioWMA,
76    &WriterAudioWMAPRO,
77   
78    &WriterVideoH264,
79    &WriterVideoH265,
80    &WriterVideoH263,
81    &WriterVideoMPEG4,
82    &WriterVideoMPEG2,
83    &WriterVideoMPEG1,
84    &WriterVideoVC1,
85    &WriterVideoDIVX3,
86    &WriterVideoVP6,
87    &WriterVideoVP8,
88    &WriterVideoVP9,
89    &WriterVideoSPARK,
90    &WriterVideoWMV,
91    NULL
92};
93
94/* ***************************** */
95/* Prototypes                    */
96/* ***************************** */
97
98/* ***************************** */
99/*  Functions                    */
100/* ***************************** */
101static void FlusPipe(int pipefd)
102{
103    char tmp;
104    while(1 == read(pipefd, &tmp, 1));
105}
106
107ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size)
108{
109    fd_set rfds;
110    fd_set wfds;
111   
112    ssize_t ret;
113    int retval = -1;
114    int maxFd = pipefd > fd ? pipefd : fd;
115    struct timeval tv;
116   
117    while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking)
118    {
119        FD_ZERO(&rfds);
120        FD_ZERO(&wfds);
121
122        FD_SET(pipefd, &rfds);
123        FD_SET(fd, &wfds);
124
125        /* When we PAUSE LINUX DVB outputs buffers then audio/video buffers
126         * will be filled to full unfortunately, in such case after resume
127         * select never return with fd set - bug in DVB drivers?
128         * So, there will be to workarounds:
129         *   1. write to pipe pipe at resume to exit select immediately
130         *   2. even if fd is not set exit from select after 0,1s
131         *      (it seems that second workaround is not needed)
132         */
133        //tv.tv_sec = 0;
134        //tv.tv_usec = 100000; // 100ms
135       
136        retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); //&tv);
137        if (retval < 0)
138        {
139            break;
140        }
141       
142        //if (retval == 0)
143        //{
144        //    //printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n");
145        //    continue;
146        //}
147       
148        if(FD_ISSET(pipefd, &rfds))
149        {
150            FlusPipe(pipefd);
151            //printf("RETURN FROM SELECT DUE TO pipefd SET\n");
152            continue;
153        }
154       
155        if(FD_ISSET(fd, &wfds))
156        {
157            ret = write(fd, buf, size);
158            if (ret < 0)
159            {
160                switch(errno)
161                {
162                    case EINTR:
163                    case EAGAIN:
164                        continue;
165                    default:
166                        retval = -3;
167                        break;
168                }
169                if (retval < 0)
170                {
171                    break;
172                }
173               
174                return ret;
175            }
176            else if (ret == 0)
177            {
178                //printf("This should not happen. Select return fd ready to write, but write return 0, errno [%d]\n", errno);
179                tv.tv_sec = 0;
180                tv.tv_usec = 10000; // 10ms
181                retval = select(pipefd + 1, &rfds, NULL, NULL, &tv);
182                if (retval)
183                    FlusPipe(pipefd);
184                continue;
185            }
186           
187            size -= ret;
188            buf += ret;
189        }
190    }
191    return 0;
192}
193
194ssize_t write_with_retry(int fd, const void *buf, size_t size)
195{
196    ssize_t ret;
197    int retval = 0;
198//obi
199//    while(size > 0 && 0 == PlaybackDieNow(0))
200    while(size > 0)
201//obi (end)
202    {
203        ret = write(fd, buf, size);
204        //printf("[%d] write [%lld]\n", fd, ret);
205        if (ret < 0)
206        {
207            switch(errno)
208            {
209                case EINTR:
210                case EAGAIN:
211                    usleep(1000);
212                    continue;
213                default:
214                    retval = -3;
215                    break;
216            }
217            if (retval < 0)
218            {
219                break;
220            }
221        }
222           
223        if (ret < 0)
224        {
225            return ret;
226        }
227       
228        size -= ret;
229        buf += ret;
230       
231        if(size > 0)
232        {
233            if( usleep(1000) )
234            {
235                writer_err("usleep error \n");
236            }
237        }
238    }
239    return 0;
240}
241
242ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic)
243{
244    ssize_t len = 0;
245    int i = 0;
246    for(i=0; i<ic; ++i)
247    {
248        write_with_retry(fd, iov[i].iov_base, iov[i].iov_len);
249        len += iov[i].iov_len;
250        if(PlaybackDieNow(0))
251        {
252//obi
253//            return -1;
254//obi (end)
255        }
256    }
257    return len;
258}
259
260Writer_t* getWriter(char* encoding)
261{
262    int i;
263
264    for (i = 0; AvailableWriter[i] != NULL; i++)
265    {
266        if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0)
267        {
268            writer_printf(50, "%s: found writer \"%s\" for \"%s\"\n", __func__, AvailableWriter[i]->caps->name, encoding);
269            return AvailableWriter[i];
270        }
271    }
272
273    writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, encoding);
274
275    return NULL;
276}
277
278Writer_t* getDefaultVideoWriter()
279{
280    int i;
281
282    for (i = 0; AvailableWriter[i] != NULL; i++)
283    {
284        if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0)
285        {
286            writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
287            return AvailableWriter[i];
288        }
289    }
290
291    writer_printf(1, "%s: no writer found\n", __func__);
292
293    return NULL;
294}
295
296Writer_t* getDefaultAudioWriter()
297{
298    int i;
299
300    for (i = 0; AvailableWriter[i] != NULL; i++)
301    {
302        if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0)
303        {
304            writer_printf(50, "%s: found writer \"%s\"\n", __func__, AvailableWriter[i]->caps->name);
305            return AvailableWriter[i];
306        }
307    }
308
309    writer_printf(1, "%s: no writer found\n", __func__);
310
311    return NULL;
312}
313
Note: See TracBrowser for help on using the repository browser.