Add buffering for Linux DVB outputs

Signed-off-by: max_10 <max_10@gmx.de>
This commit is contained in:
samsamsam
2018-03-31 11:39:41 +02:00
committed by Thilo Graf
parent b0e666e1cb
commit 2878ec69bc
25 changed files with 563 additions and 320 deletions

View File

@@ -21,6 +21,7 @@ libeplayer3_arm_la_SOURCES = \
output/linuxdvb_mipsel.c \
output/output_subtitle.c \
output/output.c \
output/linuxdvb_buffering.c \
output/writer/common/pes.c \
output/writer/common/misc.c \
output/writer/mipsel/writer.c \

View File

@@ -28,6 +28,7 @@ typedef enum
OUTPUT_DISCONTINUITY_REVERSE,
OUTPUT_GET_FRAME_COUNT,
OUTPUT_GET_PROGRESSIVE,
OUTPUT_SET_BUFFER_SIZE,
} OutputCmd_t;
typedef struct

View File

@@ -22,6 +22,7 @@ typedef struct
unsigned int Height;
unsigned char Version;
unsigned int InfoFlags;
ssize_t (* WriteV) (int, const struct iovec *, size_t);
} WriterAVCallData_t;
typedef struct WriterCaps_s

View File

@@ -480,14 +480,14 @@ static void UpdateVideoTrack()
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc");
}
static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int *pAudioTrackIdx, int *subtitleTrackIdx)
static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int *pAudioTrackIdx, int *subtitleTrackIdx, uint32_t *linuxDvbBufferSizeMB)
{
int ret = 0;
int c;
//int digit_optind = 0;
//int aopt = 0, bopt = 0;
//char *copt = 0, *dopt = 0;
while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:")) != -1)
while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:")) != -1)
{
switch (c)
{
@@ -597,6 +597,9 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int
free(ffopt);
break;
}
case 'b':
*linuxDvbBufferSizeMB = 1024 * 1024 * atoi(optarg);
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
ret = -1;
@@ -631,14 +634,16 @@ int main(int argc, char *argv[])
memset(audioFile, '\0', sizeof(audioFile));
int audioTrackIdx = -1;
int subtitleTrackIdx = -1;
uint32_t linuxDvbBufferSizeMB = 0;
char argvBuff[256];
memset(argvBuff, '\0', sizeof(argvBuff));
int commandRetVal = -1;
/* inform client that we can handle additional commands */
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 40);
if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx))
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 41);
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("[-b size] Linux DVB output buffer size in MB\n");
printf("[-a 0|1|2|3] AAC software decoding - 1 bit - AAC ADTS, 2 - bit AAC LATM\n");
printf("[-e] EAC3 software decoding\n");
printf("[-3] AC3 software decoding\n");
@@ -707,6 +712,9 @@ int main(int argc, char *argv[])
g_player->output->Command(g_player, OUTPUT_ADD, "audio");
g_player->output->Command(g_player, OUTPUT_ADD, "video");
g_player->output->Command(g_player, OUTPUT_ADD, "subtitle");
//Set LINUX DVB additional write buffer size
if (linuxDvbBufferSizeMB)
g_player->output->Command(g_player, OUTPUT_SET_BUFFER_SIZE, &linuxDvbBufferSizeMB);
g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack);
if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4))
{

View File

@@ -0,0 +1,389 @@
/*
* RAM write buffering utilities
* samsamsam 2018
*
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "common.h"
#include "misc.h"
#include "writer.h"
/* ***************************** */
/* Types */
/* ***************************** */
typedef enum OutputType_e{
OUTPUT_UNK,
OUTPUT_AUDIO,
OUTPUT_VIDEO,
} OutputType_t;
typedef struct BufferingNode_s {
uint32_t dataSize;
OutputType_t dataType;
struct BufferingNode_s *next;
} BufferingNode_t;
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
#define cERR_LINUX_DVB_BUFFERING_NO_ERROR 0
#define cERR_LINUX_DVB_BUFFERING_ERROR -1
//#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG
#define LINUX_DVB_BUFFERING_DEBUG
#else
#define LINUX_DVB_BUFFERING_SILENT
#endif
#ifdef LINUX_DVB_BUFFERING_DEBUG
static const uint16_t debug_level = 40;
#define buff_printf(level, fmt, x...) do { \
if (debug_level >= level) printf("[%s:%d:%s] " fmt, __FILE__, __LINE__, __FUNCTION__, ## x); } while (0)
#else
#define buff_printf(level, fmt, x...)
#endif
#ifndef LINUX_DVB_BUFFERING_SILENT
#define buff_err(fmt, x...) do { printf("[%s:%d:%s] " fmt, __FILE__, __LINE__, __FUNCTION__, ## x); } while (0)
#else
#define buff_err(fmt, x...)
#endif
/* ***************************** */
/* Varaibles */
/* ***************************** */
static pthread_t bufferingThread;
static pthread_mutex_t bufferingMtx;
static pthread_cond_t bufferingExitCond;
static pthread_cond_t bufferingDataConsumedCond;
static pthread_cond_t bufferingdDataAddedCond;
static bool hasBufferingThreadStarted = false;
static BufferingNode_t *bufferingQueueHead = NULL;
static BufferingNode_t *bufferingQueueTail = NULL;
static uint32_t maxBufferingDataSize = 0;
static uint32_t bufferingDataSize = 0;
static int videofd = -1;
static int audiofd = -1;
/* ***************************** */
/* Prototypes */
/* ***************************** */
/* ***************************** */
/* MISC Functions */
/* ***************************** */
/* **************************** */
/* Worker Thread */
/* **************************** */
static void LinuxDvbBuffThread(Context_t *context)
{
static BufferingNode_t *nodePtr = NULL;
buff_printf(20, "ENTER\n");
while (0 == PlaybackDieNow(0))
{
pthread_mutex_lock(&bufferingMtx);
if (nodePtr)
{
free(nodePtr);
nodePtr = NULL;
/* signal that we free some space in queue */
pthread_cond_signal(&bufferingDataConsumedCond);
}
if (!bufferingQueueHead)
{
assert(bufferingQueueTail == NULL);
/* Queue is empty we need to wait for data to be added */
pthread_cond_wait(&bufferingdDataAddedCond, &bufferingMtx);
pthread_mutex_unlock(&bufferingMtx);
continue; /* To check PlaybackDieNow(0) */
}
else
{
nodePtr = bufferingQueueHead;
bufferingQueueHead = bufferingQueueHead->next;
if (bufferingQueueHead == NULL)
{
bufferingQueueTail = NULL;
}
if (bufferingDataSize >= (nodePtr->dataSize + sizeof(BufferingNode_t)))
{
bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t));
}
else
{
assert(bufferingDataSize == 0);
bufferingDataSize = 0;
}
}
pthread_mutex_unlock(&bufferingMtx);
/* We will write data without mutex
* this have some disadvantage because we can
* write some portion of data after LinuxDvbBuffFlush,
* for example after seek, this will be fixed later
*/
if (nodePtr && !context->playback->isSeeking)
{
/* Write data to valid output */
uint8_t *dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t);
int fd = nodePtr->dataType == OUTPUT_VIDEO ? videofd : audiofd;
if (0 != write_with_retry(fd, dataPtr, nodePtr->dataSize))
{
printf("Something is WRONG\n");
}
}
}
pthread_mutex_lock(&bufferingMtx);
pthread_cond_signal(&bufferingExitCond);
pthread_mutex_unlock(&bufferingMtx);
buff_printf(20, "EXIT\n");
hasBufferingThreadStarted = false;
}
int32_t WriteSetBufferingSize(const uint32_t bufferSize)
{
maxBufferingDataSize = bufferSize;
return cERR_LINUX_DVB_BUFFERING_NO_ERROR;
}
int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd)
{
int32_t error = 0;
int32_t ret = cERR_LINUX_DVB_BUFFERING_NO_ERROR;
buff_printf(10, "\n");
if (!hasBufferingThreadStarted)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0)
{
buff_printf(10, "Creating thread, error:%d:%s\n", error, strerror(error));
hasBufferingThreadStarted = false;
ret = cERR_LINUX_DVB_BUFFERING_ERROR;
}
else
{
buff_printf(10, "Created thread\n");
hasBufferingThreadStarted = true;
/* init synchronization prymitives */
pthread_mutex_init(&bufferingMtx, NULL);
pthread_cond_init(&bufferingExitCond, NULL);
pthread_cond_init(&bufferingDataConsumedCond, NULL);
pthread_cond_init(&bufferingdDataAddedCond, NULL);
}
}
if (!ret)
{
if (!strcmp("video", type) && -1 == videofd)
{
videofd = outfd;
}
else if (!strcmp("audio", type) && -1 == audiofd)
{
audiofd = outfd;
}
else
{
ret = cERR_LINUX_DVB_BUFFERING_ERROR;
}
}
buff_printf(10, "exiting with value %d\n", ret);
return ret;
}
int32_t LinuxDvbBuffClose(Context_t *context)
{
int32_t ret = 0;
buff_printf(10, "\n");
videofd = -1;
audiofd = -1;
if (hasBufferingThreadStarted)
{
struct timespec max_wait = {0, 0};
pthread_mutex_lock(&bufferingMtx);
/* wait for thread end */
clock_gettime(CLOCK_REALTIME, &max_wait);
max_wait.tv_sec += 1;
pthread_cond_timedwait(&bufferingExitCond, &bufferingMtx, &max_wait);
pthread_mutex_unlock(&bufferingMtx);
if (!hasBufferingThreadStarted)
{
/* destroy synchronization prymitives?
* for a moment, we'll exit linux process,
* so the system will do this for us
*/
/*
pthread_mutex_destroy(&bufferingMtx);
pthread_cond_destroy(&bufferingDataConsumedCond);
pthread_cond_destroy(&bufferingdDataAddedCond);
*/
}
}
ret = hasBufferingThreadStarted ? cERR_LINUX_DVB_BUFFERING_ERROR : cERR_LINUX_DVB_BUFFERING_NO_ERROR;
buff_printf(10, "exiting with value %d\n", ret);
return ret;
}
int32_t LinuxDvbBuffFlush(Context_t *context)
{
static BufferingNode_t *nodePtr = NULL;
buff_printf(40, "ENTER bufferingQueueHead[%p]\n", bufferingQueueHead);
pthread_mutex_lock(&bufferingMtx);
while (bufferingQueueHead)
{
nodePtr = bufferingQueueHead;
bufferingQueueHead = nodePtr->next;
bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t));
free(nodePtr);
}
bufferingQueueHead = NULL;
bufferingQueueTail = NULL;
buff_printf(40, "bufferingDataSize [%u]\n", bufferingDataSize);
assert(bufferingDataSize == 0);
bufferingDataSize = 0;
/* signal that queue is empty */
pthread_cond_signal(&bufferingDataConsumedCond);
pthread_mutex_unlock(&bufferingMtx);
buff_printf(40, "EXIT\n");
return 0;
}
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic)
{
OutputType_t dataType = OUTPUT_UNK;
BufferingNode_t *nodePtr = NULL;
uint8_t *dataPtr = NULL;
uint32_t chunkSize = 0;
uint32_t i = 0;
buff_printf(60, "ENTER\n");
if (fd == videofd)
{
buff_printf(60, "VIDEO\n");
dataType = OUTPUT_VIDEO;
}
else if (fd == audiofd)
{
buff_printf(60, "AUDIO\n");
dataType = OUTPUT_AUDIO;
}
else
{
buff_err("Unknown output type\n");
return cERR_LINUX_DVB_BUFFERING_ERROR;
}
for (i=0; i<ic; ++i)
{
chunkSize += iov[i].iov_len;
}
chunkSize += sizeof(BufferingNode_t);
/* Allocate memory for queue node + data */
nodePtr = malloc(chunkSize);
if (!nodePtr)
{
buff_err("OUT OF MEM\n");
return cERR_LINUX_DVB_BUFFERING_ERROR;
}
/* Copy data to new buffer */
dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t);
for (i=0; i<ic; ++i)
{
memcpy(dataPtr, iov[i].iov_base, iov[i].iov_len);
dataPtr += iov[i].iov_len;
}
pthread_mutex_lock(&bufferingMtx);
while (0 == PlaybackDieNow(0))
{
if (bufferingDataSize + chunkSize >= maxBufferingDataSize)
{
/* Buffering queue is full we need wait for space*/
pthread_cond_wait(&bufferingDataConsumedCond, &bufferingMtx);
}
else
{
/* Add chunk to buffering queue */
if (bufferingQueueHead == NULL)
{
bufferingQueueHead = nodePtr;
bufferingQueueTail = nodePtr;
}
else
{
bufferingQueueTail->next = nodePtr;
bufferingQueueTail = nodePtr;
}
bufferingDataSize += chunkSize;
chunkSize -= sizeof(BufferingNode_t);
nodePtr->dataSize = chunkSize;
nodePtr->dataType = dataType;
nodePtr->next = NULL;
/* signal that we added some data to queue */
pthread_cond_signal(&bufferingdDataAddedCond);
break;
}
}
pthread_mutex_unlock(&bufferingMtx);
buff_printf(60, "EXIT\n");
return chunkSize;
}

View File

@@ -25,6 +25,7 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -93,13 +94,18 @@ struct DVBApiVideoInfo_s
static struct DVBApiVideoInfo_s videoInfo = {-1, -1, -1, -1, -1};
unsigned long long int sCURRENT_PTS = 0;
bool isBufferedOutput = false;
pthread_mutex_t LinuxDVBmutex;
/* ***************************** */
/* Prototypes */
/* ***************************** */
int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd);
int32_t LinuxDvbBuffClose(Context_t *context);
int32_t LinuxDvbBuffFlush(Context_t *context);
ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic);
int32_t WriteSetBufferingSize(const uint32_t bufferSize);
int LinuxDvbStop(Context_t *context, char *type);
/* ***************************** */
@@ -108,15 +114,12 @@ int LinuxDvbStop(Context_t *context, char *type);
void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused)))
{
linuxdvb_printf(250, "requesting mutex\n");
pthread_mutex_lock(&LinuxDVBmutex);
linuxdvb_printf(250, "received mutex\n");
}
void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused)))
{
pthread_mutex_unlock(&LinuxDVBmutex);
linuxdvb_printf(250, "released mutex\n");
}
static int LinuxDvbMapBypassMode(int bypass)
@@ -130,66 +133,62 @@ static int LinuxDvbMapBypassMode(int bypass)
int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type)
{
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd < 0)
{
videofd = open(VIDEODEV, O_RDWR | O_CLOEXEC);
if (videofd < 0)
{
linuxdvb_err("failed to open %s - errno %d\n", VIDEODEV, errno);
linuxdvb_err("%s\n", strerror(errno));
linuxdvb_err("failed to open %s - errno %d, %s\n", VIDEODEV, errno, strerror(errno));
return cERR_LINUXDVB_ERROR;
}
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno));
linuxdvb_err("VIDEO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(videofd, VIDEO_FREEZE) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno));
linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno));
}
if (isBufferedOutput)
LinuxDvbBuffOpen(context, type, videofd);
}
if (audio && audiofd < 0)
{
audiofd = open(AUDIODEV, O_RDWR | O_CLOEXEC);
if (audiofd < 0)
{
linuxdvb_err("failed to open %s - errno %d\n", AUDIODEV, errno);
linuxdvb_err("%s\n", strerror(errno));
linuxdvb_err("failed to open %s - errno %d, %s\n", AUDIODEV, errno, strerror(errno));
return cERR_LINUXDVB_ERROR;
}
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(audiofd, AUDIO_PAUSE) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno));
}
if (isBufferedOutput)
LinuxDvbBuffOpen(context, type, audiofd);
}
return cERR_LINUXDVB_NO_ERROR;
}
int LinuxDvbClose(Context_t *context, char *type)
{
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
/* closing stand alone is not allowed, so prevent
* user from closing and don't call stop. stop will
@@ -207,6 +206,8 @@ int LinuxDvbClose(Context_t *context, char *type)
close(audiofd);
audiofd = -1;
}
if (isBufferedOutput)
LinuxDvbBuffClose(context);
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
return cERR_LINUXDVB_NO_ERROR;
}
@@ -215,8 +216,8 @@ int LinuxDvbPlay(Context_t *context, char *type)
{
int ret = cERR_LINUXDVB_NO_ERROR;
Writer_t *writer;
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1)
{
@@ -224,15 +225,6 @@ int LinuxDvbPlay(Context_t *context, char *type)
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(10, "V %s\n", Encoding);
writer = getWriter(Encoding);
// SULGE VU 4K dont like this
/*
if (0 != ioctl(videofd, VIDEO_STOP))
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
*/
if (writer == NULL)
{
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -243,27 +235,23 @@ int LinuxDvbPlay(Context_t *context, char *type)
linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) writer->caps->dvbStreamType) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
free(Encoding);
if (0 != ioctl(videofd, VIDEO_PLAY))
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno));
linuxdvb_err("VIDEO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
if (ioctl(videofd, VIDEO_CONTINUE) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno));
linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
}
}
if (audio && audiofd != -1)
@@ -272,15 +260,6 @@ int LinuxDvbPlay(Context_t *context, char *type)
context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding);
linuxdvb_printf(20, "0 A %s\n", Encoding);
writer = getWriter(Encoding);
// SULGE VU 4K dont like this
/*
if (0 != ioctl(audiofd, AUDIO_STOP))
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
*/
if (writer == NULL)
{
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -291,21 +270,18 @@ int LinuxDvbPlay(Context_t *context, char *type)
linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) < 0)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
if (ioctl(audiofd, AUDIO_PLAY) < 0)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
if (ioctl(audiofd, AUDIO_CONTINUE) < 0)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
free(Encoding);
@@ -326,13 +302,11 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
{
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(videofd, VIDEO_STOP) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
ioctl(videofd, VIDEO_SLOWMOTION, 0);
@@ -343,21 +317,11 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
{
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
}
/* set back to normal speed (end trickmodes) */
/*
if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno));
}
*/
if (ioctl(audiofd, AUDIO_STOP) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX);
@@ -368,17 +332,16 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
{
int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1)
{
if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno));
linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -386,8 +349,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
{
if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -397,9 +359,9 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type)
int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
{
int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1)
{
@@ -409,8 +371,7 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
}
if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno));
linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -418,8 +379,7 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
{
if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -427,22 +387,6 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type)
return ret;
}
int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus __attribute__((unused)))
{
int ret = cERR_LINUXDVB_NO_ERROR;
/*
int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus;
linuxdvb_printf(50, "\n");
if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno));
}
linuxdvb_printf(50, "exiting\n");
*/
return ret;
}
int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag)
{
int ret = cERR_LINUXDVB_NO_ERROR;
@@ -451,25 +395,17 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag)
{
if (*flag == '1')
{
//AUDIO_SET_MUTE has no effect with new player
//if (ioctl(audiofd, AUDIO_SET_MUTE, 1) == -1)
if (ioctl(audiofd, AUDIO_STOP, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
//linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
else
{
//AUDIO_SET_MUTE has no effect with new player
//if (ioctl(audiofd, AUDIO_SET_MUTE, 0) == -1)
if (ioctl(audiofd, AUDIO_PLAY) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
//linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -480,52 +416,23 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag)
int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type __attribute__((unused)))
{
/*
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1))
{
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (video && videofd != -1)
{
if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno));
}
}
if (audio && audiofd != -1)
{
if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno));
}
}
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
}
linuxdvb_printf(10, "exiting\n");
*/
return cERR_LINUXDVB_NO_ERROR;
}
#ifndef use_set_speed_instead_ff
int LinuxDvbFastForward(Context_t *context, char *type)
{
int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
if (audio) {}
linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed);
if (video && videofd != -1)
{
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
/* konfetti comment: speed is a value given in skipped frames */
// konfetti comment: speed is a value given in skipped frames
if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_FAST_FORWARD: %s\n", strerror(errno));
linuxdvb_err("VIDEO_FAST_FORWARD: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
@@ -533,69 +440,12 @@ int LinuxDvbFastForward(Context_t *context, char *type)
linuxdvb_printf(10, "exiting with value %d\n", ret);
return ret;
}
#else
static unsigned int SpeedList[] =
{
1000, 1100, 1200, 1300, 1500,
2000, 3000, 4000, 5000, 8000,
12000, 16000,
125, 250, 500, 700, 800, 900
};
int LinuxDvbFastForward(Context_t *context, char *type)
{
int ret = cERR_LINUXDVB_NO_ERROR;
int speedIndex;
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (video && videofd != -1)
{
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int));
linuxdvb_printf(1, "speedIndex %d\n", speedIndex);
/*
if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
*/
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
}
if (audio && audiofd != -1)
{
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int));
linuxdvb_printf(1, "speedIndex %d\n", speedIndex);
/*
if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
*/
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
}
linuxdvb_printf(10, "exiting with value %d\n", ret);
return ret;
}
#endif
int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __attribute__((unused)))
{
int ret = cERR_LINUXDVB_NO_ERROR;
return ret;
}
int LinuxDvbSlowMotion(Context_t *context, char *type)
{
int ret = cERR_LINUXDVB_NO_ERROR;
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1))
{
@@ -604,8 +454,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type)
{
if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SLOWMOTION: %s\n", strerror(errno));
linuxdvb_err("VIDEO_SLOWMOTION: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -617,7 +466,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type)
int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attribute__((unused)))
{
int ret = cERR_LINUXDVB_NO_ERROR;
int32_t ret = cERR_LINUXDVB_NO_ERROR;
/* konfetti: this one is dedicated to audiofd so we
* are ignoring what is given by type! I think we should
* remove this param. Therefor we should add a variable
@@ -629,8 +478,7 @@ int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attr
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno));
linuxdvb_err("AUDIO_SET_AV_SYNC: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
@@ -643,7 +491,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
int32_t ret = cERR_LINUXDVB_NO_ERROR;
uint8_t video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
linuxdvb_printf(10, ">>>>>>>>>>LinuxDvbClear v%d a%d\n", video, audio);
linuxdvb_printf(10, "LinuxDvbClear v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1))
{
getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__);
@@ -651,8 +499,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
{
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -660,8 +507,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
{
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
}
@@ -673,17 +519,16 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type)
int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts)
{
int ret = cERR_LINUXDVB_ERROR;
int32_t ret = cERR_LINUXDVB_ERROR;
linuxdvb_printf(50, "\n");
// pts is a non writting requests and can be done in parallel to other requests
//getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
// GET_PTS is immutable call, so it can be done in parallel to other requests
if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS))
{
ret = cERR_LINUXDVB_NO_ERROR;
}
else
{
linuxdvb_err("VIDEO_GET_PTS: %d (%s)\n", errno, strerror(errno));
linuxdvb_err("VIDEO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno));
}
if (ret != cERR_LINUXDVB_NO_ERROR)
{
@@ -693,7 +538,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i
}
else
{
linuxdvb_err("AUDIO_GET_PTS: %d (%s)\n", errno, strerror(errno));
linuxdvb_err("AUDIO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno));
}
}
if (ret != cERR_LINUXDVB_NO_ERROR)
@@ -701,20 +546,18 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i
sCURRENT_PTS = 0;
}
*((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS;
//releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
return ret;
}
int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned long long int *frameCount __attribute__((unused)))
{
int ret = cERR_LINUXDVB_NO_ERROR;
return ret;
return cERR_LINUXDVB_NO_ERROR;
}
int LinuxDvbSwitch(Context_t *context, char *type)
{
unsigned char audio = !strcmp("audio", type);
unsigned char video = !strcmp("video", type);
uint8_t audio = !strcmp("audio", type);
uint8_t video = !strcmp("video", type);
Writer_t *writer;
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if ((video && videofd != -1) || (audio && audiofd != -1))
@@ -730,38 +573,27 @@ int LinuxDvbSwitch(Context_t *context, char *type)
writer = getWriter(Encoding);
if (ioctl(audiofd, AUDIO_STOP, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno));
linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
}
if (writer == NULL)
{
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
/*
if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) AUDIO_ENCODING_MP3) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
}
*/
}
else
{
linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno));
linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno));
}
}
if (ioctl(audiofd, AUDIO_PLAY) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno));
linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno));
}
free(Encoding);
}
@@ -778,34 +610,24 @@ int LinuxDvbSwitch(Context_t *context, char *type)
context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding);
if (ioctl(videofd, VIDEO_STOP, NULL) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno));
linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno));
}
if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno));
linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno));
}
linuxdvb_printf(10, "V %s\n", Encoding);
writer = getWriter(Encoding);
if (writer == NULL)
{
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
/*
if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) VIDEO_ENCODING_AUTO) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
}
*/
}
else
{
linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding);
if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) writer->caps->dvbStreamType) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno));
linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno));
}
}
if (ioctl(videofd, VIDEO_PLAY) == -1)
@@ -813,8 +635,7 @@ int LinuxDvbSwitch(Context_t *context, char *type)
/* konfetti: fixme: think on this, I think we should
* return an error here and stop the playback mode
*/
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno));
linuxdvb_err("VIDEO_PLAY:ERROR %d, %s\n", errno, strerror(errno));
}
free(Encoding);
}
@@ -832,11 +653,11 @@ int LinuxDvbSwitch(Context_t *context, char *type)
static int Write(Context_t *context, void *_out)
{
AudioVideoOut_t *out = (AudioVideoOut_t *) _out;
int ret = cERR_LINUXDVB_NO_ERROR;
int res = 0;
unsigned char video = 0;
unsigned char audio = 0;
Writer_t *writer;
int32_t ret = cERR_LINUXDVB_NO_ERROR;
int32_t res = 0;
uint8_t video = 0;
uint8_t audio = 0;
Writer_t *writer = NULL;
WriterAVCallData_t call;
if (out == NULL)
{
@@ -921,7 +742,8 @@ static int Write(Context_t *context, void *_out)
call.Width = out->width;
call.Height = out->height;
call.InfoFlags = out->infoFlags;
call.Version = 0; // is unsingned char
call.Version = 0;
call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry;
if (writer->writeData)
{
res = writer->writeData(&call);
@@ -963,7 +785,8 @@ static int Write(Context_t *context, void *_out)
call.FrameRate = out->frameRate;
call.FrameScale = out->timeScale;
call.InfoFlags = out->infoFlags;
call.Version = 0; /* -1; unsigned char cannot be negative */
call.Version = 0;
call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry;
if (writer->writeData)
{
res = writer->writeData(&call);
@@ -1009,6 +832,8 @@ static int reset(Context_t *context)
writer->reset();
}
free(Encoding);
if (isBufferedOutput)
LinuxDvbBuffFlush(context);
return ret;
}
@@ -1065,11 +890,6 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
return LinuxDvbFastForward(context, (char *)argument);
break;
}
case OUTPUT_REVERSE:
{
return LinuxDvbReverse(context, (char *)argument);
break;
}
case OUTPUT_AVSYNC:
{
ret = LinuxDvbAVSync(context, (char *)argument);
@@ -1104,11 +924,6 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
return LinuxDvbAudioMute(context, (char *)argument);
break;
}
case OUTPUT_DISCONTINUITY_REVERSE:
{
return LinuxDvbReverseDiscontinuity(context, (int *)argument);
break;
}
case OUTPUT_GET_FRAME_COUNT:
{
unsigned long long int frameCount = 0;
@@ -1122,6 +937,21 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
*((int *)argument) = videoInfo.progressive;
break;
}
case OUTPUT_SET_BUFFER_SIZE:
{
ret = cERR_LINUXDVB_ERROR;
if (!isBufferedOutput)
{
uint32_t bufferSize = *((uint32_t*)argument);
ret = cERR_LINUXDVB_NO_ERROR;
if (bufferSize > 0)
{
WriteSetBufferingSize(bufferSize);
isBufferedOutput = true;
}
}
break;
}
default:
linuxdvb_err("ContainerCmd %d not supported!\n", command);
ret = cERR_LINUXDVB_ERROR;

View File

@@ -522,21 +522,40 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
ret = cERR_OUTPUT_INTERNAL_ERROR;
}
break;
case OUTPUT_GET_PROGRESSIVE:
}
case OUTPUT_GET_PROGRESSIVE:
{
if (context && context->playback)
{
if (context && context->playback)
if (context->playback->isVideo)
{
if (context->playback->isVideo)
{
return context->output->video->Command(context, OUTPUT_GET_PROGRESSIVE, (void *) argument);
}
return context->output->video->Command(context, OUTPUT_GET_PROGRESSIVE, (void *) argument);
}
else
{
ret = cERR_OUTPUT_INTERNAL_ERROR;
}
break;
}
else
{
ret = cERR_OUTPUT_INTERNAL_ERROR;
}
break;
}
case OUTPUT_SET_BUFFER_SIZE:
{
if (context && context->playback)
{
if (context->output->video)
{
return context->output->video->Command(context, OUTPUT_SET_BUFFER_SIZE, argument);
}
else if (context->output->audio)
{
return context->output->audio->Command(context, OUTPUT_SET_BUFFER_SIZE, argument);
}
}
else
{
ret = cERR_OUTPUT_INTERNAL_ERROR;
}
break;
}
default:
output_err("%s::%s OutputCmd %d not supported!\n", __FILE__, __FUNCTION__, command);

View File

@@ -195,7 +195,7 @@ static int _writeData(WriterAVCallData_t *call, int type)
iov[0].iov_len = HeaderLength;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return writev_with_retry(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
static int writeDataADTS(WriterAVCallData_t *call)
@@ -253,7 +253,7 @@ static int writeDataADTS(WriterAVCallData_t *call)
iov[0].iov_len = headerSize + AAC_HEADER_LENGTH;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return writev_with_retry(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
static int writeDataLATM(WriterAVCallData_t *call)
@@ -309,7 +309,7 @@ static int writeDataLATM(WriterAVCallData_t *call)
iov[1].iov_len = 3;
iov[2].iov_base = pLATMCtx->buffer;
iov[2].iov_len = pLATMCtx->len;
return writev_with_retry(call->fd, iov, 3);
return call->WriteV(call->fd, iov, 3);
}
/* ***************************** */

View File

@@ -126,7 +126,7 @@ static int writeData(WriterAVCallData_t *call)
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
ac3_printf(40, "PES HEADER LEN %d\n", iov[0].iov_len);
return writev_with_retry(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
/* ***************************** */

View File

@@ -145,7 +145,7 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = headerSize;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
int len = writev_with_retry(call->fd, iov, 2);
int len = call->WriteV(call->fd, iov, 2);
amr_printf(10, "amr_Write-< len=%d\n", len);
return len;
}

View File

@@ -169,7 +169,7 @@ static int writeData(WriterAVCallData_t *call)
iov[ic++].iov_len = headerSize;
iov[ic].iov_base = call->data;
iov[ic++].iov_len = call->len;
int len = writev_with_retry(call->fd, iov, ic);
int len = call->WriteV(call->fd, iov, ic);
divx_printf(10, "xvid_Write < len=%d\n", len);
return len;
}

View File

@@ -150,7 +150,7 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
iov[1].iov_base = Data;
iov[1].iov_len = Size;
int32_t len = writev_with_retry(call->fd, iov, 2);
int32_t len = call->WriteV(call->fd, iov, 2);
dts_printf(10, "< len %d\n", len);
return len;
}

View File

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

View File

@@ -55,6 +55,7 @@
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
#define H264_SILENT
//#define H264_DEBUG
#ifdef H264_DEBUG
@@ -348,7 +349,7 @@ static int writeData(WriterAVCallData_t *call)
iov[ic++].iov_len = call->len;
PacketLength += call->len;
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
return writev_with_retry(call->fd, iov, ic);
return call->WriteV(call->fd, iov, ic);
}
else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0])
{
@@ -418,7 +419,7 @@ static int writeData(WriterAVCallData_t *call)
while ((pos + NalLengthBytes) < call->len);
h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength);
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
len = writev_with_retry(call->fd, iov, ic);
len = call->WriteV(call->fd, iov, ic);
PacketLength += iov[0].iov_len;
if (PacketLength != len)
{

View File

@@ -55,6 +55,7 @@
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
#define H264_SILENT
//#define H265_DEBUG
#ifdef H265_DEBUG
@@ -220,7 +221,7 @@ static int writeData(WriterAVCallData_t *call)
iov[ic++].iov_len = call->len;
PacketLength += call->len;
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
return writev_with_retry(call->fd, iov, ic);
return call->WriteV(call->fd, iov, ic);
}
uint32_t PacketLength = 0;
ic = 0;
@@ -275,7 +276,7 @@ static int writeData(WriterAVCallData_t *call)
while ((pos + NalLengthBytes) < call->len);
h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength);
iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
len = writev_with_retry(call->fd, iov, ic);
len = call->WriteV(call->fd, iov, ic);
PacketLength += iov[0].iov_len;
if (PacketLength != len)
{

View File

@@ -238,7 +238,7 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = pes_header_size;
iov[1].iov_base = frame;
iov[1].iov_len = i_frame_size;
i_ret_size += writev_with_retry(call->fd, iov, 2);
i_ret_size += call->WriteV(call->fd, iov, 2);
}
memcpy(p_buffer, call->data + i_bytes_consumed, i_leftover_samples * i_channels * 2);
i_buffer_used = i_leftover_samples;

View File

@@ -123,7 +123,7 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = headerSize;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
int len = writev_with_retry(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

@@ -125,7 +125,7 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0);
iov[1].iov_base = call->data + Position;
iov[1].iov_len = PacketLength;
ssize_t l = writev_with_retry(call->fd, iov, 2);
ssize_t l = call->WriteV(call->fd, iov, 2);
if (l < 0)
{
len = l;

View File

@@ -137,7 +137,7 @@ static int writeData(WriterAVCallData_t *call)
}
iov[ic].iov_base = call->data;
iov[ic++].iov_len = call->len;
int len = writev_with_retry(call->fd, iov, ic);
int len = call->WriteV(call->fd, iov, ic);
mpeg4_printf(10, "xvid_Write < len=%d\n", len);
return len;
}

View File

@@ -265,10 +265,10 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = headerSize;
iov[1].iov_base = fixed_buffer;
iov[1].iov_len = fixed_buffersize;
writev_with_retry(call->fd, iov, 2);
call->WriteV(call->fd, iov, 2);
fixed_buffertimestamp += fixed_bufferduration;
int g_fd_dump = open("/hdd/lpcm/ffmpeg.pes", O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
writev_with_retry(g_fd_dump, iov, 2);
call->WriteV(g_fd_dump, iov, 2);
close(g_fd_dump);
}
return size;

View File

@@ -175,7 +175,7 @@ static int writeData(WriterAVCallData_t *call)
free(videocodecdata.data);
videocodecdata.data = NULL;
}
return writev_with_retry(call->fd, iov, ic);
return call->WriteV(call->fd, iov, ic);
}
/* ***************************** */

View File

@@ -138,7 +138,7 @@ static int writeData(WriterAVCallData_t *call, int is_vp6)
iov[0].iov_len = pes_header_len;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return writev_with_retry(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
static int writeDataVP6(WriterAVCallData_t *call)

View File

@@ -158,7 +158,7 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = headerSize;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return writev_with_retry(call->fd, iov, 2);
return call->WriteV(call->fd, iov, 2);
}
/* ***************************** */

View File

@@ -181,7 +181,7 @@ static int writeData(WriterAVCallData_t *call)
free(videocodecdata.data);
videocodecdata.data = NULL;
}
return writev_with_retry(call->fd, iov, ic);
return call->WriteV(call->fd, iov, ic);
}
/* ***************************** */

View File

@@ -468,14 +468,6 @@ static int PlaybackFastBackward(Context_t *context, int *speed)
playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard);
}
context->output->Command(context, OUTPUT_CLEAR, NULL);
if (context->output->Command(context, OUTPUT_REVERSE, NULL) < 0)
{
playback_err("OUTPUT_REVERSE failed\n");
context->playback->BackWard = 0;
context->playback->Speed = 1;
context->playback->isSeeking = 0;
ret = cERR_PLAYBACK_ERROR;
}
}
else
{