Hello!
I'm experiencing what I'd call a glitch of VDR's frame detector class.
There's a define #define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 5.
According to my experiences, this number of TS packages in not always
enough to detect frames as early as possible. Thus it is a matter of chance
if detection will be fed with enough data to detect the first frame or if it
will glitch through to another one. I think we should avoid such situations.
I attached demo code (needs some includes and to be compiled and linked
with VDR) which shows the behaviour and I stored a short TS sample at
http://ein-eike.de/wordpress/wp-content/uploads/2014/01/vdr-sample.ts
The code checks when an I frame is found, at first with full data available,
and then with data dripping in with a frame size of 5, 6 ... until the
dripping data yields the same result as the flooding data.
I get the following output from the given example:
Checking file at offset 0
Without frame limit... Found I frame after 190256 bytes
With frame limit 5... Found I frame after 398560 bytes
With frame limit 6... Found I frame after 190256 bytes
TS package frame size needed for this video block: 6
Maximum TS package frame size needed for this video recording: 6
Unfortunately, I cannot tell if 6 is the definite number to avoid such glitches
or if other circumstances would need a higher number. I wrote the code such
as people might try it out on their video files so we could experiment.
(I could provide a Linux executable as well.)
Ciao,
Eike
cPatPmtParser parser;
uint doAnalyze(uchar* Data, uint readBytes, int frameSize)
{
if (frameSize == 0)
{
printf("Without frame limit... ");
}
else
{
printf("With frame limit %d... ", frameSize);
}
uint analyzed = 0;
cFrameDetector* m_bufferFrameDetector = new cFrameDetector(parser.Vpid(), parser.Vtype());
cRingBufferLinear m_syncBuffer(readBytes, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE);
m_syncBuffer.Put(Data, readBytes);
while (m_syncBuffer.Available() >= frameSize * 188)
{
int r;
uchar *b = m_syncBuffer.Get(r);
if (b)
{
int Count = m_bufferFrameDetector->Analyze(b, (frameSize == 0)? r : min(r, frameSize * 188));
analyzed += Count;
/*
if (m_bufferFrameDetector->Synced())
{
printf("Synced after %d bytes\n", analyzed);
}
*/
if (Count)
{
if (m_bufferFrameDetector->Synced() && m_bufferFrameDetector->NewFrame() && m_bufferFrameDetector->IndependentFrame())
{
printf("Found I frame after %d bytes\n", analyzed);
break;
}
m_syncBuffer.Del(Count);
}
}
}
return analyzed;
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Please pass the path of a VDR video recording file (*.ts)! \n");
exit(-1);
}
char* fileName = argv[1];
static FILE* readFile = fopen(fileName, "rb");
fseek(readFile, 0 , SEEK_END);
uint64_t filesize = ftell(readFile);
fseek(readFile, 0 , SEEK_SET);
uint blocksize = (10 * 1024 * 1024) / 188 * 188;
uchar* Data = (uchar*)malloc(blocksize);
uint readsize = fread(Data, 1, blocksize, readFile);
parser.ParsePatPmt(Data, readsize);
if (parser.Vpid() == 0 || parser.Vtype() == 0)
{
printf("Pid or vtype not found! \n");
return -1;
}
fseek(readFile, 0 , SEEK_SET);
int maxFrameSize = 0;
int offset = 0;
do
{
printf("Checking file at offset %d \n", offset);
uint readsize = fread(Data, 1, blocksize, readFile);
uint analyzed = doAnalyze(Data, readsize, 0);
bool frameSizeFound = false;
for (int frameSize = 5; frameSize <= 100; frameSize++)
{
if (doAnalyze(Data, readsize, frameSize) == analyzed)
{
printf("TS package frame size needed for this video block: %d \n", frameSize);
frameSizeFound = true;
if (frameSize > maxFrameSize) maxFrameSize = frameSize;
break;
}
}
if (!frameSizeFound)
{
printf("No TS package frame size found for this video!?! \n");
}
offset += blocksize;
} while (filesize > offset + blocksize && readsize == blocksize);
fclose(readFile);
if (maxFrameSize > 0)
{
printf("Maximum TS package frame size needed for this video recording: %d \n", maxFrameSize);
}
return 0;
}
signature.asc
Description: This is a digitally signed message part.
___
vdr mailing list
vdr@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr