Add buffering for SH4

Signed-off-by: max_10 <max_10@gmx.de>
This commit is contained in:
samsamsam
2018-04-14 19:41:08 +02:00
committed by Thilo Graf
parent b35e8af698
commit 0783d816b0
26 changed files with 261 additions and 70 deletions

View File

@@ -0,0 +1,74 @@
/*
* linuxdvb output/writer handling.
*
* konfetti 2010
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* ***************************** */
/* Includes */
/* ***************************** */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "misc.h"
#include "writer.h"
#include "common.h"
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
#define WRITER_DEBUG
#ifdef WRITER_DEBUG
static short debug_level = 0;
#define writer_printf(level, x...) do { \
if (debug_level >= level) printf(x); } while (0)
#else
#define writer_printf(level, x...)
#endif
#ifndef WRITER_SILENT
#define writer_err(x...) do { printf(x); } while (0)
#else
#define writer_err(x...)
#endif
/* ***************************** */
/* Types */
/* ***************************** */
/* ***************************** */
/* Varaibles */
/* ***************************** */
/* ***************************** */
/* Prototypes */
/* ***************************** */
/* ***************************** */
/* Functions */
/* ***************************** */
void FlusPipe(int pipefd)
{
char tmp;
while(1 == read(pipefd, &tmp, 1));
}

View File

@@ -323,8 +323,8 @@ static int writeDataLATM(WriterAVCallData_t *call)
int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size);
if (ret)
{
printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", (int)call->data[0], (int)call->data[1], (int)call->data[2], (int)call->data[3], \
(int)call->data[4], (int)call->data[5], (int)call->data[6], (int)call->data[7]);
//printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", (int)call->data[0], (int)call->data[1], (int)call->data[2], (int)call->data[3], \
// (int)call->data[4], (int)call->data[5], (int)call->data[6], (int)call->data[7]);
aac_err("latm_decode_extradata failed. ignoring...\n");
return 0;
}

View File

@@ -101,13 +101,7 @@ static Writer_t *AvailableWriter[] =
/* Functions */
/* ***************************** */
static void FlusPipe(int pipefd)
{
char tmp;
while(1 == read(pipefd, &tmp, 1));
}
ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size)
ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size)
{
fd_set rfds;
fd_set wfds;
@@ -194,14 +188,13 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
return 0;
}
ssize_t write_with_retry(int fd, const void *buf, size_t size)
ssize_t write_with_retry(int fd, const void *buf, int size)
{
ssize_t ret;
int retval = 0;
while (size > 0 && 0 == PlaybackDieNow(0))
{
ret = write(fd, buf, size);
//printf("[%d] write [%lld]\n", fd, ret);
if (ret < 0)
{
switch (errno)
@@ -239,7 +232,7 @@ ssize_t write_with_retry(int fd, const void *buf, size_t size)
return 0;
}
ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic)
ssize_t writev_with_retry(int fd, const struct iovec *iov, int ic)
{
ssize_t len = 0;
uint32_t i = 0;

View File

@@ -211,7 +211,7 @@ static int _writeData(void *_call, int type)
iov[0].iov_len = HeaderLength;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return writev(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
static int writeDataADTS(void *_call)
@@ -279,7 +279,7 @@ static int writeDataADTS(void *_call)
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return writev(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
static int writeDataLATM(void *_call)
@@ -325,8 +325,8 @@ static int writeDataLATM(void *_call)
int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size);
if (ret)
{
printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", (int)call->data[0], (int)call->data[1], (int)call->data[2], (int)call->data[3], \
(int)call->data[4], (int)call->data[5], (int)call->data[6], (int)call->data[7]);
//printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", (int)call->data[0], (int)call->data[1], (int)call->data[2], (int)call->data[3], \
// (int)call->data[4], (int)call->data[5], (int)call->data[6], (int)call->data[7]);
aac_err("latm_decode_extradata failed. ignoring...\n");
return 0;
}
@@ -349,7 +349,7 @@ static int writeDataLATM(void *_call)
iov[2].iov_base = pLATMCtx->buffer;
iov[2].iov_len = pLATMCtx->len;
return writev(call->fd, iov, 3);
return call->WriteV(call->fd, iov, 3);
}
/* ***************************** */

View File

@@ -130,7 +130,7 @@ static int writeData(void *_call)
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return writev(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
/* ***************************** */

View File

@@ -179,7 +179,7 @@ static int writeData(void *_call)
iov[ic].iov_base = call->data;
iov[ic++].iov_len = call->len;
int len = writev(call->fd, iov, ic);
int len = call->WriteV(call->fd, iov, ic);
divx_printf(10, "xvid_Write < len=%d\n", len);

View File

@@ -209,7 +209,7 @@ static int writeData(void *_call)
iov[ic].iov_base = call->data;
iov[ic++].iov_len = call->len;
int len = writev(call->fd, iov, ic);
int len = call->WriteV(call->fd, iov, ic);
divx_printf(10, "xvid_Write < len=%d\n", len);

View File

@@ -161,7 +161,7 @@ static int32_t writeData(void *_call)
iov[1].iov_base = Data;
iov[1].iov_len = Size;
int32_t len = writev(call->fd, iov, 2);
int32_t len = call->WriteV(call->fd, iov, 2);
dts_printf(10, "< len %d\n", len);
return len;
}

View File

@@ -141,7 +141,7 @@ static int writeData(void *_call)
iov[0].iov_len = HeaderLength;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
len = writev(call->fd, iov, 2);
len = call->WriteV(call->fd, iov, 2);
h263_printf(10, "< len %d\n", len);
return len;

View File

@@ -100,7 +100,6 @@ const uint8_t Head[] = {0, 0, 0, 1};
static int32_t initialHeader = 1;
static uint32_t NalLengthBytes = 1;
static int avc3 = 0;
static int sps_pps_in_stream = 0;
/* ***************************** */
/* Prototypes */
/* ***************************** */
@@ -263,23 +262,12 @@ static int32_t writeData(void *_call)
(call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) ||
(call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))
{
uint32_t i = 0;
uint8_t InsertPrivData = !sps_pps_in_stream;
uint32_t PacketLength = 0;
uint32_t FakeStartCode = PES_VERSION_FAKE_START_CODE;
uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE;
iov[ic++].iov_base = PesHeader;
while (InsertPrivData && i < 36 && (call->len - i) > 5)
{
if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68)))
{
InsertPrivData = 0;
sps_pps_in_stream = 1;
}
i += 1;
}
if (InsertPrivData && call->private_size > 0 /*&& initialHeader*/) // some rtsp streams can update codec data at runtime
initialHeader = 0;
if (initialHeader)
{
initialHeader = 0;
iov[ic].iov_base = call->private_data;
@@ -301,7 +289,7 @@ static int32_t writeData(void *_call)
iov[ic++].iov_len = 1;
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
int ret = writev(call->fd, iov, ic);
int ret = call->WriteV(call->fd, iov, ic);
return ret;
}
else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0])
@@ -310,7 +298,7 @@ static int32_t writeData(void *_call)
return 0;
}
if (!avc3)
if (initialHeader)
{
uint8_t *private_data = call->private_data;
uint32_t private_size = call->private_size;
@@ -368,7 +356,7 @@ static int32_t writeData(void *_call)
iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
iov[ic].iov_base = HeaderData;
iov[ic++].iov_len = ParametersLength;
len = writev(call->fd, iov, ic);
len = call->WriteV(call->fd, iov, ic);
if (len < 0)
{
return len;
@@ -424,7 +412,7 @@ static int32_t writeData(void *_call)
}
iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
ssize_t l = writev(call->fd, iov, ic);
ssize_t l = call->WriteV(call->fd, iov, ic);
if (private_data != call->private_data)
{
@@ -498,7 +486,7 @@ static int32_t writeData(void *_call)
h264_printf(20, " pts=%llu\n", VideoPts);
iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
ssize_t l = writev(call->fd, iov, ic);
ssize_t l = call->WriteV(call->fd, iov, ic);
if (l < 0)
return l;
len += l;
@@ -537,4 +525,4 @@ struct Writer_s WriterVideoH264 =
&reset,
&writeData,
&caps
};
};

View File

@@ -128,7 +128,7 @@ static int writeData(void *_call)
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
int len = writev(call->fd, iov, 2);
int len = call->WriteV(call->fd, iov, 2);
mp3_printf(10, "mp3_Write-< len=%d\n", len);
return len;

View File

@@ -140,7 +140,7 @@ static int writeData(void *_call)
iov[1].iov_base = call->data + Position;
iov[1].iov_len = PacketLength;
ssize_t l = writev(call->fd, iov, 2);
ssize_t l = call->WriteV(call->fd, iov, 2);
if (l < 0)
{
len = l;

View File

@@ -333,7 +333,7 @@ static int32_t writeData(void *_call)
lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F);
iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, call->Pts, 0);
int32_t len = writev(call->fd, iov, 3);
int32_t len = call->WriteV(call->fd, iov, 3);
if (len < 0)
{
break;

View File

@@ -199,14 +199,14 @@ static int writeData(void *_call)
iov[1].iov_base = PesPayload;
iov[1].iov_len = PesPtr - PesPayload;
iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
len = writev(call->fd, iov, 2);
len = call->WriteV(call->fd, iov, 2);
/* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */
iov[0].iov_base = PesHeader;
iov[1].iov_base = call->private_data;
iov[1].iov_len = call->private_size;
iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
len = writev(call->fd, iov, 2);
len = call->WriteV(call->fd, iov, 2);
initialHeader = 0;
}
@@ -251,7 +251,7 @@ static int writeData(void *_call)
iov[1].iov_base = call->data + Position;
iov[1].iov_len = PacketLength;
ssize_t l = writev(call->fd, iov, 2);
ssize_t l = call->WriteV(call->fd, iov, 2);
if (l < 0)
{
len = l;

View File

@@ -140,7 +140,7 @@ static int writeData(void *_call)
iov[0].iov_len = InsertPesHeader(PesHeader, call->private_size, MPEG_AUDIO_PES_START_CODE, 0, 0);
iov[1].iov_base = call->private_data;
iov[1].iov_len = call->private_size;
len = writev(call->fd, iov, 2);
len = call->WriteV(call->fd, iov, 2);
initialHeader = 0;
}
@@ -153,7 +153,7 @@ static int writeData(void *_call)
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
ssize_t l = writev(call->fd, iov, 2);
ssize_t l = call->WriteV(call->fd, iov, 2);
len = (l > -1) ? len + l : l;
}

View File

@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include "misc.h"
#include "writer.h"
/* ***************************** */
@@ -96,6 +97,54 @@ static Writer_t *AvailableWriter[] =
/* ***************************** */
/* Functions */
/* ***************************** */
ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size)
{
fd_set rfds;
ssize_t ret;
int retval = -1;
struct timeval tv;
while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking)
{
if (context->playback->isPaused)
{
FD_ZERO(&rfds);
FD_SET(pipefd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 500000; // 500ms
retval = select(pipefd + 1, &rfds, NULL, NULL, &tv);
if (retval < 0)
{
break;
}
if (retval == 0)
{
//printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n");
continue;
}
if(FD_ISSET(pipefd, &rfds))
{
FlusPipe(pipefd);
//printf("RETURN FROM SELECT DUE TO pipefd SET\n");
continue;
}
}
//printf(">> Before Write fd [%d]\n", fd);
ret = write(fd, buf, size);
//printf(">> After Write ret[%d] size[%d]\n", (int)ret, size);
if (ret == size)
ret = 0; // no error
break;
}
return ret;
}
Writer_t *getWriter(char *encoding)
{