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;
}

Attachment: 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

Reply via email to