mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 23:13:16 +02:00
Improve Zgemma H9S playback start with new drivers, deploy version v54
This commit is contained in:
@@ -698,7 +698,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", 53);
|
||||
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 54);
|
||||
|
||||
PlayFiles_t playbackFiles;
|
||||
memset(&playbackFiles, 0x00, sizeof(playbackFiles));
|
||||
|
@@ -61,6 +61,11 @@
|
||||
/* Variables */
|
||||
/* ***************************** */
|
||||
|
||||
static bool must_send_header = true;
|
||||
static uint8_t *private_data = NULL;
|
||||
static uint32_t private_size = 0;
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
/* ***************************** */
|
||||
@@ -71,6 +76,7 @@
|
||||
|
||||
static int reset()
|
||||
{
|
||||
must_send_header = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -78,8 +84,9 @@ static int writeData(WriterAVCallData_t *call)
|
||||
{
|
||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||
|
||||
int len = 0;
|
||||
unsigned int Position = 0;
|
||||
static uint8_t PesHeader[PES_MAX_HEADER_SIZE];
|
||||
int32_t len = 0;
|
||||
uint32_t Position = 0;
|
||||
|
||||
mpeg2_printf(10, "\n");
|
||||
|
||||
@@ -103,35 +110,143 @@ static int writeData(WriterAVCallData_t *call)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (Position < call->len)
|
||||
uint8_t *data = call->data;
|
||||
uint32_t data_len = call->len;
|
||||
|
||||
if (!private_data && !call->private_data && data_len > 3 && !memcmp(data, "\x00\x00\x01\xb3", 4))
|
||||
{
|
||||
int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
|
||||
(call->len - Position) : MAX_PES_PACKET_SIZE;
|
||||
|
||||
int Remaining = call->len - Position - PacketLength;
|
||||
|
||||
mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);
|
||||
|
||||
struct iovec iov[2];
|
||||
iov[0].iov_base = PesHeader;
|
||||
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 = call->WriteV(call->fd, iov, 2);
|
||||
if (l < 0)
|
||||
bool ok = true;
|
||||
uint32_t pos = 4;
|
||||
uint32_t sheader_data_len = 0;
|
||||
while (pos < data_len && ok)
|
||||
{
|
||||
len = l;
|
||||
if (pos >= data_len) break;
|
||||
pos += 7;
|
||||
if (pos >= data_len) break;
|
||||
sheader_data_len = 12;
|
||||
if (data[pos] & 2)
|
||||
{
|
||||
// intra matrix
|
||||
pos += 64;
|
||||
if (pos >= data_len) break;
|
||||
sheader_data_len += 64;
|
||||
}
|
||||
if (data[pos] & 1)
|
||||
{
|
||||
// non intra matrix
|
||||
pos += 64;
|
||||
if (pos >= data_len) break;
|
||||
sheader_data_len += 64;
|
||||
}
|
||||
pos += 1;
|
||||
if (pos + 3 >= data_len) break;
|
||||
if (!memcmp(&data[pos], "\x00\x00\x01\xb5", 4))
|
||||
{
|
||||
// extended start code
|
||||
pos += 3;
|
||||
sheader_data_len += 3;
|
||||
do
|
||||
{
|
||||
pos += 1;
|
||||
++sheader_data_len;
|
||||
if (pos + 2 > data_len)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (memcmp(&data[pos], "\x00\x00\x01", 3));
|
||||
if (!ok) break;
|
||||
}
|
||||
if (pos + 3 >= data_len) break;
|
||||
if (!memcmp(&data[pos], "\x00\x00\x01\xb2", 4))
|
||||
{
|
||||
// private data
|
||||
pos += 3;
|
||||
sheader_data_len += 3;
|
||||
do
|
||||
{
|
||||
pos += 1;
|
||||
++sheader_data_len;
|
||||
if (pos + 2 > data_len)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (memcmp(&data[pos], "\x00\x00\x01", 3));
|
||||
if (!ok) break;
|
||||
}
|
||||
|
||||
free(private_data);
|
||||
private_data = malloc(sheader_data_len);
|
||||
if (private_data)
|
||||
{
|
||||
private_size = sheader_data_len;
|
||||
memcpy(private_data, data + pos - sheader_data_len, sheader_data_len);
|
||||
}
|
||||
must_send_header = false;
|
||||
break;
|
||||
}
|
||||
len += l;
|
||||
}
|
||||
else if ((private_data || call->private_data) && must_send_header)
|
||||
{
|
||||
uint8_t *codec_data = NULL;
|
||||
uint32_t codec_data_size = 0;
|
||||
int pos = 0;
|
||||
|
||||
Position += PacketLength;
|
||||
call->Pts = INVALID_PTS_VALUE;
|
||||
if (private_data)
|
||||
{
|
||||
codec_data = private_data;
|
||||
codec_data_size = private_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
codec_data = call->private_data;
|
||||
codec_data_size = call->private_size;
|
||||
}
|
||||
|
||||
while (pos <= data_len - 4)
|
||||
{
|
||||
if (memcmp(&data[pos], "\x00\x00\x01\xb8", 4)) /* find group start code */
|
||||
{
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
struct iovec iov[4];
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, call->len + codec_data_size, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
|
||||
iov[1].iov_base = data;
|
||||
iov[1].iov_len = pos;
|
||||
|
||||
iov[2].iov_base = codec_data;
|
||||
iov[2].iov_len = codec_data_size;
|
||||
|
||||
iov[3].iov_base = data + pos;
|
||||
iov[3].iov_len = data_len - pos;
|
||||
|
||||
must_send_header = false;
|
||||
return call->WriteV(call->fd, iov, 4);
|
||||
}
|
||||
}
|
||||
|
||||
mpeg2_printf(10, "< len %d\n", len);
|
||||
return len;
|
||||
struct iovec iov[2];
|
||||
|
||||
iov[0].iov_base = PesHeader;
|
||||
iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
|
||||
|
||||
iov[1].iov_base = data;
|
||||
iov[1].iov_len = data_len;
|
||||
|
||||
PesHeader[6] = 0x81;
|
||||
|
||||
UpdatePesHeaderPayloadSize(PesHeader, data_len + iov[0].iov_len - 6);
|
||||
if (iov[0].iov_len != WriteExt(call->WriteV, call->fd, iov[0].iov_base, iov[0].iov_len)) return -1;
|
||||
if (iov[1].iov_len != WriteExt(call->WriteV, call->fd, iov[1].iov_base, iov[1].iov_len)) return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ***************************** */
|
||||
@@ -144,7 +259,7 @@ static WriterCaps_t caps =
|
||||
"V_MPEG2",
|
||||
VIDEO_ENCODING_AUTO,
|
||||
STREAMTYPE_MPEG2,
|
||||
CT_MPEG2
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG2 =
|
||||
@@ -159,9 +274,9 @@ static WriterCaps_t mpg1_caps =
|
||||
"mpge1",
|
||||
eVideo,
|
||||
"V_MPEG1",
|
||||
VIDEO_ENCODING_H264,
|
||||
VIDEO_ENCODING_AUTO,
|
||||
STREAMTYPE_MPEG1,
|
||||
CT_MPEG1
|
||||
-1
|
||||
};
|
||||
|
||||
struct Writer_s WriterVideoMPEG1 =
|
||||
|
@@ -40,8 +40,6 @@
|
||||
#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 */
|
||||
/* ***************************** */
|
||||
@@ -108,6 +106,15 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, co
|
||||
int maxFd = pipefd > fd ? pipefd : fd;
|
||||
struct timeval tv;
|
||||
|
||||
static bool first = true;
|
||||
if (first && STB_HISILICON == GetSTBType())
|
||||
{
|
||||
// workaround: playback of some files does not start
|
||||
// if injection of the frist frame is to fast
|
||||
usleep(100000);
|
||||
}
|
||||
first = false;
|
||||
|
||||
while (size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking)
|
||||
{
|
||||
FD_ZERO(&rfds);
|
||||
@@ -149,70 +156,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, co
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ret = write(fd, buf, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
switch (errno)
|
||||
|
Reference in New Issue
Block a user