00001 /* 00002 * Directshow capture interface 00003 * Copyright (c) 2010 Ramiro Polla 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavutil/parseutils.h" 00023 #include "libavutil/pixdesc.h" 00024 #include "libavutil/opt.h" 00025 #include "libavformat/internal.h" 00026 #include "avdevice.h" 00027 #include "dshow_capture.h" 00028 00029 struct dshow_ctx { 00030 const AVClass *class; 00031 00032 IGraphBuilder *graph; 00033 00034 char *device_name[2]; 00035 int video_device_number; 00036 int audio_device_number; 00037 00038 int list_options; 00039 int list_devices; 00040 int audio_buffer_size; 00041 00042 IBaseFilter *device_filter[2]; 00043 IPin *device_pin[2]; 00044 libAVFilter *capture_filter[2]; 00045 libAVPin *capture_pin[2]; 00046 00047 HANDLE mutex; 00048 HANDLE event; 00049 AVPacketList *pktl; 00050 00051 int64_t curbufsize; 00052 unsigned int video_frame_num; 00053 00054 IMediaControl *control; 00055 00056 enum PixelFormat pixel_format; 00057 enum AVCodecID video_codec_id; 00058 char *framerate; 00059 00060 int requested_width; 00061 int requested_height; 00062 AVRational requested_framerate; 00063 00064 int sample_rate; 00065 int sample_size; 00066 int channels; 00067 }; 00068 00069 static enum PixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount) 00070 { 00071 switch(biCompression) { 00072 case MKTAG('U', 'Y', 'V', 'Y'): 00073 return PIX_FMT_UYVY422; 00074 case MKTAG('Y', 'U', 'Y', '2'): 00075 return PIX_FMT_YUYV422; 00076 case MKTAG('I', '4', '2', '0'): 00077 return PIX_FMT_YUV420P; 00078 case BI_BITFIELDS: 00079 case BI_RGB: 00080 switch(biBitCount) { /* 1-8 are untested */ 00081 case 1: 00082 return PIX_FMT_MONOWHITE; 00083 case 4: 00084 return PIX_FMT_RGB4; 00085 case 8: 00086 return PIX_FMT_RGB8; 00087 case 16: 00088 return PIX_FMT_RGB555; 00089 case 24: 00090 return PIX_FMT_BGR24; 00091 case 32: 00092 return PIX_FMT_RGB32; 00093 } 00094 } 00095 return PIX_FMT_NONE; 00096 } 00097 00098 static enum AVCodecID dshow_codecid(DWORD biCompression) 00099 { 00100 switch(biCompression) { 00101 case MKTAG('d', 'v', 's', 'd'): 00102 return AV_CODEC_ID_DVVIDEO; 00103 case MKTAG('M', 'J', 'P', 'G'): 00104 case MKTAG('m', 'j', 'p', 'g'): 00105 return AV_CODEC_ID_MJPEG; 00106 } 00107 return AV_CODEC_ID_NONE; 00108 } 00109 00110 static int 00111 dshow_read_close(AVFormatContext *s) 00112 { 00113 struct dshow_ctx *ctx = s->priv_data; 00114 AVPacketList *pktl; 00115 00116 if (ctx->control) { 00117 IMediaControl_Stop(ctx->control); 00118 IMediaControl_Release(ctx->control); 00119 } 00120 00121 if (ctx->graph) { 00122 IEnumFilters *fenum; 00123 int r; 00124 r = IGraphBuilder_EnumFilters(ctx->graph, &fenum); 00125 if (r == S_OK) { 00126 IBaseFilter *f; 00127 IEnumFilters_Reset(fenum); 00128 while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) { 00129 if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK) 00130 IEnumFilters_Reset(fenum); /* When a filter is removed, 00131 * the list must be reset. */ 00132 IBaseFilter_Release(f); 00133 } 00134 IEnumFilters_Release(fenum); 00135 } 00136 IGraphBuilder_Release(ctx->graph); 00137 } 00138 00139 if (ctx->capture_pin[VideoDevice]) 00140 libAVPin_Release(ctx->capture_pin[VideoDevice]); 00141 if (ctx->capture_pin[AudioDevice]) 00142 libAVPin_Release(ctx->capture_pin[AudioDevice]); 00143 if (ctx->capture_filter[VideoDevice]) 00144 libAVFilter_Release(ctx->capture_filter[VideoDevice]); 00145 if (ctx->capture_filter[AudioDevice]) 00146 libAVFilter_Release(ctx->capture_filter[AudioDevice]); 00147 00148 if (ctx->device_pin[VideoDevice]) 00149 IPin_Release(ctx->device_pin[VideoDevice]); 00150 if (ctx->device_pin[AudioDevice]) 00151 IPin_Release(ctx->device_pin[AudioDevice]); 00152 if (ctx->device_filter[VideoDevice]) 00153 IBaseFilter_Release(ctx->device_filter[VideoDevice]); 00154 if (ctx->device_filter[AudioDevice]) 00155 IBaseFilter_Release(ctx->device_filter[AudioDevice]); 00156 00157 if (ctx->device_name[0]) 00158 av_free(ctx->device_name[0]); 00159 if (ctx->device_name[1]) 00160 av_free(ctx->device_name[1]); 00161 00162 if(ctx->mutex) 00163 CloseHandle(ctx->mutex); 00164 if(ctx->event) 00165 CloseHandle(ctx->event); 00166 00167 pktl = ctx->pktl; 00168 while (pktl) { 00169 AVPacketList *next = pktl->next; 00170 av_destruct_packet(&pktl->pkt); 00171 av_free(pktl); 00172 pktl = next; 00173 } 00174 00175 return 0; 00176 } 00177 00178 static char *dup_wchar_to_utf8(wchar_t *w) 00179 { 00180 char *s = NULL; 00181 int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0); 00182 s = av_malloc(l); 00183 if (s) 00184 WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0); 00185 return s; 00186 } 00187 00188 static int shall_we_drop(AVFormatContext *s) 00189 { 00190 struct dshow_ctx *ctx = s->priv_data; 00191 const uint8_t dropscore[] = {62, 75, 87, 100}; 00192 const int ndropscores = FF_ARRAY_ELEMS(dropscore); 00193 unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer; 00194 00195 if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) { 00196 av_log(s, AV_LOG_ERROR, 00197 "real-time buffer %d%% full! frame dropped!\n", buffer_fullness); 00198 return 1; 00199 } 00200 00201 return 0; 00202 } 00203 00204 static void 00205 callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time) 00206 { 00207 AVFormatContext *s = priv_data; 00208 struct dshow_ctx *ctx = s->priv_data; 00209 AVPacketList **ppktl, *pktl_next; 00210 00211 // dump_videohdr(s, vdhdr); 00212 00213 WaitForSingleObject(ctx->mutex, INFINITE); 00214 00215 if(shall_we_drop(s)) 00216 goto fail; 00217 00218 pktl_next = av_mallocz(sizeof(AVPacketList)); 00219 if(!pktl_next) 00220 goto fail; 00221 00222 if(av_new_packet(&pktl_next->pkt, buf_size) < 0) { 00223 av_free(pktl_next); 00224 goto fail; 00225 } 00226 00227 pktl_next->pkt.stream_index = index; 00228 pktl_next->pkt.pts = time; 00229 memcpy(pktl_next->pkt.data, buf, buf_size); 00230 00231 for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next); 00232 *ppktl = pktl_next; 00233 00234 ctx->curbufsize += buf_size; 00235 00236 SetEvent(ctx->event); 00237 ReleaseMutex(ctx->mutex); 00238 00239 return; 00240 fail: 00241 ReleaseMutex(ctx->mutex); 00242 return; 00243 } 00244 00251 static int 00252 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, 00253 enum dshowDeviceType devtype, IBaseFilter **pfilter) 00254 { 00255 struct dshow_ctx *ctx = avctx->priv_data; 00256 IBaseFilter *device_filter = NULL; 00257 IEnumMoniker *classenum = NULL; 00258 IMoniker *m = NULL; 00259 const char *device_name = ctx->device_name[devtype]; 00260 int skip = (devtype == VideoDevice) ? ctx->video_device_number 00261 : ctx->audio_device_number; 00262 int r; 00263 00264 const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory, 00265 &CLSID_AudioInputDeviceCategory }; 00266 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio"; 00267 00268 r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype], 00269 (IEnumMoniker **) &classenum, 0); 00270 if (r != S_OK) { 00271 av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n", 00272 devtypename); 00273 return AVERROR(EIO); 00274 } 00275 00276 while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) { 00277 IPropertyBag *bag = NULL; 00278 char *buf = NULL; 00279 VARIANT var; 00280 00281 r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag); 00282 if (r != S_OK) 00283 goto fail1; 00284 00285 var.vt = VT_BSTR; 00286 r = IPropertyBag_Read(bag, L "FriendlyName", &var, NULL); 00287 if (r != S_OK) 00288 goto fail1; 00289 00290 buf = dup_wchar_to_utf8(var.bstrVal); 00291 00292 if (pfilter) { 00293 if (strcmp(device_name, buf)) 00294 goto fail1; 00295 00296 if (!skip--) 00297 IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter); 00298 } else { 00299 av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf); 00300 } 00301 00302 fail1: 00303 if (buf) 00304 av_free(buf); 00305 if (bag) 00306 IPropertyBag_Release(bag); 00307 IMoniker_Release(m); 00308 } 00309 00310 IEnumMoniker_Release(classenum); 00311 00312 if (pfilter) { 00313 if (!device_filter) { 00314 av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n", 00315 devtypename); 00316 return AVERROR(EIO); 00317 } 00318 *pfilter = device_filter; 00319 } 00320 00321 return 0; 00322 } 00323 00330 static void 00331 dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, 00332 IPin *pin, int *pformat_set) 00333 { 00334 struct dshow_ctx *ctx = avctx->priv_data; 00335 IAMStreamConfig *config = NULL; 00336 AM_MEDIA_TYPE *type = NULL; 00337 int format_set = 0; 00338 void *caps = NULL; 00339 int i, n, size; 00340 00341 if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK) 00342 return; 00343 if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK) 00344 goto end; 00345 00346 caps = av_malloc(size); 00347 if (!caps) 00348 goto end; 00349 00350 for (i = 0; i < n && !format_set; i++) { 00351 IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps); 00352 00353 #if DSHOWDEBUG 00354 ff_print_AM_MEDIA_TYPE(type); 00355 #endif 00356 00357 if (devtype == VideoDevice) { 00358 VIDEO_STREAM_CONFIG_CAPS *vcaps = caps; 00359 BITMAPINFOHEADER *bih; 00360 int64_t *fr; 00361 #if DSHOWDEBUG 00362 ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps); 00363 #endif 00364 if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) { 00365 VIDEOINFOHEADER *v = (void *) type->pbFormat; 00366 fr = &v->AvgTimePerFrame; 00367 bih = &v->bmiHeader; 00368 } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) { 00369 VIDEOINFOHEADER2 *v = (void *) type->pbFormat; 00370 fr = &v->AvgTimePerFrame; 00371 bih = &v->bmiHeader; 00372 } else { 00373 goto next; 00374 } 00375 if (!pformat_set) { 00376 enum PixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount); 00377 if (pix_fmt == PIX_FMT_NONE) { 00378 enum AVCodecID codec_id = dshow_codecid(bih->biCompression); 00379 AVCodec *codec = avcodec_find_decoder(codec_id); 00380 if (codec_id == AV_CODEC_ID_NONE || !codec) { 00381 av_log(avctx, AV_LOG_INFO, " unknown compression type"); 00382 } else { 00383 av_log(avctx, AV_LOG_INFO, " vcodec=%s", codec->name); 00384 } 00385 } else { 00386 av_log(avctx, AV_LOG_INFO, " pixel_format=%s", av_get_pix_fmt_name(pix_fmt)); 00387 } 00388 av_log(avctx, AV_LOG_INFO, " min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n", 00389 vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy, 00390 1e7 / vcaps->MaxFrameInterval, 00391 vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy, 00392 1e7 / vcaps->MinFrameInterval); 00393 continue; 00394 } 00395 if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) { 00396 if (ctx->video_codec_id != dshow_codecid(bih->biCompression)) 00397 goto next; 00398 } 00399 if (ctx->pixel_format != PIX_FMT_NONE && 00400 ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) { 00401 goto next; 00402 } 00403 if (ctx->framerate) { 00404 int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000) 00405 / ctx->requested_framerate.num; 00406 if (framerate > vcaps->MaxFrameInterval || 00407 framerate < vcaps->MinFrameInterval) 00408 goto next; 00409 *fr = framerate; 00410 } 00411 if (ctx->requested_width && ctx->requested_height) { 00412 if (ctx->requested_width > vcaps->MaxOutputSize.cx || 00413 ctx->requested_width < vcaps->MinOutputSize.cx || 00414 ctx->requested_height > vcaps->MaxOutputSize.cy || 00415 ctx->requested_height < vcaps->MinOutputSize.cy) 00416 goto next; 00417 bih->biWidth = ctx->requested_width; 00418 bih->biHeight = ctx->requested_height; 00419 } 00420 } else { 00421 AUDIO_STREAM_CONFIG_CAPS *acaps = caps; 00422 WAVEFORMATEX *fx; 00423 #if DSHOWDEBUG 00424 ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps); 00425 #endif 00426 if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) { 00427 fx = (void *) type->pbFormat; 00428 } else { 00429 goto next; 00430 } 00431 if (!pformat_set) { 00432 av_log(avctx, AV_LOG_INFO, " min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n", 00433 acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency, 00434 acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency); 00435 continue; 00436 } 00437 if (ctx->sample_rate) { 00438 if (ctx->sample_rate > acaps->MaximumSampleFrequency || 00439 ctx->sample_rate < acaps->MinimumSampleFrequency) 00440 goto next; 00441 fx->nSamplesPerSec = ctx->sample_rate; 00442 } 00443 if (ctx->sample_size) { 00444 if (ctx->sample_size > acaps->MaximumBitsPerSample || 00445 ctx->sample_size < acaps->MinimumBitsPerSample) 00446 goto next; 00447 fx->wBitsPerSample = ctx->sample_size; 00448 } 00449 if (ctx->channels) { 00450 if (ctx->channels > acaps->MaximumChannels || 00451 ctx->channels < acaps->MinimumChannels) 00452 goto next; 00453 fx->nChannels = ctx->channels; 00454 } 00455 } 00456 if (IAMStreamConfig_SetFormat(config, type) != S_OK) 00457 goto next; 00458 format_set = 1; 00459 next: 00460 if (type->pbFormat) 00461 CoTaskMemFree(type->pbFormat); 00462 CoTaskMemFree(type); 00463 } 00464 end: 00465 IAMStreamConfig_Release(config); 00466 if (caps) 00467 av_free(caps); 00468 if (pformat_set) 00469 *pformat_set = format_set; 00470 } 00471 00476 static int 00477 dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin) 00478 { 00479 struct dshow_ctx *ctx = avctx->priv_data; 00480 IAMBufferNegotiation *buffer_negotiation = NULL; 00481 ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 }; 00482 IAMStreamConfig *config = NULL; 00483 AM_MEDIA_TYPE *type = NULL; 00484 int ret = AVERROR(EIO); 00485 00486 if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK) 00487 goto end; 00488 if (IAMStreamConfig_GetFormat(config, &type) != S_OK) 00489 goto end; 00490 if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) 00491 goto end; 00492 00493 props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec) 00494 * ctx->audio_buffer_size / 1000; 00495 00496 if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK) 00497 goto end; 00498 if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK) 00499 goto end; 00500 00501 ret = 0; 00502 00503 end: 00504 if (buffer_negotiation) 00505 IAMBufferNegotiation_Release(buffer_negotiation); 00506 if (type) { 00507 if (type->pbFormat) 00508 CoTaskMemFree(type->pbFormat); 00509 CoTaskMemFree(type); 00510 } 00511 if (config) 00512 IAMStreamConfig_Release(config); 00513 00514 return ret; 00515 } 00516 00523 static int 00524 dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype, 00525 IBaseFilter *device_filter, IPin **ppin) 00526 { 00527 struct dshow_ctx *ctx = avctx->priv_data; 00528 IEnumPins *pins = 0; 00529 IPin *device_pin = NULL; 00530 IPin *pin; 00531 int r; 00532 00533 const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio }; 00534 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio"; 00535 00536 int set_format = (devtype == VideoDevice && (ctx->framerate || 00537 (ctx->requested_width && ctx->requested_height) || 00538 ctx->pixel_format != PIX_FMT_NONE || 00539 ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO)) 00540 || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate)); 00541 int format_set = 0; 00542 00543 r = IBaseFilter_EnumPins(device_filter, &pins); 00544 if (r != S_OK) { 00545 av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n"); 00546 return AVERROR(EIO); 00547 } 00548 00549 if (!ppin) { 00550 av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n", 00551 devtypename); 00552 } 00553 while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) { 00554 IKsPropertySet *p = NULL; 00555 IEnumMediaTypes *types = NULL; 00556 PIN_INFO info = {0}; 00557 AM_MEDIA_TYPE *type; 00558 GUID category; 00559 DWORD r2; 00560 00561 IPin_QueryPinInfo(pin, &info); 00562 IBaseFilter_Release(info.pFilter); 00563 00564 if (info.dir != PINDIR_OUTPUT) 00565 goto next; 00566 if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK) 00567 goto next; 00568 if (IKsPropertySet_Get(p, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, 00569 NULL, 0, &category, sizeof(GUID), &r2) != S_OK) 00570 goto next; 00571 if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE)) 00572 goto next; 00573 00574 if (!ppin) { 00575 char *buf = dup_wchar_to_utf8(info.achName); 00576 av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf); 00577 av_free(buf); 00578 dshow_cycle_formats(avctx, devtype, pin, NULL); 00579 goto next; 00580 } 00581 if (set_format) { 00582 dshow_cycle_formats(avctx, devtype, pin, &format_set); 00583 if (!format_set) { 00584 goto next; 00585 } 00586 } 00587 if (devtype == AudioDevice && ctx->audio_buffer_size) { 00588 if (dshow_set_audio_buffer_size(avctx, pin) < 0) 00589 goto next; 00590 } 00591 00592 if (IPin_EnumMediaTypes(pin, &types) != S_OK) 00593 goto next; 00594 00595 IEnumMediaTypes_Reset(types); 00596 while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) { 00597 if (IsEqualGUID(&type->majortype, mediatype[devtype])) { 00598 device_pin = pin; 00599 goto next; 00600 } 00601 CoTaskMemFree(type); 00602 } 00603 00604 next: 00605 if (types) 00606 IEnumMediaTypes_Release(types); 00607 if (p) 00608 IKsPropertySet_Release(p); 00609 if (device_pin != pin) 00610 IPin_Release(pin); 00611 } 00612 00613 IEnumPins_Release(pins); 00614 00615 if (ppin) { 00616 if (set_format && !format_set) { 00617 av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename); 00618 return AVERROR(EIO); 00619 } 00620 if (!device_pin) { 00621 av_log(avctx, AV_LOG_ERROR, 00622 "Could not find output pin from %s capture device.\n", devtypename); 00623 return AVERROR(EIO); 00624 } 00625 *ppin = device_pin; 00626 } 00627 00628 return 0; 00629 } 00630 00636 static int 00637 dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum, 00638 enum dshowDeviceType devtype) 00639 { 00640 struct dshow_ctx *ctx = avctx->priv_data; 00641 IBaseFilter *device_filter = NULL; 00642 int r; 00643 00644 if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) 00645 return r; 00646 ctx->device_filter[devtype] = device_filter; 00647 if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0) 00648 return r; 00649 00650 return 0; 00651 } 00652 00653 static int 00654 dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, 00655 enum dshowDeviceType devtype) 00656 { 00657 struct dshow_ctx *ctx = avctx->priv_data; 00658 IBaseFilter *device_filter = NULL; 00659 IGraphBuilder *graph = ctx->graph; 00660 IPin *device_pin = NULL; 00661 libAVPin *capture_pin = NULL; 00662 libAVFilter *capture_filter = NULL; 00663 int ret = AVERROR(EIO); 00664 int r; 00665 00666 const wchar_t *filter_name[2] = { L "Audio capture filter", L "Video capture filter" }; 00667 00668 if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) { 00669 ret = r; 00670 goto error; 00671 } 00672 00673 ctx->device_filter [devtype] = device_filter; 00674 00675 r = IGraphBuilder_AddFilter(graph, device_filter, NULL); 00676 if (r != S_OK) { 00677 av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n"); 00678 goto error; 00679 } 00680 00681 if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) { 00682 ret = r; 00683 goto error; 00684 } 00685 ctx->device_pin[devtype] = device_pin; 00686 00687 capture_filter = libAVFilter_Create(avctx, callback, devtype); 00688 if (!capture_filter) { 00689 av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n"); 00690 goto error; 00691 } 00692 ctx->capture_filter[devtype] = capture_filter; 00693 00694 r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter, 00695 filter_name[devtype]); 00696 if (r != S_OK) { 00697 av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n"); 00698 goto error; 00699 } 00700 00701 libAVPin_AddRef(capture_filter->pin); 00702 capture_pin = capture_filter->pin; 00703 ctx->capture_pin[devtype] = capture_pin; 00704 00705 r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL); 00706 if (r != S_OK) { 00707 av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n"); 00708 goto error; 00709 } 00710 00711 ret = 0; 00712 00713 error: 00714 return ret; 00715 } 00716 00717 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt) 00718 { 00719 switch (sample_fmt) { 00720 case AV_SAMPLE_FMT_U8: return AV_CODEC_ID_PCM_U8; 00721 case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE; 00722 case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE; 00723 default: return AV_CODEC_ID_NONE; /* Should never happen. */ 00724 } 00725 } 00726 00727 static enum AVSampleFormat sample_fmt_bits_per_sample(int bits) 00728 { 00729 switch (bits) { 00730 case 8: return AV_SAMPLE_FMT_U8; 00731 case 16: return AV_SAMPLE_FMT_S16; 00732 case 32: return AV_SAMPLE_FMT_S32; 00733 default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */ 00734 } 00735 } 00736 00737 static int 00738 dshow_add_device(AVFormatContext *avctx, 00739 enum dshowDeviceType devtype) 00740 { 00741 struct dshow_ctx *ctx = avctx->priv_data; 00742 AM_MEDIA_TYPE type; 00743 AVCodecContext *codec; 00744 AVStream *st; 00745 int ret = AVERROR(EIO); 00746 00747 st = avformat_new_stream(avctx, NULL); 00748 if (!st) { 00749 ret = AVERROR(ENOMEM); 00750 goto error; 00751 } 00752 st->id = devtype; 00753 00754 ctx->capture_filter[devtype]->stream_index = st->index; 00755 00756 libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type); 00757 00758 codec = st->codec; 00759 if (devtype == VideoDevice) { 00760 BITMAPINFOHEADER *bih = NULL; 00761 AVRational time_base; 00762 00763 if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) { 00764 VIDEOINFOHEADER *v = (void *) type.pbFormat; 00765 time_base = (AVRational) { v->AvgTimePerFrame, 10000000 }; 00766 bih = &v->bmiHeader; 00767 } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) { 00768 VIDEOINFOHEADER2 *v = (void *) type.pbFormat; 00769 time_base = (AVRational) { v->AvgTimePerFrame, 10000000 }; 00770 bih = &v->bmiHeader; 00771 } 00772 if (!bih) { 00773 av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n"); 00774 goto error; 00775 } 00776 00777 codec->time_base = time_base; 00778 codec->codec_type = AVMEDIA_TYPE_VIDEO; 00779 codec->width = bih->biWidth; 00780 codec->height = bih->biHeight; 00781 codec->pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount); 00782 if (codec->pix_fmt == PIX_FMT_NONE) { 00783 codec->codec_id = dshow_codecid(bih->biCompression); 00784 if (codec->codec_id == AV_CODEC_ID_NONE) { 00785 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. " 00786 "Please report verbose (-v 9) debug information.\n"); 00787 dshow_read_close(avctx); 00788 return AVERROR_PATCHWELCOME; 00789 } 00790 codec->bits_per_coded_sample = bih->biBitCount; 00791 } else { 00792 codec->codec_id = AV_CODEC_ID_RAWVIDEO; 00793 if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) { 00794 codec->bits_per_coded_sample = bih->biBitCount; 00795 codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE); 00796 if (codec->extradata) { 00797 codec->extradata_size = 9; 00798 memcpy(codec->extradata, "BottomUp", 9); 00799 } 00800 } 00801 } 00802 } else { 00803 WAVEFORMATEX *fx = NULL; 00804 00805 if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) { 00806 fx = (void *) type.pbFormat; 00807 } 00808 if (!fx) { 00809 av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n"); 00810 goto error; 00811 } 00812 00813 codec->codec_type = AVMEDIA_TYPE_AUDIO; 00814 codec->sample_fmt = sample_fmt_bits_per_sample(fx->wBitsPerSample); 00815 codec->codec_id = waveform_codec_id(codec->sample_fmt); 00816 codec->sample_rate = fx->nSamplesPerSec; 00817 codec->channels = fx->nChannels; 00818 } 00819 00820 avpriv_set_pts_info(st, 64, 1, 10000000); 00821 00822 ret = 0; 00823 00824 error: 00825 return ret; 00826 } 00827 00828 static int parse_device_name(AVFormatContext *avctx) 00829 { 00830 struct dshow_ctx *ctx = avctx->priv_data; 00831 char **device_name = ctx->device_name; 00832 char *name = av_strdup(avctx->filename); 00833 char *tmp = name; 00834 int ret = 1; 00835 char *type; 00836 00837 while ((type = strtok(tmp, "="))) { 00838 char *token = strtok(NULL, ":"); 00839 tmp = NULL; 00840 00841 if (!strcmp(type, "video")) { 00842 device_name[0] = token; 00843 } else if (!strcmp(type, "audio")) { 00844 device_name[1] = token; 00845 } else { 00846 device_name[0] = NULL; 00847 device_name[1] = NULL; 00848 break; 00849 } 00850 } 00851 00852 if (!device_name[0] && !device_name[1]) { 00853 ret = 0; 00854 } else { 00855 if (device_name[0]) 00856 device_name[0] = av_strdup(device_name[0]); 00857 if (device_name[1]) 00858 device_name[1] = av_strdup(device_name[1]); 00859 } 00860 00861 av_free(name); 00862 return ret; 00863 } 00864 00865 static int dshow_read_header(AVFormatContext *avctx) 00866 { 00867 struct dshow_ctx *ctx = avctx->priv_data; 00868 IGraphBuilder *graph = NULL; 00869 ICreateDevEnum *devenum = NULL; 00870 IMediaControl *control = NULL; 00871 int ret = AVERROR(EIO); 00872 int r; 00873 00874 if (!ctx->list_devices && !parse_device_name(avctx)) { 00875 av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n"); 00876 goto error; 00877 } 00878 00879 ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id 00880 : AV_CODEC_ID_RAWVIDEO; 00881 if (ctx->pixel_format != PIX_FMT_NONE) { 00882 if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) { 00883 av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when " 00884 "video codec is not set or set to rawvideo\n"); 00885 ret = AVERROR(EINVAL); 00886 goto error; 00887 } 00888 } 00889 if (ctx->framerate) { 00890 r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate); 00891 if (r < 0) { 00892 av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate); 00893 goto error; 00894 } 00895 } 00896 00897 CoInitialize(0); 00898 00899 r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 00900 &IID_IGraphBuilder, (void **) &graph); 00901 if (r != S_OK) { 00902 av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n"); 00903 goto error; 00904 } 00905 ctx->graph = graph; 00906 00907 r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, 00908 &IID_ICreateDevEnum, (void **) &devenum); 00909 if (r != S_OK) { 00910 av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n"); 00911 goto error; 00912 } 00913 00914 if (ctx->list_devices) { 00915 av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n"); 00916 dshow_cycle_devices(avctx, devenum, VideoDevice, NULL); 00917 av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n"); 00918 dshow_cycle_devices(avctx, devenum, AudioDevice, NULL); 00919 ret = AVERROR_EXIT; 00920 goto error; 00921 } 00922 if (ctx->list_options) { 00923 if (ctx->device_name[VideoDevice]) 00924 dshow_list_device_options(avctx, devenum, VideoDevice); 00925 if (ctx->device_name[AudioDevice]) 00926 dshow_list_device_options(avctx, devenum, AudioDevice); 00927 ret = AVERROR_EXIT; 00928 goto error; 00929 } 00930 00931 if (ctx->device_name[VideoDevice]) { 00932 ret = dshow_open_device(avctx, devenum, VideoDevice); 00933 if (ret < 0) 00934 goto error; 00935 ret = dshow_add_device(avctx, VideoDevice); 00936 if (ret < 0) 00937 goto error; 00938 } 00939 if (ctx->device_name[AudioDevice]) { 00940 ret = dshow_open_device(avctx, devenum, AudioDevice); 00941 if (ret < 0) 00942 goto error; 00943 ret = dshow_add_device(avctx, AudioDevice); 00944 if (ret < 0) 00945 goto error; 00946 } 00947 00948 ctx->mutex = CreateMutex(NULL, 0, NULL); 00949 if (!ctx->mutex) { 00950 av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n"); 00951 goto error; 00952 } 00953 ctx->event = CreateEvent(NULL, 1, 0, NULL); 00954 if (!ctx->event) { 00955 av_log(avctx, AV_LOG_ERROR, "Could not create Event\n"); 00956 goto error; 00957 } 00958 00959 r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control); 00960 if (r != S_OK) { 00961 av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n"); 00962 goto error; 00963 } 00964 ctx->control = control; 00965 00966 r = IMediaControl_Run(control); 00967 if (r == S_FALSE) { 00968 OAFilterState pfs; 00969 r = IMediaControl_GetState(control, 0, &pfs); 00970 } 00971 if (r != S_OK) { 00972 av_log(avctx, AV_LOG_ERROR, "Could not run filter\n"); 00973 goto error; 00974 } 00975 00976 ret = 0; 00977 00978 error: 00979 00980 if (ret < 0) 00981 dshow_read_close(avctx); 00982 00983 if (devenum) 00984 ICreateDevEnum_Release(devenum); 00985 00986 return ret; 00987 } 00988 00989 static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt) 00990 { 00991 struct dshow_ctx *ctx = s->priv_data; 00992 AVPacketList *pktl = NULL; 00993 00994 while (!pktl) { 00995 WaitForSingleObject(ctx->mutex, INFINITE); 00996 pktl = ctx->pktl; 00997 if (pktl) { 00998 *pkt = pktl->pkt; 00999 ctx->pktl = ctx->pktl->next; 01000 av_free(pktl); 01001 ctx->curbufsize -= pkt->size; 01002 } 01003 ResetEvent(ctx->event); 01004 ReleaseMutex(ctx->mutex); 01005 if (!pktl) { 01006 if (s->flags & AVFMT_FLAG_NONBLOCK) { 01007 return AVERROR(EAGAIN); 01008 } else { 01009 WaitForSingleObject(ctx->event, INFINITE); 01010 } 01011 } 01012 } 01013 01014 return pkt->size; 01015 } 01016 01017 #define OFFSET(x) offsetof(struct dshow_ctx, x) 01018 #define DEC AV_OPT_FLAG_DECODING_PARAM 01019 static const AVOption options[] = { 01020 { "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 }, 01021 { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.str = NULL}, 0, 0, DEC }, 01022 { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, 01023 { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC }, 01024 { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC }, 01025 { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC }, 01026 { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" }, 01027 { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" }, 01028 { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" }, 01029 { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_options" }, 01030 { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_options" }, 01031 { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_options" }, 01032 { "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 }, 01033 { "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 }, 01034 { "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 }, 01035 { NULL }, 01036 }; 01037 01038 static const AVClass dshow_class = { 01039 .class_name = "DirectShow indev", 01040 .item_name = av_default_item_name, 01041 .option = options, 01042 .version = LIBAVUTIL_VERSION_INT, 01043 }; 01044 01045 AVInputFormat ff_dshow_demuxer = { 01046 .name = "dshow", 01047 .long_name = NULL_IF_CONFIG_SMALL("DirectShow capture"), 01048 .priv_data_size = sizeof(struct dshow_ctx), 01049 .read_header = dshow_read_header, 01050 .read_packet = dshow_read_packet, 01051 .read_close = dshow_read_close, 01052 .flags = AVFMT_NOFILE, 01053 .priv_class = &dshow_class, 01054 };