Update on I frame only extraction

This follows on from my previous post on how to extract the ‘I’ frames only from a piece of video when the GOP structure changes during the duration.

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.

timestamp

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)

ffplay inputfile.avc

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:

[STREAM]
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
width=720
height=576
sample_aspect_ratio=0:1
display_aspect_ratio=0:1
pix_fmt=yuv420p
timecode=N/A
r_frame_rate=50/2
avg_frame_rate=25/1
time_base=1/1200000
nb_read_frames=555
[/STREAM]

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

excel

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

rewrap

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.

avikeyframes

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.

Advertisements

2 comments on “Update on I frame only extraction

  1. Pingback: Virtualdub, FFmpeg and I frames! | Spreadys Space

  2. Pingback: SSF Files with BKPlayer.exe | Spreadys Space

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s