Discussion:
[FFmpeg-user] Cutting video at i-frames to avoid recoding
Andy Civil
2012-08-18 21:30:21 UTC
Permalink
Hi

Context: I have some home movies of animals doing cute things, where I left the
camera running so a good portion is garbage. I want to cut out and keep the good
parts, but I don't want to re-encode because then it wouldn't feel like the
'original' footage, as it were. I know that you can't cut a H.264 movie just
anywhere, because the output file has to start with an i-frame.

I know that FFmpeg can "-vcodec copy" and I know that you can also set "-ss"
start time and duration; but I don't know if you can do both at once, and if you
can, how does it behave? (I'm thinking that the GOP could be as many as 300
frames, and I believe FFmpeg 'only goes forwards' so it is not reasonable to
think that you could specify a start time and expect it to go BACK in the stream
to the previous i-frame; that's just not how it works, right?)

So my basic question is: how can I cut a h.264 movie without recoding anything,
specifying a start and stop time?

It would be perfectly acceptable if the first frames were simply grey,
containing only the differences - I know this is possible because sometimes on
youtube, you see videos that have been cut this way; here's an example:

(watch just the first few seconds "are about to perform" before an i-frame comes
along and clears things up).
It would also be acceptable for FFmpeg to count to the specified time, then wait
for the next i-frame to arrive before doing the stream copy (I can find my GOP
and ensure that I add at least that time prior to the cute parts).
It would also be acceptable if I had to use a tool like "FFprobe" with "show
frames" to locate the exact time of an i-frame, and then use that as my "-ss" time.

Thank you for any insight into this. I know it's similar to Gregory1234's
question, but I don't think that thread really came to a conclusion.

--
Andy
Stefano Sabatini
2012-08-18 21:43:06 UTC
Permalink
Post by Andy Civil
Hi
Context: I have some home movies of animals doing cute things, where
I left the camera running so a good portion is garbage. I want to
cut out and keep the good parts, but I don't want to re-encode
because then it wouldn't feel like the 'original' footage, as it
were. I know that you can't cut a H.264 movie just anywhere, because
the output file has to start with an i-frame.
I know that FFmpeg can "-vcodec copy" and I know that you can also
set "-ss" start time and duration; but I don't know if you can do
both at once, and if you can, how does it behave? (I'm thinking that
the GOP could be as many as 300 frames, and I believe FFmpeg 'only
goes forwards' so it is not reasonable to think that you could
specify a start time and expect it to go BACK in the stream to the
previous i-frame; that's just not how it works, right?)
So my basic question is: how can I cut a h.264 movie without
recoding anything, specifying a start and stop time?
It would be perfectly acceptable if the first frames were simply
grey, containing only the differences - I know this is possible
because sometimes on youtube, you see videos that have been cut this
http://youtu.be/SwRFoxgEcHc
(watch just the first few seconds "are about to perform" before an
i-frame comes along and clears things up).
I don't think skipping I-frames is a good idea if you want a decent
footage quality (much better to re-code the file in that case).

You may have a look at the segment muxer, it may be useful depending
on what you want to exactly achieve.
--
ffmpeg-user random tip #22
See the capture of a video4linux device:
ffplay -s 640x480 -f video4linux /dev/video0
Andy Civil
2012-08-19 02:07:00 UTC
Permalink
Post by Stefano Sabatini
I don't think skipping I-frames is a good idea if you want a decent
footage quality (much better to re-code the file in that case).
Re-coding is unacceptable as a matter of principle; this is my 'stock footage',
i.e. raw (as shot) out of my camera. I think movie editors refer to it as
"assets". My objective is to cut out gigabytes of unwanted stuff, to save disk
space; the stock footage must remain "original".

What I'm saying is that if the first few frames are trashed, it doesn't matter
to me, because those seconds would never make it into a movie production anyway.
Post by Stefano Sabatini
You may have a look at the segment muxer, it may be useful depending
on what you want to exactly achieve.
Actually, that could be an answer. Thank you for giving me something to google
for "segment muxer" - sometimes, knowing what to look for is all the help a user
needs - LOL.

It certainly looks like it splits files at i-frames, which is what I need. I
could split my files into 10s segments and then delete ones which contain
nothing useful. It would mean that I'd be loading multiple segments into my
movie editor, but that's probably acceptable.

I wondered if I could concatenate the segments I want back together again, but
I've been reading the old thread started by Acer Yang on 2012-02-12 and it looks
like it's hard to get the "moov" atom to show the right time.

Thanks for the start, Stefano, if anyone else has any other ideas...

--
Andy
Francois Visagie
2012-08-19 15:08:53 UTC
Permalink
-----Original Message-----
Sent: 19 August 2012 04:07
To: FFmpeg user questions
Subject: Re: [FFmpeg-user] Cutting video at i-frames to avoid recoding
Thanks for the start, Stefano, if anyone else has any other ideas...
Experiment? You came up with some pretty decent-looking suggestions
yourself. I suspect your concern is whether ffmpeg will ensure that start
time and duration coincide in some way with I-frames. With utilities like
Avidemux (and VirtualDub with an H.264 decoder) you can see where the
I-frames are in your source footage. Then you can run some test "copy
encodes" with ffmpeg and evaluate results?

Failing all else with ffmpeg, Avidemux should do the job for you. Manually
set the cutting boundaries at I-frames.
Andy Civil
2012-09-02 05:15:40 UTC
Permalink
Post by Francois Visagie
Experiment? You came up with some pretty decent-looking suggestions
yourself. I suspect your concern is whether ffmpeg will ensure that start
time and duration coincide in some way with I-frames.
In the end, that's what I did. I'm reporting back, for anyone who searches the
archives for the same information.

Things got a bit easier when I found that 'ffprobe -show_frames' would give tons
of information about frame types and times.

My source file had i-frames at regular 0.5s intervals, and only p-frames
otherwise, so I didn't have the complication of b-frames.

To create an artificially bad situation, I used FFmpeg to produce a 30s file
with a GOP of 300 (an i-frame every 10s at 30fps). I then asked it to 'copy' the
file starting at 5 seconds in.

What I got out was very interesting. The sound frames started at the beginning
of the file at 0s, from 5s into the original just as I had asked. There were NO
video frames at all until the first i-frame, which was originally timed at 10s,
but was now timed at 5s in the new file because of my cut. In a way, this makes
perfect sense, but it seemed odd that I now had a video file which had five
seconds of sound with no picture at the start!

(As a side issue, I noticed that FFmpeg had re-ordered the frames, the original
had a bunch of audio frames, followed by a bunch of video frames; FFmpeg
interleaved them more chronologically.)

I was curious to know how this file would play. VLC obediently played the sound
right from the start (at the 5s point of the original, of course) and continued
to show its orange cone logo on the screen. At the 5s point when the first
i-frame came along, the logo was replaced with the video. It was perfectly
synchronised. This is obviously a good result.

My only remaining concern was that my video editor (I use Vegas) would mess up,
and ignore the frame times, leaving me with audio and video that were 5s out of
synch. When I loaded the file in, I noticed that there was no missing 5s of
video, as there had been on VLC. However, Vegas did not go out of synch, nor did
it cut off the first five seconds of sound: what it did do was to grab that
first i-frame and stretch it back to the start of the file. So the video was
'freeze framed' for five seconds while the audio was playing, then at the 5s
point it continued perfectly.

After these experiments, I'm confident to use FFmpeg to cut the garbage out of
my 'original' footage, but knowing how this works, and having observed the 0.5s
GOP on my original, I will also specify a start time that causes an i-frame to
occur at the start of the cut file, for the cleanest result.

--
Andy
Francois Visagie
2012-09-03 07:13:35 UTC
Permalink
-----Original Message-----
Sent: 02 September 2012 07:16
To: FFmpeg user questions
Subject: Re: [FFmpeg-user] Cutting video at i-frames to avoid recoding
Post by Francois Visagie
Experiment? You came up with some pretty decent-looking suggestions
yourself. I suspect your concern is whether ffmpeg will ensure that
start time and duration coincide in some way with I-frames.
In the end, that's what I did. I'm reporting back, for anyone who searches the
archives for the same information.
Great stuff.
Things got a bit easier when I found that 'ffprobe -show_frames' would
give
tons of information about frame types and times.
My source file had i-frames at regular 0.5s intervals, and only p-frames
otherwise, so I didn't have the complication of b-frames.
To create an artificially bad situation, I used FFmpeg to produce a 30s
file with
a GOP of 300 (an i-frame every 10s at 30fps). I then asked it to 'copy'
the file
starting at 5 seconds in.
What I got out was very interesting. The sound frames started at the
beginning of the file at 0s, from 5s into the original just as I had
asked. There
were NO video frames at all until the first i-frame, which was originally
timed
at 10s, but was now timed at 5s in the new file because of my cut. In a
way,
this makes perfect sense, but it seemed odd that I now had a video file
which
had five seconds of sound with no picture at the start!
(As a side issue, I noticed that FFmpeg had re-ordered the frames, the
original had a bunch of audio frames, followed by a bunch of video frames;
FFmpeg interleaved them more chronologically.)
I was curious to know how this file would play. VLC obediently played the
sound right from the start (at the 5s point of the original, of course)
and
continued to show its orange cone logo on the screen. At the 5s point when
the first i-frame came along, the logo was replaced with the video. It was
perfectly synchronised. This is obviously a good result.
My only remaining concern was that my video editor (I use Vegas) would
mess up, and ignore the frame times, leaving me with audio and video that
were 5s out of synch. When I loaded the file in, I noticed that there was
no
missing 5s of video, as there had been on VLC. However, Vegas did not go
out of synch, nor did it cut off the first five seconds of sound: what it
did do
was to grab that first i-frame and stretch it back to the start of the
file. So the
video was 'freeze framed' for five seconds while the audio was playing,
then
at the 5s point it continued perfectly.
This kind of behaviour is often configurable in the player or editor. I.e.
there might not always be a sure-fire way of determining player behaviour in
the encoder, just bear that in mind.
After these experiments, I'm confident to use FFmpeg to cut the garbage
out
of my 'original' footage, but knowing how this works, and having observed
the 0.5s GOP on my original, I will also specify a start time that causes
an i-
frame to occur at the start of the cut file, for the cleanest result.
--
Andy
_______________________________________________
ffmpeg-user mailing list
http://ffmpeg.org/mailman/listinfo/ffmpeg-user
Jim Worrall
2012-08-18 22:34:24 UTC
Permalink
So my basic question is: how can I cut a h.264 movie without recoding anything, specifying a start and stop time?
Instead of stop time, you specify the duration of the clip you want.
Maybe try this:
ffmpeg -ss [start time] -i [input] -t [duration] -c copy [output]

Jim
Carl Eugen Hoyos
2012-08-19 15:18:57 UTC
Permalink
Post by Jim Worrall
ffmpeg -ss [start time] -i [input] -t [duration] -c copy [output]
Iirc, -t does not always work with -c copy,
but this is of course how it should work.

Carl Eugen
Carl Eugen Hoyos
2012-08-19 15:15:39 UTC
Permalink
Post by Andy Civil
It would be perfectly acceptable if the first
frames were simply grey
FFmpeg by default only seeks to key-frames.
(MPlayer developers do not like this and set a
flag to allow to seek to - grey - non-key frames,
but I am not sure this can be done from the
command line.)

Carl Eugen
Loading...