[FFmpeg-devel] [PATCH] More DirectShow patches
Stefano Sabatini
stefasab at gmail.com
Wed Sep 5 16:34:26 CEST 2012
On date Tuesday 2012-09-04 21:28:49 -0300, Ramiro Polla encoded:
> On Tue, Sep 4, 2012 at 1:25 PM, Stefano Sabatini <stefasab at gmail.com> wrote:
[...]
> From 773200980d70569fa25475052ea4061a9672aba5 Mon Sep 17 00:00:00 2001
> From: Ramiro Polla <ramiro.polla at gmail.com>
> Date: Tue, 4 Sep 2012 20:59:39 -0300
> Subject: [PATCH] dshow: support video codec and pixel format selection
>
> ---
> libavdevice/dshow.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 44 insertions(+), 1 deletions(-)
>
> diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
> index 18adf8f..0beb186 100644
> --- a/libavdevice/dshow.c
> +++ b/libavdevice/dshow.c
> @@ -20,6 +20,7 @@
> */
>
> #include "libavutil/parseutils.h"
> +#include "libavutil/pixdesc.h"
> #include "libavutil/opt.h"
> #include "libavformat/internal.h"
> #include "avdevice.h"
> @@ -52,6 +53,9 @@ struct dshow_ctx {
>
> IMediaControl *control;
>
> + char *pixel_format_str;
> + enum PixelFormat pixel_format;
> + enum AVCodecID video_codec_id;
> char *video_size;
> char *framerate;
>
> @@ -371,6 +375,18 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
> goto next;
> }
> if (!pformat_set) {
> + enum PixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
> + if (pix_fmt == PIX_FMT_NONE) {
> + enum AVCodecID codec_id = dshow_codecid(bih->biCompression);
> + AVCodec *codec = avcodec_find_decoder(codec_id);
> + if (codec_id == AV_CODEC_ID_NONE || !codec) {
> + av_log(avctx, AV_LOG_INFO, " unknown compression type");
> + } else {
> + av_log(avctx, AV_LOG_INFO, " video_codec=%s", codec->name);
> + }
> + } else {
> + av_log(avctx, AV_LOG_INFO, " pix_fmt=%s", av_get_pix_fmt_name(pix_fmt));
> + }
> av_log(avctx, AV_LOG_INFO, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
> vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
> 1e7 / vcaps->MaxFrameInterval,
> @@ -378,6 +394,14 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
> 1e7 / vcaps->MinFrameInterval);
> continue;
> }
> + if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
> + if (ctx->video_codec_id != dshow_codecid(bih->biCompression))
> + goto next;
> + }
> + if (ctx->pixel_format_str &&
> + ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
> + goto next;
> + }
> if (ctx->framerate) {
> int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
> / ctx->requested_framerate.num;
> @@ -511,7 +535,9 @@ dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
> const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
> const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
>
> - int set_format = (devtype == VideoDevice && (ctx->video_size || ctx->framerate))
> + int set_format = (devtype == VideoDevice && (ctx->video_size || ctx->framerate ||
> + ctx->pixel_format_str ||
> + ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
> || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
> int format_set = 0;
>
> @@ -851,6 +877,22 @@ static int dshow_read_header(AVFormatContext *avctx)
> goto error;
> }
>
> + ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
> + : AV_CODEC_ID_RAWVIDEO;
> + if (ctx->pixel_format_str) {
> + if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
> + av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
> + "video codec is not set or set to rawvideo.\n");
Nit: ending "." is inconsistent with the prevailing convention in the codebase
> + ret = AVERROR(EINVAL);
> + goto error;
> + }
> + ctx->pixel_format = av_get_pix_fmt(ctx->pixel_format_str);
> + if (ctx->pixel_format == PIX_FMT_NONE) {
> + av_log(avctx, AV_LOG_ERROR, "No such pixel format '%s'.\n", ctx->pixel_format_str);
Nit: same (or you could use AV_OPT_TYPE_PIXEL_FMT)
> + ret = AVERROR(EINVAL);
> + goto error;
> + }
> + }
> if (ctx->video_size) {
> r = av_parse_video_size(&ctx->requested_width, &ctx->requested_height, ctx->video_size);
> if (r < 0) {
> @@ -990,6 +1032,7 @@ static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
> #define DEC AV_OPT_FLAG_DECODING_PARAM
> static const AVOption options[] = {
> { "video_size", "set video size given a string such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
> + { "pixel_format", "set video pixel format", OFFSET(pixel_format_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
Nit: pixel_format for consistency with the other options, which are
also taking a string.
> { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
> { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, DEC },
> { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 16, DEC },
Also: missing docs in indevs.texi for pixel_format option.
Should be good otherwise if tested (I'll apply with the nits fixed if
you won't send an updated patch in a few days).
--
FFmpeg = Frightening & Fancy Mortal Pacific Elected Gigant
More information about the ffmpeg-devel
mailing list