[FFmpeg-devel] [PATCH] allow v4l2 to select a frame rate
klchxbec at freenet.de
klchxbec
Thu Dec 17 09:29:19 CET 2009
Hello.
??
Attached patch fixes the problem with v4l2 where if the user does
not specify the frame rate using -r option, it would fail with:
Error while opening encoder for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height
The patch tries to apply the user-specified frame rate. If that does
not work, it reads the frame rate from the driver. Tested with a
couple of Logitech webcams.
??
--
K. Chowksey
??
Ist Ihr wunschname at freenet.de noch frei?
Jetzt pr?fen und kostenlose E-Mail-Adresse sichern!
http://email.freenet.de/dienste/emailoffice/produktuebersicht/basic/mail/index.html?pid=6829
-------------- next part --------------
Index: libavdevice/v4l2.c
===================================================================
--- libavdevice/v4l2.c (revision 20888)
+++ libavdevice/v4l2.c (working copy)
@@ -543,9 +543,55 @@
}
}
+ if (ap->time_base.num != 0 && ap->time_base.den != 0) {
+ struct v4l2_streamparm parm = {
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE
+ };
+
+ if (ioctl(s->fd, VIDIOC_G_PARM, &parm) < 0) {
+ av_log(s1, AV_LOG_INFO, "The V4L2 driver ioctl get parm failed\n");
+ } else {
+ if (parm.parm.capture.timeperframe.numerator != ap->time_base.num ||
+ parm.parm.capture.timeperframe.denominator != ap->time_base.den) {
+ parm.parm.capture.timeperframe.numerator = ap->time_base.num;
+ parm.parm.capture.timeperframe.denominator = ap->time_base.den;
+ if (ioctl(s->fd, VIDIOC_S_PARM, &parm) < 0) {
+ av_log(s1, AV_LOG_INFO, "The V4L2 driver ioctl to set frame rate %lf"
+ " failed\n", 1/av_q2d(ap->time_base));
+ }
+ }
+ }
+ }
return 0;
}
+static void v4l2_find_frame_rate(AVFormatContext *ctx, AVStream *st, AVFormatParameters *ap)
+{
+ struct video_data *s = ctx->priv_data;
+ struct v4l2_streamparm parm = {
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE
+ };
+
+ if (ioctl(s->fd, VIDIOC_G_PARM, &parm) < 0) {
+ if (ap->time_base.den != 0 && ap->time_base.num != 0) {
+ av_log(ctx, AV_LOG_INFO, "The V4L2 driver ioctl get parm failed, assuming "
+ "user-specified rate %lf\n", 1/av_q2d(ap->time_base));
+ }
+ st->codec->time_base.den = ap->time_base.den;
+ st->codec->time_base.num = ap->time_base.num;
+ } else {
+ st->codec->time_base.num = parm.parm.capture.timeperframe.numerator;
+ st->codec->time_base.den = parm.parm.capture.timeperframe.denominator;
+ if (ap->time_base.den != 0 && ap->time_base.num != 0 &&
+ (st->codec->time_base.num != ap->time_base.num ||
+ st->codec->time_base.den != ap->time_base.den)) {
+ av_log(ctx, AV_LOG_INFO, "The V4L2 driver changed the frame rate from "
+ "%lf to %lf\n", 1/av_q2d(ap->time_base),
+ 1/av_q2d(st->codec->time_base));
+ }
+ }
+}
+
uint32_t device_try_init(AVFormatContext *s1,
const AVFormatParameters *ap,
int *width,
@@ -650,8 +696,7 @@
st->codec->codec_id = codec_id;
st->codec->width = width;
st->codec->height = height;
- st->codec->time_base.den = ap->time_base.den;
- st->codec->time_base.num = ap->time_base.num;
+ v4l2_find_frame_rate(s1, st, ap);
st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
return 0;
More information about the ffmpeg-devel
mailing list