mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-libstb-hal.git
synced 2025-08-26 23:12:44 +02:00
Improve playback of VP9 codec
Origin commit data
------------------
Branch: master
Commit: e6638a72af
Author: samsamsam <samsamsam@o2.pl>
Date: 2019-02-02 (Sat, 02 Feb 2019)
------------------
No further description and justification available within origin commit message!
------------------
This commit was generated by Migit
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef misc_123
|
||||
#define misc_123
|
||||
#ifndef _exteplayer3_misc_
|
||||
#define _exteplayer3_misc_
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
@@ -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_
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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));
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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))
|
||||
{
|
||||
size = -1; // unbounded
|
||||
}
|
||||
|
||||
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 += 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0);
|
||||
}
|
||||
|
||||
if (size > MAX_PES_PACKET_SIZE || size < 0)
|
||||
{
|
||||
size = 0; // unbounded
|
||||
}
|
||||
|
||||
//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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#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;
|
||||
@@ -135,7 +149,70 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf,
|
||||
|
||||
if (FD_ISSET(fd, &wfds))
|
||||
{
|
||||
// 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)
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user