diff --git a/libeplayer3-arm/Makefile.am b/libeplayer3-arm/Makefile.am index b1bdd32..1f7f51e 100644 --- a/libeplayer3-arm/Makefile.am +++ b/libeplayer3-arm/Makefile.am @@ -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 \ diff --git a/libeplayer3-arm/include/output.h b/libeplayer3-arm/include/output.h index 5b0fedb..16a61f1 100644 --- a/libeplayer3-arm/include/output.h +++ b/libeplayer3-arm/include/output.h @@ -28,6 +28,7 @@ typedef enum OUTPUT_DISCONTINUITY_REVERSE, OUTPUT_GET_FRAME_COUNT, OUTPUT_GET_PROGRESSIVE, + OUTPUT_SET_BUFFER_SIZE, } OutputCmd_t; typedef struct diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index c027899..28c74d3 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -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 diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 0589587..a71e33b 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -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)) { diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c new file mode 100644 index 0000000..c8f106e --- /dev/null +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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= 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; +} diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 1699f7d..4ef70df 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -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; diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 168c203..8c1580f 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -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); diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index 8e6d163..c1cec2d 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -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); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/ac3.c b/libeplayer3-arm/output/writer/mipsel/ac3.c index b71b089..37ee989 100644 --- a/libeplayer3-arm/output/writer/mipsel/ac3.c +++ b/libeplayer3-arm/output/writer/mipsel/ac3.c @@ -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); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/amr.c b/libeplayer3-arm/output/writer/mipsel/amr.c index cb843b5..d509ea5 100644 --- a/libeplayer3-arm/output/writer/mipsel/amr.c +++ b/libeplayer3-arm/output/writer/mipsel/amr.c @@ -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; } diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index 98f1f4a..de7ebab 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -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; } diff --git a/libeplayer3-arm/output/writer/mipsel/dts.c b/libeplayer3-arm/output/writer/mipsel/dts.c index b56969b..beb8e28 100644 --- a/libeplayer3-arm/output/writer/mipsel/dts.c +++ b/libeplayer3-arm/output/writer/mipsel/dts.c @@ -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; } diff --git a/libeplayer3-arm/output/writer/mipsel/h263.c b/libeplayer3-arm/output/writer/mipsel/h263.c index 152b026..39c4ed2 100644 --- a/libeplayer3-arm/output/writer/mipsel/h263.c +++ b/libeplayer3-arm/output/writer/mipsel/h263.c @@ -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; } diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 9855288..4dbf2b6 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -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) { diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index cb21d99..ad59853 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -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) { diff --git a/libeplayer3-arm/output/writer/mipsel/lpcm.c b/libeplayer3-arm/output/writer/mipsel/lpcm.c index aca119e..f03fc5d 100644 --- a/libeplayer3-arm/output/writer/mipsel/lpcm.c +++ b/libeplayer3-arm/output/writer/mipsel/lpcm.c @@ -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; diff --git a/libeplayer3-arm/output/writer/mipsel/mp3.c b/libeplayer3-arm/output/writer/mipsel/mp3.c index 88c5a82..3271f98 100644 --- a/libeplayer3-arm/output/writer/mipsel/mp3.c +++ b/libeplayer3-arm/output/writer/mipsel/mp3.c @@ -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; } diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg2.c b/libeplayer3-arm/output/writer/mipsel/mpeg2.c index daa9daf..2e53f70 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg2.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg2.c @@ -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; diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg4.c b/libeplayer3-arm/output/writer/mipsel/mpeg4.c index 7abce59..23cb154 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg4.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg4.c @@ -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; } diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index bc63b09..8246100 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -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; diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index f6997ab..d291e2a 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -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); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/vp.c b/libeplayer3-arm/output/writer/mipsel/vp.c index 2e31151..0c61c8c 100644 --- a/libeplayer3-arm/output/writer/mipsel/vp.c +++ b/libeplayer3-arm/output/writer/mipsel/vp.c @@ -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) diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index 6500c7e..cea0459 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -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); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/wmv.c b/libeplayer3-arm/output/writer/mipsel/wmv.c index 96db958..225697b 100644 --- a/libeplayer3-arm/output/writer/mipsel/wmv.c +++ b/libeplayer3-arm/output/writer/mipsel/wmv.c @@ -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); } /* ***************************** */ diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index f9364e9..1cf422f 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -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 {