mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-27 07:23:11 +02:00
Linux DVB output - workaround for BUG? in the DVB drivers
Signed-off-by: max_10 <max_10@gmx.de>
This commit is contained in:
@@ -638,7 +638,7 @@ int main(int argc, char *argv[])
|
|||||||
memset(argvBuff, '\0', sizeof(argvBuff));
|
memset(argvBuff, '\0', sizeof(argvBuff));
|
||||||
int commandRetVal = -1;
|
int commandRetVal = -1;
|
||||||
/* inform client that we can handle additional commands */
|
/* inform client that we can handle additional commands */
|
||||||
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 43);
|
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 44);
|
||||||
if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB))
|
if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB))
|
||||||
{
|
{
|
||||||
printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n");
|
printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n");
|
||||||
|
@@ -349,6 +349,13 @@ int32_t LinuxDvbBuffFlush(Context_t *context __attribute__((unused)))
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t LinuxDvbBuffResume(Context_t *context __attribute__((unused)))
|
||||||
|
{
|
||||||
|
/* signal if we are waiting for write to DVB decoders */
|
||||||
|
WriteWakeUp();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic)
|
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic)
|
||||||
{
|
{
|
||||||
OutputType_t dataType = OUTPUT_UNK;
|
OutputType_t dataType = OUTPUT_UNK;
|
||||||
|
@@ -104,6 +104,8 @@ pthread_mutex_t LinuxDVBmutex;
|
|||||||
int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd);
|
int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd);
|
||||||
int32_t LinuxDvbBuffClose(Context_t *context);
|
int32_t LinuxDvbBuffClose(Context_t *context);
|
||||||
int32_t LinuxDvbBuffFlush(Context_t *context);
|
int32_t LinuxDvbBuffFlush(Context_t *context);
|
||||||
|
int32_t LinuxDvbBuffResume(Context_t *context);
|
||||||
|
|
||||||
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic);
|
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic);
|
||||||
int32_t WriteSetBufferingSize(const uint32_t bufferSize);
|
int32_t WriteSetBufferingSize(const uint32_t bufferSize);
|
||||||
int LinuxDvbStop(Context_t *context, char *type);
|
int LinuxDvbStop(Context_t *context, char *type);
|
||||||
@@ -383,6 +385,8 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
|
|||||||
ret = cERR_LINUXDVB_ERROR;
|
ret = cERR_LINUXDVB_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isBufferedOutput)
|
||||||
|
LinuxDvbBuffResume(context);
|
||||||
linuxdvb_printf(10, "exiting\n");
|
linuxdvb_printf(10, "exiting\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -227,8 +227,6 @@ static int writeDataADTS(WriterAVCallData_t *call)
|
|||||||
if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) ||
|
if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) ||
|
||||||
HasADTSHeader(call->data, call->len))
|
HasADTSHeader(call->data, call->len))
|
||||||
{
|
{
|
||||||
//(aacbuf[2] & 0x1F) | 0x40
|
|
||||||
|
|
||||||
//printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]);
|
//printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]);
|
||||||
return _writeData(call, 0);
|
return _writeData(call, 0);
|
||||||
}
|
}
|
||||||
|
@@ -101,6 +101,12 @@ static Writer_t *AvailableWriter[] =
|
|||||||
/* Functions */
|
/* 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, size_t size)
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
@@ -109,6 +115,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int maxFd = pipefd > fd ? pipefd : fd;
|
int maxFd = pipefd > fd ? pipefd : fd;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking)
|
while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking)
|
||||||
{
|
{
|
||||||
@@ -118,18 +125,34 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
|
|||||||
FD_SET(pipefd, &rfds);
|
FD_SET(pipefd, &rfds);
|
||||||
FD_SET(fd, &wfds);
|
FD_SET(fd, &wfds);
|
||||||
|
|
||||||
retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL);
|
/* When we PAUSE LINUX DVB outputs buffers then audio/video buffers
|
||||||
|
* will be filled to full unfortunately, in such case after resume
|
||||||
|
* select never return with fd set - bug in DVB drivers?
|
||||||
|
* So, there will be to workarounds:
|
||||||
|
* 1. write to pipe pipe at resume to exit select immediately
|
||||||
|
* 2. even if fd is not set exit from select after 0,1s
|
||||||
|
* (it seems that second workaround is not needed)
|
||||||
|
*/
|
||||||
|
//tv.tv_sec = 0;
|
||||||
|
//tv.tv_usec = 100000; // 100ms
|
||||||
|
|
||||||
|
retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); //&tv);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if (retval == 0)
|
||||||
|
//{
|
||||||
|
// //printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n");
|
||||||
|
// continue;
|
||||||
|
//}
|
||||||
|
|
||||||
if(FD_ISSET(pipefd, &rfds))
|
if(FD_ISSET(pipefd, &rfds))
|
||||||
{
|
{
|
||||||
char tmp;
|
FlusPipe(pipefd);
|
||||||
/* flush pipefd pipe */
|
//printf("RETURN FROM SELECT DUE TO pipefd SET\n");
|
||||||
while(1 == read(pipefd, &tmp, 1));
|
continue;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FD_ISSET(fd, &wfds))
|
if(FD_ISSET(fd, &wfds))
|
||||||
@@ -150,12 +173,19 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
else if (ret == 0)
|
||||||
|
{
|
||||||
|
//printf("This should not happen. Select return fd ready to write, but write return 0, errno [%d]\n", errno);
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 10000; // 10ms
|
||||||
|
retval = select(pipefd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (retval)
|
||||||
|
FlusPipe(pipefd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
size -= ret;
|
size -= ret;
|
||||||
buf += ret;
|
buf += ret;
|
||||||
|
Reference in New Issue
Block a user