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 "libavutil/parseutils.h" 23#include "libavutil/pixdesc.h" 24#include "libavutil/opt.h" 25#include "libavformat/internal.h" 26#include "libavformat/riff.h" 27#include "avdevice.h" 28#include "dshow_capture.h" 29#include "libavcodec/raw.h" 30 31struct dshow_ctx { 32 const AVClass *class; 33 34 IGraphBuilder *graph; 35 36 char *device_name[2]; 37 int video_device_number; 38 int audio_device_number; 39 40 int list_options; 41 int list_devices; 42 int audio_buffer_size; 43 44 IBaseFilter *device_filter[2]; 45 IPin *device_pin[2]; 46 libAVFilter *capture_filter[2]; 47 libAVPin *capture_pin[2]; 48 49 HANDLE mutex; 50 HANDLE event[2]; /* event[0] is set by DirectShow 51 * event[1] is set by callback() */ 52 AVPacketList *pktl; 53 54 int eof; 55 56 int64_t curbufsize[2]; 57 unsigned int video_frame_num; 58 59 IMediaControl *control; 60 IMediaEvent *media_event; 61 62 enum AVPixelFormat pixel_format; 63 enum AVCodecID video_codec_id; 64 char *framerate; 65 66 int requested_width; 67 int requested_height; 68 AVRational requested_framerate; 69 70 int sample_rate; 71 int sample_size; 72 int channels; 73}; 74 75static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount) 76{ 77 switch(biCompression) { 78 case BI_BITFIELDS: 79 case BI_RGB: 80 switch(biBitCount) { /* 1-8 are untested */ 81 case 1: 82 return AV_PIX_FMT_MONOWHITE; 83 case 4: 84 return AV_PIX_FMT_RGB4; 85 case 8: 86 return AV_PIX_FMT_RGB8; 87 case 16: 88 return AV_PIX_FMT_RGB555; 89 case 24: 90 return AV_PIX_FMT_BGR24; 91 case 32: 92 return AV_PIX_FMT_0RGB32; 93 } 94 } 95 return avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, biCompression); // all others 96} 97 98static int 99dshow_read_close(AVFormatContext *s) 100{ 101 struct dshow_ctx *ctx = s->priv_data; 102 AVPacketList *pktl; 103 104 if (ctx->control) { 105 IMediaControl_Stop(ctx->control); 106 IMediaControl_Release(ctx->control); 107 } 108 109 if (ctx->media_event) 110 IMediaEvent_Release(ctx->media_event); 111 112 if (ctx->graph) { 113 IEnumFilters *fenum; 114 int r; 115 r = IGraphBuilder_EnumFilters(ctx->graph, &fenum); 116 if (r == S_OK) { 117 IBaseFilter *f; 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); 124 } 125 IEnumFilters_Release(fenum); 126 } 127 IGraphBuilder_Release(ctx->graph); 128 } 129 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]); 138 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]); 147 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]); 152 153 if(ctx->mutex) 154 CloseHandle(ctx->mutex); 155 if(ctx->event[0]) 156 CloseHandle(ctx->event[0]); 157 if(ctx->event[1]) 158 CloseHandle(ctx->event[1]); 159 160 pktl = ctx->pktl; 161 while (pktl) { 162 AVPacketList *next = pktl->next; 163 av_destruct_packet(&pktl->pkt); 164 av_free(pktl); 165 pktl = next; 166 } 167 168 CoUninitialize(); 169 170 return 0; 171} 172 173static char *dup_wchar_to_utf8(wchar_t *w) 174{ 175 char *s = NULL; 176 int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0); 177 s = av_malloc(l); 178 if (s) 179 WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0); 180 return s; 181} 182 183static int shall_we_drop(AVFormatContext *s, int index, enum dshowDeviceType devtype) 184{ 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; 189 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); 193 return 1; 194 } 195 196 return 0; 197} 198 199static void 200callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype) 201{ 202 AVFormatContext *s = priv_data; 203 struct dshow_ctx *ctx = s->priv_data; 204 AVPacketList **ppktl, *pktl_next; 205 206// dump_videohdr(s, vdhdr); 207 208 WaitForSingleObject(ctx->mutex, INFINITE); 209 210 if(shall_we_drop(s, index, devtype)) 211 goto fail; 212 213 pktl_next = av_mallocz(sizeof(AVPacketList)); 214 if(!pktl_next) 215 goto fail; 216 217 if(av_new_packet(&pktl_next->pkt, buf_size) < 0) { 218 av_free(pktl_next); 219 goto fail; 220 } 221 222 pktl_next->pkt.stream_index = index; 223 pktl_next->pkt.pts = time; 224 memcpy(pktl_next->pkt.data, buf, buf_size); 225 226 for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next); 227 *ppktl = pktl_next; 228 ctx->curbufsize[index] += buf_size; 229 230 SetEvent(ctx->event[1]); 231 ReleaseMutex(ctx->mutex); 232 233 return; 234fail: 235 ReleaseMutex(ctx->mutex); 236 return; 237} 238 239/** 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. 244 */ 245static int 246dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, 247 enum dshowDeviceType devtype, IBaseFilter **pfilter) 248{ 249 struct dshow_ctx *ctx = avctx->priv_data; 250 IBaseFilter *device_filter = NULL; 251 IEnumMoniker *classenum = NULL; 252 IMoniker *m = NULL; 253 const char *device_name = ctx->device_name[devtype]; 254 int skip = (devtype == VideoDevice) ? ctx->video_device_number 255 : ctx->audio_device_number; 256 int r; 257 258 const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory, 259 &CLSID_AudioInputDeviceCategory }; 260 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio"; 261 262 r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype], 263 (IEnumMoniker **) &classenum, 0); 264 if (r != S_OK) { 265 av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n", 266 devtypename); 267 return AVERROR(EIO); 268 } 269 270 while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) { 271 IPropertyBag *bag = NULL; 272 char *buf = NULL; 273 VARIANT var; 274 275 r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag); 276 if (r != S_OK) 277 goto fail1; 278 279 var.vt = VT_BSTR; 280 r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL); 281 if (r != S_OK) 282 goto fail1; 283 284 buf = dup_wchar_to_utf8(var.bstrVal); 285 286 if (pfilter) { 287 if (strcmp(device_name, buf)) 288 goto fail1; 289 290 if (!skip--) 291 IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter); 292 } else { 293 av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf); 294 } 295 296fail1: 297 if (buf) 298 av_free(buf); 299 if (bag) 300 IPropertyBag_Release(bag); 301 IMoniker_Release(m); 302 } 303 304 IEnumMoniker_Release(classenum); 305 306 if (pfilter) { 307 if (!device_filter) { 308 av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n", 309 devtypename); 310 return AVERROR(EIO); 311 } 312 *pfilter = device_filter; 313 } 314 315 return 0; 316} 317 318/** 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. 323 */ 324static void 325dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, 326 IPin *pin, int *pformat_set) 327{ 328 struct dshow_ctx *ctx = avctx->priv_data; 329 IAMStreamConfig *config = NULL; 330 AM_MEDIA_TYPE *type = NULL; 331 int format_set = 0; 332 void *caps = NULL; 333 int i, n, size; 334 335 if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK) 336 return; 337 if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK) 338 goto end; 339 340 caps = av_malloc(size); 341 if (!caps) 342 goto end; 343 344 for (i = 0; i < n && !format_set; i++) { 345 IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps); 346 347#if DSHOWDEBUG 348 ff_print_AM_MEDIA_TYPE(type); 349#endif 350 351 if (devtype == VideoDevice) { 352 VIDEO_STREAM_CONFIG_CAPS *vcaps = caps; 353 BITMAPINFOHEADER *bih; 354 int64_t *fr; 355#if DSHOWDEBUG 356 ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps); 357#endif 358 if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) { 359 VIDEOINFOHEADER *v = (void *) type->pbFormat; 360 fr = &v->AvgTimePerFrame; 361 bih = &v->bmiHeader; 362 } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) { 363 VIDEOINFOHEADER2 *v = (void *) type->pbFormat; 364 fr = &v->AvgTimePerFrame; 365 bih = &v->bmiHeader; 366 } else { 367 goto next; 368 } 369 if (!pformat_set) { 370 enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount); 371 if (pix_fmt == AV_PIX_FMT_NONE) { 372 enum AVCodecID codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression); 373 AVCodec *codec = avcodec_find_decoder(codec_id); 374 if (codec_id == AV_CODEC_ID_NONE || !codec) { 375 av_log(avctx, AV_LOG_INFO, " unknown compression type 0x%X", (int) bih->biCompression); 376 } else { 377 av_log(avctx, AV_LOG_INFO, " vcodec=%s", codec->name); 378 } 379 } else { 380 av_log(avctx, AV_LOG_INFO, " pixel_format=%s", av_get_pix_fmt_name(pix_fmt)); 381 } 382 av_log(avctx, AV_LOG_INFO, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n", 383 vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy, 384 1e7 / vcaps->MaxFrameInterval, 385 vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy, 386 1e7 / vcaps->MinFrameInterval); 387 continue; 388 } 389 if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) { 390 if (ctx->video_codec_id != ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression)) 391 goto next; 392 } 393 if (ctx->pixel_format != AV_PIX_FMT_NONE && 394 ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) { 395 goto next; 396 } 397 if (ctx->framerate) { 398 int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000) 399 / ctx->requested_framerate.num; 400 if (framerate > vcaps->MaxFrameInterval || 401 framerate < vcaps->MinFrameInterval) 402 goto next; 403 *fr = framerate; 404 } 405 if (ctx->requested_width && ctx->requested_height) { 406 if (ctx->requested_width > vcaps->MaxOutputSize.cx || 407 ctx->requested_width < vcaps->MinOutputSize.cx || 408 ctx->requested_height > vcaps->MaxOutputSize.cy || 409 ctx->requested_height < vcaps->MinOutputSize.cy) 410 goto next; 411 bih->biWidth = ctx->requested_width; 412 bih->biHeight = ctx->requested_height; 413 } 414 } else { 415 AUDIO_STREAM_CONFIG_CAPS *acaps = caps; 416 WAVEFORMATEX *fx; 417#if DSHOWDEBUG 418 ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps); 419#endif 420 if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) { 421 fx = (void *) type->pbFormat; 422 } else { 423 goto next; 424 } 425 if (!pformat_set) { 426 av_log(avctx, AV_LOG_INFO, " min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n", 427 acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency, 428 acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency); 429 continue; 430 } 431 if (ctx->sample_rate) { 432 if (ctx->sample_rate > acaps->MaximumSampleFrequency || 433 ctx->sample_rate < acaps->MinimumSampleFrequency) 434 goto next; 435 fx->nSamplesPerSec = ctx->sample_rate; 436 } 437 if (ctx->sample_size) { 438 if (ctx->sample_size > acaps->MaximumBitsPerSample || 439 ctx->sample_size < acaps->MinimumBitsPerSample) 440 goto next; 441 fx->wBitsPerSample = ctx->sample_size; 442 } 443 if (ctx->channels) { 444 if (ctx->channels > acaps->MaximumChannels || 445 ctx->channels < acaps->MinimumChannels) 446 goto next; 447 fx->nChannels = ctx->channels; 448 } 449 } 450 if (IAMStreamConfig_SetFormat(config, type) != S_OK) 451 goto next; 452 format_set = 1; 453next: 454 if (type->pbFormat) 455 CoTaskMemFree(type->pbFormat); 456 CoTaskMemFree(type); 457 } 458end: 459 IAMStreamConfig_Release(config); 460 if (caps) 461 av_free(caps); 462 if (pformat_set) 463 *pformat_set = format_set; 464} 465 466/** 467 * Set audio device buffer size in milliseconds (which can directly impact 468 * latency, depending on the device). 469 */ 470static int 471dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin) 472{ 473 struct dshow_ctx *ctx = avctx->priv_data; 474 IAMBufferNegotiation *buffer_negotiation = NULL; 475 ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 }; 476 IAMStreamConfig *config = NULL; 477 AM_MEDIA_TYPE *type = NULL; 478 int ret = AVERROR(EIO); 479 480 if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK) 481 goto end; 482 if (IAMStreamConfig_GetFormat(config, &type) != S_OK) 483 goto end; 484 if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) 485 goto end; 486 487 props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec) 488 * ctx->audio_buffer_size / 1000; 489 490 if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK) 491 goto end; 492 if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK) 493 goto end; 494 495 ret = 0; 496 497end: 498 if (buffer_negotiation) 499 IAMBufferNegotiation_Release(buffer_negotiation); 500 if (type) { 501 if (type->pbFormat) 502 CoTaskMemFree(type->pbFormat); 503 CoTaskMemFree(type); 504 } 505 if (config) 506 IAMStreamConfig_Release(config); 507 508 return ret; 509} 510 511/** 512 * Cycle through available pins using the device_filter device, of type 513 * devtype, retrieve the first output pin and return the pointer to the 514 * object found in *ppin. 515 * If ppin is NULL, cycle through all pins listing audio/video capabilities. 516 */ 517static int 518dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype, 519 IBaseFilter *device_filter, IPin **ppin) 520{ 521 struct dshow_ctx *ctx = avctx->priv_data; 522 IEnumPins *pins = 0; 523 IPin *device_pin = NULL; 524 IPin *pin; 525 int r; 526 527 const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio }; 528 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio"; 529 530 int set_format = (devtype == VideoDevice && (ctx->framerate || 531 (ctx->requested_width && ctx->requested_height) || 532 ctx->pixel_format != AV_PIX_FMT_NONE || 533 ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO)) 534 || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate)); 535 int format_set = 0; 536 537 r = IBaseFilter_EnumPins(device_filter, &pins); 538 if (r != S_OK) { 539 av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n"); 540 return AVERROR(EIO); 541 } 542 543 if (!ppin) { 544 av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n", 545 devtypename); 546 } 547 while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) { 548 IKsPropertySet *p = NULL; 549 IEnumMediaTypes *types = NULL; 550 PIN_INFO info = {0}; 551 AM_MEDIA_TYPE *type; 552 GUID category; 553 DWORD r2; 554 555 IPin_QueryPinInfo(pin, &info); 556 IBaseFilter_Release(info.pFilter); 557 558 if (info.dir != PINDIR_OUTPUT) 559 goto next; 560 if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK) 561 goto next; 562 if (IKsPropertySet_Get(p, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, 563 NULL, 0, &category, sizeof(GUID), &r2) != S_OK) 564 goto next; 565 if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE)) 566 goto next; 567 568 if (!ppin) { 569 char *buf = dup_wchar_to_utf8(info.achName); 570 av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf); 571 av_free(buf); 572 dshow_cycle_formats(avctx, devtype, pin, NULL); 573 goto next; 574 } 575 if (set_format) { 576 dshow_cycle_formats(avctx, devtype, pin, &format_set); 577 if (!format_set) { 578 goto next; 579 } 580 } 581 if (devtype == AudioDevice && ctx->audio_buffer_size) { 582 if (dshow_set_audio_buffer_size(avctx, pin) < 0) { 583 av_log(avctx, AV_LOG_ERROR, "unable to set audio buffer size %d to pin, using pin anyway...", ctx->audio_buffer_size); 584 } 585 } 586 587 if (IPin_EnumMediaTypes(pin, &types) != S_OK) 588 goto next; 589 590 IEnumMediaTypes_Reset(types); 591 while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) { 592 if (IsEqualGUID(&type->majortype, mediatype[devtype])) { 593 device_pin = pin; 594 goto next; 595 } 596 CoTaskMemFree(type); 597 } 598 599next: 600 if (types) 601 IEnumMediaTypes_Release(types); 602 if (p) 603 IKsPropertySet_Release(p); 604 if (device_pin != pin) 605 IPin_Release(pin); 606 } 607 608 IEnumPins_Release(pins); 609 610 if (ppin) { 611 if (set_format && !format_set) { 612 av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename); 613 return AVERROR(EIO); 614 } 615 if (!device_pin) { 616 av_log(avctx, AV_LOG_ERROR, 617 "Could not find output pin from %s capture device.\n", devtypename); 618 return AVERROR(EIO); 619 } 620 *ppin = device_pin; 621 } 622 623 return 0; 624} 625 626/** 627 * List options for device with type devtype. 628 * 629 * @param devenum device enumerator used for accessing the device 630 */ 631static int 632dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum, 633 enum dshowDeviceType devtype) 634{ 635 struct dshow_ctx *ctx = avctx->priv_data; 636 IBaseFilter *device_filter = NULL; 637 int r; 638 639 if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) 640 return r; 641 ctx->device_filter[devtype] = device_filter; 642 if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0) 643 return r; 644 645 return 0; 646} 647 648static int 649dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, 650 enum dshowDeviceType devtype) 651{ 652 struct dshow_ctx *ctx = avctx->priv_data; 653 IBaseFilter *device_filter = NULL; 654 IGraphBuilder *graph = ctx->graph; 655 IPin *device_pin = NULL; 656 libAVPin *capture_pin = NULL; 657 libAVFilter *capture_filter = NULL; 658 int ret = AVERROR(EIO); 659 int r; 660 661 const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" }; 662 663 if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) { 664 ret = r; 665 goto error; 666 } 667 668 ctx->device_filter [devtype] = device_filter; 669 670 r = IGraphBuilder_AddFilter(graph, device_filter, NULL); 671 if (r != S_OK) { 672 av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n"); 673 goto error; 674 } 675 676 if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) { 677 ret = r; 678 goto error; 679 } 680 ctx->device_pin[devtype] = device_pin; 681 682 capture_filter = libAVFilter_Create(avctx, callback, devtype); 683 if (!capture_filter) { 684 av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n"); 685 goto error; 686 } 687 ctx->capture_filter[devtype] = capture_filter; 688 689 r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter, 690 filter_name[devtype]); 691 if (r != S_OK) { 692 av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n"); 693 goto error; 694 } 695 696 libAVPin_AddRef(capture_filter->pin); 697 capture_pin = capture_filter->pin; 698 ctx->capture_pin[devtype] = capture_pin; 699 700 r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL); 701 if (r != S_OK) { 702 av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n"); 703 goto error; 704 } 705 706 ret = 0; 707 708error: 709 return ret; 710} 711 712static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt) 713{ 714 switch (sample_fmt) { 715 case AV_SAMPLE_FMT_U8: return AV_CODEC_ID_PCM_U8; 716 case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE; 717 case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE; 718 default: return AV_CODEC_ID_NONE; /* Should never happen. */ 719 } 720} 721 722static enum AVSampleFormat sample_fmt_bits_per_sample(int bits) 723{ 724 switch (bits) { 725 case 8: return AV_SAMPLE_FMT_U8; 726 case 16: return AV_SAMPLE_FMT_S16; 727 case 32: return AV_SAMPLE_FMT_S32; 728 default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */ 729 } 730} 731 732static int 733dshow_add_device(AVFormatContext *avctx, 734 enum dshowDeviceType devtype) 735{ 736 struct dshow_ctx *ctx = avctx->priv_data; 737 AM_MEDIA_TYPE type; 738 AVCodecContext *codec; 739 AVStream *st; 740 int ret = AVERROR(EIO); 741 742 st = avformat_new_stream(avctx, NULL); 743 if (!st) { 744 ret = AVERROR(ENOMEM); 745 goto error; 746 } 747 st->id = devtype; 748 749 ctx->capture_filter[devtype]->stream_index = st->index; 750 751 libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type); 752 753 codec = st->codec; 754 if (devtype == VideoDevice) { 755 BITMAPINFOHEADER *bih = NULL; 756 AVRational time_base; 757 758 if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) { 759 VIDEOINFOHEADER *v = (void *) type.pbFormat; 760 time_base = (AVRational) { v->AvgTimePerFrame, 10000000 }; 761 bih = &v->bmiHeader; 762 } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) { 763 VIDEOINFOHEADER2 *v = (void *) type.pbFormat; 764 time_base = (AVRational) { v->AvgTimePerFrame, 10000000 }; 765 bih = &v->bmiHeader; 766 } 767 if (!bih) { 768 av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n"); 769 goto error; 770 } 771 772 codec->time_base = time_base; 773 codec->codec_type = AVMEDIA_TYPE_VIDEO; 774 codec->width = bih->biWidth; 775 codec->height = bih->biHeight; 776 codec->codec_tag = bih->biCompression; 777 codec->pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount); 778 if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) { 779 av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n"); 780 codec->color_range = AVCOL_RANGE_MPEG; // just in case it needs this... 781 } 782 if (codec->pix_fmt == AV_PIX_FMT_NONE) { 783 codec->codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression); 784 if (codec->codec_id == AV_CODEC_ID_NONE) { 785 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. " 786 "Please report type 0x%X.\n", (int) bih->biCompression); 787 return AVERROR_PATCHWELCOME; 788 } 789 codec->bits_per_coded_sample = bih->biBitCount; 790 } else { 791 codec->codec_id = AV_CODEC_ID_RAWVIDEO; 792 if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) { 793 codec->bits_per_coded_sample = bih->biBitCount; 794 codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE); 795 if (codec->extradata) { 796 codec->extradata_size = 9; 797 memcpy(codec->extradata, "BottomUp", 9); 798 } 799 } 800 } 801 } else { 802 WAVEFORMATEX *fx = NULL; 803 804 if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) { 805 fx = (void *) type.pbFormat; 806 } 807 if (!fx) { 808 av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n"); 809 goto error; 810 } 811 812 codec->codec_type = AVMEDIA_TYPE_AUDIO; 813 codec->sample_fmt = sample_fmt_bits_per_sample(fx->wBitsPerSample); 814 codec->codec_id = waveform_codec_id(codec->sample_fmt); 815 codec->sample_rate = fx->nSamplesPerSec; 816 codec->channels = fx->nChannels; 817 } 818 819 avpriv_set_pts_info(st, 64, 1, 10000000); 820 821 ret = 0; 822 823error: 824 return ret; 825} 826 827static int parse_device_name(AVFormatContext *avctx) 828{ 829 struct dshow_ctx *ctx = avctx->priv_data; 830 char **device_name = ctx->device_name; 831 char *name = av_strdup(avctx->filename); 832 char *tmp = name; 833 int ret = 1; 834 char *type; 835 836 while ((type = strtok(tmp, "="))) { 837 char *token = strtok(NULL, ":"); 838 tmp = NULL; 839 840 if (!strcmp(type, "video")) { 841 device_name[0] = token; 842 } else if (!strcmp(type, "audio")) { 843 device_name[1] = token; 844 } else { 845 device_name[0] = NULL; 846 device_name[1] = NULL; 847 break; 848 } 849 } 850 851 if (!device_name[0] && !device_name[1]) { 852 ret = 0; 853 } else { 854 if (device_name[0]) 855 device_name[0] = av_strdup(device_name[0]); 856 if (device_name[1]) 857 device_name[1] = av_strdup(device_name[1]); 858 } 859 860 av_free(name); 861 return ret; 862} 863 864static int dshow_read_header(AVFormatContext *avctx) 865{ 866 struct dshow_ctx *ctx = avctx->priv_data; 867 IGraphBuilder *graph = NULL; 868 ICreateDevEnum *devenum = NULL; 869 IMediaControl *control = NULL; 870 IMediaEvent *media_event = NULL; 871 HANDLE media_event_handle; 872 HANDLE proc; 873 int ret = AVERROR(EIO); 874 int r; 875 876 CoInitialize(0); 877 878 if (!ctx->list_devices && !parse_device_name(avctx)) { 879 av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n"); 880 goto error; 881 } 882 883 ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id 884 : AV_CODEC_ID_RAWVIDEO; 885 if (ctx->pixel_format != AV_PIX_FMT_NONE) { 886 if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) { 887 av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when " 888 "video codec is not set or set to rawvideo\n"); 889 ret = AVERROR(EINVAL); 890 goto error; 891 } 892 } 893 if (ctx->framerate) { 894 r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate); 895 if (r < 0) { 896 av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate); 897 goto error; 898 } 899 } 900 901 r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 902 &IID_IGraphBuilder, (void **) &graph); 903 if (r != S_OK) { 904 av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n"); 905 goto error; 906 } 907 ctx->graph = graph; 908 909 r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, 910 &IID_ICreateDevEnum, (void **) &devenum); 911 if (r != S_OK) { 912 av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n"); 913 goto error; 914 } 915 916 if (ctx->list_devices) { 917 av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n"); 918 dshow_cycle_devices(avctx, devenum, VideoDevice, NULL); 919 av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n"); 920 dshow_cycle_devices(avctx, devenum, AudioDevice, NULL); 921 ret = AVERROR_EXIT; 922 goto error; 923 } 924 if (ctx->list_options) { 925 if (ctx->device_name[VideoDevice]) 926 dshow_list_device_options(avctx, devenum, VideoDevice); 927 if (ctx->device_name[AudioDevice]) 928 dshow_list_device_options(avctx, devenum, AudioDevice); 929 ret = AVERROR_EXIT; 930 goto error; 931 } 932 933 if (ctx->device_name[VideoDevice]) { 934 if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 0 || 935 (r = dshow_add_device(avctx, VideoDevice)) < 0) { 936 ret = r; 937 goto error; 938 } 939 } 940 if (ctx->device_name[AudioDevice]) { 941 if ((r = dshow_open_device(avctx, devenum, AudioDevice)) < 0 || 942 (r = dshow_add_device(avctx, AudioDevice)) < 0) { 943 ret = r; 944 goto error; 945 } 946 } 947 ctx->curbufsize[0] = 0; 948 ctx->curbufsize[1] = 0; 949 ctx->mutex = CreateMutex(NULL, 0, NULL); 950 if (!ctx->mutex) { 951 av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n"); 952 goto error; 953 } 954 ctx->event[1] = CreateEvent(NULL, 1, 0, NULL); 955 if (!ctx->event[1]) { 956 av_log(avctx, AV_LOG_ERROR, "Could not create Event\n"); 957 goto error; 958 } 959 960 r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control); 961 if (r != S_OK) { 962 av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n"); 963 goto error; 964 } 965 ctx->control = control; 966 967 r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event); 968 if (r != S_OK) { 969 av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n"); 970 goto error; 971 } 972 ctx->media_event = media_event; 973 974 r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle); 975 if (r != S_OK) { 976 av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n"); 977 goto error; 978 } 979 proc = GetCurrentProcess(); 980 r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0], 981 0, 0, DUPLICATE_SAME_ACCESS); 982 if (!r) { 983 av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n"); 984 goto error; 985 } 986 987 r = IMediaControl_Run(control); 988 if (r == S_FALSE) { 989 OAFilterState pfs; 990 r = IMediaControl_GetState(control, 0, &pfs); 991 } 992 if (r != S_OK) { 993 av_log(avctx, AV_LOG_ERROR, "Could not run filter\n"); 994 goto error; 995 } 996 997 ret = 0; 998 999error: 1000 1001 if (devenum) 1002 ICreateDevEnum_Release(devenum); 1003 1004 if (ret < 0) 1005 dshow_read_close(avctx); 1006 1007 return ret; 1008} 1009 1010/** 1011 * Checks media events from DirectShow and returns -1 on error or EOF. Also 1012 * purges all events that might be in the event queue to stop the trigger 1013 * of event notification. 1014 */ 1015static int dshow_check_event_queue(IMediaEvent *media_event) 1016{ 1017 LONG_PTR p1, p2; 1018 long code; 1019 int ret = 0; 1020 1021 while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) { 1022 if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT) 1023 ret = -1; 1024 IMediaEvent_FreeEventParams(media_event, code, p1, p2); 1025 } 1026 1027 return ret; 1028} 1029 1030static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt) 1031{ 1032 struct dshow_ctx *ctx = s->priv_data; 1033 AVPacketList *pktl = NULL; 1034 1035 while (!ctx->eof && !pktl) { 1036 WaitForSingleObject(ctx->mutex, INFINITE); 1037 pktl = ctx->pktl; 1038 if (pktl) { 1039 *pkt = pktl->pkt; 1040 ctx->pktl = ctx->pktl->next; 1041 av_free(pktl); 1042 ctx->curbufsize[pkt->stream_index] -= pkt->size; 1043 } 1044 ResetEvent(ctx->event[1]); 1045 ReleaseMutex(ctx->mutex); 1046 if (!pktl) { 1047 if (dshow_check_event_queue(ctx->media_event) < 0) { 1048 ctx->eof = 1; 1049 } else if (s->flags & AVFMT_FLAG_NONBLOCK) { 1050 return AVERROR(EAGAIN); 1051 } else { 1052 WaitForMultipleObjects(2, ctx->event, 0, INFINITE); 1053 } 1054 } 1055 } 1056 1057 return ctx->eof ? AVERROR(EIO) : pkt->size; 1058} 1059 1060#define OFFSET(x) offsetof(struct dshow_ctx, x) 1061#define DEC AV_OPT_FLAG_DECODING_PARAM 1062static const AVOption options[] = { 1063 { "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 }, 1064 { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX, DEC }, 1065 { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, 1066 { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC }, 1067 { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC }, 1068 { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC }, 1069 { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" }, 1070 { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" }, 1071 { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" }, 1072 { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_options" }, 1073 { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_options" }, 1074 { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_options" }, 1075 { "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 }, 1076 { "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 }, 1077 { "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 }, 1078 { NULL }, 1079}; 1080 1081static const AVClass dshow_class = { 1082 .class_name = "dshow indev", 1083 .item_name = av_default_item_name, 1084 .option = options, 1085 .version = LIBAVUTIL_VERSION_INT, 1086 .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, 1087}; 1088 1089AVInputFormat ff_dshow_demuxer = { 1090 .name = "dshow", 1091 .long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"), 1092 .priv_data_size = sizeof(struct dshow_ctx), 1093 .read_header = dshow_read_header, 1094 .read_packet = dshow_read_packet, 1095 .read_close = dshow_read_close, 1096 .flags = AVFMT_NOFILE, 1097 .priv_class = &dshow_class, 1098}; 1099