2 * Directshow capture interface
3 * Copyright (c) 2010 Ramiro Polla
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "dshow_capture.h"
23 #include "libavutil/parseutils.h"
24 #include "libavutil/pixdesc.h"
25 #include "libavutil/opt.h"
26 #include "libavformat/internal.h"
27 #include "libavformat/riff.h"
29 #include "libavcodec/raw.h"
37 int video_device_number
;
38 int audio_device_number
;
42 int audio_buffer_size
;
44 IBaseFilter
*device_filter
[2];
46 libAVFilter
*capture_filter
[2];
47 libAVPin
*capture_pin
[2];
50 HANDLE event
[2]; /* event[0] is set by DirectShow
51 * event[1] is set by callback() */
56 int64_t curbufsize
[2];
57 unsigned int video_frame_num
;
59 IMediaControl
*control
;
60 IMediaEvent
*media_event
;
62 enum AVPixelFormat pixel_format
;
63 enum AVCodecID video_codec_id
;
68 AVRational requested_framerate
;
75 static enum AVPixelFormat
dshow_pixfmt(DWORD biCompression
, WORD biBitCount
)
77 switch(biCompression
) {
80 switch(biBitCount
) { /* 1-8 are untested */
82 return AV_PIX_FMT_MONOWHITE
;
84 return AV_PIX_FMT_RGB4
;
86 return AV_PIX_FMT_RGB8
;
88 return AV_PIX_FMT_RGB555
;
90 return AV_PIX_FMT_BGR24
;
92 return AV_PIX_FMT_0RGB32
;
95 return avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), biCompression
); // all others
99 dshow_read_close(AVFormatContext
*s
)
101 struct dshow_ctx
*ctx
= s
->priv_data
;
105 IMediaControl_Stop(ctx
->control
);
106 IMediaControl_Release(ctx
->control
);
109 if (ctx
->media_event
)
110 IMediaEvent_Release(ctx
->media_event
);
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
); /* When a filter is removed,
122 * the list must be reset. */
123 IBaseFilter_Release(f
);
125 IEnumFilters_Release(fenum
);
127 IGraphBuilder_Release(ctx
->graph
);
130 if (ctx
->capture_pin
[VideoDevice
])
131 libAVPin_Release(ctx
->capture_pin
[VideoDevice
]);
132 if (ctx
->capture_pin
[AudioDevice
])
133 libAVPin_Release(ctx
->capture_pin
[AudioDevice
]);
134 if (ctx
->capture_filter
[VideoDevice
])
135 libAVFilter_Release(ctx
->capture_filter
[VideoDevice
]);
136 if (ctx
->capture_filter
[AudioDevice
])
137 libAVFilter_Release(ctx
->capture_filter
[AudioDevice
]);
139 if (ctx
->device_pin
[VideoDevice
])
140 IPin_Release(ctx
->device_pin
[VideoDevice
]);
141 if (ctx
->device_pin
[AudioDevice
])
142 IPin_Release(ctx
->device_pin
[AudioDevice
]);
143 if (ctx
->device_filter
[VideoDevice
])
144 IBaseFilter_Release(ctx
->device_filter
[VideoDevice
]);
145 if (ctx
->device_filter
[AudioDevice
])
146 IBaseFilter_Release(ctx
->device_filter
[AudioDevice
]);
148 if (ctx
->device_name
[0])
149 av_free(ctx
->device_name
[0]);
150 if (ctx
->device_name
[1])
151 av_free(ctx
->device_name
[1]);
154 CloseHandle(ctx
->mutex
);
156 CloseHandle(ctx
->event
[0]);
158 CloseHandle(ctx
->event
[1]);
162 AVPacketList
*next
= pktl
->next
;
163 av_destruct_packet(&pktl
->pkt
);
173 static char *dup_wchar_to_utf8(wchar_t *w
)
176 int l
= WideCharToMultiByte(CP_UTF8
, 0, w
, -1, 0, 0, 0, 0);
179 WideCharToMultiByte(CP_UTF8
, 0, w
, -1, s
, l
, 0, 0);
183 static int shall_we_drop(AVFormatContext
*s
, int index
, enum dshowDeviceType devtype
)
185 struct dshow_ctx
*ctx
= s
->priv_data
;
186 static const uint8_t dropscore
[] = {62, 75, 87, 100};
187 const int ndropscores
= FF_ARRAY_ELEMS(dropscore
);
188 unsigned int buffer_fullness
= (ctx
->curbufsize
[index
]*100)/s
->max_picture_buffer
;
190 if(dropscore
[++ctx
->video_frame_num
%ndropscores
] <= buffer_fullness
) {
191 av_log(s
, AV_LOG_ERROR
,
192 "real-time buffer[%s] too full (%d%% of size: %d)! frame dropped!\n", ctx
->device_name
[devtype
], buffer_fullness
, s
->max_picture_buffer
);
200 callback(void *priv_data
, int index
, uint8_t *buf
, int buf_size
, int64_t time
, enum dshowDeviceType devtype
)
202 AVFormatContext
*s
= priv_data
;
203 struct dshow_ctx
*ctx
= s
->priv_data
;
204 AVPacketList
**ppktl
, *pktl_next
;
206 // dump_videohdr(s, vdhdr);
208 WaitForSingleObject(ctx
->mutex
, INFINITE
);
210 if(shall_we_drop(s
, index
, devtype
))
213 pktl_next
= av_mallocz(sizeof(AVPacketList
));
217 if(av_new_packet(&pktl_next
->pkt
, buf_size
) < 0) {
222 pktl_next
->pkt
.stream_index
= index
;
223 pktl_next
->pkt
.pts
= time
;
224 memcpy(pktl_next
->pkt
.data
, buf
, buf_size
);
226 for(ppktl
= &ctx
->pktl
; *ppktl
; ppktl
= &(*ppktl
)->next
);
228 ctx
->curbufsize
[index
] += buf_size
;
230 SetEvent(ctx
->event
[1]);
231 ReleaseMutex(ctx
->mutex
);
235 ReleaseMutex(ctx
->mutex
);
240 * Cycle through available devices using the device enumerator devenum,
241 * retrieve the device with type specified by devtype and return the
242 * pointer to the object found in *pfilter.
243 * If pfilter is NULL, list all device names.
246 dshow_cycle_devices(AVFormatContext
*avctx
, ICreateDevEnum
*devenum
,
247 enum dshowDeviceType devtype
, IBaseFilter
**pfilter
)
249 struct dshow_ctx
*ctx
= avctx
->priv_data
;
250 IBaseFilter
*device_filter
= NULL
;
251 IEnumMoniker
*classenum
= NULL
;
253 const char *device_name
= ctx
->device_name
[devtype
];
254 int skip
= (devtype
== VideoDevice
) ? ctx
->video_device_number
255 : ctx
->audio_device_number
;
258 const GUID
*device_guid
[2] = { &CLSID_VideoInputDeviceCategory
,
259 &CLSID_AudioInputDeviceCategory
};
260 const char *devtypename
= (devtype
== VideoDevice
) ? "video" : "audio";
262 r
= ICreateDevEnum_CreateClassEnumerator(devenum
, device_guid
[devtype
],
263 (IEnumMoniker
**) &classenum
, 0);
265 av_log(avctx
, AV_LOG_ERROR
, "Could not enumerate %s devices.\n",
270 while (!device_filter
&& IEnumMoniker_Next(classenum
, 1, &m
, NULL
) == S_OK
) {
271 IPropertyBag
*bag
= NULL
;
275 r
= IMoniker_BindToStorage(m
, 0, 0, &IID_IPropertyBag
, (void *) &bag
);
280 r
= IPropertyBag_Read(bag
, L
"FriendlyName", &var
, NULL
);
284 buf
= dup_wchar_to_utf8(var
.bstrVal
);
287 if (strcmp(device_name
, buf
))
291 IMoniker_BindToObject(m
, 0, 0, &IID_IBaseFilter
, (void *) &device_filter
);
293 av_log(avctx
, AV_LOG_INFO
, " \"%s\"\n", buf
);
300 IPropertyBag_Release(bag
);
304 IEnumMoniker_Release(classenum
);
307 if (!device_filter
) {
308 av_log(avctx
, AV_LOG_ERROR
, "Could not find %s device.\n",
312 *pfilter
= device_filter
;
319 * Cycle through available formats using the specified pin,
320 * try to set parameters specified through AVOptions and if successful
321 * return 1 in *pformat_set.
322 * If pformat_set is NULL, list all pin capabilities.
325 dshow_cycle_formats(AVFormatContext
*avctx
, enum dshowDeviceType devtype
,
326 IPin
*pin
, int *pformat_set
)
328 struct dshow_ctx
*ctx
= avctx
->priv_data
;
329 IAMStreamConfig
*config
= NULL
;
330 AM_MEDIA_TYPE
*type
= NULL
;
335 if (IPin_QueryInterface(pin
, &IID_IAMStreamConfig
, (void **) &config
) != S_OK
)
337 if (IAMStreamConfig_GetNumberOfCapabilities(config
, &n
, &size
) != S_OK
)
340 caps
= av_malloc(size
);
344 for (i
= 0; i
< n
&& !format_set
; i
++) {
345 IAMStreamConfig_GetStreamCaps(config
, i
, &type
, (void *) caps
);
348 ff_print_AM_MEDIA_TYPE(type
);
351 if (devtype
== VideoDevice
) {
352 VIDEO_STREAM_CONFIG_CAPS
*vcaps
= caps
;
353 BITMAPINFOHEADER
*bih
;
355 const AVCodecTag
*const tags
[] = { avformat_get_riff_video_tags(), NULL
};
357 ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps
);
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
;
371 enum AVPixelFormat pix_fmt
= dshow_pixfmt(bih
->biCompression
, bih
->biBitCount
);
372 if (pix_fmt
== AV_PIX_FMT_NONE
) {
373 enum AVCodecID codec_id
= av_codec_get_id(tags
, bih
->biCompression
);
374 AVCodec
*codec
= avcodec_find_decoder(codec_id
);
375 if (codec_id
== AV_CODEC_ID_NONE
|| !codec
) {
376 av_log(avctx
, AV_LOG_INFO
, " unknown compression type 0x%X", (int) bih
->biCompression
);
378 av_log(avctx
, AV_LOG_INFO
, " vcodec=%s", codec
->name
);
381 av_log(avctx
, AV_LOG_INFO
, " pixel_format=%s", av_get_pix_fmt_name(pix_fmt
));
383 av_log(avctx
, AV_LOG_INFO
, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
384 vcaps
->MinOutputSize
.cx
, vcaps
->MinOutputSize
.cy
,
385 1e7
/ vcaps
->MaxFrameInterval
,
386 vcaps
->MaxOutputSize
.cx
, vcaps
->MaxOutputSize
.cy
,
387 1e7
/ vcaps
->MinFrameInterval
);
390 if (ctx
->video_codec_id
!= AV_CODEC_ID_RAWVIDEO
) {
391 if (ctx
->video_codec_id
!= av_codec_get_id(tags
, bih
->biCompression
))
394 if (ctx
->pixel_format
!= AV_PIX_FMT_NONE
&&
395 ctx
->pixel_format
!= dshow_pixfmt(bih
->biCompression
, bih
->biBitCount
)) {
398 if (ctx
->framerate
) {
399 int64_t framerate
= ((int64_t) ctx
->requested_framerate
.den
*10000000)
400 / ctx
->requested_framerate
.num
;
401 if (framerate
> vcaps
->MaxFrameInterval
||
402 framerate
< vcaps
->MinFrameInterval
)
406 if (ctx
->requested_width
&& ctx
->requested_height
) {
407 if (ctx
->requested_width
> vcaps
->MaxOutputSize
.cx
||
408 ctx
->requested_width
< vcaps
->MinOutputSize
.cx
||
409 ctx
->requested_height
> vcaps
->MaxOutputSize
.cy
||
410 ctx
->requested_height
< vcaps
->MinOutputSize
.cy
)
412 bih
->biWidth
= ctx
->requested_width
;
413 bih
->biHeight
= ctx
->requested_height
;
416 AUDIO_STREAM_CONFIG_CAPS
*acaps
= caps
;
419 ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps
);
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
);
432 if (ctx
->sample_rate
) {
433 if (ctx
->sample_rate
> acaps
->MaximumSampleFrequency
||
434 ctx
->sample_rate
< acaps
->MinimumSampleFrequency
)
436 fx
->nSamplesPerSec
= ctx
->sample_rate
;
438 if (ctx
->sample_size
) {
439 if (ctx
->sample_size
> acaps
->MaximumBitsPerSample
||
440 ctx
->sample_size
< acaps
->MinimumBitsPerSample
)
442 fx
->wBitsPerSample
= ctx
->sample_size
;
445 if (ctx
->channels
> acaps
->MaximumChannels
||
446 ctx
->channels
< acaps
->MinimumChannels
)
448 fx
->nChannels
= ctx
->channels
;
451 if (IAMStreamConfig_SetFormat(config
, type
) != S_OK
)
456 CoTaskMemFree(type
->pbFormat
);
460 IAMStreamConfig_Release(config
);
464 *pformat_set
= format_set
;
468 * Set audio device buffer size in milliseconds (which can directly impact
469 * latency, depending on the device).
472 dshow_set_audio_buffer_size(AVFormatContext
*avctx
, IPin
*pin
)
474 struct dshow_ctx
*ctx
= avctx
->priv_data
;
475 IAMBufferNegotiation
*buffer_negotiation
= NULL
;
476 ALLOCATOR_PROPERTIES props
= { -1, -1, -1, -1 };
477 IAMStreamConfig
*config
= NULL
;
478 AM_MEDIA_TYPE
*type
= NULL
;
479 int ret
= AVERROR(EIO
);
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
)
489 * ctx
->audio_buffer_size
/ 1000;
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
);
513 * Cycle through available pins using the device_filter device, of type
514 * devtype, retrieve the first output pin and return the pointer to the
515 * object found in *ppin.
516 * If ppin is NULL, cycle through all pins listing audio/video capabilities.
519 dshow_cycle_pins(AVFormatContext
*avctx
, enum dshowDeviceType devtype
,
520 IBaseFilter
*device_filter
, IPin
**ppin
)
522 struct dshow_ctx
*ctx
= avctx
->priv_data
;
524 IPin
*device_pin
= NULL
;
528 const GUID
*mediatype
[2] = { &MEDIATYPE_Video
, &MEDIATYPE_Audio
};
529 const char *devtypename
= (devtype
== VideoDevice
) ? "video" : "audio";
531 int set_format
= (devtype
== VideoDevice
&& (ctx
->framerate
||
532 (ctx
->requested_width
&& ctx
->requested_height
) ||
533 ctx
->pixel_format
!= AV_PIX_FMT_NONE
||
534 ctx
->video_codec_id
!= AV_CODEC_ID_RAWVIDEO
))
535 || (devtype
== AudioDevice
&& (ctx
->channels
|| ctx
->sample_rate
));
538 r
= IBaseFilter_EnumPins(device_filter
, &pins
);
540 av_log(avctx
, AV_LOG_ERROR
, "Could not enumerate pins.\n");
545 av_log(avctx
, AV_LOG_INFO
, "DirectShow %s device options\n",
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
))
570 char *buf
= dup_wchar_to_utf8(info
.achName
);
571 av_log(avctx
, AV_LOG_INFO
, " Pin \"%s\"\n", buf
);
573 dshow_cycle_formats(avctx
, devtype
, pin
, NULL
);
577 dshow_cycle_formats(avctx
, devtype
, pin
, &format_set
);
582 if (devtype
== AudioDevice
&& ctx
->audio_buffer_size
) {
583 if (dshow_set_audio_buffer_size(avctx
, pin
) < 0) {
584 av_log(avctx
, AV_LOG_ERROR
, "unable to set audio buffer size %d to pin, using pin anyway...", ctx
->audio_buffer_size
);
588 if (IPin_EnumMediaTypes(pin
, &types
) != S_OK
)
591 IEnumMediaTypes_Reset(types
);
592 while (!device_pin
&& IEnumMediaTypes_Next(types
, 1, &type
, NULL
) == S_OK
) {
593 if (IsEqualGUID(&type
->majortype
, mediatype
[devtype
])) {
602 IEnumMediaTypes_Release(types
);
604 IKsPropertySet_Release(p
);
605 if (device_pin
!= pin
)
609 IEnumPins_Release(pins
);
612 if (set_format
&& !format_set
) {
613 av_log(avctx
, AV_LOG_ERROR
, "Could not set %s options\n", devtypename
);
617 av_log(avctx
, AV_LOG_ERROR
,
618 "Could not find output pin from %s capture device.\n", devtypename
);
628 * List options for device with type devtype.
630 * @param devenum device enumerator used for accessing the device
633 dshow_list_device_options(AVFormatContext
*avctx
, ICreateDevEnum
*devenum
,
634 enum dshowDeviceType devtype
)
636 struct dshow_ctx
*ctx
= avctx
->priv_data
;
637 IBaseFilter
*device_filter
= NULL
;
640 if ((r
= dshow_cycle_devices(avctx
, devenum
, devtype
, &device_filter
)) < 0)
642 ctx
->device_filter
[devtype
] = device_filter
;
643 if ((r
= dshow_cycle_pins(avctx
, devtype
, device_filter
, NULL
)) < 0)
650 dshow_open_device(AVFormatContext
*avctx
, ICreateDevEnum
*devenum
,
651 enum dshowDeviceType devtype
)
653 struct dshow_ctx
*ctx
= avctx
->priv_data
;
654 IBaseFilter
*device_filter
= NULL
;
655 IGraphBuilder
*graph
= ctx
->graph
;
656 IPin
*device_pin
= NULL
;
657 libAVPin
*capture_pin
= NULL
;
658 libAVFilter
*capture_filter
= NULL
;
659 int ret
= AVERROR(EIO
);
662 const wchar_t *filter_name
[2] = { L
"Audio capture filter", L
"Video capture filter" };
664 if ((r
= dshow_cycle_devices(avctx
, devenum
, devtype
, &device_filter
)) < 0) {
669 ctx
->device_filter
[devtype
] = device_filter
;
671 r
= IGraphBuilder_AddFilter(graph
, device_filter
, NULL
);
673 av_log(avctx
, AV_LOG_ERROR
, "Could not add device filter to graph.\n");
677 if ((r
= dshow_cycle_pins(avctx
, devtype
, device_filter
, &device_pin
)) < 0) {
681 ctx
->device_pin
[devtype
] = device_pin
;
683 capture_filter
= libAVFilter_Create(avctx
, callback
, devtype
);
684 if (!capture_filter
) {
685 av_log(avctx
, AV_LOG_ERROR
, "Could not create grabber filter.\n");
688 ctx
->capture_filter
[devtype
] = capture_filter
;
690 r
= IGraphBuilder_AddFilter(graph
, (IBaseFilter
*) capture_filter
,
691 filter_name
[devtype
]);
693 av_log(avctx
, AV_LOG_ERROR
, "Could not add capture filter to graph\n");
697 libAVPin_AddRef(capture_filter
->pin
);
698 capture_pin
= capture_filter
->pin
;
699 ctx
->capture_pin
[devtype
] = capture_pin
;
701 r
= IGraphBuilder_ConnectDirect(graph
, device_pin
, (IPin
*) capture_pin
, NULL
);
703 av_log(avctx
, AV_LOG_ERROR
, "Could not connect pins\n");
713 static enum AVCodecID
waveform_codec_id(enum AVSampleFormat sample_fmt
)
715 switch (sample_fmt
) {
716 case AV_SAMPLE_FMT_U8
: return AV_CODEC_ID_PCM_U8
;
717 case AV_SAMPLE_FMT_S16
: return AV_CODEC_ID_PCM_S16LE
;
718 case AV_SAMPLE_FMT_S32
: return AV_CODEC_ID_PCM_S32LE
;
719 default: return AV_CODEC_ID_NONE
; /* Should never happen. */
723 static enum AVSampleFormat
sample_fmt_bits_per_sample(int bits
)
726 case 8: return AV_SAMPLE_FMT_U8
;
727 case 16: return AV_SAMPLE_FMT_S16
;
728 case 32: return AV_SAMPLE_FMT_S32
;
729 default: return AV_SAMPLE_FMT_NONE
; /* Should never happen. */
734 dshow_add_device(AVFormatContext
*avctx
,
735 enum dshowDeviceType devtype
)
737 struct dshow_ctx
*ctx
= avctx
->priv_data
;
739 AVCodecContext
*codec
;
741 int ret
= AVERROR(EIO
);
743 st
= avformat_new_stream(avctx
, NULL
);
745 ret
= AVERROR(ENOMEM
);
750 ctx
->capture_filter
[devtype
]->stream_index
= st
->index
;
752 libAVPin_ConnectionMediaType(ctx
->capture_pin
[devtype
], &type
);
755 if (devtype
== VideoDevice
) {
756 BITMAPINFOHEADER
*bih
= NULL
;
757 AVRational time_base
;
759 if (IsEqualGUID(&type
.formattype
, &FORMAT_VideoInfo
)) {
760 VIDEOINFOHEADER
*v
= (void *) type
.pbFormat
;
761 time_base
= (AVRational
) { v
->AvgTimePerFrame
, 10000000 };
763 } else if (IsEqualGUID(&type
.formattype
, &FORMAT_VideoInfo2
)) {
764 VIDEOINFOHEADER2
*v
= (void *) type
.pbFormat
;
765 time_base
= (AVRational
) { v
->AvgTimePerFrame
, 10000000 };
769 av_log(avctx
, AV_LOG_ERROR
, "Could not get media type.\n");
773 codec
->time_base
= time_base
;
774 codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
775 codec
->width
= bih
->biWidth
;
776 codec
->height
= bih
->biHeight
;
777 codec
->codec_tag
= bih
->biCompression
;
778 codec
->pix_fmt
= dshow_pixfmt(bih
->biCompression
, bih
->biBitCount
);
779 if (bih
->biCompression
== MKTAG('H', 'D', 'Y', 'C')) {
780 av_log(avctx
, AV_LOG_DEBUG
, "attempt to use full range for HDYC...\n");
781 codec
->color_range
= AVCOL_RANGE_MPEG
; // just in case it needs this...
783 if (codec
->pix_fmt
== AV_PIX_FMT_NONE
) {
784 const AVCodecTag
*const tags
[] = { avformat_get_riff_video_tags(), NULL
};
785 codec
->codec_id
= av_codec_get_id(tags
, bih
->biCompression
);
786 if (codec
->codec_id
== AV_CODEC_ID_NONE
) {
787 av_log(avctx
, AV_LOG_ERROR
, "Unknown compression type. "
788 "Please report type 0x%X.\n", (int) bih
->biCompression
);
789 return AVERROR_PATCHWELCOME
;
791 codec
->bits_per_coded_sample
= bih
->biBitCount
;
793 codec
->codec_id
= AV_CODEC_ID_RAWVIDEO
;
794 if (bih
->biCompression
== BI_RGB
|| bih
->biCompression
== BI_BITFIELDS
) {
795 codec
->bits_per_coded_sample
= bih
->biBitCount
;
796 codec
->extradata
= av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE
);
797 if (codec
->extradata
) {
798 codec
->extradata_size
= 9;
799 memcpy(codec
->extradata
, "BottomUp", 9);
804 WAVEFORMATEX
*fx
= NULL
;
806 if (IsEqualGUID(&type
.formattype
, &FORMAT_WaveFormatEx
)) {
807 fx
= (void *) type
.pbFormat
;
810 av_log(avctx
, AV_LOG_ERROR
, "Could not get media type.\n");
814 codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
815 codec
->sample_fmt
= sample_fmt_bits_per_sample(fx
->wBitsPerSample
);
816 codec
->codec_id
= waveform_codec_id(codec
->sample_fmt
);
817 codec
->sample_rate
= fx
->nSamplesPerSec
;
818 codec
->channels
= fx
->nChannels
;
821 avpriv_set_pts_info(st
, 64, 1, 10000000);
829 static int parse_device_name(AVFormatContext
*avctx
)
831 struct dshow_ctx
*ctx
= avctx
->priv_data
;
832 char **device_name
= ctx
->device_name
;
833 char *name
= av_strdup(avctx
->filename
);
838 while ((type
= strtok(tmp
, "="))) {
839 char *token
= strtok(NULL
, ":");
842 if (!strcmp(type
, "video")) {
843 device_name
[0] = token
;
844 } else if (!strcmp(type
, "audio")) {
845 device_name
[1] = token
;
847 device_name
[0] = NULL
;
848 device_name
[1] = NULL
;
853 if (!device_name
[0] && !device_name
[1]) {
857 device_name
[0] = av_strdup(device_name
[0]);
859 device_name
[1] = av_strdup(device_name
[1]);
866 static int dshow_read_header(AVFormatContext
*avctx
)
868 struct dshow_ctx
*ctx
= avctx
->priv_data
;
869 IGraphBuilder
*graph
= NULL
;
870 ICreateDevEnum
*devenum
= NULL
;
871 IMediaControl
*control
= NULL
;
872 IMediaEvent
*media_event
= NULL
;
873 HANDLE media_event_handle
;
875 int ret
= AVERROR(EIO
);
880 if (!ctx
->list_devices
&& !parse_device_name(avctx
)) {
881 av_log(avctx
, AV_LOG_ERROR
, "Malformed dshow input string.\n");
885 ctx
->video_codec_id
= avctx
->video_codec_id
? avctx
->video_codec_id
886 : AV_CODEC_ID_RAWVIDEO
;
887 if (ctx
->pixel_format
!= AV_PIX_FMT_NONE
) {
888 if (ctx
->video_codec_id
!= AV_CODEC_ID_RAWVIDEO
) {
889 av_log(avctx
, AV_LOG_ERROR
, "Pixel format may only be set when "
890 "video codec is not set or set to rawvideo\n");
891 ret
= AVERROR(EINVAL
);
895 if (ctx
->framerate
) {
896 r
= av_parse_video_rate(&ctx
->requested_framerate
, ctx
->framerate
);
898 av_log(avctx
, AV_LOG_ERROR
, "Could not parse framerate '%s'.\n", ctx
->framerate
);
903 r
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
,
904 &IID_IGraphBuilder
, (void **) &graph
);
906 av_log(avctx
, AV_LOG_ERROR
, "Could not create capture graph.\n");
911 r
= CoCreateInstance(&CLSID_SystemDeviceEnum
, NULL
, CLSCTX_INPROC_SERVER
,
912 &IID_ICreateDevEnum
, (void **) &devenum
);
914 av_log(avctx
, AV_LOG_ERROR
, "Could not enumerate system devices.\n");
918 if (ctx
->list_devices
) {
919 av_log(avctx
, AV_LOG_INFO
, "DirectShow video devices\n");
920 dshow_cycle_devices(avctx
, devenum
, VideoDevice
, NULL
);
921 av_log(avctx
, AV_LOG_INFO
, "DirectShow audio devices\n");
922 dshow_cycle_devices(avctx
, devenum
, AudioDevice
, NULL
);
926 if (ctx
->list_options
) {
927 if (ctx
->device_name
[VideoDevice
])
928 dshow_list_device_options(avctx
, devenum
, VideoDevice
);
929 if (ctx
->device_name
[AudioDevice
])
930 dshow_list_device_options(avctx
, devenum
, AudioDevice
);
935 if (ctx
->device_name
[VideoDevice
]) {
936 if ((r
= dshow_open_device(avctx
, devenum
, VideoDevice
)) < 0 ||
937 (r
= dshow_add_device(avctx
, VideoDevice
)) < 0) {
942 if (ctx
->device_name
[AudioDevice
]) {
943 if ((r
= dshow_open_device(avctx
, devenum
, AudioDevice
)) < 0 ||
944 (r
= dshow_add_device(avctx
, AudioDevice
)) < 0) {
949 ctx
->curbufsize
[0] = 0;
950 ctx
->curbufsize
[1] = 0;
951 ctx
->mutex
= CreateMutex(NULL
, 0, NULL
);
953 av_log(avctx
, AV_LOG_ERROR
, "Could not create Mutex\n");
956 ctx
->event
[1] = CreateEvent(NULL
, 1, 0, NULL
);
957 if (!ctx
->event
[1]) {
958 av_log(avctx
, AV_LOG_ERROR
, "Could not create Event\n");
962 r
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **) &control
);
964 av_log(avctx
, AV_LOG_ERROR
, "Could not get media control.\n");
967 ctx
->control
= control
;
969 r
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaEvent
, (void **) &media_event
);
971 av_log(avctx
, AV_LOG_ERROR
, "Could not get media event.\n");
974 ctx
->media_event
= media_event
;
976 r
= IMediaEvent_GetEventHandle(media_event
, (void *) &media_event_handle
);
978 av_log(avctx
, AV_LOG_ERROR
, "Could not get media event handle.\n");
981 proc
= GetCurrentProcess();
982 r
= DuplicateHandle(proc
, media_event_handle
, proc
, &ctx
->event
[0],
983 0, 0, DUPLICATE_SAME_ACCESS
);
985 av_log(avctx
, AV_LOG_ERROR
, "Could not duplicate media event handle.\n");
989 r
= IMediaControl_Run(control
);
992 r
= IMediaControl_GetState(control
, 0, &pfs
);
995 av_log(avctx
, AV_LOG_ERROR
, "Could not run filter\n");
1004 ICreateDevEnum_Release(devenum
);
1007 dshow_read_close(avctx
);
1013 * Checks media events from DirectShow and returns -1 on error or EOF. Also
1014 * purges all events that might be in the event queue to stop the trigger
1015 * of event notification.
1017 static int dshow_check_event_queue(IMediaEvent
*media_event
)
1023 while (IMediaEvent_GetEvent(media_event
, &code
, &p1
, &p2
, 0) != E_ABORT
) {
1024 if (code
== EC_COMPLETE
|| code
== EC_DEVICE_LOST
|| code
== EC_ERRORABORT
)
1026 IMediaEvent_FreeEventParams(media_event
, code
, p1
, p2
);
1032 static int dshow_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
1034 struct dshow_ctx
*ctx
= s
->priv_data
;
1035 AVPacketList
*pktl
= NULL
;
1037 while (!ctx
->eof
&& !pktl
) {
1038 WaitForSingleObject(ctx
->mutex
, INFINITE
);
1042 ctx
->pktl
= ctx
->pktl
->next
;
1044 ctx
->curbufsize
[pkt
->stream_index
] -= pkt
->size
;
1046 ResetEvent(ctx
->event
[1]);
1047 ReleaseMutex(ctx
->mutex
);
1049 if (dshow_check_event_queue(ctx
->media_event
) < 0) {
1051 } else if (s
->flags
& AVFMT_FLAG_NONBLOCK
) {
1052 return AVERROR(EAGAIN
);
1054 WaitForMultipleObjects(2, ctx
->event
, 0, INFINITE
);
1059 return ctx
->eof
? AVERROR(EIO
) : pkt
->size
;
1062 #define OFFSET(x) offsetof(struct dshow_ctx, x)
1063 #define DEC AV_OPT_FLAG_DECODING_PARAM
1064 static const AVOption options
[] = {
1065 { "video_size", "set video size given a string such as 640x480 or hd720.", OFFSET(requested_width
), AV_OPT_TYPE_IMAGE_SIZE
, {.str
= NULL
}, 0, 0, DEC
},
1066 { "pixel_format", "set video pixel format", OFFSET(pixel_format
), AV_OPT_TYPE_PIXEL_FMT
, {.i64
= AV_PIX_FMT_NONE
}, -1, INT_MAX
, DEC
},
1067 { "framerate", "set video frame rate", OFFSET(framerate
), AV_OPT_TYPE_STRING
, {.str
= NULL
}, 0, 0, DEC
},
1068 { "sample_rate", "set audio sample rate", OFFSET(sample_rate
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, INT_MAX
, DEC
},
1069 { "sample_size", "set audio sample size", OFFSET(sample_size
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, 16, DEC
},
1070 { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, INT_MAX
, DEC
},
1071 { "list_devices", "list available devices", OFFSET(list_devices
), AV_OPT_TYPE_INT
, {.i64
=0}, 0, 1, DEC
, "list_devices" },
1072 { "true", "", 0, AV_OPT_TYPE_CONST
, {.i64
=1}, 0, 0, DEC
, "list_devices" },
1073 { "false", "", 0, AV_OPT_TYPE_CONST
, {.i64
=0}, 0, 0, DEC
, "list_devices" },
1074 { "list_options", "list available options for specified device", OFFSET(list_options
), AV_OPT_TYPE_INT
, {.i64
=0}, 0, 1, DEC
, "list_options" },
1075 { "true", "", 0, AV_OPT_TYPE_CONST
, {.i64
=1}, 0, 0, DEC
, "list_options" },
1076 { "false", "", 0, AV_OPT_TYPE_CONST
, {.i64
=0}, 0, 0, DEC
, "list_options" },
1077 { "video_device_number", "set video device number for devices with same name (starts at 0)", OFFSET(video_device_number
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, INT_MAX
, DEC
},
1078 { "audio_device_number", "set audio device number for devices with same name (starts at 0)", OFFSET(audio_device_number
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, INT_MAX
, DEC
},
1079 { "audio_buffer_size", "set audio device buffer latency size in milliseconds (default is the device's default)", OFFSET(audio_buffer_size
), AV_OPT_TYPE_INT
, {.i64
= 0}, 0, INT_MAX
, DEC
},
1083 static const AVClass dshow_class
= {
1084 .class_name
= "dshow indev",
1085 .item_name
= av_default_item_name
,
1087 .version
= LIBAVUTIL_VERSION_INT
,
1088 .category
= AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT
,
1091 AVInputFormat ff_dshow_demuxer
= {
1093 .long_name
= NULL_IF_CONFIG_SMALL("DirectShow capture"),
1094 .priv_data_size
= sizeof(struct dshow_ctx
),
1095 .read_header
= dshow_read_header
,
1096 .read_packet
= dshow_read_packet
,
1097 .read_close
= dshow_read_close
,
1098 .flags
= AVFMT_NOFILE
,
1099 .priv_class
= &dshow_class
,