Browse code

dshow: add option to list audio/video options

Signed-off-by: Stefano Sabatini <stefasab@gmail.com>

Ramiro Polla authored on 2011/09/09 12:15:14
Showing 2 changed files
... ...
@@ -24,7 +24,7 @@
24 24
 
25 25
 #define LIBAVDEVICE_VERSION_MAJOR 53
26 26
 #define LIBAVDEVICE_VERSION_MINOR  3
27
-#define LIBAVDEVICE_VERSION_MICRO  1
27
+#define LIBAVDEVICE_VERSION_MICRO  2
28 28
 
29 29
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
30 30
                                                LIBAVDEVICE_VERSION_MINOR, \
... ...
@@ -32,6 +32,7 @@ struct dshow_ctx {
32 32
 
33 33
     char *device_name[2];
34 34
 
35
+    int   list_options;
35 36
     int   list_devices;
36 37
 
37 38
     IBaseFilter *device_filter[2];
... ...
@@ -311,6 +312,7 @@ fail1:
311 311
  * Cycle through available formats using the specified pin,
312 312
  * try to set parameters specified through AVOptions and if successful
313 313
  * return 1 in *pformat_set.
314
+ * If pformat_set is NULL, list all pin capabilities.
314 315
  */
315 316
 static void
316 317
 dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
... ...
@@ -357,6 +359,14 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
357 357
             } else {
358 358
                 goto next;
359 359
             }
360
+            if (!pformat_set) {
361
+                av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
362
+                       vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
363
+                       1e7 / vcaps->MinFrameInterval,
364
+                       vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
365
+                       1e7 / vcaps->MaxFrameInterval);
366
+                continue;
367
+            }
360 368
             if (ctx->framerate) {
361 369
                 int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
362 370
                                             /  ctx->requested_framerate.num;
... ...
@@ -385,6 +395,12 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
385 385
             } else {
386 386
                 goto next;
387 387
             }
388
+            if (!pformat_set) {
389
+                av_log(avctx, AV_LOG_INFO, "  min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
390
+                       acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
391
+                       acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
392
+                continue;
393
+            }
388 394
             if (ctx->sample_rate) {
389 395
                 if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
390 396
                     ctx->sample_rate < acaps->MinimumSampleFrequency)
... ...
@@ -416,6 +432,7 @@ end:
416 416
     IAMStreamConfig_Release(config);
417 417
     if (caps)
418 418
         av_free(caps);
419
+    if (pformat_set)
419 420
     *pformat_set = format_set;
420 421
 }
421 422
 
... ...
@@ -423,6 +440,7 @@ end:
423 423
  * Cycle through available pins using the device_filter device, of type
424 424
  * devtype, retrieve the first output pin and return the pointer to the
425 425
  * object found in *ppin.
426
+ * If ppin is NULL, cycle through all pins listing audio/video capabilities.
426 427
  */
427 428
 static int
428 429
 dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
... ...
@@ -447,6 +465,10 @@ dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
447 447
         return AVERROR(EIO);
448 448
     }
449 449
 
450
+    if (!ppin) {
451
+        av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
452
+               devtypename);
453
+    }
450 454
     while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK && !device_pin) {
451 455
         IKsPropertySet *p = NULL;
452 456
         IEnumMediaTypes *types = NULL;
... ...
@@ -468,6 +490,13 @@ dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
468 468
         if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
469 469
             goto next;
470 470
 
471
+        if (!ppin) {
472
+            char *buf = dup_wchar_to_utf8(info.achName);
473
+            av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
474
+            av_free(buf);
475
+            dshow_cycle_formats(avctx, devtype, pin, NULL);
476
+            goto next;
477
+        }
471 478
         if (set_format) {
472 479
             dshow_cycle_formats(avctx, devtype, pin, &format_set);
473 480
             if (!format_set) {
... ...
@@ -498,6 +527,7 @@ next:
498 498
 
499 499
     IEnumPins_Release(pins);
500 500
 
501
+    if (ppin) {
501 502
     if (set_format && !format_set) {
502 503
         av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
503 504
         return AVERROR(EIO);
... ...
@@ -508,6 +538,27 @@ next:
508 508
         return AVERROR(EIO);
509 509
     }
510 510
     *ppin = device_pin;
511
+    }
512
+
513
+    return 0;
514
+}
515
+
516
+/**
517
+ * List options for device with type devtype.
518
+ *
519
+ * @param devenum device enumerator used for accessing the device
520
+ */
521
+static int
522
+dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
523
+                          enum dshowDeviceType devtype)
524
+{
525
+    IBaseFilter *device_filter = NULL;
526
+    int r;
527
+
528
+    if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0)
529
+        return r;
530
+    if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0)
531
+        return r;
511 532
 
512 533
     return 0;
513 534
 }
... ...
@@ -774,6 +825,14 @@ static int dshow_read_header(AVFormatContext *avctx, AVFormatParameters *ap)
774 774
         ret = AVERROR_EXIT;
775 775
         goto error;
776 776
     }
777
+    if (ctx->list_options) {
778
+        if (ctx->device_name[VideoDevice])
779
+            dshow_list_device_options(avctx, devenum, VideoDevice);
780
+        if (ctx->device_name[AudioDevice])
781
+            dshow_list_device_options(avctx, devenum, AudioDevice);
782
+        ret = AVERROR_EXIT;
783
+        goto error;
784
+    }
777 785
 
778 786
     if (ctx->device_name[VideoDevice]) {
779 787
         ret = dshow_open_device(avctx, devenum, VideoDevice);
... ...
@@ -873,6 +932,9 @@ static const AVOption options[] = {
873 873
     { "list_devices", "list available devices", OFFSET(list_devices), FF_OPT_TYPE_INT, {.dbl=0}, 0, 1, DEC, "list_devices" },
874 874
     { "true", "", 0, FF_OPT_TYPE_CONST, {.dbl=1}, 0, 0, DEC, "list_devices" },
875 875
     { "false", "", 0, FF_OPT_TYPE_CONST, {.dbl=0}, 0, 0, DEC, "list_devices" },
876
+    { "list_options", "list available options for specified device", OFFSET(list_options), FF_OPT_TYPE_INT, {.dbl=0}, 0, 1, DEC, "list_options" },
877
+    { "true", "", 0, FF_OPT_TYPE_CONST, {.dbl=1}, 0, 0, DEC, "list_options" },
878
+    { "false", "", 0, FF_OPT_TYPE_CONST, {.dbl=0}, 0, 0, DEC, "list_options" },
876 879
     { NULL },
877 880
 };
878 881