implement new grabbing interface, as described here:
authorRamiro Polla <ramiro@lisha.ufsc.br>
Wed, 14 Feb 2007 17:01:32 +0000 (17:01 +0000)
committerGuillaume Poirier <gpoirier@mplayerhq.hu>
Wed, 14 Feb 2007 17:01:32 +0000 (17:01 +0000)
ttp://thread.gmane.org/gmane.comp.video.ffmpeg.devel/42920
patch by Ramiro Polla % ramiro A lisha P ufsc P br %
Original thread:
Date: Jan 31, 2007 8:56 PM
Subject: [Ffmpeg-devel] [PATCH] New grabbing interface

Originally committed as revision 7983 to svn://svn.ffmpeg.org/ffmpeg/trunk

doc/ffmpeg-doc.texi
ffmpeg.c
libavformat/audio.c
libavformat/avformat.h
libavformat/beosaudio.cpp
libavformat/dc1394.c
libavformat/dv1394.c
libavformat/grab.c
libavformat/grab_bktr.c
libavformat/v4l2.c
libavformat/x11grab.c

index 768471b..40bed30 100644 (file)
@@ -26,11 +26,11 @@ video on the fly with a high quality polyphase filter.
 @c man begin EXAMPLES
 @section Video and Audio grabbing
 
-FFmpeg can use a video4linux compatible video source and any Open Sound
-System audio source:
+FFmpeg can grab video and audio from devices given that you specify the input
+format and device.
 
 @example
-ffmpeg /tmp/out.mpg
+ffmpeg -f audio_device -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg
 @end example
 
 Note that you must activate the right video source and channel before
@@ -44,14 +44,14 @@ standard mixer.
 FFmpeg can grab the X11 display.
 
 @example
-ffmpeg -f x11grab -vd x11:0.0 /tmp/out.mpg
+ffmpeg -f x11grab -:0.0 /tmp/out.mpg
 @end example
 
 0.0 is display.screen number of your X11 server, same as
 the DISPLAY environment variable.
 
 @example
-ffmpeg -f x11grab -vd x11:0.0+10,20 /tmp/out.mpg
+ffmpeg -f x11grab -:0.0+10,20 /tmp/out.mpg
 @end example
 
 0.0 is display.screen number of your X11 server, same as the DISPLAY environment
@@ -154,8 +154,6 @@ ffmpeg [[infile options][@option{-i} @var{infile}]]... @{[outfile options] @var{
 @c man end
 @end example
 @c man begin DESCRIPTION
-If no input file is given, audio/video grabbing is done.
-
 As a general rule, options are applied to the next specified
 file. Therefore, order is important, and you can have the same
 option on the command line multiple times. Each occurrence is
@@ -609,20 +607,12 @@ Set the ISO 639 language code (3 letters) of the current subtitle stream.
 @section Audio/Video grab options
 
 @table @option
-@item -vd device
-sEt video grab device (e.g. @file{/dev/video0}).
 @item -vc channel
 Set video grab channel (DV1394 only).
 @item -tvstd standard
 Set television standard (NTSC, PAL (SECAM)).
-@item -dv1394
-Set DV1394 grab.
-@item -ad device
-Set audio device (e.g. @file{/dev/dsp}).
-@item -grab format
-Request grabbing using.
-@item -gd device
-Set grab device.
+@item -isync
+Synchronize read on input.
 @end table
 
 @section Advanced options
index 7eb7011..5f79d7f 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -181,22 +181,9 @@ static int video_global_header = 0;
 
 static int rate_emu = 0;
 
-#ifdef CONFIG_BKTR
-static const char *video_grab_format = "bktr";
-#else
-#ifdef CONFIG_VIDEO4LINUX2
-static const char *video_grab_format = "video4linux2";
-#else
-static const char *video_grab_format = "video4linux";
-#endif
-#endif
-static char *video_device = NULL;
-static char *grab_device = NULL;
 static int  video_channel = 0;
 static char *video_standard = "ntsc";
 
-static const char *audio_grab_format = "audio_device";
-static char *audio_device = NULL;
 static int audio_volume = 256;
 
 static int using_stdin = 0;
@@ -2357,16 +2344,6 @@ static void opt_audio_channels(const char *arg)
     audio_channels = atoi(arg);
 }
 
-static void opt_video_device(const char *arg)
-{
-    video_device = av_strdup(arg);
-}
-
-static void opt_grab_device(const char *arg)
-{
-    grab_device = av_strdup(arg);
-}
-
 static void opt_video_channel(const char *arg)
 {
     video_channel = strtol(arg, NULL, 0);
@@ -2377,11 +2354,6 @@ static void opt_video_standard(const char *arg)
     video_standard = av_strdup(arg);
 }
 
-static void opt_audio_device(const char *arg)
-{
-    audio_device = av_strdup(arg);
-}
-
 static void opt_codec(int *pstream_copy, int *pcodec_id,
                       int codec_type, const char *arg)
 {
@@ -2573,7 +2545,6 @@ static void opt_input_file(const char *filename)
     ap->width = frame_width + frame_padleft + frame_padright;
     ap->height = frame_height + frame_padtop + frame_padbottom;
     ap->pix_fmt = frame_pix_fmt;
-    ap->device  = grab_device;
     ap->channel = video_channel;
     ap->standard = video_standard;
     ap->video_codec_id = video_codec_id;
@@ -2699,18 +2670,11 @@ static void opt_input_file(const char *filename)
     file_iformat = NULL;
     file_oformat = NULL;
 
-    grab_device = NULL;
     video_channel = 0;
 
     rate_emu = 0;
 }
 
-static void opt_grab(const char *arg)
-{
-    file_iformat = av_find_input_format(arg);
-    opt_input_file("");
-}
-
 static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
 {
     int has_video, has_audio, i, j;
@@ -3179,107 +3143,6 @@ static void opt_output_file(const char *filename)
     file_iformat = NULL;
 }
 
-/* prepare dummy protocols for grab */
-static void prepare_grab(void)
-{
-    int has_video, has_audio, i, j;
-    AVFormatContext *oc;
-    AVFormatContext *ic;
-    AVFormatParameters vp1, *vp = &vp1;
-    AVFormatParameters ap1, *ap = &ap1;
-
-    /* see if audio/video inputs are needed */
-    has_video = 0;
-    has_audio = 0;
-    memset(ap, 0, sizeof(*ap));
-    memset(vp, 0, sizeof(*vp));
-    vp->time_base.num= 1;
-    for(j=0;j<nb_output_files;j++) {
-        oc = output_files[j];
-        for(i=0;i<oc->nb_streams;i++) {
-            AVCodecContext *enc = oc->streams[i]->codec;
-            switch(enc->codec_type) {
-            case CODEC_TYPE_AUDIO:
-                if (enc->sample_rate > ap->sample_rate)
-                    ap->sample_rate = enc->sample_rate;
-                if (enc->channels > ap->channels)
-                    ap->channels = enc->channels;
-                has_audio = 1;
-                break;
-            case CODEC_TYPE_VIDEO:
-                if (enc->width > vp->width)
-                    vp->width = enc->width;
-                if (enc->height > vp->height)
-                    vp->height = enc->height;
-
-                if (vp->time_base.num*(int64_t)enc->time_base.den > enc->time_base.num*(int64_t)vp->time_base.den){
-                    vp->time_base = enc->time_base;
-                    vp->width += frame_leftBand + frame_rightBand;
-                    vp->width -= (frame_padleft + frame_padright);
-                    vp->height += frame_topBand + frame_bottomBand;
-                    vp->height -= (frame_padtop + frame_padbottom);
-                }
-                has_video = 1;
-                break;
-            default:
-                av_abort();
-            }
-        }
-    }
-
-    if (has_video == 0 && has_audio == 0) {
-        fprintf(stderr, "Output file must have at least one audio or video stream\n");
-        exit(1);
-    }
-
-    if (has_video) {
-        AVInputFormat *fmt1;
-#warning FIXME: find a better interface
-        if(video_device&&!strncmp(video_device,"x11:",4)) {
-            video_grab_format="x11grab";
-        }
-        fmt1 = av_find_input_format(video_grab_format);
-        vp->device  = video_device;
-        vp->channel = video_channel;
-        vp->standard = video_standard;
-        vp->pix_fmt = frame_pix_fmt;
-        if (av_open_input_file(&ic, "", fmt1, 0, vp) < 0) {
-            fprintf(stderr, "Could not find video grab device\n");
-            exit(1);
-        }
-        /* If not enough info to get the stream parameters, we decode the
-           first frames to get it. */
-        if ((ic->ctx_flags & AVFMTCTX_NOHEADER) && av_find_stream_info(ic) < 0) {
-            fprintf(stderr, "Could not find video grab parameters\n");
-            exit(1);
-        }
-        /* by now video grab has one stream */
-        ic->streams[0]->r_frame_rate.num = vp->time_base.den;
-        ic->streams[0]->r_frame_rate.den = vp->time_base.num;
-        input_files[nb_input_files] = ic;
-
-        if (verbose >= 0)
-            dump_format(ic, nb_input_files, "", 0);
-
-        nb_input_files++;
-    }
-    if (has_audio && audio_grab_format) {
-        AVInputFormat *fmt1;
-        fmt1 = av_find_input_format(audio_grab_format);
-        ap->device = audio_device;
-        if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) {
-            fprintf(stderr, "Could not find audio grab device\n");
-            exit(1);
-        }
-        input_files[nb_input_files] = ic;
-
-        if (verbose >= 0)
-            dump_format(ic, nb_input_files, "", 0);
-
-        nb_input_files++;
-    }
-}
-
 /* same option as mencoder */
 static void opt_pass(const char *pass_str)
 {
@@ -3789,14 +3652,9 @@ const OptionDef options[] = {
     { "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" },
 
     /* grab options */
-    { "vd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_device}, "set video grab device", "device" },
     { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
     { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_standard}, "set television standard (NTSC, PAL (SECAM))", "standard" },
-    { "ad", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_GRAB, {(void*)opt_audio_device}, "set audio device", "device" },
-
-    /* G.2 grab options */
-    { "grab", HAS_ARG | OPT_EXPERT | OPT_GRAB, {(void*)opt_grab}, "request grabbing using", "format" },
-    { "gd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_grab_device}, "set grab device", "device" },
+    { "isync", OPT_BOOL | OPT_EXPERT | OPT_GRAB, {(void*)&input_sync}, "sync read on input", "" },
 
     /* muxer options */
     { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT, {(void*)&mux_max_delay}, "set the maximum demux-decode delay", "seconds" },
@@ -3928,8 +3786,8 @@ int main(int argc, char **argv)
     }
 
     if (nb_input_files == 0) {
-        input_sync = 1;
-        prepare_grab();
+        fprintf(stderr, "Must supply at least one input file\n");
+        exit(1);
     }
 
     ti = getutime();
index 52f74db..a9e5bff 100644 (file)
@@ -53,14 +53,6 @@ static int audio_open(AudioData *s, int is_output, const char *audio_device)
     int tmp, err;
     char *flip = getenv("AUDIO_FLIP_LEFT");
 
-    /* open linux audio device */
-    if (!audio_device)
-#ifdef __OpenBSD__
-        audio_device = "/dev/sound";
-#else
-        audio_device = "/dev/dsp";
-#endif
-
     if (is_output)
         audio_fd = open(audio_device, O_WRONLY);
     else
@@ -229,7 +221,7 @@ static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     s->sample_rate = ap->sample_rate;
     s->channels = ap->channels;
 
-    ret = audio_open(s, 0, ap->device);
+    ret = audio_open(s, 0, s1->filename);
     if (ret < 0) {
         av_free(st);
         return AVERROR_IO;
index 636748c..dad18ce 100644 (file)
@@ -117,7 +117,9 @@ typedef struct AVFormatParameters {
     int height;
     enum PixelFormat pix_fmt;
     int channel; /* used to select dv channel */
+#if LIBAVFORMAT_VERSION_INT < (52<<16)
     const char *device; /* video, audio or DV device */
+#endif
     const char *standard; /* tv standard, NTSC, PAL, SECAM */
     int mpeg2ts_raw:1;  /* force raw MPEG2 transport stream output, if possible */
     int mpeg2ts_compute_pcr:1; /* compute exact PCR for each transport
index ae77809..6c16f00 100644 (file)
@@ -361,7 +361,7 @@ static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     s->sample_rate = ap->sample_rate;
     s->channels = ap->channels;
 
-    ret = audio_open(s, 0, ap->device);
+    ret = audio_open(s, 0, s1->filename);
     if (ret < 0) {
         av_free(st);
         return AVERROR(EIO);
index 70bbf2e..bf140c4 100644 (file)
@@ -118,7 +118,7 @@ static int dc1394_read_header(AVFormatContext *c, AVFormatParameters * ap)
                                    fmt->frame_size_id,
                                    SPEED_400,
                                    fps->frame_rate_id, 8, 1,
-                                   ap->device,
+                                   c->filename,
                                    &dc1394->camera);
     dc1394_free_camera_nodes(camera_nodes);
     if (res != DC1394_SUCCESS) {
index c5795ca..3a5f479 100644 (file)
@@ -83,7 +83,6 @@ static int dv1394_start(struct dv1394_data *dv)
 static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap)
 {
     struct dv1394_data *dv = context->priv_data;
-    const char *video_device;
 
     dv->dv_demux = dv_init_demux(context);
     if (!dv->dv_demux)
@@ -100,10 +99,7 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap
         dv->channel = DV1394_DEFAULT_CHANNEL;
 
     /* Open and initialize DV1394 device */
-    video_device = ap->device;
-    if (!video_device)
-        video_device = "/dev/dv1394/0";
-    dv->fd = open(video_device, O_RDONLY);
+    dv->fd = open(context->filename, O_RDONLY);
     if (dv->fd < 0) {
         perror("Failed to open DV interface");
         goto failed;
index 11acdac..5e778ec 100644 (file)
@@ -68,7 +68,6 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     struct video_tuner tuner;
     struct video_audio audio;
     struct video_picture pict;
-    const char *video_device;
     int j;
 
     if (ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) {
@@ -100,12 +99,9 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     s->frame_rate      = frame_rate;
     s->frame_rate_base = frame_rate_base;
 
-    video_device = ap->device;
-    if (!video_device)
-        video_device = "/dev/video";
-    video_fd = open(video_device, O_RDWR);
+    video_fd = open(s1->filename, O_RDWR);
     if (video_fd < 0) {
-        perror(video_device);
+        perror(s1->filename);
         goto fail;
     }
 
index 86348af..100653d 100644 (file)
@@ -243,7 +243,6 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     int frame_rate;
     int frame_rate_base;
     int format = -1;
-    const char *video_device;
 
     if (ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0)
         return -1;
@@ -253,10 +252,6 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     frame_rate = ap->time_base.den;
     frame_rate_base = ap->time_base.num;
 
-    video_device = ap->device;
-    if (!video_device)
-        video_device = "/dev/bktr0";
-
     st = av_new_stream(s1, 0);
     if (!st)
         return AVERROR(ENOMEM);
@@ -285,7 +280,7 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
             format = NTSC;
     }
 
-    if (bktr_init(video_device, width, height, format,
+    if (bktr_init(s1->filename, width, height, format,
             &(s->video_fd), &(s->tuner_fd), -1, 0.0) < 0)
         return AVERROR(EIO);
 
index 5f669bd..ef661ae 100644 (file)
@@ -114,16 +114,16 @@ static struct fmt_map fmt_conversion_table[] = {
     },
 };
 
-static int device_open(AVFormatContext *ctx, const char *devname, uint32_t *capabilities)
+static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
 {
     struct v4l2_capability cap;
     int fd;
     int res;
 
-    fd = open(devname, O_RDWR /*| O_NONBLOCK*/, 0);
+    fd = open(ctx->filename, O_RDWR /*| O_NONBLOCK*/, 0);
     if (fd < 0) {
         av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
-                 devname, strerror(errno));
+                 ctx->filename, strerror(errno));
 
         return -1;
     }
@@ -429,7 +429,6 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     int width, height;
     int res, frame_rate, frame_rate_base;
     uint32_t desired_format, capabilities;
-    const char *video_device;
 
     if (ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) {
         av_log(s1, AV_LOG_ERROR, "Missing/Wrong parameters\n");
@@ -459,12 +458,8 @@ static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     s->frame_rate      = frame_rate;
     s->frame_rate_base = frame_rate_base;
 
-    video_device = ap->device;
-    if (!video_device) {
-        video_device = "/dev/video";
-    }
     capabilities = 0;
-    s->fd = device_open(s1, video_device, &capabilities);
+    s->fd = device_open(s1, &capabilities);
     if (s->fd < 0) {
         av_free(st);
 
index 231c43d..8916d79 100644 (file)
@@ -97,25 +97,14 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
     int use_shm;
     char *param, *offset;
 
-    if (!ap->device) {
-        av_log(s1, AV_LOG_ERROR, "AVParameters don't specify any device. Use -vd.\n");
-        return AVERROR_IO;
-    }
-
-    param = strchr(ap->device, ':');
-    if (!param) {
-        av_free(st);
-        return AVERROR_IO;
-    }
-
-    param = av_strdup(param);
+    param = av_strdup(s1->filename);
     offset = strchr(param, '+');
     if (offset) {
         sscanf(offset, "%d,%d", &x_off, &y_off);
         *offset= 0;
     }
 
-    av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", ap->device, param, x_off, y_off, ap->width, ap->height);
+    av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", s1->filename, param, x_off, y_off, ap->width, ap->height);
 
     dpy = XOpenDisplay(param);
     if(!dpy) {