This is another post that I have been meaning to get around to for a while so, whilst dealing with an AVC file, I thought it would be a good example. Files with the .avc extension are becoming more common now, with most purely raw streams, and are easily dealt with. Most also have the date and time overlay on the footage.
This one though didn’t! There are problems in the footage and the times written into the file-name do not match the duration! Just another day in the world of CCTV!!
When accessing the DVR through the network client, the time details are present as a yellow overlay on the bottom of the video.
The problem though is that this overlay is not carried across when a native export is completed. This highlights as a good reminder to note down what frame rate the DVR is actually set to record at so this can be replicated at a later time using the video. (Remember also that even though it says 100FPS across 4 cameras, it may never get that high and they probably wont be evenly spread out!)
Back to the AVC file and the naming convention is date&time – date&time. This indicates a 15 minute period. The first thing is quickly take a look at the file…
Using FFplay (quick guide)
The footage appeared to play fine, although very fast due to the raw stream having no frame rate connected to it.
Before doing anything else I wanted to get some information on the stream.
ffprobe - show_streams -count_frames -pretty in.avc > out.txt
This output a text file with some important information:
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
Along with this text file, if the task requires identification of specific frame types, I run another FFprobe command and produce an xml table with all required details. This is a much improved way of doing things from the original text file and powershell method.
ffprobe -show_frames -print_format xml -v quiet inputfile.avc > out.xml
There are a number of benefits from outputting the results in this format but the main one for our specific purpose is to identify, and count, how many ‘I’ frames there are in the raw stream. By using the drop-down selection menu, we can chose a specific type and filter the results accordingly. By doing this, it reported 142 of 555 frames were ‘I’ frames and also identified which ones they were. I also noted that although there was a standard 4 frame GOP, this was interspersed in a number of locations with either 2 ‘I’ frames together or a 2 frame GOP.
Time to get it wrapped up into something more flexible so a better look could be taken at the footage. It was over to the usual FFmpeg command of:
ffmpeg -i inputfile.avc -vcodec copy -f avi -vsync drop -fflags genpts rewrap.avi
By scrubbing through the video in Virtualdub I could visually see the breaks in the video at the points where the GOP structure faltered. These ‘errors’ appear to be caused by an ineffective Motion Detection system but this is not verified.
We can now deal with the video in anyway necessary but, what about the ‘I’ frames?
The whole purpose is to extract a series of I frames and then layer these in Photoshop before frame averaging. Anyone who read my previous articles on ‘I’ frame identification and extraction will be aware of the new -vf frame filter in FFmpeg. This has been updated recently so its much easier to use. It can be used a number of ways but I have settled on this method for the time being.
ffmpeg -i inputfile.avc -vf select='eq(pict_type\,I)' -vsync drop -f avi -vcodec rawvideo out.avi
Using the original .avc file I have output an uncompressed avi file using the I frames only. This is achieved by using the -vf, and then selecting the ‘I’ picture types. The result is an Uncompressed RGB video file that, in our example here, contains just the 142 I frames.
It’s possible now to visually select a portion or all of the frames and output those as an image sequence for the frame averaging in Photoshop.
You could miss out the video part and use FFmpeg to output the image sequence directly but personally I still prefer to do this part from the video in Virtualdub.
If you wanted to select all the frames from the entire clip and output them as tiff files directly from ffmpeg:
ffmpeg -i input.avc -vsync drop -f image2
-pix_fmt rgb24 framesfolder\frame%05d.tiff
Then if you wanted select the entire clip but only extract the I Frames:
ffmpeg -i input.avc -vsync drop -vf select='eq(pict_type\,I)'
-f image2 -pix_fmt rgb24 Iframesfolder\Iframe%05d.tiff
I hope some of those new methods can help you out when researching your video files, and when you require to extract a series of ‘I’ frames only.