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@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr