Add --ls_devices argument to encoder.

Lists available capture devices and exits when specified on the
command line.

Change-Id: I6a93875c251ad20139ce7b439e32121b8642874d
diff --git a/encoder/CMakeLists.txt b/encoder/CMakeLists.txt
index dec2a2c..544b952 100644
--- a/encoder/CMakeLists.txt
+++ b/encoder/CMakeLists.txt
@@ -115,6 +115,7 @@
                buffer_pool.h
                buffer_util.cc
                buffer_util.h
+               capture_source_list.h
                dash_writer.cc
                dash_writer.h
                data_sink.cc
@@ -153,6 +154,7 @@
   add_library(encoder_win STATIC
               win/audio_sink_filter.cc
               win/audio_sink_filter.h
+              win/capture_source_list_dshow.cc
               win/dshow_util.cc
               win/dshow_util.h
               win/media_source_dshow.cc
diff --git a/encoder/capture_source_list.h b/encoder/capture_source_list.h
new file mode 100644
index 0000000..f709e21
--- /dev/null
+++ b/encoder/capture_source_list.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2015 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+#ifndef WEBMLIVE_ENCODER_WIN_CAPTURE_SOURCE_LIST_DSHOW_H_
+#define WEBMLIVE_ENCODER_WIN_CAPTURE_SOURCE_LIST_DSHOW_H_
+
+#include <string>
+
+namespace webmlive {
+
+// Returns new line separated list of audio capture sources in the format:
+// index: name, or an empty string upon failure.
+std::string GetAudioSourceList();
+
+// Returns new line separated list of video capture sources in the format:
+// index: name, or an empty string upon failure.
+std::string GetVideoSourceList();
+
+}  // namespace webmlive
+
+#endif  // WEBMLIVE_ENCODER_WIN_CAPTURE_SOURCE_LIST_DSHOW_H_
\ No newline at end of file
diff --git a/encoder/encoder_main.cc b/encoder/encoder_main.cc
index ec7fb20..01ffaa9 100644
--- a/encoder/encoder_main.cc
+++ b/encoder/encoder_main.cc
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "encoder/buffer_util.h"
+#include "encoder/capture_source_list.h"
 #include "encoder/file_writer.h"
 #include "encoder/http_uploader.h"
 #include "encoder/time_util.h"
@@ -44,6 +45,7 @@
 
   bool enable_file_output;
   bool enable_http_upload;
+  bool list_devices;
 };
 
 }  // anonymous namespace
@@ -54,6 +56,7 @@
   printf("Usage: %s <args>\n", argv[0]);
   printf("  General options:\n");
   printf("    -h | -? | --help               Show this message and exit.\n");
+  printf("    --ls_devices                   List capture devices and exit.\n");
   printf("    --disable_file_output          Disables local file output.\n");
   printf("    --disable_http_upload          Disables upload of output to\n");
   printf("                                   HTTP servers.\n");
@@ -164,6 +167,13 @@
   printf("                                       decoding.\n");
 }
 
+void ListCaptureDevices() {
+  const std::string audio_sources = webmlive::GetAudioSourceList();
+  const std::string video_sources = webmlive::GetVideoSourceList();
+  printf("Audio devices:\n%s\nVideo devices:\n%s\n",
+         audio_sources.c_str(), video_sources.c_str());
+}
+
 // Parses name value pairs in the format name:value from |unparsed_entries|,
 // and stores results in |out_map|.
 int StoreStringMapEntries(const StringVector& unparsed_entries,
@@ -211,6 +221,9 @@
         !strcmp("--help", argv[i])) {
       Usage(argv);
       exit(EXIT_SUCCESS);
+    } else if (!strcmp("--ls_devices", argv[i])) {
+      ListCaptureDevices();
+      exit(EXIT_SUCCESS);
     } else if (!strcmp("--disable_file_output", argv[i])) {
       config->enable_file_output = false;
     } else if (!strcmp("--disable_http_upload", argv[i])) {
diff --git a/encoder/win/capture_source_list_dshow.cc b/encoder/win/capture_source_list_dshow.cc
new file mode 100644
index 0000000..28ef11f
--- /dev/null
+++ b/encoder/win/capture_source_list_dshow.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2015 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS.  All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+#include "encoder/capture_source_list.h"
+
+#include <sstream>
+
+#include "glog/logging.h"
+
+#include "encoder/win/media_source_dshow.h"
+#include "encoder/win/string_util_win.h"
+
+class AutoComInit {
+ public:
+  AutoComInit() { CoInitialize(NULL); }
+  ~AutoComInit() { CoUninitialize(); }
+};
+
+namespace webmlive {
+
+std::string GetAudioSourceList() {
+  AutoComInit com_init;
+  CaptureSourceLoader loader;
+  const int status = loader.Init(CLSID_AudioInputDeviceCategory);
+  if (status) {
+    LOG(ERROR) << "no video source!";
+    return "";
+  }
+
+  std::ostringstream aud_list;
+  for (int i = 0; i < loader.GetNumSources(); ++i) {
+    const std::string dev_name =
+        WStringToString(loader.GetSourceName(i).c_str());
+    LOG(INFO) << "adev" << i << ": " << dev_name;
+    aud_list << i << ": " << dev_name << "\n";
+  }
+
+  return aud_list.str();
+}
+
+std::string GetVideoSourceList() {
+  AutoComInit com_init;
+  CaptureSourceLoader loader;
+  const int status = loader.Init(CLSID_VideoInputDeviceCategory);
+  if (status) {
+    LOG(ERROR) << "no video source!";
+    return "";
+  }
+
+  std::ostringstream vid_list;
+  for (int i = 0; i < loader.GetNumSources(); ++i) {
+    const std::string dev_name =
+        WStringToString(loader.GetSourceName(i).c_str());
+    LOG(INFO) << "vdev" << i << ": " << dev_name;
+    vid_list << i << ": " << dev_name << "\n";
+  }
+
+  return vid_list.str();
+}
+
+}  // namespace webmlive
\ No newline at end of file