1/* 2 * Directshow capture interface 3 * Copyright (c) 2010 Ramiro Polla 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "dshow_capture.h" 23 24long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src) 25{ 26 uint8_t *pbFormat = NULL; 27 28 if (src->cbFormat) { 29 pbFormat = CoTaskMemAlloc(src->cbFormat); 30 if (!pbFormat) 31 return E_OUTOFMEMORY; 32 memcpy(pbFormat, src->pbFormat, src->cbFormat); 33 } 34 35 *dst = *src; 36 dst->pUnk = NULL; 37 dst->pbFormat = pbFormat; 38 39 return S_OK; 40} 41 42void ff_printGUID(const GUID *g) 43{ 44#if DSHOWDEBUG 45 const uint32_t *d = (const uint32_t *) &g->Data1; 46 const uint16_t *w = (const uint16_t *) &g->Data2; 47 const uint8_t *c = (const uint8_t *) &g->Data4; 48 49 dshowdebug("0x%08x 0x%04x 0x%04x %02x%02x%02x%02x%02x%02x%02x%02x", 50 d[0], w[0], w[1], 51 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]); 52#endif 53} 54 55static const char *dshow_context_to_name(void *ptr) 56{ 57 return "dshow"; 58} 59static const AVClass ff_dshow_context_class = { "DirectShow", dshow_context_to_name }; 60const AVClass *ff_dshow_context_class_ptr = &ff_dshow_context_class; 61 62#define dstruct(pctx, sname, var, type) \ 63 dshowdebug(" "#var":\t%"type"\n", sname->var) 64 65#if DSHOWDEBUG 66static void dump_bih(void *s, BITMAPINFOHEADER *bih) 67{ 68 dshowdebug(" BITMAPINFOHEADER\n"); 69 dstruct(s, bih, biSize, "lu"); 70 dstruct(s, bih, biWidth, "ld"); 71 dstruct(s, bih, biHeight, "ld"); 72 dstruct(s, bih, biPlanes, "d"); 73 dstruct(s, bih, biBitCount, "d"); 74 dstruct(s, bih, biCompression, "lu"); 75 dshowdebug(" biCompression:\t\"%.4s\"\n", 76 (char*) &bih->biCompression); 77 dstruct(s, bih, biSizeImage, "lu"); 78 dstruct(s, bih, biXPelsPerMeter, "lu"); 79 dstruct(s, bih, biYPelsPerMeter, "lu"); 80 dstruct(s, bih, biClrUsed, "lu"); 81 dstruct(s, bih, biClrImportant, "lu"); 82} 83#endif 84 85void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps) 86{ 87#if DSHOWDEBUG 88 dshowdebug(" VIDEO_STREAM_CONFIG_CAPS\n"); 89 dshowdebug(" guid\t"); 90 ff_printGUID(&caps->guid); 91 dshowdebug("\n"); 92 dshowdebug(" VideoStandard\t%lu\n", caps->VideoStandard); 93 dshowdebug(" InputSize %ld\t%ld\n", caps->InputSize.cx, caps->InputSize.cy); 94 dshowdebug(" MinCroppingSize %ld\t%ld\n", caps->MinCroppingSize.cx, caps->MinCroppingSize.cy); 95 dshowdebug(" MaxCroppingSize %ld\t%ld\n", caps->MaxCroppingSize.cx, caps->MaxCroppingSize.cy); 96 dshowdebug(" CropGranularityX\t%d\n", caps->CropGranularityX); 97 dshowdebug(" CropGranularityY\t%d\n", caps->CropGranularityY); 98 dshowdebug(" CropAlignX\t%d\n", caps->CropAlignX); 99 dshowdebug(" CropAlignY\t%d\n", caps->CropAlignY); 100 dshowdebug(" MinOutputSize %ld\t%ld\n", caps->MinOutputSize.cx, caps->MinOutputSize.cy); 101 dshowdebug(" MaxOutputSize %ld\t%ld\n", caps->MaxOutputSize.cx, caps->MaxOutputSize.cy); 102 dshowdebug(" OutputGranularityX\t%d\n", caps->OutputGranularityX); 103 dshowdebug(" OutputGranularityY\t%d\n", caps->OutputGranularityY); 104 dshowdebug(" StretchTapsX\t%d\n", caps->StretchTapsX); 105 dshowdebug(" StretchTapsY\t%d\n", caps->StretchTapsY); 106 dshowdebug(" ShrinkTapsX\t%d\n", caps->ShrinkTapsX); 107 dshowdebug(" ShrinkTapsY\t%d\n", caps->ShrinkTapsY); 108 dshowdebug(" MinFrameInterval\t%"PRId64"\n", caps->MinFrameInterval); 109 dshowdebug(" MaxFrameInterval\t%"PRId64"\n", caps->MaxFrameInterval); 110 dshowdebug(" MinBitsPerSecond\t%ld\n", caps->MinBitsPerSecond); 111 dshowdebug(" MaxBitsPerSecond\t%ld\n", caps->MaxBitsPerSecond); 112#endif 113} 114 115void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps) 116{ 117#if DSHOWDEBUG 118 dshowdebug(" AUDIO_STREAM_CONFIG_CAPS\n"); 119 dshowdebug(" guid\t"); 120 ff_printGUID(&caps->guid); 121 dshowdebug("\n"); 122 dshowdebug(" MinimumChannels\t%lu\n", caps->MinimumChannels); 123 dshowdebug(" MaximumChannels\t%lu\n", caps->MaximumChannels); 124 dshowdebug(" ChannelsGranularity\t%lu\n", caps->ChannelsGranularity); 125 dshowdebug(" MinimumBitsPerSample\t%lu\n", caps->MinimumBitsPerSample); 126 dshowdebug(" MaximumBitsPerSample\t%lu\n", caps->MaximumBitsPerSample); 127 dshowdebug(" BitsPerSampleGranularity\t%lu\n", caps->BitsPerSampleGranularity); 128 dshowdebug(" MinimumSampleFrequency\t%lu\n", caps->MinimumSampleFrequency); 129 dshowdebug(" MaximumSampleFrequency\t%lu\n", caps->MaximumSampleFrequency); 130 dshowdebug(" SampleFrequencyGranularity\t%lu\n", caps->SampleFrequencyGranularity); 131#endif 132} 133 134void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type) 135{ 136#if DSHOWDEBUG 137 dshowdebug(" majortype\t"); 138 ff_printGUID(&type->majortype); 139 dshowdebug("\n"); 140 dshowdebug(" subtype\t"); 141 ff_printGUID(&type->subtype); 142 dshowdebug("\n"); 143 dshowdebug(" bFixedSizeSamples\t%d\n", type->bFixedSizeSamples); 144 dshowdebug(" bTemporalCompression\t%d\n", type->bTemporalCompression); 145 dshowdebug(" lSampleSize\t%lu\n", type->lSampleSize); 146 dshowdebug(" formattype\t"); 147 ff_printGUID(&type->formattype); 148 dshowdebug("\n"); 149 dshowdebug(" pUnk\t%p\n", type->pUnk); 150 dshowdebug(" cbFormat\t%lu\n", type->cbFormat); 151 dshowdebug(" pbFormat\t%p\n", type->pbFormat); 152 153 if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) { 154 VIDEOINFOHEADER *v = (void *) type->pbFormat; 155 dshowdebug(" rcSource: left %ld top %ld right %ld bottom %ld\n", 156 v->rcSource.left, v->rcSource.top, v->rcSource.right, v->rcSource.bottom); 157 dshowdebug(" rcTarget: left %ld top %ld right %ld bottom %ld\n", 158 v->rcTarget.left, v->rcTarget.top, v->rcTarget.right, v->rcTarget.bottom); 159 dshowdebug(" dwBitRate: %lu\n", v->dwBitRate); 160 dshowdebug(" dwBitErrorRate: %lu\n", v->dwBitErrorRate); 161 dshowdebug(" AvgTimePerFrame: %"PRId64"\n", v->AvgTimePerFrame); 162 dump_bih(NULL, &v->bmiHeader); 163 } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) { 164 VIDEOINFOHEADER2 *v = (void *) type->pbFormat; 165 dshowdebug(" rcSource: left %ld top %ld right %ld bottom %ld\n", 166 v->rcSource.left, v->rcSource.top, v->rcSource.right, v->rcSource.bottom); 167 dshowdebug(" rcTarget: left %ld top %ld right %ld bottom %ld\n", 168 v->rcTarget.left, v->rcTarget.top, v->rcTarget.right, v->rcTarget.bottom); 169 dshowdebug(" dwBitRate: %lu\n", v->dwBitRate); 170 dshowdebug(" dwBitErrorRate: %lu\n", v->dwBitErrorRate); 171 dshowdebug(" AvgTimePerFrame: %"PRId64"\n", v->AvgTimePerFrame); 172 dshowdebug(" dwInterlaceFlags: %lu\n", v->dwInterlaceFlags); 173 dshowdebug(" dwCopyProtectFlags: %lu\n", v->dwCopyProtectFlags); 174 dshowdebug(" dwPictAspectRatioX: %lu\n", v->dwPictAspectRatioX); 175 dshowdebug(" dwPictAspectRatioY: %lu\n", v->dwPictAspectRatioY); 176// dshowdebug(" dwReserved1: %lu\n", v->u.dwReserved1); /* mingw-w64 is buggy and doesn't name unnamed unions */ 177 dshowdebug(" dwReserved2: %lu\n", v->dwReserved2); 178 dump_bih(NULL, &v->bmiHeader); 179 } else if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) { 180 WAVEFORMATEX *fx = (void *) type->pbFormat; 181 dshowdebug(" wFormatTag: %u\n", fx->wFormatTag); 182 dshowdebug(" nChannels: %u\n", fx->nChannels); 183 dshowdebug(" nSamplesPerSec: %lu\n", fx->nSamplesPerSec); 184 dshowdebug(" nAvgBytesPerSec: %lu\n", fx->nAvgBytesPerSec); 185 dshowdebug(" nBlockAlign: %u\n", fx->nBlockAlign); 186 dshowdebug(" wBitsPerSample: %u\n", fx->wBitsPerSample); 187 dshowdebug(" cbSize: %u\n", fx->cbSize); 188 } 189#endif 190} 191