22 #include "libavutil/parseutils.h"
23 #include "libavutil/pixdesc.h"
24 #include "libavutil/opt.h"
77 switch(biCompression) {
105 IMediaControl_Stop(ctx->
control);
106 IMediaControl_Release(ctx->
control);
115 r = IGraphBuilder_EnumFilters(ctx->
graph, &fenum);
118 IEnumFilters_Reset(fenum);
119 while (IEnumFilters_Next(fenum, 1, &f, NULL) ==
S_OK) {
120 if (IGraphBuilder_RemoveFilter(ctx->
graph, f) ==
S_OK)
121 IEnumFilters_Reset(fenum);
123 IBaseFilter_Release(f);
125 IEnumFilters_Release(fenum);
127 IGraphBuilder_Release(ctx->
graph);
154 CloseHandle(ctx->
mutex);
156 CloseHandle(ctx->
event[0]);
158 CloseHandle(ctx->
event[1]);
176 int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
179 WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
186 static const uint8_t dropscore[] = {62, 75, 87, 100};
192 "real-time buffer %d%% full! frame dropped!\n", buffer_fullness);
208 WaitForSingleObject(ctx->
mutex, INFINITE);
223 pktl_next->
pkt.
pts = time;
224 memcpy(pktl_next->
pkt.
data, buf, buf_size);
226 for(ppktl = &ctx->
pktl ; *ppktl ; ppktl = &(*ppktl)->
next);
231 SetEvent(ctx->
event[1]);
232 ReleaseMutex(ctx->
mutex);
236 ReleaseMutex(ctx->
mutex);
252 IEnumMoniker *classenum = NULL;
259 const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
260 &CLSID_AudioInputDeviceCategory };
261 const char *devtypename = (devtype ==
VideoDevice) ?
"video" :
"audio";
263 r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
264 (IEnumMoniker **) &classenum, 0);
272 IPropertyBag *bag = NULL;
276 r = IMoniker_BindToStorage(
m, 0, 0, &IID_IPropertyBag, (
void *) &bag);
281 r = IPropertyBag_Read(bag,
L"FriendlyName", &var, NULL);
292 IMoniker_BindToObject(
m, 0, 0, &IID_IBaseFilter, (
void *) &
device_filter);
301 IPropertyBag_Release(bag);
305 IEnumMoniker_Release(classenum);
327 IPin *pin,
int *pformat_set)
330 IAMStreamConfig *
config = NULL;
331 AM_MEDIA_TYPE *
type = NULL;
336 if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (
void **) &config) !=
S_OK)
338 if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) !=
S_OK)
345 for (i = 0; i < n && !format_set; i++) {
346 IAMStreamConfig_GetStreamCaps(config, i, &type, (
void *) caps);
353 VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
354 BITMAPINFOHEADER *bih;
359 if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
360 VIDEOINFOHEADER *
v = (
void *) type->pbFormat;
361 fr = &v->AvgTimePerFrame;
363 }
else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
364 VIDEOINFOHEADER2 *
v = (
void *) type->pbFormat;
365 fr = &v->AvgTimePerFrame;
376 av_log(avctx,
AV_LOG_INFO,
" unknown compression type 0x%X", (
int) bih->biCompression);
384 vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
385 1e7 / vcaps->MaxFrameInterval,
386 vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
387 1e7 / vcaps->MinFrameInterval);
401 if (framerate > vcaps->MaxFrameInterval ||
402 framerate < vcaps->MinFrameInterval)
416 AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
421 if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
422 fx = (
void *) type->pbFormat;
427 av_log(avctx,
AV_LOG_INFO,
" min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
428 acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
429 acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
433 if (ctx->
sample_rate > acaps->MaximumSampleFrequency ||
439 if (ctx->
sample_size > acaps->MaximumBitsPerSample ||
445 if (ctx->
channels > acaps->MaximumChannels ||
446 ctx->
channels < acaps->MinimumChannels)
451 if (IAMStreamConfig_SetFormat(config, type) !=
S_OK)
456 CoTaskMemFree(type->pbFormat);
460 IAMStreamConfig_Release(config);
464 *pformat_set = format_set;
475 IAMBufferNegotiation *buffer_negotiation = NULL;
476 ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
477 IAMStreamConfig *
config = NULL;
478 AM_MEDIA_TYPE *
type = NULL;
481 if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (
void **) &config) !=
S_OK)
483 if (IAMStreamConfig_GetFormat(config, &type) !=
S_OK)
485 if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
488 props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
491 if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (
void **) &buffer_negotiation) !=
S_OK)
493 if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) !=
S_OK)
499 if (buffer_negotiation)
500 IAMBufferNegotiation_Release(buffer_negotiation);
503 CoTaskMemFree(type->pbFormat);
507 IAMStreamConfig_Release(config);
528 const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
529 const char *devtypename = (devtype ==
VideoDevice) ?
"video" :
"audio";
538 r = IBaseFilter_EnumPins(device_filter, &pins);
548 while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) ==
S_OK) {
549 IKsPropertySet *p = NULL;
550 IEnumMediaTypes *types = NULL;
556 IPin_QueryPinInfo(pin, &info);
557 IBaseFilter_Release(info.pFilter);
559 if (info.dir != PINDIR_OUTPUT)
561 if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (
void **) &p) !=
S_OK)
563 if (IKsPropertySet_Get(p, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
564 NULL, 0, &category,
sizeof(
GUID), &r2) !=
S_OK)
566 if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
587 if (IPin_EnumMediaTypes(pin, &types) !=
S_OK)
590 IEnumMediaTypes_Reset(types);
591 while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) ==
S_OK) {
592 if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
601 IEnumMediaTypes_Release(types);
603 IKsPropertySet_Release(p);
604 if (device_pin != pin)
608 IEnumPins_Release(pins);
611 if (set_format && !format_set) {
617 "Could not find output pin from %s capture device.\n", devtypename);
661 const wchar_t *filter_name[2] = {
L"Audio capture filter",
L"Video capture filter" };
670 r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
676 if ((r =
dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) {
683 if (!capture_filter) {
689 r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
690 filter_name[devtype]);
697 capture_pin = capture_filter->
pin;
700 r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
714 switch (sample_fmt) {
755 BITMAPINFOHEADER *bih = NULL;
758 if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
759 VIDEOINFOHEADER *
v = (
void *) type.pbFormat;
760 time_base = (
AVRational) { v->AvgTimePerFrame, 10000000 };
762 }
else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
763 VIDEOINFOHEADER2 *
v = (
void *) type.pbFormat;
764 time_base = (
AVRational) { v->AvgTimePerFrame, 10000000 };
774 codec->
width = bih->biWidth;
775 codec->
height = bih->biHeight;
777 if (bih->biCompression ==
MKTAG(
'H',
'D',
'Y',
'C')) {
785 "Please report type 0x%X.\n", (
int) bih->biCompression);
791 if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
801 WAVEFORMATEX *fx = NULL;
803 if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
804 fx = (
void *) type.pbFormat;
835 while ((type = strtok(tmp,
"="))) {
836 char *token = strtok(NULL,
":");
839 if (!strcmp(type,
"video")) {
840 device_name[0] = token;
841 }
else if (!strcmp(type,
"audio")) {
842 device_name[1] = token;
844 device_name[0] = NULL;
845 device_name[1] = NULL;
850 if (!device_name[0] && !device_name[1]) {
854 device_name[0] =
av_strdup(device_name[0]);
856 device_name[1] =
av_strdup(device_name[1]);
866 IGraphBuilder *
graph = NULL;
867 ICreateDevEnum *devenum = NULL;
870 HANDLE media_event_handle;
887 "video codec is not set or set to rawvideo\n");
900 r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
901 &IID_IGraphBuilder, (
void **) &graph);
908 r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
909 &IID_ICreateDevEnum, (
void **) &devenum);
947 ctx->
mutex = CreateMutex(NULL, 0, NULL);
952 ctx->
event[1] = CreateEvent(NULL, 1, 0, NULL);
953 if (!ctx->
event[1]) {
958 r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (
void **) &control);
965 r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (
void **) &media_event);
972 r = IMediaEvent_GetEventHandle(media_event, (
void *) &media_event_handle);
977 proc = GetCurrentProcess();
978 r = DuplicateHandle(proc, media_event_handle, proc, &ctx->
event[0],
979 0, 0, DUPLICATE_SAME_ACCESS);
985 r = IMediaControl_Run(control);
988 r = IMediaControl_GetState(control, 0, &pfs);
1000 ICreateDevEnum_Release(devenum);
1019 while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
1020 if (code == EC_COMPLETE || code ==
EC_DEVICE_LOST || code == EC_ERRORABORT)
1022 IMediaEvent_FreeEventParams(media_event, code, p1, p2);
1033 while (!ctx->
eof && !pktl) {
1034 WaitForSingleObject(ctx->
mutex, INFINITE);
1042 ResetEvent(ctx->
event[1]);
1043 ReleaseMutex(ctx->
mutex);
1050 WaitForMultipleObjects(2, ctx->
event, 0, INFINITE);
1058 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1059 #define DEC AV_OPT_FLAG_DECODING_PARAM
1089 .priv_data_size =
sizeof(
struct dshow_ctx),
static int dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype)
#define AVERROR_PATCHWELCOME
static void callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
static int shall_we_drop(AVFormatContext *s)
void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps)
#define LIBAVUTIL_VERSION_INT
char * av_strdup(const char *s) av_malloc_attrib
Duplicate the string s.
static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
unsigned int max_picture_buffer
Maximum amount of memory in bytes to use for buffering frames obtained from realtime capture devices...
AVInputFormat ff_dshow_demuxer
unsigned long WINAPI libAVPin_Release(libAVPin *)
AVCodecContext * codec
Codec context associated with this stream.
enum AVColorRange color_range
MPEG vs JPEG YUV range.
IMediaEvent * media_event
int index
stream index in AVFormatContext
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static int dshow_add_device(AVFormatContext *avctx, enum dshowDeviceType devtype)
struct AVCodecTag * avformat_get_riff_video_tags(void)
enum AVCodecID video_codec_id
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
if((e=av_dict_get(options,"", NULL, AV_DICT_IGNORE_SUFFIX)))
packed RGB 8:8:8, 24bpp, BGRBGR...
IBaseFilter * device_filter[2]
const char * av_default_item_name(void *ctx)
Return the context name.
enum AVSampleFormat sample_fmt
audio sample format
#define AV_PIX_FMT_RGB555
static int dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype)
List options for device with type devtype.
static int dshow_read_close(AVFormatContext *s)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
static av_cold int end(AVCodecContext *avctx)
libAVFilter * libAVFilter_Create(void *, void *, enum dshowDeviceType)
int id
Format-specific stream ID.
static void dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, IPin *pin, int *pformat_set)
Cycle through available formats using the specified pin, try to set parameters specified through AVOp...
const PixelFormatTag ff_raw_pix_fmt_tags[]
const char * name
Name of the codec implementation.
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
enum AVPixelFormat pix_fmt
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
const OptionDef options[]
enum AVCodecID video_codec_id
Forced video codec_id.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
AVCodecID
Identify the syntax and semantics of the bitstream.
libAVPin * capture_pin[2]
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
void * priv_data
Format private data.
char filename[1024]
input or output filename
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
unsigned long WINAPI libAVPin_AddRef(libAVPin *)
AVPixelFormat
Pixel format.
int av_parse_video_rate(AVRational *rate, const char *str)
Parse str and store the detected values in *rate.
static char * dup_wchar_to_utf8(wchar_t *w)
static const AVClass dshow_class
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in ...
#define FF_ARRAY_ELEMS(a)
static int parse_device_name(AVFormatContext *avctx)
void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
int width
picture width / height.
static int dshow_read_header(AVFormatContext *avctx)
void * av_malloc(size_t size) av_malloc_attrib 1(1)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
AVRational requested_framerate
internal header for RIFF based (de)muxers do NOT include this in end user applications ...
static int dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype, IBaseFilter *device_filter, IPin **ppin)
Cycle through available pins using the device_filter device, of type devtype, retrieve the first outp...
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
AVSampleFormat
Audio Sample Formats.
attribute_deprecated void av_destruct_packet(AVPacket *pkt)
Default packet destructor.
enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
#define AV_LOG_INFO
Standard information.
static int set_format(void *obj, const char *name, int fmt, int search_flags, enum AVOptionType type, const char *desc, int nb_fmts)
enum AVMediaType codec_type
int sample_rate
samples per second
static int dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, IBaseFilter **pfilter)
Cycle through available devices using the device enumerator devenum, retrieve the device with type sp...
main external API structure.
static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
Main libavdevice API header.
static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
Describe the class of an AVClass context structure.
#define MKTAG(a, b, c, d)
enum AVPixelFormat pixel_format
rational number numerator/denominator
static int dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
Set audio device buffer size in milliseconds (which can directly impact latency, depending on the dev...
offset must point to two consecutive integers
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
unsigned long WINAPI libAVFilter_Release(libAVFilter *)
libAVFilter * capture_filter[2]
long WINAPI libAVPin_ConnectionMediaType(libAVPin *, AM_MEDIA_TYPE *)
static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
int channels
number of audio channels
void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type)
the normal 219*2^(n-8) "MPEG" YUV ranges
static int dshow_check_event_queue(IMediaEvent *media_event)
Checks media events from DirectShow and returns -1 on error or EOF.
unsigned int video_frame_num
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
void * av_mallocz(size_t size) av_malloc_attrib 1(1)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
struct AVPacketList * next
static int control(struct vf_instance *vf, int request, void *data)