Can you losslessly ediit H264 at the GOP level? My scenario is this: I have a few .mp4 files containing H264 video with AAC audio. Each file was encoded from a DVR source. There are a few frames too many at both the beginning and end of the file (less than 1 second worth). I want to edit off these few frames.

The problem is that I can tell that the first keyframe falls a couple seconds into the desired video. 

I'd like to chop the first few undesired frames off of the video, but I'd like to not have to re-encode the entire file because this comes with the inherent generation loss of re-encoding already compressed video (and the time taken).

(I'm ignoring audio issues for the moment - for MP3 there are frame-level editors like MP3DirectCut and I think there's something similar for AAC audio. I can use ffmpeg to split the two streams out and work with them independently and then later remux them into a new .mp4 file.)

Here's a simple illustration of what I'd like to do:

Source file
|------GOP---------|------GOP---------|------GOP-----|
IBBPBBPBBPBBPBBPBBPIBBPBBPBBPBBPBBPBBPIBBPBBPBBPBBPBBI...
^   ^     
|   first desired frame
- undesired frame(s)

Re-encoded first GOP, other GOPs copied losslessly:
|----New GOP----|------GOP---------|------GOP-----|
IBPBBPBBPBBPBBBPIBBPBBPBBPBBPBBPBBPIBBPBBPBBPBBPBBI
|               |
+---------------+
re-encode just these
frames to a new short
GOP, copy all remaining
GOPs losslessly


I could be completely wrong, but my understanding of video encoding leads me to believe that GOPs are independent sets of frames that can stand alone; you need all of the frames of a GOP to decode the GOP, but one GOP will not be dependent upon another GOP. So, unless that assumption is completely wrong, I imagine something like this should work, theoretically:


Re-encode the first couple of seconds of the video, starting at the desired frame, using the same settings (profile, level, etc.) that encoded the original source. I'd need to be able to do one of the following: 


Extract off the first GOP of this newly-encoded file, and truncate that GOP so it ends on the frame right before the keyframe of the next GOP in the original file.
Specify a hard limit on the number of frames per GOP during encoding, so that I could then extract off the first GOP and it would already be the correct size.

Take this new shortened GOP and append all but the first GOP of the original file. The end result would be a new H264 stream where only the first GOP has been re-encoded; all the rest of the GOPs would be copied losslessly.


I'm not necessarily against a paid tool, but pretty much any NLE is going to involve re-encoding the video at some stage. My goal is to bring as much as possible over from the original video losslessly. (Basically, if I could do this, the only area I'd be suffering any generation loss is in the first second of the file, which is likely to be a fade-in or even some black frames and of little importance to the overall presentation.)

Can this be done??
This is possible to do, in theory. The key is to match all relevant source bitstream properties when encoding.

#1 Segment source video

ffmpeg -i source.mp4 -c copy -an -f segment -segment_time 0.01 seg%d.ts


Since the segment muxer by default only splits at keyframes, by providing a very low segment time, each produced segment will be one GOP long.

(I suggest using the whole audio from the source, we don't extract it here)

#2 Re-encode first segment

ffmpeg -i seg1.ts {-encoding args} -copyts -x264opts stitchable{+any-other-args} new1.ts


It's important here to match source settings.

#3 Rejoin segments

ffmpeg -i "concat:new1.ts|seg2.ts|..." -i source.mp4 -c copy -map 0 -map 1:a new.mp4