PR #23607 opened by hit-labvn URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23607 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23607.patch
Some DirectShow devices report uncompressed RGB formats with RGB555, RGB565, RGB24, or RGB32 media subtype values instead of BI_RGB or BI_BITFIELDS. FFmpeg currently treats those subtypes as unsupported, so capture from such devices fails even though the frames are raw RGB. Map those values to rawvideo pixel formats and include them in the bottom-up RGB handling. Clear codec_tag once the subtype has been translated so rawvideo receives the selected pixel format instead of the DirectShow subtype. Signed-off-by: Hao Truong <[email protected]> # Summary of changes Briefly describe what this PR does and why. <!-- If this PR requires new FATE test samples, attach them to the PR and list their target paths below (relative to the fate-suite root). Attached filenames must match the sample's filename: ```fate-samples # e.g. vorbis/new-sample.ogg ``` --> >From a50a6feba200d76f529d2b899fe9ed84a05fbe2f Mon Sep 17 00:00:00 2001 From: Hao Truong <[email protected]> Date: Fri, 26 Jun 2026 23:18:34 +0700 Subject: [PATCH] avdevice/dshow: handle DirectShow RGB media subtypes Some DirectShow devices report uncompressed RGB formats with RGB555, RGB565, RGB24, or RGB32 media subtype values instead of BI_RGB or BI_BITFIELDS. FFmpeg currently treats those subtypes as unsupported, so capture from such devices fails even though the frames are raw RGB. Map those values to rawvideo pixel formats and include them in the bottom-up RGB handling. Clear codec_tag once the subtype has been translated so rawvideo receives the selected pixel format instead of the DirectShow subtype. Signed-off-by: Hao Truong <[email protected]> --- libavdevice/dshow.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c index 6e97304850..6a555846b7 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -56,6 +56,10 @@ # define AMCONTROL_COLORINFO_PRESENT 0x00000080 // if set, indicates DXVA color info is present in the upper (24) bits of the dwControlFlags #endif +#define DSHOW_MEDIASUBTYPE_RGB565 0xe436eb7b +#define DSHOW_MEDIASUBTYPE_RGB555 0xe436eb7c +#define DSHOW_MEDIASUBTYPE_RGB24 0xe436eb7d +#define DSHOW_MEDIASUBTYPE_RGB32 0xe436eb7e static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount) { @@ -76,10 +80,33 @@ static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount) case 32: return AV_PIX_FMT_0RGB32; } + case DSHOW_MEDIASUBTYPE_RGB565: + return AV_PIX_FMT_RGB565; + case DSHOW_MEDIASUBTYPE_RGB555: + return AV_PIX_FMT_RGB555; + case DSHOW_MEDIASUBTYPE_RGB24: + return AV_PIX_FMT_BGR24; + case DSHOW_MEDIASUBTYPE_RGB32: + return AV_PIX_FMT_0RGB32; } return avpriv_pix_fmt_find(PIX_FMT_LIST_RAW, biCompression); // all others } +static int dshow_is_bottomup_rgb(DWORD biCompression) +{ + switch (biCompression) { + case BI_RGB: + case BI_BITFIELDS: + case DSHOW_MEDIASUBTYPE_RGB565: + case DSHOW_MEDIASUBTYPE_RGB555: + case DSHOW_MEDIASUBTYPE_RGB24: + case DSHOW_MEDIASUBTYPE_RGB32: + return 1; + default: + return 0; + } +} + static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info) { switch (fmt_info->NominalRange) @@ -1581,7 +1608,7 @@ dshow_add_device(AVFormatContext *avctx, par->codec_type = AVMEDIA_TYPE_VIDEO; par->width = fmt_info->width; par->height = fmt_info->height; - par->codec_tag = bih->biCompression; + par->codec_tag = fmt_info->pix_fmt == AV_PIX_FMT_NONE ? bih->biCompression : 0; par->format = fmt_info->pix_fmt; if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) { av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n"); @@ -1594,7 +1621,7 @@ dshow_add_device(AVFormatContext *avctx, par->chroma_location = fmt_info->chroma_loc; par->codec_id = fmt_info->codec_id; if (par->codec_id == AV_CODEC_ID_RAWVIDEO) { - if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) { + if (dshow_is_bottomup_rgb(bih->biCompression)) { par->bits_per_coded_sample = bih->biBitCount; if (par->height < 0) { par->height *= -1; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
