Note that there are some explanatory texts on larger screens.

plurals
  1. POData corruption when reading realtime H.264 output from AVAssetWriter
    primarykey
    data
    text
    <p>I'm using some tricks to try to read the raw output of an AVAssetWriter while it is being written to disk. When I reassemble the individual files by concatenating them, the resulting file is the same exact number of bytes as the AVAssetWriter's output file. However, the reassembled file will not play in QuickTime or be parsed by FFmpeg because there is data corruption. A few bytes here and there have been changed, rendering the resulting file unusable. I assume this is occurring on the EOF boundary of each read, but it isn't consistent corruption.</p> <p>I plan to eventually use code similar to this to parse out individual H.264 NAL units from the encoder to packetize them and send them over RTP, however if I can't trust the data being read from disk I might have to use another solution.</p> <p>Is there an explanation/fix for this data corruption? And are there any other resources/links you have found on how to parse the NAL units to packetize over RTP?</p> <p>Full code here: <a href="https://github.com/chrisballinger/FFmpeg-iOS-Encoder/blob/master/AVAppleEncoder.m" rel="nofollow noreferrer">AVAppleEncoder.m</a></p> <pre><code>// Modified from // http://www.davidhamrick.com/2011/10/13/Monitoring-Files-With-GCD-Being-Edited-With-A-Text-Editor.html - (void)watchOutputFileHandle { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); int fildes = open([[movieURL path] UTF8String], O_EVTONLY); source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,fildes, DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE, queue); dispatch_source_set_event_handler(source, ^ { unsigned long flags = dispatch_source_get_data(source); if(flags &amp; DISPATCH_VNODE_DELETE) { dispatch_source_cancel(source); //[blockSelf watchStyleSheet:path]; } if(flags &amp; DISPATCH_VNODE_EXTEND) { //NSLog(@"File size changed"); NSError *error = nil; NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:movieURL error:&amp;error]; if (error) { [self showError:error]; } [fileHandle seekToFileOffset:fileOffset]; NSData *newData = [fileHandle readDataToEndOfFile]; if ([newData length] &gt; 0) { NSLog(@"newData (%lld): %d bytes", fileOffset, [newData length]); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] &gt; 0) ? [paths objectAtIndex:0] : nil; NSString *movieName = [NSString stringWithFormat:@"%d.%lld.%d.mp4", fileNumber, fileOffset, [newData length]]; NSString *path = [NSString stringWithFormat:@"%@/%@", basePath, movieName]; [newData writeToFile:path atomically:NO]; fileNumber++; fileOffset = [fileHandle offsetInFile]; } } }); dispatch_source_set_cancel_handler(source, ^(void) { close(fildes); }); dispatch_resume(source); } </code></pre> <p>Here are some similar questions I have found, but don't exactly answer my question:</p> <ul> <li><a href="https://stackoverflow.com/questions/11087676/get-pts-from-raw-h264-mdat-generated-by-ios-avassetwriter">Get PTS from raw H264 mdat generated by iOS AVAssetWriter</a></li> <li><a href="https://stackoverflow.com/questions/3444791/streaming-video-from-an-iphone">streaming video FROM an iPhone</a></li> <li><a href="https://stackoverflow.com/questions/11717538/parsing-h-264-nal-units-from-a-quicktime-mov-file">Parsing h.264 NAL units from a quicktime MOV file</a></li> <li><a href="https://stackoverflow.com/questions/5719538/realtime-audio-video-streaming-from-iphone-to-another-device-browser-or-iphone?lq=1">Realtime Audio/Video Streaming FROM iPhone to another device (Browser, or iPhone)</a></li> </ul> <p>When I eventually figure this out, I will release an open source library to assist people who try to do this in the future.</p> <p>Thank you!</p> <p><strong>Update:</strong> The corruption doesn't happen at the EOF boundary. It seems like parts of the file are re-written after <code>finishWriting</code> is called. This first file was chunked at 4KB, so the area changed isn't anywhere near an EOF boundary. It seems to be corrupted near new "moov" elements as well when <code>movieFragmentInterval</code> is enabled.</p> <p><img src="https://i.imgur.com/2Ayuu.png" alt="broken file"> Correct file on the left, broken file on the right.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload