From cc58300e30e7aea6acfecd72a04a3886b285cfd8 Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Wed, 14 Feb 2007 17:01:32 +0000 Subject: [PATCH] implement new grabbing interface, as described here: 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 | 24 +++----- ffmpeg.c | 148 +--------------------------------------------- libavformat/audio.c | 10 +--- libavformat/avformat.h | 2 + libavformat/beosaudio.cpp | 2 +- libavformat/dc1394.c | 2 +- libavformat/dv1394.c | 6 +- libavformat/grab.c | 8 +-- libavformat/grab_bktr.c | 7 +-- libavformat/v4l2.c | 13 ++-- libavformat/x11grab.c | 15 +---- 11 files changed, 25 insertions(+), 212 deletions(-) diff --git a/doc/ffmpeg-doc.texi b/doc/ffmpeg-doc.texi index 768471b53f..40bed30f1c 100644 --- a/doc/ffmpeg-doc.texi +++ b/doc/ffmpeg-doc.texi @@ -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 -i :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 -i :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 diff --git a/ffmpeg.c b/ffmpeg.c index 7eb7011e84..5f79d7f6d3 100644 --- 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;jnb_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(); diff --git a/libavformat/audio.c b/libavformat/audio.c index 52f74db391..a9e5bffd5f 100644 --- a/libavformat/audio.c +++ b/libavformat/audio.c @@ -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; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 636748c6d1..dad18ced35 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -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 diff --git a/libavformat/beosaudio.cpp b/libavformat/beosaudio.cpp index ae77809747..6c16f0048c 100644 --- a/libavformat/beosaudio.cpp +++ b/libavformat/beosaudio.cpp @@ -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); diff --git a/libavformat/dc1394.c b/libavformat/dc1394.c index 70bbf2e75a..bf140c4664 100644 --- a/libavformat/dc1394.c +++ b/libavformat/dc1394.c @@ -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) { diff --git a/libavformat/dv1394.c b/libavformat/dv1394.c index c5795ca022..3a5f479c8e 100644 --- a/libavformat/dv1394.c +++ b/libavformat/dv1394.c @@ -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; diff --git a/libavformat/grab.c b/libavformat/grab.c index 11acdac3b1..5e778ecc06 100644 --- a/libavformat/grab.c +++ b/libavformat/grab.c @@ -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; } diff --git a/libavformat/grab_bktr.c b/libavformat/grab_bktr.c index 86348af5b1..100653db79 100644 --- a/libavformat/grab_bktr.c +++ b/libavformat/grab_bktr.c @@ -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); diff --git a/libavformat/v4l2.c b/libavformat/v4l2.c index 5f669bd66c..ef661ae2ff 100644 --- a/libavformat/v4l2.c +++ b/libavformat/v4l2.c @@ -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); diff --git a/libavformat/x11grab.c b/libavformat/x11grab.c index 231c43da7e..8916d799a6 100644 --- a/libavformat/x11grab.c +++ b/libavformat/x11grab.c @@ -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) { -- 2.11.0