From de9ff6374a24d2ef0f3bb21a63ff496a823529dc Mon Sep 17 00:00:00 2001 From: samsamsam Date: Sat, 2 Feb 2019 18:41:46 +0100 Subject: [PATCH] Improve playback of VP9 codec Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e6638a72af6ca14b1900d6ffc2e1870b2dacf8a4 Author: samsamsam Date: 2019-02-02 (Sat, 02 Feb 2019) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 6 +- libeplayer3-arm/include/misc.h | 64 ++-------- libeplayer3-arm/include/pes.h | 1 + libeplayer3-arm/include/writer.h | 7 +- libeplayer3-arm/main/exteplayer.c | 8 +- libeplayer3-arm/output/linuxdvb_buffering.c | 14 +- libeplayer3-arm/output/linuxdvb_mipsel.c | 8 +- libeplayer3-arm/output/linuxdvb_sh4.c | 6 +- libeplayer3-arm/output/writer/common/misc.c | 27 ++++ libeplayer3-arm/output/writer/common/pes.c | 35 +++-- libeplayer3-arm/output/writer/common/writer.c | 8 ++ libeplayer3-arm/output/writer/mipsel/pcm.c | 4 +- libeplayer3-arm/output/writer/mipsel/vc1.c | 2 +- libeplayer3-arm/output/writer/mipsel/vp.c | 120 ++++++++++++++++-- libeplayer3-arm/output/writer/mipsel/wma.c | 4 +- libeplayer3-arm/output/writer/mipsel/wmv.c | 2 +- libeplayer3-arm/output/writer/mipsel/writer.c | 99 +++++++++++++-- libeplayer3-arm/output/writer/sh4/writer.c | 2 +- 18 files changed, 306 insertions(+), 111 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 2ee1699..676aaae 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -838,7 +838,7 @@ static void FFMPEGThread(Context_t *context) else #endif { - uint8_t skipPacket = 0; + bool skipPacket = false; currentVideoPts = videoTrack->pts = pts = calcPts(cAVIdx, videoTrack->stream, packet.pts); videoTrack->dts = dts = calcPts(cAVIdx, videoTrack->stream, packet.dts); @@ -860,14 +860,14 @@ static void FFMPEGThread(Context_t *context) { // skip already injected VIDEO packet ffmpeg_printf(200, "skip already injected VIDEO packet\n"); - skipPacket = 1; + skipPacket = true; } } else { // skip VIDEO packet with unknown DTS ffmpeg_printf(200, "skip VIDEO packet with unknown DTS\n"); - skipPacket = 1; + skipPacket = true; } } diff --git a/libeplayer3-arm/include/misc.h b/libeplayer3-arm/include/misc.h index f1114b4..7bf2ed4 100644 --- a/libeplayer3-arm/include/misc.h +++ b/libeplayer3-arm/include/misc.h @@ -1,5 +1,5 @@ -#ifndef misc_123 -#define misc_123 +#ifndef _exteplayer3_misc_ +#define _exteplayer3_misc_ #include #include @@ -20,6 +20,15 @@ typedef struct BitPacker_s int32_t Remaining; /* number of remaining in the shifter */ } BitPacker_t; +typedef enum +{ + STB_UNKNOWN, + STB_DREAMBOX, + STB_VUPLUS, + STB_HISILICON, + STB_OTHER = 999, +} stb_type_t; + /* ***************************** */ /* Makros/Constants */ /* ***************************** */ @@ -33,6 +42,7 @@ typedef struct BitPacker_s void PutBits(BitPacker_t *ld, uint32_t code, uint32_t length); void FlushBits(BitPacker_t *ld); int8_t PlaybackDieNow(int8_t val); +stb_type_t GetSTBType(); /* ***************************** */ /* MISC Functions */ @@ -51,54 +61,6 @@ static inline char *getExtension(char *name) return NULL; } -/* the function returns the base name */ -static inline char *basename(char *name) -{ - int i = 0; - int pos = 0; - - while (name[i] != 0) - { - if (name[i] == '/') - pos = i; - i++; - } - - if (name[pos] == '/') - pos++; - - return name + pos; -} - -/* the function returns the directry name */ -static inline char *dirname(char *name) -{ - static char path[100]; - uint32_t i = 0; - int32_t pos = 0; - - while ((name[i] != 0) && (i < sizeof(path))) - { - if (name[i] == '/') - { - pos = i; - } - path[i] = name[i]; - i++; - } - - path[i] = 0; - path[pos] = 0; - - return path; -} - -static inline int32_t IsDreambox() -{ - struct stat buffer; - return (stat("/proc/stb/tpm/0/serial", &buffer) == 0); -} - static inline uint32_t ReadUint32(uint8_t *buffer) { uint32_t num = (uint32_t)buffer[0] << 24 | @@ -115,4 +77,4 @@ static inline uint16_t ReadUInt16(uint8_t *buffer) return num; } -#endif +#endif // _exteplayer3_misc_ diff --git a/libeplayer3-arm/include/pes.h b/libeplayer3-arm/include/pes.h index 1b2d019..cca5ee7 100644 --- a/libeplayer3-arm/include/pes.h +++ b/libeplayer3-arm/include/pes.h @@ -28,5 +28,6 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t pts, int32_t pic_start_code); int32_t InsertVideoPrivateDataHeader(uint8_t *data, int32_t payload_size); +void UpdatePesHeaderPayloadSize(uint8_t *data, int32_t size); #endif diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index 9b7b7b5..e97909f 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -7,6 +7,7 @@ #include "common.h" typedef enum { eNone, eAudio, eVideo} eWriterType_t; +typedef ssize_t (* WriteV_t)(int, const struct iovec *, int); typedef struct { @@ -23,7 +24,7 @@ typedef struct unsigned int Height; unsigned char Version; unsigned int InfoFlags; - ssize_t (* WriteV) (int, const struct iovec *, int); + WriteV_t WriteV; } WriterAVCallData_t; @@ -91,6 +92,8 @@ Writer_t *getDefaultAudioWriter(); ssize_t write_with_retry(int fd, const void *buf, int size); ssize_t writev_with_retry(int fd, const struct iovec *iov, int ic); -ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size); +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, const void *buf, int size); void FlushPipe(int pipefd); + +ssize_t WriteExt(WriteV_t _call, int fd, void *data, size_t size); #endif diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index c8ba127..f9761db 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -93,7 +93,11 @@ static pthread_mutex_t playbackStartMtx; static void TerminateWakeUp() { - write(g_pfd[1], "x", 1); + int ret = write(g_pfd[1], "x", 1); + if (ret != 1) + { + printf("TerminateWakeUp write return %d\n", ret); + } } static void *TermThreadFun(void *arg __attribute__((unused))) @@ -695,7 +699,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 51); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 52); PlayFiles_t playbackFiles; memset(&playbackFiles, 0x00, sizeof(playbackFiles)); diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c index 3f70d47..cfe53d5 100644 --- a/libeplayer3-arm/output/linuxdvb_buffering.c +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -83,6 +83,8 @@ static int videofd = -1; static int audiofd = -1; static int g_pfd[2] = {-1, -1}; +static pthread_mutex_t *g_pDVBMtx = NULL; + /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -93,7 +95,11 @@ static int g_pfd[2] = {-1, -1}; static void WriteWakeUp() { - write(g_pfd[1], "x", 1); + int ret = write(g_pfd[1], "x", 1); + if (ret != 1) + { + buff_printf(20, "WriteWakeUp write return %d\n", ret); + } } /* ***************************** */ @@ -189,7 +195,7 @@ static void LinuxDvbBuffThread(Context_t *context) /* Write data to valid output */ uint8_t *dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t); int fd = nodePtr->dataType == OUTPUT_VIDEO ? videofd : audiofd; - if (0 != WriteWithRetry(context, g_pfd[0], fd, dataPtr, nodePtr->dataSize)) + if (0 != WriteWithRetry(context, g_pfd[0], fd, g_pDVBMtx, dataPtr, nodePtr->dataSize)) { buff_err("Something is WRONG\n"); } @@ -220,7 +226,7 @@ uint32_t LinuxDvbBuffGetSize() return maxBufferingDataSize; } -int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx) { int32_t error = 0; int32_t ret = cERR_LINUX_DVB_BUFFERING_NO_ERROR; @@ -233,6 +239,8 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + g_pDVBMtx = mtx; + if ((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0) { buff_printf(10, "Creating thread, error:%d:%s\n", error, strerror(error)); diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 95d36ce..24342ac 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -78,7 +78,7 @@ pthread_mutex_t LinuxDVBmutex; /* ***************************** */ /* Prototypes */ /* ***************************** */ -int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd); +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx); int32_t LinuxDvbBuffClose(Context_t *context); int32_t LinuxDvbBuffFlush(Context_t *context); int32_t LinuxDvbBuffResume(Context_t *context); @@ -98,7 +98,7 @@ int LinuxDvbStop(Context_t *context, char *type); static int LinuxDvbMapBypassMode(int bypass) { - if (0x30 == bypass && IsDreambox()) + if (0x30 == bypass && STB_DREAMBOX == GetSTBType()) { return 0x0f; } @@ -139,7 +139,7 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) } if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, videofd); + LinuxDvbBuffOpen(context, type, videofd, &LinuxDVBmutex); } if (audio && audiofd < 0) { @@ -167,7 +167,7 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) } if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, audiofd); + LinuxDvbBuffOpen(context, type, audiofd, &LinuxDVBmutex); } return cERR_LINUXDVB_NO_ERROR; diff --git a/libeplayer3-arm/output/linuxdvb_sh4.c b/libeplayer3-arm/output/linuxdvb_sh4.c index a29dc07..dedc77f 100644 --- a/libeplayer3-arm/output/linuxdvb_sh4.c +++ b/libeplayer3-arm/output/linuxdvb_sh4.c @@ -78,7 +78,7 @@ pthread_mutex_t LinuxDVBmutex; /* ***************************** */ /* Prototypes */ /* ***************************** */ -int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd); +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx); int32_t LinuxDvbBuffClose(Context_t *context); int32_t LinuxDvbBuffFlush(Context_t *context); int32_t LinuxDvbBuffResume(Context_t *context); @@ -139,7 +139,7 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) } if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, videofd); + LinuxDvbBuffOpen(context, type, videofd, &LinuxDVBmutex); } if (audio && audiofd < 0) { @@ -173,7 +173,7 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) } if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, audiofd); + LinuxDvbBuffOpen(context, type, audiofd, &LinuxDVBmutex); } return cERR_LINUXDVB_NO_ERROR; diff --git a/libeplayer3-arm/output/writer/common/misc.c b/libeplayer3-arm/output/writer/common/misc.c index 71c5ec1..a514faa 100644 --- a/libeplayer3-arm/output/writer/common/misc.c +++ b/libeplayer3-arm/output/writer/common/misc.c @@ -126,3 +126,30 @@ void FlushBits(BitPacker_t *ld) ld->Remaining = 32; ld->BitBuffer = 0; } + +stb_type_t GetSTBType() +{ + static stb_type_t type = STB_UNKNOWN; + if (type == STB_UNKNOWN) + { + struct stat buffer; + if (access("/proc/stb/tpm/0/serial", F_OK) != -1) + { + type = STB_DREAMBOX; + } + else if (access("/proc/stb/info/vumodel", F_OK) != -1) + { + type = STB_VUPLUS; + } + else if (access("/sys/firmware/devicetree/base/soc/hisilicon_clock/name", F_OK) != -1) + { + type = STB_HISILICON; + } + else + { + type = STB_OTHER; + } + } + + return type; +} diff --git a/libeplayer3-arm/output/writer/common/pes.c b/libeplayer3-arm/output/writer/common/pes.c index e4788c5..f91be82 100644 --- a/libeplayer3-arm/output/writer/common/pes.c +++ b/libeplayer3-arm/output/writer/common/pes.c @@ -88,31 +88,38 @@ int32_t InsertVideoPrivateDataHeader(uint8_t *data, int32_t payload_size) FlushBits(&ld2); return PES_PRIVATE_DATA_LENGTH + 1; +} +void UpdatePesHeaderPayloadSize(uint8_t *data, int32_t size) +{ + if (size > MAX_PES_PACKET_SIZE || size < 0) + size = 0; + data[4] = size >> 8; + data[5] = size & 0xFF; } int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t pts, int32_t pic_start_code) { BitPacker_t ld2 = {data, 0, 32}; - if (size > (MAX_PES_PACKET_SIZE - 13)) + PutBits(&ld2, 0x0, 8); + PutBits(&ld2, 0x0, 8); + PutBits(&ld2, 0x1, 8); // Start Code + PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream + + if (size > 0) { - size = -1; // unbounded + size += 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0); + } + + if (size > MAX_PES_PACKET_SIZE || size < 0) + { + size = 0; // unbounded } - PutBits(&ld2, 0x0, 8); - PutBits(&ld2, 0x0, 8); - PutBits(&ld2, 0x1, 8); // Start Code - PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream //4 - if (-1 == size) - { - PutBits(&ld2, 0x0, 16); - } - else - { - PutBits(&ld2, size + 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0), 16); // PES_packet_length - } + PutBits(&ld2, size, 16); // PES_packet_length + //6 = 4+2 PutBits(&ld2, 0x2, 2); // 10 PutBits(&ld2, 0x0, 2); // PES_Scrambling_control diff --git a/libeplayer3-arm/output/writer/common/writer.c b/libeplayer3-arm/output/writer/common/writer.c index 8f8a18d..63fcb19 100644 --- a/libeplayer3-arm/output/writer/common/writer.c +++ b/libeplayer3-arm/output/writer/common/writer.c @@ -55,3 +55,11 @@ void FlushPipe(int pipefd) char tmp; while (1 == read(pipefd, &tmp, 1)); } + +ssize_t WriteExt(WriteV_t _call, int fd, void *data, size_t size) +{ + struct iovec iov[1]; + iov[0].iov_base = data; + iov[0].iov_len = size; + return _call(fd, iov, 1); +} diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index f8bb938..d24b4e2 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -224,12 +224,12 @@ static int writeData(WriterAVCallData_t *call) size -= cpSize; uint32_t addHeaderSize = 0; - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { addHeaderSize = 4; } uint32_t headerSize = InsertPesHeader(PesHeader, fixed_buffersize + 4 + addHeaderSize + sizeof(codec_data), MPEG_AUDIO_PES_START_CODE, fixed_buffertimestamp, 0); - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { PesHeader[headerSize++] = 0x42; // B PesHeader[headerSize++] = 0x43; // C diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index 8d54c10..79635fd 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -129,7 +129,7 @@ static int writeData(WriterAVCallData_t *call) videocodecdata.data = malloc(videocodecdata.length); memset(videocodecdata.data, 0, videocodecdata.length); memcpy(videocodecdata.data + 8, call->private_data, call->private_size); - if (IsDreambox() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) + if (STB_DREAMBOX == GetSTBType() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) { iov[ic].iov_base = videocodecdata.data; iov[ic++].iov_len = videocodecdata.length; diff --git a/libeplayer3-arm/output/writer/mipsel/vp.c b/libeplayer3-arm/output/writer/mipsel/vp.c index b64291f..3bfc97e 100644 --- a/libeplayer3-arm/output/writer/mipsel/vp.c +++ b/libeplayer3-arm/output/writer/mipsel/vp.c @@ -74,7 +74,8 @@ static int reset() return 0; } -static int writeData(WriterAVCallData_t *call, int is_vp6) +static uint8_t PesHeader[256]; +static int writeData(WriterAVCallData_t *call, bool is_vp6, bool is_vp9) { vp_printf(10, "\n"); @@ -99,14 +100,21 @@ static int writeData(WriterAVCallData_t *call, int is_vp6) vp_printf(10, "VideoPts %lld\n", call->Pts); vp_printf(10, "Got Private Size %d\n", call->private_size); - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; struct iovec iov[2]; + uint64_t pts = is_vp9 && STB_VUPLUS == GetSTBType() ? 0 : call->Pts; iov[0].iov_base = PesHeader; - uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, pts, 0); uint32_t len = call->len + 4 + 6; memcpy(PesHeader + pes_header_len, "BCMV", 4); pes_header_len += 4; + + if (is_vp9 && STB_VUPLUS == GetSTBType()) + { + uint32_t vp9_pts = (call->Pts == INVALID_PTS_VALUE ? call->Dts : call->Pts) / 2; + memcpy(&PesHeader[9], &vp9_pts, sizeof(vp9_pts)); + } + if (is_vp6) ++len; PesHeader[pes_header_len++] = (len & 0xFF000000) >> 24; @@ -114,24 +122,114 @@ static int writeData(WriterAVCallData_t *call, int is_vp6) PesHeader[pes_header_len++] = (len & 0x0000FF00) >> 8; PesHeader[pes_header_len++] = (len & 0x000000FF) >> 0; PesHeader[pes_header_len++] = 0; - PesHeader[pes_header_len++] = 0; + PesHeader[pes_header_len++] = STB_VUPLUS != GetSTBType() && is_vp9 ? 1 : 0; if (is_vp6) PesHeader[pes_header_len++] = 0; iov[0].iov_len = pes_header_len; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - return call->WriteV(call->fd, iov, 2); + int32_t payload_len = call->len + pes_header_len - 6; + + if (!is_vp9 || STB_VUPLUS == GetSTBType() || STB_HISILICON == GetSTBType() || STB_DREAMBOX == GetSTBType()) + { + UpdatePesHeaderPayloadSize(PesHeader, payload_len); + // it looks like for VUPLUS drivers PES header must be written separately + int ret = call->WriteV(call->fd, iov, 1); + if (iov[0].iov_len != ret) + return ret; + ret = call->WriteV(call->fd, iov + 1, 1); + return iov[0].iov_len + ret; + } + else + { + if (payload_len > 0x8008) + payload_len = 0x8008; + + int offs = 0; + int bytes = payload_len - 10 - 8; + UpdatePesHeaderPayloadSize(PesHeader, payload_len); + // pes header + if (pes_header_len != WriteExt(call->WriteV, call->fd, PesHeader, pes_header_len)) return -1; + if (bytes != WriteExt(call->WriteV, call->fd, call->data, bytes)) return -1; + + offs += bytes; + + while (bytes < call->len) + { + int left = call->len - bytes; + int wr = 0x8000; + if (wr > left) + wr = left; + + //gst_buffer_unmap(self->pesheader_buffer, &pesheadermap); + //gst_buffer_map(self->pesheader_buffer, &pesheadermap, GST_MAP_WRITE); + //pes_header = pesheadermap.data; + + //PesHeader[0] = 0x00; + //PesHeader[1] = 0x00; + //PesHeader[2] = 0x01; + //PesHeader[3] = 0xE0; + PesHeader[6] = 0x81; + PesHeader[7] = 0x00; + PesHeader[8] = 0x00; + pes_header_len = 9; + + UpdatePesHeaderPayloadSize(PesHeader, wr + 3); + + if (pes_header_len != WriteExt(call->WriteV, call->fd, PesHeader, pes_header_len)) return -1; + if (wr != WriteExt(call->WriteV, call->fd, call->data + offs, wr)) return -1; + + bytes += wr; + offs += wr; + } + + //gst_buffer_unmap(self->pesheader_buffer, &pesheadermap); + //gst_buffer_map(self->pesheader_buffer, &pesheadermap, GST_MAP_WRITE); + //pes_header = pesheadermap.data; + + //PesHeader[0] = 0x00; + //PesHeader[1] = 0x00; + //PesHeader[2] = 0x01; + //PesHeader[3] = 0xE0; + PesHeader[4] = 0x00; + PesHeader[5] = 0xB2; + PesHeader[6] = 0x81; + PesHeader[7] = 0x01; + PesHeader[8] = 0x14; + PesHeader[9] = 0x80; + PesHeader[10] = 'B'; + PesHeader[11] = 'R'; + PesHeader[12] = 'C'; + PesHeader[13] = 'M'; + memset(PesHeader + 14, 0, 170); + PesHeader[26] = 0xFF; + PesHeader[27] = 0xFF; + PesHeader[28] = 0xFF; + PesHeader[29] = 0xFF; + PesHeader[33] = 0x85; + + if (pes_header_len != WriteExt(call->WriteV, call->fd, PesHeader, 184)) return -1; + + return 1; + } + + //return call->WriteV(call->fd, iov, 2); } static int writeDataVP6(WriterAVCallData_t *call) { - return writeData(call, 1); + return writeData(call, true, false); } -static int writeDataVP89(WriterAVCallData_t *call) +static int writeDataVP8(WriterAVCallData_t *call) { - return writeData(call, 0); + return writeData(call, false, false); +} + +static int writeDataVP9(WriterAVCallData_t *call) +{ + return writeData(call, false, true); } /* ***************************** */ @@ -168,7 +266,7 @@ static WriterCaps_t capsVP8 = struct Writer_s WriterVideoVP8 = { &reset, - &writeDataVP89, + &writeDataVP8, &capsVP8 }; @@ -185,7 +283,7 @@ static WriterCaps_t capsVP9 = struct Writer_s WriterVideoVP9 = { &reset, - &writeDataVP89, + &writeDataVP9, &capsVP9 }; @@ -202,6 +300,6 @@ static WriterCaps_t capsSPARK = struct Writer_s WriterVideoSPARK = { &reset, - &writeDataVP89, + &writeDataVP8, &capsSPARK }; diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index 9d888e9..ae69d12 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -107,7 +107,7 @@ static int writeData(WriterAVCallData_t *call) uint32_t packetLength = 4 + call->private_size + call->len; - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { packetLength += 4; } @@ -123,7 +123,7 @@ static int writeData(WriterAVCallData_t *call) } uint32_t headerSize = InsertPesHeader(PesHeader, packetLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { PesHeader[headerSize++] = 0x42; // B PesHeader[headerSize++] = 0x43; // C diff --git a/libeplayer3-arm/output/writer/mipsel/wmv.c b/libeplayer3-arm/output/writer/mipsel/wmv.c index 36ee772..24e1567 100644 --- a/libeplayer3-arm/output/writer/mipsel/wmv.c +++ b/libeplayer3-arm/output/writer/mipsel/wmv.c @@ -136,7 +136,7 @@ static int writeData(WriterAVCallData_t *call) *(data++) = (call->Height >> 8) & 0xff; *(data++) = call->Height & 0xff; if (call->private_data && codec_size) memcpy(data, call->private_data, codec_size); - if (IsDreambox() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) + if (STB_DREAMBOX == GetSTBType() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) { iov[ic].iov_base = videocodecdata.data; iov[ic++].iov_len = videocodecdata.length; diff --git a/libeplayer3-arm/output/writer/mipsel/writer.c b/libeplayer3-arm/output/writer/mipsel/writer.c index 4ce9539..4852940 100644 --- a/libeplayer3-arm/output/writer/mipsel/writer.c +++ b/libeplayer3-arm/output/writer/mipsel/writer.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "misc.h" #include "writer.h" @@ -36,10 +37,23 @@ /* Makros/Constants */ /* ***************************** */ +#define getDVBMutex(pmtx) do { if (pmtx) pthread_mutex_lock(pmtx);} while(false); +#define releaseDVBMutex(pmtx) do { if (pmtx) pthread_mutex_unlock(pmtx);} while(false); + +#define FULL_PROTECTION_MODE 1 + /* ***************************** */ /* Types */ /* ***************************** */ +typedef enum +{ + DVB_STS_UNKNOWN, + DVB_STS_SEEK, + DVB_STS_PAUSE, + DVB_STS_EXIT +} DVBState_t; + /* ***************************** */ /* Variables */ /* ***************************** */ @@ -84,7 +98,7 @@ static Writer_t *AvailableWriter[] = /* Functions */ /* ***************************** */ -ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size) +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, const void *buf, int size) { fd_set rfds; fd_set wfds; @@ -102,15 +116,15 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, FD_SET(pipefd, &rfds); FD_SET(fd, &wfds); - /* When we PAUSE LINUX DVB outputs buffers, then audio/video buffers - * will continue to be filled. Unfortunately, in such case after resume - * select() will never return with fd set - bug in DVB drivers? - * There are to workarounds possible: - * 1. write to pipe at resume to return from select() immediately - * 2. make timeout select(), limit max time spend in the select() - * to for example 0,1s - * (at now first workaround is used) - */ + /* When we PAUSE LINUX DVB outputs buffers, then audio/video buffers + * will continue to be filled. Unfortunately, in such case after resume + * select() will never return with fd set - bug in DVB drivers? + * There are to workarounds possible: + * 1. write to pipe at resume to return from select() immediately + * 2. make timeout select(), limit max time spend in the select() + * to for example 0,1s + * (at now first workaround is used) + */ //tv.tv_sec = 0; //tv.tv_usec = 100000; // 100ms @@ -135,7 +149,70 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, if (FD_ISSET(fd, &wfds)) { - ret = write(fd, buf, size); + // special protection to not allow inject AV data + // at PAUSE, SEEK and vice versa + if (pDVBMtx && STB_HISILICON == GetSTBType()) + { + DVBState_t dvbSts = DVB_STS_UNKNOWN; + getDVBMutex(pDVBMtx); + ret = 0; + if (PlaybackDieNow(0)) + dvbSts = DVB_STS_EXIT; + else if (context->playback->isSeeking) + dvbSts = DVB_STS_SEEK; + else if (context->playback->isPaused) + dvbSts = DVB_STS_PAUSE; + else + { +#ifdef FULL_PROTECTION_MODE + ret = write(fd, buf, size); +#endif + } + releaseDVBMutex(pDVBMtx); + + if (dvbSts == DVB_STS_EXIT || dvbSts == DVB_STS_SEEK) + { + return 0; + } + else if (dvbSts == DVB_STS_PAUSE) + { + FD_ZERO(&rfds); + FD_SET(pipefd, &rfds); + + tv.tv_sec = 0; + tv.tv_usec = 500000; // 500ms + + retval = select(pipefd + 1, &rfds, NULL, NULL, &tv); + if (retval < 0) + { + break; + } + + if (retval == 0) + { + //printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n"); + continue; + } + + if (FD_ISSET(pipefd, &rfds)) + { + FlushPipe(pipefd); + //printf("RETURN FROM SELECT DUE TO pipefd SET\n"); + continue; + } + } +#ifndef FULL_PROTECTION_MODE + else + { + ret = write(fd, buf, size); + } +#endif + } + else + { + ret = write(fd, buf, size); + } + if (ret < 0) { switch (errno) diff --git a/libeplayer3-arm/output/writer/sh4/writer.c b/libeplayer3-arm/output/writer/sh4/writer.c index 653b299..f1bd83e 100644 --- a/libeplayer3-arm/output/writer/sh4/writer.c +++ b/libeplayer3-arm/output/writer/sh4/writer.c @@ -97,7 +97,7 @@ static Writer_t *AvailableWriter[] = /* ***************************** */ /* Functions */ /* ***************************** */ -ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size) +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, const void *buf, int size) { fd_set rfds;