| | 58 | static 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 | // values from MediaFoundation SDK (mfobjects.h) |
| | 73 | case 4: // MFNominalRange_64_127 |
| | 74 | // not an ffmpeg color range |
| | 75 | return AVCOL_RANGE_UNSPECIFIED; |
| | 76 | |
| | 77 | default: |
| | 78 | return DXVA_NominalRange_Unknown; |
| | 79 | } |
| | 80 | } |
| | 81 | |
| | 82 | static enum AVColorSpace dshow_color_space(DXVA_ExtendedFormat* fmt_info) |
| | 83 | { |
| | 84 | enum AVColorSpace ret = AVCOL_SPC_UNSPECIFIED; |
| | 85 | |
| | 86 | switch (fmt_info->VideoTransferMatrix) |
| | 87 | { |
| | 88 | case DXVA_VideoTransferMatrix_BT709: |
| | 89 | ret = AVCOL_SPC_BT709; |
| | 90 | break; |
| | 91 | case DXVA_VideoTransferMatrix_BT601: |
| | 92 | ret = AVCOL_SPC_BT470BG; |
| | 93 | break; |
| | 94 | case DXVA_VideoTransferMatrix_SMPTE240M: |
| | 95 | ret = AVCOL_SPC_SMPTE240M; |
| | 96 | break; |
| | 97 | |
| | 98 | // values from MediaFoundation SDK (mfobjects.h) |
| | 99 | case 4: // MFVideoTransferMatrix_BT2020_10 |
| | 100 | case 5: // MFVideoTransferMatrix_BT2020_12 |
| | 101 | if (fmt_info->VideoTransferFunction==12) // MFVideoTransFunc_2020_const |
| | 102 | ret = AVCOL_SPC_BT2020_CL; |
| | 103 | else |
| | 104 | ret = AVCOL_SPC_BT2020_NCL; |
| | 105 | break; |
| | 106 | } |
| | 107 | |
| | 108 | if (ret == AVCOL_SPC_UNSPECIFIED) |
| | 109 | { |
| | 110 | // if color space not yet known, fall back to using primaries to guess color space |
| | 111 | switch (fmt_info->VideoPrimaries) |
| | 112 | { |
| | 113 | case DXVA_VideoPrimaries_BT709: |
| | 114 | ret = AVCOL_SPC_BT709; |
| | 115 | break; |
| | 116 | case DXVA_VideoPrimaries_BT470_2_SysM: |
| | 117 | ret = AVCOL_SPC_FCC; |
| | 118 | break; |
| | 119 | case DXVA_VideoPrimaries_BT470_2_SysBG: |
| | 120 | case DXVA_VideoPrimaries_EBU3213: // this is PAL |
| | 121 | ret = AVCOL_SPC_BT470BG; |
| | 122 | break; |
| | 123 | case DXVA_VideoPrimaries_SMPTE170M: |
| | 124 | case DXVA_VideoPrimaries_SMPTE_C: |
| | 125 | ret = AVCOL_SPC_SMPTE170M; |
| | 126 | break; |
| | 127 | case DXVA_VideoPrimaries_SMPTE240M: |
| | 128 | ret = AVCOL_SPC_SMPTE240M; |
| | 129 | break; |
| | 130 | } |
| | 131 | } |
| | 132 | |
| | 133 | return ret; |
| | 134 | } |
| | 135 | |
| | 136 | static enum AVColorPrimaries dshow_color_primaries(DXVA_ExtendedFormat* fmt_info) |
| | 137 | { |
| | 138 | switch (fmt_info->VideoPrimaries) |
| | 139 | { |
| | 140 | case DXVA_VideoPrimaries_Unknown: |
| | 141 | return AVCOL_PRI_UNSPECIFIED; |
| | 142 | case DXVA_VideoPrimaries_reserved: |
| | 143 | return AVCOL_PRI_RESERVED; |
| | 144 | case DXVA_VideoPrimaries_BT709: |
| | 145 | return AVCOL_PRI_BT709; |
| | 146 | case DXVA_VideoPrimaries_BT470_2_SysM: |
| | 147 | return AVCOL_PRI_BT470M; |
| | 148 | case DXVA_VideoPrimaries_BT470_2_SysBG: |
| | 149 | case DXVA_VideoPrimaries_EBU3213: // this is PAL |
| | 150 | return AVCOL_PRI_BT470BG; |
| | 151 | case DXVA_VideoPrimaries_SMPTE170M: |
| | 152 | case DXVA_VideoPrimaries_SMPTE_C: |
| | 153 | return AVCOL_PRI_SMPTE170M; |
| | 154 | case DXVA_VideoPrimaries_SMPTE240M: |
| | 155 | return AVCOL_PRI_SMPTE240M; |
| | 156 | |
| | 157 | // values from MediaFoundation SDK (mfobjects.h) |
| | 158 | case 9: // MFVideoPrimaries_BT2020 |
| | 159 | return AVCOL_PRI_BT2020; |
| | 160 | case 10: // MFVideoPrimaries_XYZ |
| | 161 | return AVCOL_PRI_SMPTE428; |
| | 162 | case 11: // MFVideoPrimaries_DCI_P3 |
| | 163 | return AVCOL_PRI_SMPTE431; |
| | 164 | case 12: // MFVideoPrimaries_ACES (Academy Color Encoding System) |
| | 165 | // not an FFmpeg color primary |
| | 166 | return AVCOL_PRI_UNSPECIFIED; |
| | 167 | |
| | 168 | default: |
| | 169 | return AVCOL_PRI_UNSPECIFIED; |
| | 170 | } |
| | 171 | } |
| | 172 | |
| | 173 | static enum AVColorTransferCharacteristic dshow_color_trc(DXVA_ExtendedFormat* fmt_info) |
| | 174 | { |
| | 175 | switch (fmt_info->VideoTransferFunction) |
| | 176 | { |
| | 177 | case DXVA_VideoTransFunc_Unknown: |
| | 178 | return AVCOL_TRC_UNSPECIFIED; |
| | 179 | case DXVA_VideoTransFunc_10: |
| | 180 | return AVCOL_TRC_LINEAR; |
| | 181 | case DXVA_VideoTransFunc_18: |
| | 182 | // not an FFmpeg transfer characteristic |
| | 183 | return AVCOL_TRC_UNSPECIFIED; |
| | 184 | case DXVA_VideoTransFunc_20: |
| | 185 | // not an FFmpeg transfer characteristic |
| | 186 | return AVCOL_TRC_UNSPECIFIED; |
| | 187 | case DXVA_VideoTransFunc_22: |
| | 188 | return AVCOL_TRC_GAMMA22; |
| | 189 | case DXVA_VideoTransFunc_22_709: |
| | 190 | return AVCOL_TRC_BT709; |
| | 191 | case DXVA_VideoTransFunc_22_240M: |
| | 192 | return AVCOL_TRC_SMPTE240M; |
| | 193 | case DXVA_VideoTransFunc_22_8bit_sRGB: |
| | 194 | return AVCOL_TRC_IEC61966_2_1; |
| | 195 | case DXVA_VideoTransFunc_28: |
| | 196 | return AVCOL_TRC_GAMMA28; |
| | 197 | |
| | 198 | // values from MediaFoundation SDK (mfobjects.h) |
| | 199 | case 9: // MFVideoTransFunc_Log_100 |
| | 200 | return AVCOL_TRC_LOG; |
| | 201 | case 10: // MFVideoTransFunc_Log_316 |
| | 202 | return AVCOL_TRC_LOG_SQRT; |
| | 203 | case 11: // MFVideoTransFunc_709_sym |
| | 204 | // not an FFmpeg transfer characteristic |
| | 205 | return AVCOL_TRC_UNSPECIFIED; |
| | 206 | case 12: // MFVideoTransFunc_2020_const |
| | 207 | case 13: // MFVideoTransFunc_2020 |
| | 208 | if (fmt_info->VideoTransferMatrix==5) // MFVideoTransferMatrix_BT2020_12 |
| | 209 | return AVCOL_TRC_BT2020_12; |
| | 210 | else |
| | 211 | return AVCOL_TRC_BT2020_10; |
| | 212 | case 14: // MFVideoTransFunc_26 |
| | 213 | // not an FFmpeg transfer characteristic |
| | 214 | return AVCOL_TRC_UNSPECIFIED; |
| | 215 | case 15: // MFVideoTransFunc_2084 |
| | 216 | return AVCOL_TRC_SMPTEST2084; |
| | 217 | case 16: // MFVideoTransFunc_HLG |
| | 218 | return AVCOL_TRC_ARIB_STD_B67; |
| | 219 | case 17: // MFVideoTransFunc_10_rel |
| | 220 | // not an FFmpeg transfer characteristic? Undocumented also by MS |
| | 221 | return AVCOL_TRC_UNSPECIFIED; |
| | 222 | |
| | 223 | default: |
| | 224 | return AVCOL_TRC_UNSPECIFIED; |
| | 225 | } |
| | 226 | } |
| | 227 | |
| | 228 | static enum AVChromaLocation dshow_chroma_loc(DXVA_ExtendedFormat* fmt_info) |
| | 229 | { |
| | 230 | if (fmt_info->VideoChromaSubsampling == DXVA_VideoChromaSubsampling_Cosited) // that is: (DXVA_VideoChromaSubsampling_Horizontally_Cosited | DXVA_VideoChromaSubsampling_Vertically_Cosited | DXVA_VideoChromaSubsampling_Vertically_AlignedChromaPlanes) |
| | 231 | return AVCHROMA_LOC_TOPLEFT; |
| | 232 | else if (fmt_info->VideoChromaSubsampling == DXVA_VideoChromaSubsampling_MPEG1) // that is: DXVA_VideoChromaSubsampling_Vertically_AlignedChromaPlanes |
| | 233 | return AVCHROMA_LOC_CENTER; |
| | 234 | else if (fmt_info->VideoChromaSubsampling == DXVA_VideoChromaSubsampling_MPEG2) // that is: (DXVA_VideoChromaSubsampling_Horizontally_Cosited | DXVA_VideoChromaSubsampling_Vertically_AlignedChromaPlanes) |
| | 235 | return AVCHROMA_LOC_LEFT; |
| | 236 | else if (fmt_info->VideoChromaSubsampling == DXVA_VideoChromaSubsampling_DV_PAL)// that is: (DXVA_VideoChromaSubsampling_Horizontally_Cosited | DXVA_VideoChromaSubsampling_Vertically_Cosited) |
| | 237 | return AVCHROMA_LOC_TOPLEFT; |
| | 238 | else |
| | 239 | // unknown |
| | 240 | return AVCHROMA_LOC_UNSPECIFIED; |
| | 241 | } |
| | 242 | |
| | 575 | if (extended_format_info) { |
| | 576 | enum AVColorRange col_range = dshow_color_range(extended_format_info); |
| | 577 | enum AVColorSpace col_space = dshow_color_space(extended_format_info); |
| | 578 | enum AVColorPrimaries col_prim = dshow_color_primaries(extended_format_info); |
| | 579 | enum AVColorTransferCharacteristic col_trc = dshow_color_trc(extended_format_info); |
| | 580 | enum AVChromaLocation chroma_loc = dshow_chroma_loc(extended_format_info); |
| | 581 | if (col_range != AVCOL_RANGE_UNSPECIFIED || col_space != AVCOL_SPC_UNSPECIFIED || col_prim != AVCOL_PRI_UNSPECIFIED || col_trc != AVCOL_TRC_UNSPECIFIED) { |
| | 582 | const char* range = av_color_range_name(col_range); |
| | 583 | const char* space = av_color_space_name(col_space); |
| | 584 | const char* prim = av_color_primaries_name(col_prim); |
| | 585 | const char* trc = av_color_transfer_name(col_trc); |
| | 586 | av_log(avctx, AV_LOG_INFO, " (%s, %s/%s/%s", |
| | 587 | range ? range : "unknown", |
| | 588 | space ? space : "unknown", |
| | 589 | prim ? prim : "unknown", |
| | 590 | trc ? trc : "unknown"); |
| | 591 | if (chroma_loc != AVCHROMA_LOC_UNSPECIFIED) { |
| | 592 | const char* chroma = av_chroma_location_name(chroma_loc); |
| | 593 | av_log(avctx, AV_LOG_INFO, ", %s", chroma ? chroma : "unknown"); |
| | 594 | } |
| | 595 | av_log(avctx, AV_LOG_INFO, ")"); |
| | 596 | } |
| | 597 | else if (chroma_loc != AVCHROMA_LOC_UNSPECIFIED) { |
| | 598 | const char* chroma = av_chroma_location_name(chroma_loc); |
| | 599 | av_log(avctx, AV_LOG_INFO, "(%s)", chroma ? chroma : "unknown"); |
| | 600 | } |
| | 601 | } |
| | 602 | |
| | 603 | av_log(avctx, AV_LOG_INFO, "\n"); |