mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Fix bug: NAL end of sequence is 10 and not 0x10.
Cleanup, remove old cruft. Add support for pes recordings.
This commit is contained in:
parent
4cc98d7937
commit
f2d4163899
@ -1,6 +1,7 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
|
Fix bug: StillPicture NAL end of sequence is 10 and not 0x10.
|
||||||
Fix bug: AudioEnqueue crash without sound card.
|
Fix bug: AudioEnqueue crash without sound card.
|
||||||
|
|
||||||
User johns
|
User johns
|
||||||
|
135
softhddev.c
135
softhddev.c
@ -1611,40 +1611,13 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
pts =
|
pts =
|
||||||
(int64_t) (data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] &
|
(int64_t) (data[9] & 0x0E) << 29 | data[10] << 22 | (data[11] &
|
||||||
0xFE) << 14 | data[12] << 7 | (data[13] & 0xFE) >> 1;
|
0xFE) << 14 | data[12] << 7 | (data[13] & 0xFE) >> 1;
|
||||||
#ifdef DEBUG
|
|
||||||
if (!(data[13] & 1) || !(data[11] & 1) || !(data[9] & 1)) {
|
|
||||||
Error(_("[softhddev] invalid pts in video packet\n"));
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
//Debug(3, "video: pts %#012" PRIx64 "\n", pts);
|
|
||||||
if (data[13] != (((pts & 0x7F) << 1) | 1)) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
if (data[12] != ((pts >> 7) & 0xFF)) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
if (data[11] != ((((pts >> 15) & 0x7F) << 1) | 1)) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
if (data[10] != ((pts >> 22) & 0xFF)) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
if ((data[9] & 0x0F) != (((pts >> 30) << 1) | 1)) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check = data + 9 + n;
|
check = data + 9 + n;
|
||||||
if (0) {
|
|
||||||
printf("%02x: %02x %02x %02x %02x %02x %02x %02x\n", data[6], check[0],
|
|
||||||
check[1], check[2], check[3], check[4], check[5], check[6]);
|
|
||||||
}
|
|
||||||
#if 1 // FIXME: test code for better h264 detection
|
|
||||||
z = 0;
|
|
||||||
l = size - 9 - n;
|
l = size - 9 - n;
|
||||||
|
z = 0;
|
||||||
while (!*check) { // count leading zeros
|
while (!*check) { // count leading zeros
|
||||||
if (--l < 4) {
|
if (--l < 2) {
|
||||||
Warning(_("[softhddev] empty video packet %d bytes\n"), size);
|
Warning(_("[softhddev] empty video packet %d bytes\n"), size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -1652,7 +1625,7 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
++z;
|
++z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// H264 Access Unit Delimiter 0x00 0x00 0x00 0x01 0x09
|
// H264 NAL AUD Access Unit Delimiter 0x00 0x00 0x00 0x01 0x09
|
||||||
if ((data[6] & 0xC0) == 0x80 && z > 2 && check[0] == 0x01
|
if ((data[6] & 0xC0) == 0x80 && z > 2 && check[0] == 0x01
|
||||||
&& check[1] == 0x09) {
|
&& check[1] == 0x09) {
|
||||||
if (VideoCodecID == CODEC_ID_H264) {
|
if (VideoCodecID == CODEC_ID_H264) {
|
||||||
@ -1701,66 +1674,6 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
#else
|
|
||||||
// FIXME: no valid mpeg2/h264 detection yet
|
|
||||||
// FIXME: better skip all zero's >3 && 0x01 0x09 h264, >2 && 0x01 -> mpeg2
|
|
||||||
|
|
||||||
// PES_VIDEO_STREAM 0xE0 or PES start code
|
|
||||||
//(data[6] & 0xC0) != 0x80 ||
|
|
||||||
if ((!check[0] && !check[1] && check[2] == 0x1)) {
|
|
||||||
if (VideoCodecID == CODEC_ID_MPEG2VIDEO) {
|
|
||||||
VideoNextPacket(CODEC_ID_MPEG2VIDEO);
|
|
||||||
} else {
|
|
||||||
Debug(3, "video: mpeg2 detected ID %02x\n", check[3]);
|
|
||||||
VideoCodecID = CODEC_ID_MPEG2VIDEO;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (ValidateMpeg(data, size)) {
|
|
||||||
Debug(3, "softhddev/video: invalid mpeg2 video packet\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Access Unit Delimiter
|
|
||||||
} else if ((data[6] & 0xC0) == 0x80 && !check[0] && !check[1]
|
|
||||||
&& !check[2] && check[3] == 0x1 && check[4] == 0x09) {
|
|
||||||
if (VideoCodecID == CODEC_ID_H264) {
|
|
||||||
VideoNextPacket(CODEC_ID_H264);
|
|
||||||
} else {
|
|
||||||
Debug(3, "video: h264 detected\n");
|
|
||||||
VideoCodecID = CODEC_ID_H264;
|
|
||||||
}
|
|
||||||
// Access Unit Delimiter (BBC-HD)
|
|
||||||
// FIXME: the 4 offset are try & error selected
|
|
||||||
} else if ((data[6] & 0xC0) == 0x80 && !check[4 + 0] && !check[4 + 1]
|
|
||||||
&& !check[4 + 2] && check[4 + 3] == 0x1 && check[4 + 4] == 0x09) {
|
|
||||||
if (VideoCodecID == CODEC_ID_H264) {
|
|
||||||
VideoNextPacket(CODEC_ID_H264);
|
|
||||||
} else {
|
|
||||||
Debug(3, "video: h264 detected\n");
|
|
||||||
VideoCodecID = CODEC_ID_H264;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// this happens when vdr sends incomplete packets
|
|
||||||
if (VideoCodecID == CODEC_ID_NONE) {
|
|
||||||
Debug(3, "video: not detected\n");
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
// incomplete packets produce artefacts after channel switch
|
|
||||||
// packet < 65526 is the last split packet, detect it here for
|
|
||||||
// better latency
|
|
||||||
if (size < 65526 && VideoCodecID == CODEC_ID_MPEG2VIDEO) {
|
|
||||||
// mpeg codec supports incomplete packets
|
|
||||||
// waiting for a full complete packages, increases needed delays
|
|
||||||
VideoEnqueue(pts, check, size - 9 - n);
|
|
||||||
VideoNextPacket(CODEC_ID_MPEG2VIDEO);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SKIP PES header
|
|
||||||
VideoEnqueue(pts, check, size - 9 - n);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// call VDR support function
|
/// call VDR support function
|
||||||
@ -1956,7 +1869,8 @@ void StillPicture(const uint8_t * data, int size)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
static uint8_t seq_end_mpeg[] = { 0x00, 0x00, 0x01, 0xB7 };
|
static uint8_t seq_end_mpeg[] = { 0x00, 0x00, 0x01, 0xB7 };
|
||||||
static uint8_t seq_end_h264[] = { 0x00, 0x00, 0x00, 0x01, 0x10 };
|
// H264 NAL End of Sequence
|
||||||
|
static uint8_t seq_end_h264[] = { 0x00, 0x00, 0x00, 0x01, 0x0A };
|
||||||
|
|
||||||
// must be a PES start code
|
// must be a PES start code
|
||||||
if (size < 9 || !data || data[0] || data[1] || data[2] != 0x01) {
|
if (size < 9 || !data || data[0] || data[1] || data[2] != 0x01) {
|
||||||
@ -1968,14 +1882,13 @@ void StillPicture(const uint8_t * data, int size)
|
|||||||
// FIXME: should detect codec, see PlayVideo
|
// FIXME: should detect codec, see PlayVideo
|
||||||
Error(_("[softhddev] no codec known for still picture\n"));
|
Error(_("[softhddev] no codec known for still picture\n"));
|
||||||
}
|
}
|
||||||
//Clear(); // flush video buffers
|
// FIXME: can check video backend, if a frame was produced.
|
||||||
|
// output for max reference frames
|
||||||
// +1 future for deinterlace
|
for (i = 0; i < (VideoCodecID == CODEC_ID_MPEG2VIDEO ? 3 : 17); ++i) {
|
||||||
for (i = -1; i < (VideoCodecID == CODEC_ID_MPEG2VIDEO ? 3 : 17); ++i) {
|
|
||||||
//if ( 1 ) {
|
|
||||||
const uint8_t *split;
|
const uint8_t *split;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
// FIXME: vdr pes recordings sends mixed audio/video
|
||||||
if ((data[3] & 0xF0) == 0xE0) { // PES packet
|
if ((data[3] & 0xF0) == 0xE0) { // PES packet
|
||||||
split = data;
|
split = data;
|
||||||
n = size;
|
n = size;
|
||||||
@ -1983,15 +1896,31 @@ void StillPicture(const uint8_t * data, int size)
|
|||||||
do {
|
do {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = (split[4] << 8) + split[5];
|
#ifdef DEBUG
|
||||||
if (!len || len + 6 > n) {
|
if (split[0] || split[1] || split[2] != 0x01) {
|
||||||
PlayVideo(split, n); // feed remaining bytes
|
Error(_("[softhddev] invalid still video packet\n"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PlayVideo(split, len + 6); // feed it
|
#endif
|
||||||
|
|
||||||
|
len = (split[4] << 8) + split[5];
|
||||||
|
if (!len || len + 6 > n) {
|
||||||
|
// video only
|
||||||
|
if ((data[3] & 0xF0) == 0xE0) {
|
||||||
|
while (!PlayVideo(split, n)) { // feed remaining bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((data[3] & 0xF0) == 0xE0) {
|
||||||
|
// video only
|
||||||
|
while (!PlayVideo(split, len + 6)) { // feed it
|
||||||
|
}
|
||||||
|
}
|
||||||
split += 6 + len;
|
split += 6 + len;
|
||||||
n -= 6 + len;
|
n -= 6 + len;
|
||||||
} while (n > 6);
|
} while (n > 6);
|
||||||
|
|
||||||
VideoNextPacket(VideoCodecID); // terminate last packet
|
VideoNextPacket(VideoCodecID); // terminate last packet
|
||||||
|
|
||||||
if (VideoCodecID == CODEC_ID_H264) {
|
if (VideoCodecID == CODEC_ID_H264) {
|
||||||
@ -2013,6 +1942,12 @@ void StillPicture(const uint8_t * data, int size)
|
|||||||
VideoNextPacket(VideoCodecID); // terminate last packet
|
VideoNextPacket(VideoCodecID); // terminate last packet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wait for empty buffers
|
||||||
|
for (i = 0; VideoGetBuffers() && i < 10; ++i) {
|
||||||
|
usleep(10 * 1000);
|
||||||
|
}
|
||||||
|
Debug(3, "[softhddev]%s: buffers %d\n", __FUNCTION__, VideoGetBuffers());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user