Ticket #9271: 0001-avdevice-dshow-discover-source-color-space.patch

File 0001-avdevice-dshow-discover-source-color-space.patch, 6.4 KB (added by Diederick Niehorster, 5 years ago)

preliminary patch

  • libavdevice/dshow.c

    From 1d3d43d942e621fefd38211927e4c8ceef5fae7a Mon Sep 17 00:00:00 2001
    From: Diederick Niehorster <dcnieho@gmail.com>
    Date: Mon, 31 May 2021 22:32:42 +0200
    Subject: [PATCH] avdevice/dshow: discover source color space
    
    Made a start with discovering a DirectShow device's color range, space, primaries and transfer characteristics, if it exposes that information. Right now incomplete, and only logs the discovered information when the list_options options is set.
    
    Signed-off-by: Diederick Niehorster <dcnieho@gmail.com>
    ---
     libavdevice/dshow.c | 102 +++++++++++++++++++++++++++++++++++++++++++-
     1 file changed, 101 insertions(+), 1 deletion(-)
    
    diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
    index 8d0a6fcc09..7c86ee9bf2 100644
    a b  
    2929#include "libavcodec/raw.h"
    3030#include "objidl.h"
    3131#include "shlwapi.h"
     32#include "dxva.h"
    3233
    3334
    3435static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
    static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)  
    5455    return avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), biCompression); // all others
    5556}
    5657
     58static enum AVColorRange dshow_color_range(DXVA_ExtendedFormat* fmt_info)
     59{
     60    switch (fmt_info->NominalRange)
     61    {
     62    case DXVA_NominalRange_Unknown:
     63        return AVCOL_RANGE_UNSPECIFIED;
     64    case DXVA_NominalRange_Normal:  // equal to DXVA_NominalRange_0_255
     65        return AVCOL_RANGE_JPEG;
     66    case DXVA_NominalRange_Wide:    // equal to DXVA_NominalRange_16_235
     67        return AVCOL_RANGE_MPEG;
     68    case DXVA_NominalRange_48_208:
     69        // not an ffmpeg color range
     70        return AVCOL_RANGE_UNSPECIFIED;
     71
     72    default:
     73        return DXVA_NominalRange_Unknown;
     74    }
     75}
     76
     77static enum AVColorPrimaries dshow_color_primaries(DXVA_ExtendedFormat* fmt_info)
     78{
     79    switch (fmt_info->VideoPrimaries)
     80    {
     81    case DXVA_VideoPrimaries_Unknown:
     82        return AVCOL_PRI_UNSPECIFIED;
     83    case DXVA_VideoPrimaries_reserved:
     84        return AVCOL_PRI_RESERVED;
     85    case DXVA_VideoPrimaries_BT709:
     86        return AVCOL_PRI_BT709;
     87    case DXVA_VideoPrimaries_BT470_2_SysM:
     88        return AVCOL_PRI_BT470M;
     89    case DXVA_VideoPrimaries_BT470_2_SysBG:
     90        return AVCOL_PRI_BT470BG;
     91    case DXVA_VideoPrimaries_SMPTE170M:
     92    case DXVA_VideoPrimaries_SMPTE_C:
     93        return AVCOL_PRI_SMPTE170M;
     94    case DXVA_VideoPrimaries_SMPTE240M:
     95        return AVCOL_PRI_SMPTE240M;
     96    case DXVA_VideoPrimaries_EBU3213:
     97        // this is PAL
     98        return AVCOL_PRI_BT470BG;
     99
     100    default:
     101        return AVCOL_PRI_UNSPECIFIED;
     102    }
     103}
     104
     105static enum AVColorTransferCharacteristic dshow_color_trc(DXVA_ExtendedFormat* fmt_info)
     106{
     107    switch (fmt_info->VideoTransferFunction)
     108    {
     109    case DXVA_VideoTransFunc_Unknown:
     110        return AVCOL_TRC_UNSPECIFIED;
     111    case DXVA_VideoTransFunc_10:
     112        return AVCOL_TRC_LINEAR;
     113    case DXVA_VideoTransFunc_18:
     114        // not an ffmpeg transfer characteristic
     115        return AVCOL_TRC_UNSPECIFIED;
     116    case DXVA_VideoTransFunc_20:
     117        // not an ffmpeg transfer characteristic
     118        return AVCOL_TRC_UNSPECIFIED;
     119    case DXVA_VideoTransFunc_22:
     120        return AVCOL_TRC_GAMMA22;
     121    case DXVA_VideoTransFunc_22_709:
     122        return AVCOL_TRC_BT709;
     123    case DXVA_VideoTransFunc_22_240M:
     124        return AVCOL_TRC_SMPTE240M;
     125    case DXVA_VideoTransFunc_22_8bit_sRGB:
     126        return AVCOL_TRC_IEC61966_2_1;
     127    case DXVA_VideoTransFunc_28:
     128        return AVCOL_TRC_GAMMA28;
     129
     130    default:
     131        return AVCOL_TRC_UNSPECIFIED;
     132    }
     133}
     134
    57135static int
    58136dshow_read_close(AVFormatContext *s)
    59137{
    dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,  
    350428            VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
    351429            BITMAPINFOHEADER *bih;
    352430            int64_t *fr;
     431            DXVA_ExtendedFormat *extended_format_info = NULL;
    353432            const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), NULL };
    354433#if DSHOWDEBUG
    355434            ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
    dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,  
    362441                VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
    363442                fr = &v->AvgTimePerFrame;
    364443                bih = &v->bmiHeader;
     444                if (v->dwControlFlags & AMCONTROL_COLORINFO_PRESENT)
     445                    extended_format_info = (DXVA_ExtendedFormat*)&v->dwControlFlags;
    365446            } else {
    366447                goto next;
    367448            }
    dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,  
    378459                } else {
    379460                    av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
    380461                }
    381                 av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
     462                av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g",
    382463                       vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
    383464                       1e7 / vcaps->MaxFrameInterval,
    384465                       vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
    385466                       1e7 / vcaps->MinFrameInterval);
     467                if (extended_format_info) {
     468                    enum AVColorRange col_range = dshow_color_range(extended_format_info);
     469                    // TOOD: color space
     470                    enum AVColorPrimaries col_prim = dshow_color_primaries(extended_format_info);
     471                    enum AVColorTransferCharacteristic col_trc = dshow_color_trc(extended_format_info);
     472                    if (col_range != AVCOL_RANGE_UNSPECIFIED || col_prim != AVCOL_PRI_UNSPECIFIED || col_trc != AVCOL_TRC_UNSPECIFIED) {
     473                        const char* range = av_color_range_name(col_range);
     474                        // TODO: color space here
     475                        const char* prim = av_color_primaries_name(col_prim);
     476                        const char* trc = av_color_transfer_name(col_trc);
     477                        av_log(avctx, AV_LOG_INFO, " (%s, %s/%s)",
     478                            range ? range : "unknown",
     479                            // TODO: color space here
     480                            prim ? prim : "unknown",
     481                            trc ? trc : "unknown");
     482                    }
     483                }
     484               
     485                av_log(avctx, AV_LOG_INFO, "\n");
    386486                continue;
    387487            }
    388488            if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {