[FFmpeg-devel] grabbing from dv1394
Tommi Sakari Uimonen
tuimonen
Wed Jul 11 22:59:59 CEST 2007
Hello Roman, I think I found what was the problem, but I'll explain it a
bit further down the mail. First my replies..
> Well, first of all -- quite a few things become kernel threads
> (tasks?) without you even realizing it. So the fact that you still have
> just one user thread is not really that important. It seems to me
I knew I wasn't smart enough :) Well now I know.
>> The comment about single threads and encoding disk streams meant that
>> even slow computers finish their tasks without losing frames - they
>> just take longer time to get there, hence the "time" is no realtime and
>> there is no need for special manouvers.
>
> I guess I don't quite follow the above argument.
Yes, I'm having hard time to explain my thoughts from time to time. And
it's not very important issue, but since I don't like to leave you
puzzled, I'll give it another try.
The point was the differences in data sources and the method of reading
the data. DV camera plays the tape and pushes the data to ffmpeg even if
it can't read all the frames fast enough (This is true only for _slow_
computers). Encoding from an existing file to another, however, is pulling
the data from the file and ffmpeg is fully controlling the data flow.
It's like you tried to drink a bottle of soda when someone is pouring it
down your throat at constant stream; it's difficult. But if you can drink
it in your own pace, sipping it from time to time, it'll get finished and
none got spilled.
>> But I admit that using two threads is not the answer, since dvgrab is not
>> using any realtime privileges for the threads, so it must be something
>> extra that ffmpeg does, or maybe ffmpeg uses too small ringbuffer, or
>> maybe ffmpeg is too fast and processes some frames twice - that would
>> explain some of the jerkiness and incomplete frames on the output.
>
> What kernel are you running this on?
2.6.20-15
Ok, to the business. I made a short test movie that displayed big numbers
from 1 to 25 over and over again, number changing for each frame. I got it
easily exported to dv camera with kino and started experimenting.
I soon found out that instead of saving to avi format:
tuimonen at punttu:~/incoming/ffmpeg$ ./ffmpeg -f dv1394 -i /dev/dv1394/0 -f
avi -acodec copy -vcodec copy -y t1.avi
FFmpeg version SVN-r9225, Copyright (c) 2000-2007 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-pthreads --enable-x11grab
--enable-dc1394 --enable-liba52 --enable-liba52bin --enable-libfaac
--enable-libfaad --enable-libfaadbin --enable-libmp3lame --enable-libogg
--enable-libtheora --enable-libvorbis --enable-xvid
libavutil version: 49.4.0
libavcodec version: 51.40.4
libavformat version: 51.12.1
built on Jun 6 2007 00:52:53, gcc: 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
Input #0, dv1394, from '/dev/dv1394/0':
Duration: N/A, start: 0.000000, bitrate: 30336 kb/s
Stream #0.0: Video: dvvideo, yuv420p, 720x576, 28800 kb/s, 25.00 fps(r)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Output #0, avi, to 't1.avi':
Stream #0.0: Video: dvvideo, yuv420p, 720x576, q=2-31, 28800 kb/s, 25.00
fps(c)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 397 fps= 23 q=0.0 Lsize= 129917kB time=15.8
bitrate=67189.5kbits/s
video:55828kB audio:2970kB global headers:0kB muxing overhead 120.954537%
I should use dv format:
tuimonen at punttu:~/incoming/ffmpeg$ ./ffmpeg -f dv1394 -i /dev/dv1394/0 -f
dv -acodec copy -vcodec copy -y t1.avi
FFmpeg version SVN-r9225, Copyright (c) 2000-2007 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-pthreads --enable-x11grab
--enable-dc1394 --enable-liba52 --enable-liba52bin --enable-libfaac
--enable-libfaad --enable-libfaadbin --enable-libmp3lame --enable-libogg
--enable-libtheora --enable-libvorbis --enable-xvid
libavutil version: 49.4.0
libavcodec version: 51.40.4
libavformat version: 51.12.1
built on Jun 6 2007 00:52:53, gcc: 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
Input #0, dv1394, from '/dev/dv1394/0':
Duration: N/A, start: 0.000000, bitrate: 30336 kb/s
Stream #0.0: Video: dvvideo, yuv420p, 720x576, 28800 kb/s, 25.00 fps(r)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Output #0, dv, to 't1.avi':
Stream #0.0: Video: dvvideo, yuv420p, 720x576, q=2-31, 28800 kb/s, 25.00
fps(c)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 429 fps= 25 q=0.0 Lsize= 60328kB time=17.2
bitrate=28800.0kbits/s
video:60328kB audio:3218kB global headers:0kB muxing overhead -5.063291%
The avi formatted version suffered from 'choking' from time to time, I
could hear the harddisk going and the frame counter was stalled for a
while, and playback proved that frames were dropped and there was
stuttering in both video and audio at that point. By looking at the file
sizes, the avi seems to consume much more than the dv, which played just
perfectly, no frames lost or anything.
I soon found out, that the audio codec selection plays a crucial part. If
I chose '-acodec pcm_s16le' instead of '-acodec copy', the avi formatted
version started to work too:
uimonen at punttu:~/incoming/ffmpeg$ ./ffmpeg -f dv1394 -i /dev/dv1394/0 -f
avi -acodec pcm_s16le -vcodec copy -y t1.avi
FFmpeg version SVN-r9225, Copyright (c) 2000-2007 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-pthreads --enable-x11grab
--enable-dc1394 --enable-liba52 --enable-liba52bin --enable-libfaac
--enable-libfaad --enable-libfaadbin --enable-libmp3lame --enable-libogg
--enable-libtheora --enable-libvorbis --enable-xvid
libavutil version: 49.4.0
libavcodec version: 51.40.4
libavformat version: 51.12.1
built on Jun 6 2007 00:52:53, gcc: 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
Input #0, dv1394, from '/dev/dv1394/0':
Duration: N/A, start: 0.000000, bitrate: 30336 kb/s
Stream #0.0: Video: dvvideo, yuv420p, 720x576, 28800 kb/s, 25.00 fps(r)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Output #0, avi, to 't1.avi':
Stream #0.0: Video: dvvideo, yuv420p, 720x576, q=2-31, 28800 kb/s, 25.00
fps(c)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 430 fps= 25 q=0.0 Lsize= 63724kB time=17.2
bitrate=30350.2kbits/s
video:60469kB audio:3225kB global headers:0kB muxing overhead 0.046831%
As we can see, the muxing overhead has dropped from 120% to 0.04%. So
direct copying of audio is causing some extra work for ffmpeg.
Ok, now I've found the correct way to do raw copy without losing frames.
But that's not enough. I want encoding on the fly.
So I then proceeded to experiment encoding and found a working solution:
tuimonen at punttu:~/incoming/ffmpeg$ ./ffmpeg -f dv1394 -i /dev/dv1394/0 -f
mp4 -acodec pcm_s16le -sameq -y t1.avi
FFmpeg version SVN-r9225, Copyright (c) 2000-2007 Fabrice Bellard, et al.
configuration: --enable-gpl --enable-pthreads --enable-x11grab
--enable-dc1394 --enable-liba52 --enable-liba52bin --enable-libfaac
--enable-libfaad --enable-libfaadbin --enable-libmp3lame --enable-libogg
--enable-libtheora --enable-libvorbis --enable-xvid
libavutil version: 49.4.0
libavcodec version: 51.40.4
libavformat version: 51.12.1
built on Jun 6 2007 00:52:53, gcc: 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
Input #0, dv1394, from '/dev/dv1394/0':
Duration: N/A, start: 0.000000, bitrate: 30336 kb/s
Stream #0.0: Video: dvvideo, yuv420p, 720x576, 28800 kb/s, 25.00 fps(r)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Output #0, mp4, to 't1.avi':
Stream #0.0: Video: mpeg4, yuv420p, 720x576, q=2-31, 200 kb/s, 25.00
fps(c)
Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 445 fps= 25 q=0.0 Lsize= 6018kB time=17.8 bitrate=2769.6kbits/s
video:2674kB audio:3338kB global headers:0kB muxing overhead 0.106324%
It consumes about 15% cpu.
Now I'm happy. Thanks for listening!
Tommi
More information about the ffmpeg-devel
mailing list