Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.  
  31. struct 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;
  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.  
  75. static 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_RGB32;
  93.         }
  94.     }
  95.     return avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, biCompression); // all others
  96. }
  97.  
  98. static int
  99. dshow_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.  
  173. static 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.  
  183. static int shall_we_drop(AVFormatContext *s)
  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*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 %d%% full! frame dropped!\n", buffer_fullness);
  193.         return 1;
  194.     }
  195.  
  196.     return 0;
  197. }
  198.  
  199. static void
  200. callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
  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))
  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.  
  229.     ctx->curbufsize += buf_size;
  230.  
  231.     SetEvent(ctx->event[1]);
  232.     ReleaseMutex(ctx->mutex);
  233.  
  234.     return;
  235. fail:
  236.     ReleaseMutex(ctx->mutex);
  237.     return;
  238. }
  239.  
  240. /**
  241.  * Cycle through available devices using the device enumerator devenum,
  242.  * retrieve the device with type specified by devtype and return the
  243.  * pointer to the object found in *pfilter.
  244.  * If pfilter is NULL, list all device names.
  245.  */
  246. static int
  247. dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
  248.                     enum dshowDeviceType devtype, IBaseFilter **pfilter)
  249. {
  250.     struct dshow_ctx *ctx = avctx->priv_data;
  251.     IBaseFilter *device_filter = NULL;
  252.     IEnumMoniker *classenum = NULL;
  253.     IMoniker *m = NULL;
  254.     const char *device_name = ctx->device_name[devtype];
  255.     int skip = (devtype == VideoDevice) ? ctx->video_device_number
  256.                                         : ctx->audio_device_number;
  257.     int r;
  258.  
  259.     const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
  260.                                    &CLSID_AudioInputDeviceCategory };
  261.     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
  262.  
  263.     r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
  264.                                              (IEnumMoniker **) &classenum, 0);
  265.     if (r != S_OK) {
  266.         av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
  267.                devtypename);
  268.         return AVERROR(EIO);
  269.     }
  270.  
  271.     while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
  272.         IPropertyBag *bag = NULL;
  273.         char *buf = NULL;
  274.         VARIANT var;
  275.  
  276.         r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
  277.         if (r != S_OK)
  278.             goto fail1;
  279.  
  280.         var.vt = VT_BSTR;
  281.         r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
  282.         if (r != S_OK)
  283.             goto fail1;
  284.  
  285.         buf = dup_wchar_to_utf8(var.bstrVal);
  286.  
  287.         if (pfilter) {
  288.             if (strcmp(device_name, buf))
  289.                 goto fail1;
  290.  
  291.             if (!skip--)
  292.                 IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
  293.         } else {
  294.             av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
  295.         }
  296.  
  297. fail1:
  298.         if (buf)
  299.             av_free(buf);
  300.         if (bag)
  301.             IPropertyBag_Release(bag);
  302.         IMoniker_Release(m);
  303.     }
  304.  
  305.     IEnumMoniker_Release(classenum);
  306.  
  307.     if (pfilter) {
  308.         if (!device_filter) {
  309.             av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
  310.                    devtypename);
  311.             return AVERROR(EIO);
  312.         }
  313.         *pfilter = device_filter;
  314.     }
  315.  
  316.     return 0;
  317. }
  318.  
  319. /**
  320.  * Cycle through available formats using the specified pin,
  321.  * try to set parameters specified through AVOptions and if successful
  322.  * return 1 in *pformat_set.
  323.  * If pformat_set is NULL, list all pin capabilities.
  324.  */
  325. static void
  326. dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
  327.                     IPin *pin, int *pformat_set)
  328. {
  329.     struct dshow_ctx *ctx = avctx->priv_data;
  330.     IAMStreamConfig *config = NULL;
  331.     AM_MEDIA_TYPE *type = NULL;
  332.     int format_set = 0;
  333.     void *caps = NULL;
  334.     int i, n, size;
  335.  
  336.     if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
  337.         return;
  338.     if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
  339.         goto end;
  340.  
  341.     caps = av_malloc(size);
  342.     if (!caps)
  343.         goto end;
  344.  
  345.     for (i = 0; i < n && !format_set; i++) {
  346.         IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
  347.  
  348. #if DSHOWDEBUG
  349.         ff_print_AM_MEDIA_TYPE(type);
  350. #endif
  351.  
  352.         if (devtype == VideoDevice) {
  353.             VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
  354.             BITMAPINFOHEADER *bih;
  355.             int64_t *fr;
  356. #if DSHOWDEBUG
  357.             ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
  358. #endif
  359.             if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
  360.                 VIDEOINFOHEADER *v = (void *) type->pbFormat;
  361.                 fr = &v->AvgTimePerFrame;
  362.                 bih = &v->bmiHeader;
  363.             } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
  364.                 VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
  365.                 fr = &v->AvgTimePerFrame;
  366.                 bih = &v->bmiHeader;
  367.             } else {
  368.                 goto next;
  369.             }
  370.             if (!pformat_set) {
  371.                 enum AVPixelFormat pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
  372.                 if (pix_fmt == AV_PIX_FMT_NONE) {
  373.                     enum AVCodecID codec_id = ff_codec_get_id(avformat_get_riff_video_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);
  377.                     } else {
  378.                         av_log(avctx, AV_LOG_INFO, "  vcodec=%s", codec->name);
  379.                     }
  380.                 } else {
  381.                     av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
  382.                 }
  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);
  388.                 continue;
  389.             }
  390.             if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
  391.                 if (ctx->video_codec_id != ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression))
  392.                     goto next;
  393.             }
  394.             if (ctx->pixel_format != AV_PIX_FMT_NONE &&
  395.                 ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
  396.                 goto next;
  397.             }
  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)
  403.                     goto next;
  404.                 *fr = framerate;
  405.             }
  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)
  411.                     goto next;
  412.                 bih->biWidth  = ctx->requested_width;
  413.                 bih->biHeight = ctx->requested_height;
  414.             }
  415.         } else {
  416.             AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
  417.             WAVEFORMATEX *fx;
  418. #if DSHOWDEBUG
  419.             ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
  420. #endif
  421.             if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
  422.                 fx = (void *) type->pbFormat;
  423.             } else {
  424.                 goto next;
  425.             }
  426.             if (!pformat_set) {
  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);
  430.                 continue;
  431.             }
  432.             if (ctx->sample_rate) {
  433.                 if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
  434.                     ctx->sample_rate < acaps->MinimumSampleFrequency)
  435.                     goto next;
  436.                 fx->nSamplesPerSec = ctx->sample_rate;
  437.             }
  438.             if (ctx->sample_size) {
  439.                 if (ctx->sample_size > acaps->MaximumBitsPerSample ||
  440.                     ctx->sample_size < acaps->MinimumBitsPerSample)
  441.                     goto next;
  442.                 fx->wBitsPerSample = ctx->sample_size;
  443.             }
  444.             if (ctx->channels) {
  445.                 if (ctx->channels > acaps->MaximumChannels ||
  446.                     ctx->channels < acaps->MinimumChannels)
  447.                     goto next;
  448.                 fx->nChannels = ctx->channels;
  449.             }
  450.         }
  451.         if (IAMStreamConfig_SetFormat(config, type) != S_OK)
  452.             goto next;
  453.         format_set = 1;
  454. next:
  455.         if (type->pbFormat)
  456.             CoTaskMemFree(type->pbFormat);
  457.         CoTaskMemFree(type);
  458.     }
  459. end:
  460.     IAMStreamConfig_Release(config);
  461.     if (caps)
  462.         av_free(caps);
  463.     if (pformat_set)
  464.         *pformat_set = format_set;
  465. }
  466.  
  467. /**
  468.  * Set audio device buffer size in milliseconds (which can directly impact
  469.  * latency, depending on the device).
  470.  */
  471. static int
  472. dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
  473. {
  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);
  480.  
  481.     if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
  482.         goto end;
  483.     if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
  484.         goto end;
  485.     if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
  486.         goto end;
  487.  
  488.     props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
  489.                    * ctx->audio_buffer_size / 1000;
  490.  
  491.     if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
  492.         goto end;
  493.     if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
  494.         goto end;
  495.  
  496.     ret = 0;
  497.  
  498. end:
  499.     if (buffer_negotiation)
  500.         IAMBufferNegotiation_Release(buffer_negotiation);
  501.     if (type) {
  502.         if (type->pbFormat)
  503.             CoTaskMemFree(type->pbFormat);
  504.         CoTaskMemFree(type);
  505.     }
  506.     if (config)
  507.         IAMStreamConfig_Release(config);
  508.  
  509.     return ret;
  510. }
  511.  
  512. /**
  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.
  517.  */
  518. static int
  519. dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
  520.                  IBaseFilter *device_filter, IPin **ppin)
  521. {
  522.     struct dshow_ctx *ctx = avctx->priv_data;
  523.     IEnumPins *pins = 0;
  524.     IPin *device_pin = NULL;
  525.     IPin *pin;
  526.     int r;
  527.  
  528.     const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
  529.     const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
  530.  
  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));
  536.     int format_set = 0;
  537.  
  538.     r = IBaseFilter_EnumPins(device_filter, &pins);
  539.     if (r != S_OK) {
  540.         av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
  541.         return AVERROR(EIO);
  542.     }
  543.  
  544.     if (!ppin) {
  545.         av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
  546.                devtypename);
  547.     }
  548.     while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
  549.         IKsPropertySet *p = NULL;
  550.         IEnumMediaTypes *types = NULL;
  551.         PIN_INFO info = {0};
  552.         AM_MEDIA_TYPE *type;
  553.         GUID category;
  554.         DWORD r2;
  555.  
  556.         IPin_QueryPinInfo(pin, &info);
  557.         IBaseFilter_Release(info.pFilter);
  558.  
  559.         if (info.dir != PINDIR_OUTPUT)
  560.             goto next;
  561.         if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
  562.             goto next;
  563.         if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
  564.                                NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
  565.             goto next;
  566.         if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
  567.             goto next;
  568.  
  569.         if (!ppin) {
  570.             char *buf = dup_wchar_to_utf8(info.achName);
  571.             av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
  572.             av_free(buf);
  573.             dshow_cycle_formats(avctx, devtype, pin, NULL);
  574.             goto next;
  575.         }
  576.         if (set_format) {
  577.             dshow_cycle_formats(avctx, devtype, pin, &format_set);
  578.             if (!format_set) {
  579.                 goto next;
  580.             }
  581.         }
  582.         if (devtype == AudioDevice && ctx->audio_buffer_size) {
  583.             if (dshow_set_audio_buffer_size(avctx, pin) < 0)
  584.                 goto next;
  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.  
  599. next:
  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.  */
  631. static int
  632. dshow_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.  
  648. static int
  649. dshow_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.  
  708. error:
  709.     return ret;
  710. }
  711.  
  712. static 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.  
  722. static 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.  
  732. static int
  733. dshow_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->pix_fmt    = dshow_pixfmt(bih->biCompression, bih->biBitCount);
  777.         if (bih->biCompression == MKTAG('H', 'D', 'Y', 'C')) {
  778.             av_log(avctx, AV_LOG_DEBUG, "attempt to use full range for HDYC...\n");
  779.             codec->color_range = AVCOL_RANGE_MPEG; // just in case it needs this...
  780.         }
  781.         if (codec->pix_fmt == AV_PIX_FMT_NONE) {
  782.             codec->codec_id = ff_codec_get_id(avformat_get_riff_video_tags(), bih->biCompression);
  783.             if (codec->codec_id == AV_CODEC_ID_NONE) {
  784.                 av_log(avctx, AV_LOG_ERROR, "Unknown compression type. "
  785.                                  "Please report type 0x%X.\n", (int) bih->biCompression);
  786.                 return AVERROR_PATCHWELCOME;
  787.             }
  788.             codec->bits_per_coded_sample = bih->biBitCount;
  789.         } else {
  790.             codec->codec_id = AV_CODEC_ID_RAWVIDEO;
  791.             if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
  792.                 codec->bits_per_coded_sample = bih->biBitCount;
  793.                 codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
  794.                 if (codec->extradata) {
  795.                     codec->extradata_size = 9;
  796.                     memcpy(codec->extradata, "BottomUp", 9);
  797.                 }
  798.             }
  799.         }
  800.     } else {
  801.         WAVEFORMATEX *fx = NULL;
  802.  
  803.         if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
  804.             fx = (void *) type.pbFormat;
  805.         }
  806.         if (!fx) {
  807.             av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
  808.             goto error;
  809.         }
  810.  
  811.         codec->codec_type  = AVMEDIA_TYPE_AUDIO;
  812.         codec->sample_fmt  = sample_fmt_bits_per_sample(fx->wBitsPerSample);
  813.         codec->codec_id    = waveform_codec_id(codec->sample_fmt);
  814.         codec->sample_rate = fx->nSamplesPerSec;
  815.         codec->channels    = fx->nChannels;
  816.     }
  817.  
  818.     avpriv_set_pts_info(st, 64, 1, 10000000);
  819.  
  820.     ret = 0;
  821.  
  822. error:
  823.     return ret;
  824. }
  825.  
  826. static int parse_device_name(AVFormatContext *avctx)
  827. {
  828.     struct dshow_ctx *ctx = avctx->priv_data;
  829.     char **device_name = ctx->device_name;
  830.     char *name = av_strdup(avctx->filename);
  831.     char *tmp = name;
  832.     int ret = 1;
  833.     char *type;
  834.  
  835.     while ((type = strtok(tmp, "="))) {
  836.         char *token = strtok(NULL, ":");
  837.         tmp = NULL;
  838.  
  839.         if        (!strcmp(type, "video")) {
  840.             device_name[0] = token;
  841.         } else if (!strcmp(type, "audio")) {
  842.             device_name[1] = token;
  843.         } else {
  844.             device_name[0] = NULL;
  845.             device_name[1] = NULL;
  846.             break;
  847.         }
  848.     }
  849.  
  850.     if (!device_name[0] && !device_name[1]) {
  851.         ret = 0;
  852.     } else {
  853.         if (device_name[0])
  854.             device_name[0] = av_strdup(device_name[0]);
  855.         if (device_name[1])
  856.             device_name[1] = av_strdup(device_name[1]);
  857.     }
  858.  
  859.     av_free(name);
  860.     return ret;
  861. }
  862.  
  863. static int dshow_read_header(AVFormatContext *avctx)
  864. {
  865.     struct dshow_ctx *ctx = avctx->priv_data;
  866.     IGraphBuilder *graph = NULL;
  867.     ICreateDevEnum *devenum = NULL;
  868.     IMediaControl *control = NULL;
  869.     IMediaEvent *media_event = NULL;
  870.     HANDLE media_event_handle;
  871.     HANDLE proc;
  872.     int ret = AVERROR(EIO);
  873.     int r;
  874.  
  875.     CoInitialize(0);
  876.  
  877.     if (!ctx->list_devices && !parse_device_name(avctx)) {
  878.         av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
  879.         goto error;
  880.     }
  881.  
  882.     ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
  883.                                                 : AV_CODEC_ID_RAWVIDEO;
  884.     if (ctx->pixel_format != AV_PIX_FMT_NONE) {
  885.         if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
  886.             av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
  887.                               "video codec is not set or set to rawvideo\n");
  888.             ret = AVERROR(EINVAL);
  889.             goto error;
  890.         }
  891.     }
  892.     if (ctx->framerate) {
  893.         r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
  894.         if (r < 0) {
  895.             av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
  896.             goto error;
  897.         }
  898.     }
  899.  
  900.     r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
  901.                          &IID_IGraphBuilder, (void **) &graph);
  902.     if (r != S_OK) {
  903.         av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
  904.         goto error;
  905.     }
  906.     ctx->graph = graph;
  907.  
  908.     r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
  909.                          &IID_ICreateDevEnum, (void **) &devenum);
  910.     if (r != S_OK) {
  911.         av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
  912.         goto error;
  913.     }
  914.  
  915.     if (ctx->list_devices) {
  916.         av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n");
  917.         dshow_cycle_devices(avctx, devenum, VideoDevice, NULL);
  918.         av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
  919.         dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
  920.         ret = AVERROR_EXIT;
  921.         goto error;
  922.     }
  923.     if (ctx->list_options) {
  924.         if (ctx->device_name[VideoDevice])
  925.             dshow_list_device_options(avctx, devenum, VideoDevice);
  926.         if (ctx->device_name[AudioDevice])
  927.             dshow_list_device_options(avctx, devenum, AudioDevice);
  928.         ret = AVERROR_EXIT;
  929.         goto error;
  930.     }
  931.  
  932.     if (ctx->device_name[VideoDevice]) {
  933.         if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 0 ||
  934.             (r = dshow_add_device(avctx, VideoDevice)) < 0) {
  935.             ret = r;
  936.             goto error;
  937.         }
  938.     }
  939.     if (ctx->device_name[AudioDevice]) {
  940.         if ((r = dshow_open_device(avctx, devenum, AudioDevice)) < 0 ||
  941.             (r = dshow_add_device(avctx, AudioDevice)) < 0) {
  942.             ret = r;
  943.             goto error;
  944.         }
  945.     }
  946.  
  947.     ctx->mutex = CreateMutex(NULL, 0, NULL);
  948.     if (!ctx->mutex) {
  949.         av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
  950.         goto error;
  951.     }
  952.     ctx->event[1] = CreateEvent(NULL, 1, 0, NULL);
  953.     if (!ctx->event[1]) {
  954.         av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
  955.         goto error;
  956.     }
  957.  
  958.     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
  959.     if (r != S_OK) {
  960.         av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
  961.         goto error;
  962.     }
  963.     ctx->control = control;
  964.  
  965.     r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event);
  966.     if (r != S_OK) {
  967.         av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n");
  968.         goto error;
  969.     }
  970.     ctx->media_event = media_event;
  971.  
  972.     r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle);
  973.     if (r != S_OK) {
  974.         av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n");
  975.         goto error;
  976.     }
  977.     proc = GetCurrentProcess();
  978.     r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0],
  979.                         0, 0, DUPLICATE_SAME_ACCESS);
  980.     if (!r) {
  981.         av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n");
  982.         goto error;
  983.     }
  984.  
  985.     r = IMediaControl_Run(control);
  986.     if (r == S_FALSE) {
  987.         OAFilterState pfs;
  988.         r = IMediaControl_GetState(control, 0, &pfs);
  989.     }
  990.     if (r != S_OK) {
  991.         av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
  992.         goto error;
  993.     }
  994.  
  995.     ret = 0;
  996.  
  997. error:
  998.  
  999.     if (devenum)
  1000.         ICreateDevEnum_Release(devenum);
  1001.  
  1002.     if (ret < 0)
  1003.         dshow_read_close(avctx);
  1004.  
  1005.     return ret;
  1006. }
  1007.  
  1008. /**
  1009.  * Checks media events from DirectShow and returns -1 on error or EOF. Also
  1010.  * purges all events that might be in the event queue to stop the trigger
  1011.  * of event notification.
  1012.  */
  1013. static int dshow_check_event_queue(IMediaEvent *media_event)
  1014. {
  1015.     LONG_PTR p1, p2;
  1016.     long code;
  1017.     int ret = 0;
  1018.  
  1019.     while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) {
  1020.         if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT)
  1021.             ret = -1;
  1022.         IMediaEvent_FreeEventParams(media_event, code, p1, p2);
  1023.     }
  1024.  
  1025.     return ret;
  1026. }
  1027.  
  1028. static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
  1029. {
  1030.     struct dshow_ctx *ctx = s->priv_data;
  1031.     AVPacketList *pktl = NULL;
  1032.  
  1033.     while (!ctx->eof && !pktl) {
  1034.         WaitForSingleObject(ctx->mutex, INFINITE);
  1035.         pktl = ctx->pktl;
  1036.         if (pktl) {
  1037.             *pkt = pktl->pkt;
  1038.             ctx->pktl = ctx->pktl->next;
  1039.             av_free(pktl);
  1040.             ctx->curbufsize -= pkt->size;
  1041.         }
  1042.         ResetEvent(ctx->event[1]);
  1043.         ReleaseMutex(ctx->mutex);
  1044.         if (!pktl) {
  1045.             if (dshow_check_event_queue(ctx->media_event) < 0) {
  1046.                 ctx->eof = 1;
  1047.             } else if (s->flags & AVFMT_FLAG_NONBLOCK) {
  1048.                 return AVERROR(EAGAIN);
  1049.             } else {
  1050.                 WaitForMultipleObjects(2, ctx->event, 0, INFINITE);
  1051.             }
  1052.         }
  1053.     }
  1054.  
  1055.     return ctx->eof ? AVERROR(EIO) : pkt->size;
  1056. }
  1057.  
  1058. #define OFFSET(x) offsetof(struct dshow_ctx, x)
  1059. #define DEC AV_OPT_FLAG_DECODING_PARAM
  1060. static const AVOption options[] = {
  1061.     { "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 },
  1062.     { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1, DEC },
  1063.     { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
  1064.     { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
  1065.     { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
  1066.     { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
  1067.     { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" },
  1068.     { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" },
  1069.     { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" },
  1070.     { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_options" },
  1071.     { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_options" },
  1072.     { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_options" },
  1073.     { "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 },
  1074.     { "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 },
  1075.     { "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 },
  1076.     { NULL },
  1077. };
  1078.  
  1079. static const AVClass dshow_class = {
  1080.     .class_name = "dshow indev",
  1081.     .item_name  = av_default_item_name,
  1082.     .option     = options,
  1083.     .version    = LIBAVUTIL_VERSION_INT,
  1084. };
  1085.  
  1086. AVInputFormat ff_dshow_demuxer = {
  1087.     .name           = "dshow",
  1088.     .long_name      = NULL_IF_CONFIG_SMALL("DirectShow capture"),
  1089.     .priv_data_size = sizeof(struct dshow_ctx),
  1090.     .read_header    = dshow_read_header,
  1091.     .read_packet    = dshow_read_packet,
  1092.     .read_close     = dshow_read_close,
  1093.     .flags          = AVFMT_NOFILE,
  1094.     .priv_class     = &dshow_class,
  1095. };
  1096.