/* * Copyright (C) 2023 Lain Bailey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA */ #include "dshow-formats.hpp" #include "dshow-media-type.hpp" #ifndef __MINGW32__ const GUID MEDIASUBTYPE_RAW_AAC1 = {0x000000FF, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_I420 = {0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_DVM = {0x00002000, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; #endif const GUID MEDIASUBTYPE_Y800 = {0x30303859, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; #ifdef ENABLE_HEVC const GUID MEDIASUBTYPE_HEVC = {0x43564548, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; #endif namespace DShow { DWORD VFormatToFourCC(VideoFormat format) { switch (format) { /* raw formats */ case VideoFormat::ARGB: return MAKEFOURCC('A', 'R', 'G', 'B'); case VideoFormat::XRGB: return MAKEFOURCC('R', 'G', 'B', '4'); /* planar YUV formats */ case VideoFormat::I420: return MAKEFOURCC('I', '4', '2', '0'); case VideoFormat::NV12: return MAKEFOURCC('N', 'V', '1', '2'); case VideoFormat::YV12: return MAKEFOURCC('Y', 'V', '1', '2'); case VideoFormat::Y800: return MAKEFOURCC('Y', '8', '0', '0'); case VideoFormat::P010: return MAKEFOURCC('P', '0', '1', '0'); /* packed YUV formats */ case VideoFormat::YVYU: return MAKEFOURCC('Y', 'V', 'Y', 'U'); case VideoFormat::YUY2: return MAKEFOURCC('Y', 'U', 'Y', '2'); case VideoFormat::UYVY: return MAKEFOURCC('U', 'Y', 'V', 'Y'); case VideoFormat::HDYC: return MAKEFOURCC('H', 'D', 'Y', 'C'); /* encoded formats */ case VideoFormat::MJPEG: return MAKEFOURCC('M', 'J', 'P', 'G'); case VideoFormat::H264: return MAKEFOURCC('H', '2', '6', '4'); #ifdef ENABLE_HEVC case VideoFormat::HEVC: return MAKEFOURCC('H', 'E', 'V', 'C'); #endif default: return 0; } } GUID VFormatToSubType(VideoFormat format) { switch (format) { /* raw formats */ case VideoFormat::ARGB: return MEDIASUBTYPE_ARGB32; case VideoFormat::XRGB: return MEDIASUBTYPE_RGB32; /* planar YUV formats */ case VideoFormat::I420: return MEDIASUBTYPE_I420; case VideoFormat::NV12: return MEDIASUBTYPE_NV12; case VideoFormat::YV12: return MEDIASUBTYPE_YV12; case VideoFormat::Y800: return MEDIASUBTYPE_Y800; case VideoFormat::P010: return MEDIASUBTYPE_P010; /* packed YUV formats */ case VideoFormat::YVYU: return MEDIASUBTYPE_YVYU; case VideoFormat::YUY2: return MEDIASUBTYPE_YUY2; case VideoFormat::UYVY: return MEDIASUBTYPE_UYVY; /* encoded formats */ case VideoFormat::MJPEG: return MEDIASUBTYPE_MJPG; case VideoFormat::H264: return MEDIASUBTYPE_H264; #ifdef ENABLE_HEVC case VideoFormat::HEVC: return MEDIASUBTYPE_HEVC; #endif default: return GUID(); } } WORD VFormatBits(VideoFormat format) { switch (format) { /* raw formats */ case VideoFormat::ARGB: case VideoFormat::XRGB: return 32; /* planar YUV formats */ case VideoFormat::I420: case VideoFormat::NV12: case VideoFormat::YV12: return 12; case VideoFormat::Y800: return 8; /* packed YUV formats */ case VideoFormat::YVYU: case VideoFormat::YUY2: case VideoFormat::UYVY: return 16; default: return 0; } } WORD VFormatPlanes(VideoFormat format) { switch (format) { /* raw formats */ case VideoFormat::ARGB: case VideoFormat::XRGB: return 1; /* planar YUV formats */ case VideoFormat::I420: return 3; case VideoFormat::NV12: case VideoFormat::YV12: return 2; case VideoFormat::Y800: return 1; /* packed YUV formats */ case VideoFormat::YVYU: case VideoFormat::YUY2: case VideoFormat::UYVY: return 1; default: return 0; } } static bool GetFourCCVFormat(DWORD fourCC, VideoFormat &format) { switch (fourCC) { /* raw formats */ case MAKEFOURCC('R', 'G', 'B', '2'): format = VideoFormat::XRGB; break; case MAKEFOURCC('R', 'G', 'B', '4'): format = VideoFormat::XRGB; break; case MAKEFOURCC('A', 'R', 'G', 'B'): format = VideoFormat::ARGB; break; /* planar YUV formats */ case MAKEFOURCC('I', '4', '2', '0'): case MAKEFOURCC('I', 'Y', 'U', 'V'): format = VideoFormat::I420; break; case MAKEFOURCC('Y', 'V', '1', '2'): format = VideoFormat::YV12; break; case MAKEFOURCC('N', 'V', '1', '2'): format = VideoFormat::NV12; break; case MAKEFOURCC('Y', '8', '0', '0'): format = VideoFormat::Y800; break; case MAKEFOURCC('P', '0', '1', '0'): format = VideoFormat::P010; break; /* packed YUV formats */ case MAKEFOURCC('Y', 'V', 'Y', 'U'): format = VideoFormat::YVYU; break; case MAKEFOURCC('Y', 'U', 'Y', '2'): format = VideoFormat::YUY2; break; case MAKEFOURCC('U', 'Y', 'V', 'Y'): format = VideoFormat::UYVY; break; case MAKEFOURCC('H', 'D', 'Y', 'C'): format = VideoFormat::HDYC; break; /* compressed formats */ case MAKEFOURCC('H', '2', '6', '4'): format = VideoFormat::H264; break; #ifdef ENABLE_HEVC case MAKEFOURCC('H', 'E', 'V', 'C'): format = VideoFormat::HEVC; break; #endif /* compressed formats that can automatically create intermediary * filters for decompression */ case MAKEFOURCC('M', 'J', 'P', 'G'): format = VideoFormat::MJPEG; break; default: return false; } return true; } bool GetMediaTypeVFormat(const AM_MEDIA_TYPE &mt, VideoFormat &format) { if (mt.majortype != MEDIATYPE_Video) return false; const BITMAPINFOHEADER *bmih = GetBitmapInfoHeader(mt); format = VideoFormat::Unknown; /* raw formats */ if (mt.subtype == MEDIASUBTYPE_RGB24) format = VideoFormat::XRGB; else if (mt.subtype == MEDIASUBTYPE_RGB32) format = VideoFormat::XRGB; else if (mt.subtype == MEDIASUBTYPE_ARGB32) format = VideoFormat::ARGB; /* planar YUV formats */ else if (mt.subtype == MEDIASUBTYPE_I420) format = VideoFormat::I420; else if (mt.subtype == MEDIASUBTYPE_IYUV) format = VideoFormat::I420; else if (mt.subtype == MEDIASUBTYPE_YV12) format = VideoFormat::YV12; else if (mt.subtype == MEDIASUBTYPE_NV12) format = VideoFormat::NV12; else if (mt.subtype == MEDIASUBTYPE_Y800) format = VideoFormat::Y800; else if (mt.subtype == MEDIASUBTYPE_P010) format = VideoFormat::P010; /* packed YUV formats */ else if (mt.subtype == MEDIASUBTYPE_YVYU) format = VideoFormat::YVYU; else if (mt.subtype == MEDIASUBTYPE_YUY2) format = VideoFormat::YUY2; else if (mt.subtype == MEDIASUBTYPE_UYVY) format = VideoFormat::UYVY; /* compressed formats */ else if (mt.subtype == MEDIASUBTYPE_H264) format = VideoFormat::H264; #ifdef ENABLE_HEVC else if (mt.subtype == MEDIASUBTYPE_HEVC) format = VideoFormat::HEVC; #endif /* compressed formats that can automatically create intermediary * filters for decompression */ else if (mt.subtype == MEDIASUBTYPE_MJPG) format = VideoFormat::MJPEG; /* no valid types, check fourcc value instead */ else return bmih ? GetFourCCVFormat(bmih->biCompression, format) : false; return true; } }; /* namespace DShow */