yading@10: /* yading@10: * Directshow capture interface yading@10: * Copyright (c) 2010 Ramiro Polla yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: #include "dshow_capture.h" yading@10: yading@10: long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src) yading@10: { yading@10: uint8_t *pbFormat = NULL; yading@10: yading@10: if (src->cbFormat) { yading@10: pbFormat = CoTaskMemAlloc(src->cbFormat); yading@10: if (!pbFormat) yading@10: return E_OUTOFMEMORY; yading@10: memcpy(pbFormat, src->pbFormat, src->cbFormat); yading@10: } yading@10: yading@10: *dst = *src; yading@10: dst->pUnk = NULL; yading@10: dst->pbFormat = pbFormat; yading@10: yading@10: return S_OK; yading@10: } yading@10: yading@10: void ff_printGUID(const GUID *g) yading@10: { yading@10: #if DSHOWDEBUG yading@10: const uint32_t *d = (const uint32_t *) &g->Data1; yading@10: const uint16_t *w = (const uint16_t *) &g->Data2; yading@10: const uint8_t *c = (const uint8_t *) &g->Data4; yading@10: yading@10: dshowdebug("0x%08x 0x%04x 0x%04x %02x%02x%02x%02x%02x%02x%02x%02x", yading@10: d[0], w[0], w[1], yading@10: c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]); yading@10: #endif yading@10: } yading@10: yading@10: static const char *dshow_context_to_name(void *ptr) yading@10: { yading@10: return "dshow"; yading@10: } yading@10: static const AVClass ff_dshow_context_class = { "DirectShow", dshow_context_to_name }; yading@10: const AVClass *ff_dshow_context_class_ptr = &ff_dshow_context_class; yading@10: yading@10: #define dstruct(pctx, sname, var, type) \ yading@10: dshowdebug(" "#var":\t%"type"\n", sname->var) yading@10: yading@10: #if DSHOWDEBUG yading@10: static void dump_bih(void *s, BITMAPINFOHEADER *bih) yading@10: { yading@10: dshowdebug(" BITMAPINFOHEADER\n"); yading@10: dstruct(s, bih, biSize, "lu"); yading@10: dstruct(s, bih, biWidth, "ld"); yading@10: dstruct(s, bih, biHeight, "ld"); yading@10: dstruct(s, bih, biPlanes, "d"); yading@10: dstruct(s, bih, biBitCount, "d"); yading@10: dstruct(s, bih, biCompression, "lu"); yading@10: dshowdebug(" biCompression:\t\"%.4s\"\n", yading@10: (char*) &bih->biCompression); yading@10: dstruct(s, bih, biSizeImage, "lu"); yading@10: dstruct(s, bih, biXPelsPerMeter, "lu"); yading@10: dstruct(s, bih, biYPelsPerMeter, "lu"); yading@10: dstruct(s, bih, biClrUsed, "lu"); yading@10: dstruct(s, bih, biClrImportant, "lu"); yading@10: } yading@10: #endif yading@10: yading@10: void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps) yading@10: { yading@10: #if DSHOWDEBUG yading@10: dshowdebug(" VIDEO_STREAM_CONFIG_CAPS\n"); yading@10: dshowdebug(" guid\t"); yading@10: ff_printGUID(&caps->guid); yading@10: dshowdebug("\n"); yading@10: dshowdebug(" VideoStandard\t%lu\n", caps->VideoStandard); yading@10: dshowdebug(" InputSize %ld\t%ld\n", caps->InputSize.cx, caps->InputSize.cy); yading@10: dshowdebug(" MinCroppingSize %ld\t%ld\n", caps->MinCroppingSize.cx, caps->MinCroppingSize.cy); yading@10: dshowdebug(" MaxCroppingSize %ld\t%ld\n", caps->MaxCroppingSize.cx, caps->MaxCroppingSize.cy); yading@10: dshowdebug(" CropGranularityX\t%d\n", caps->CropGranularityX); yading@10: dshowdebug(" CropGranularityY\t%d\n", caps->CropGranularityY); yading@10: dshowdebug(" CropAlignX\t%d\n", caps->CropAlignX); yading@10: dshowdebug(" CropAlignY\t%d\n", caps->CropAlignY); yading@10: dshowdebug(" MinOutputSize %ld\t%ld\n", caps->MinOutputSize.cx, caps->MinOutputSize.cy); yading@10: dshowdebug(" MaxOutputSize %ld\t%ld\n", caps->MaxOutputSize.cx, caps->MaxOutputSize.cy); yading@10: dshowdebug(" OutputGranularityX\t%d\n", caps->OutputGranularityX); yading@10: dshowdebug(" OutputGranularityY\t%d\n", caps->OutputGranularityY); yading@10: dshowdebug(" StretchTapsX\t%d\n", caps->StretchTapsX); yading@10: dshowdebug(" StretchTapsY\t%d\n", caps->StretchTapsY); yading@10: dshowdebug(" ShrinkTapsX\t%d\n", caps->ShrinkTapsX); yading@10: dshowdebug(" ShrinkTapsY\t%d\n", caps->ShrinkTapsY); yading@10: dshowdebug(" MinFrameInterval\t%"PRId64"\n", caps->MinFrameInterval); yading@10: dshowdebug(" MaxFrameInterval\t%"PRId64"\n", caps->MaxFrameInterval); yading@10: dshowdebug(" MinBitsPerSecond\t%ld\n", caps->MinBitsPerSecond); yading@10: dshowdebug(" MaxBitsPerSecond\t%ld\n", caps->MaxBitsPerSecond); yading@10: #endif yading@10: } yading@10: yading@10: void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps) yading@10: { yading@10: #if DSHOWDEBUG yading@10: dshowdebug(" AUDIO_STREAM_CONFIG_CAPS\n"); yading@10: dshowdebug(" guid\t"); yading@10: ff_printGUID(&caps->guid); yading@10: dshowdebug("\n"); yading@10: dshowdebug(" MinimumChannels\t%lu\n", caps->MinimumChannels); yading@10: dshowdebug(" MaximumChannels\t%lu\n", caps->MaximumChannels); yading@10: dshowdebug(" ChannelsGranularity\t%lu\n", caps->ChannelsGranularity); yading@10: dshowdebug(" MinimumBitsPerSample\t%lu\n", caps->MinimumBitsPerSample); yading@10: dshowdebug(" MaximumBitsPerSample\t%lu\n", caps->MaximumBitsPerSample); yading@10: dshowdebug(" BitsPerSampleGranularity\t%lu\n", caps->BitsPerSampleGranularity); yading@10: dshowdebug(" MinimumSampleFrequency\t%lu\n", caps->MinimumSampleFrequency); yading@10: dshowdebug(" MaximumSampleFrequency\t%lu\n", caps->MaximumSampleFrequency); yading@10: dshowdebug(" SampleFrequencyGranularity\t%lu\n", caps->SampleFrequencyGranularity); yading@10: #endif yading@10: } yading@10: yading@10: void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type) yading@10: { yading@10: #if DSHOWDEBUG yading@10: dshowdebug(" majortype\t"); yading@10: ff_printGUID(&type->majortype); yading@10: dshowdebug("\n"); yading@10: dshowdebug(" subtype\t"); yading@10: ff_printGUID(&type->subtype); yading@10: dshowdebug("\n"); yading@10: dshowdebug(" bFixedSizeSamples\t%d\n", type->bFixedSizeSamples); yading@10: dshowdebug(" bTemporalCompression\t%d\n", type->bTemporalCompression); yading@10: dshowdebug(" lSampleSize\t%lu\n", type->lSampleSize); yading@10: dshowdebug(" formattype\t"); yading@10: ff_printGUID(&type->formattype); yading@10: dshowdebug("\n"); yading@10: dshowdebug(" pUnk\t%p\n", type->pUnk); yading@10: dshowdebug(" cbFormat\t%lu\n", type->cbFormat); yading@10: dshowdebug(" pbFormat\t%p\n", type->pbFormat); yading@10: yading@10: if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) { yading@10: VIDEOINFOHEADER *v = (void *) type->pbFormat; yading@10: dshowdebug(" rcSource: left %ld top %ld right %ld bottom %ld\n", yading@10: v->rcSource.left, v->rcSource.top, v->rcSource.right, v->rcSource.bottom); yading@10: dshowdebug(" rcTarget: left %ld top %ld right %ld bottom %ld\n", yading@10: v->rcTarget.left, v->rcTarget.top, v->rcTarget.right, v->rcTarget.bottom); yading@10: dshowdebug(" dwBitRate: %lu\n", v->dwBitRate); yading@10: dshowdebug(" dwBitErrorRate: %lu\n", v->dwBitErrorRate); yading@10: dshowdebug(" AvgTimePerFrame: %"PRId64"\n", v->AvgTimePerFrame); yading@10: dump_bih(NULL, &v->bmiHeader); yading@10: } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) { yading@10: VIDEOINFOHEADER2 *v = (void *) type->pbFormat; yading@10: dshowdebug(" rcSource: left %ld top %ld right %ld bottom %ld\n", yading@10: v->rcSource.left, v->rcSource.top, v->rcSource.right, v->rcSource.bottom); yading@10: dshowdebug(" rcTarget: left %ld top %ld right %ld bottom %ld\n", yading@10: v->rcTarget.left, v->rcTarget.top, v->rcTarget.right, v->rcTarget.bottom); yading@10: dshowdebug(" dwBitRate: %lu\n", v->dwBitRate); yading@10: dshowdebug(" dwBitErrorRate: %lu\n", v->dwBitErrorRate); yading@10: dshowdebug(" AvgTimePerFrame: %"PRId64"\n", v->AvgTimePerFrame); yading@10: dshowdebug(" dwInterlaceFlags: %lu\n", v->dwInterlaceFlags); yading@10: dshowdebug(" dwCopyProtectFlags: %lu\n", v->dwCopyProtectFlags); yading@10: dshowdebug(" dwPictAspectRatioX: %lu\n", v->dwPictAspectRatioX); yading@10: dshowdebug(" dwPictAspectRatioY: %lu\n", v->dwPictAspectRatioY); yading@10: // dshowdebug(" dwReserved1: %lu\n", v->u.dwReserved1); /* mingw-w64 is buggy and doesn't name unnamed unions */ yading@10: dshowdebug(" dwReserved2: %lu\n", v->dwReserved2); yading@10: dump_bih(NULL, &v->bmiHeader); yading@10: } else if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) { yading@10: WAVEFORMATEX *fx = (void *) type->pbFormat; yading@10: dshowdebug(" wFormatTag: %u\n", fx->wFormatTag); yading@10: dshowdebug(" nChannels: %u\n", fx->nChannels); yading@10: dshowdebug(" nSamplesPerSec: %lu\n", fx->nSamplesPerSec); yading@10: dshowdebug(" nAvgBytesPerSec: %lu\n", fx->nAvgBytesPerSec); yading@10: dshowdebug(" nBlockAlign: %u\n", fx->nBlockAlign); yading@10: dshowdebug(" wBitsPerSample: %u\n", fx->wBitsPerSample); yading@10: dshowdebug(" cbSize: %u\n", fx->cbSize); yading@10: } yading@10: #endif yading@10: }