main.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <portaudio.h>
  4. //#include <pa_debugprint.h>
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/stat.h>
  11. #include <unistd.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <fcntl.h>
  15. #include <sys/mman.h>
  16. #include <poll.h>
  17. #include <sys/ioctl.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. //v4l includes
  21. #include <linux/videodev2.h>
  22. #include <dlfcn.h>
  23. #include <alsa/asoundlib.h>
  24. #include "../libmediadeviceinfo/imediadeviceinfo.h"
  25. #ifndef MAX_STR_LEN
  26. #define MAX_STR_LEN 512
  27. #endif // !MAX_STR_LEN
  28. #ifndef MAX_PATH
  29. #define MAX_PATH 260
  30. #endif // !MAX_PATH
  31. typedef int (*lpfn_get_cameracountfun)();
  32. typedef int (*lpfn_get_videodevice_namefun)(int device_id, char* buf, int len);
  33. typedef int (*lpfn_get_videodevice_infofun)(int device_id, char* namebuf, int namelen, char* pathbuf, int pathlen);
  34. typedef int (*lpfn_get_videodeviceid)(const char* dev_name);
  35. static lpfn_get_cameracountfun get_cameracount = NULL;
  36. static lpfn_get_videodevice_namefun get_videodevice_name = NULL;
  37. static lpfn_get_videodevice_infofun get_videodevice_info = NULL;
  38. static lpfn_get_videodevice_namefun get_device_fullpathname = NULL;
  39. static lpfn_get_videodeviceid get_videodeviceid = NULL;
  40. static int audio_translate_id(int in_direction, int idx)
  41. {
  42. int i, n, ii;
  43. //audio_log_set_func(NULL);
  44. n = Pa_GetDeviceCount();
  45. for (i = 0, ii = 0; i < n; ++i) {
  46. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  47. if (in_direction) {
  48. if (info->maxInputChannels) {
  49. if (ii == idx) {
  50. //audio_log_set_func(__audio_log_func);
  51. return i;
  52. }
  53. ii++;
  54. }
  55. } else {
  56. if (info->maxOutputChannels) {
  57. if (ii == idx) {
  58. //audio_log_set_func(__audio_log_func);
  59. return i;
  60. }
  61. ii++;
  62. }
  63. }
  64. }
  65. //audio_log_set_func(__audio_log_func);
  66. return -1;
  67. }
  68. int audio_get_dev_count(int *in_cnt, int *out_cnt)
  69. {
  70. int i;
  71. int icnt = 0, ocnt = 0;
  72. int cnt = Pa_GetDeviceCount();
  73. printf("\n\ndevice count is %d.\n", cnt);
  74. for (i = 0; i < cnt; ++i) {
  75. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  76. if (info->maxInputChannels)
  77. icnt ++;
  78. if (info->maxOutputChannels)
  79. ocnt ++;
  80. }
  81. if (in_cnt)
  82. *in_cnt = icnt;
  83. if (out_cnt)
  84. *out_cnt = ocnt;
  85. return 0;
  86. }
  87. static char *audio_get_dev_name(char *buf, bool in_direction, int idx)
  88. {
  89. int cnt = Pa_GetDeviceCount();
  90. int ii, i;
  91. for (i = 0, ii = 0; i < cnt; ++i) {
  92. const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
  93. if (in_direction) {
  94. if (info->maxInputChannels) {
  95. if (idx == ii) {
  96. strcpy(buf, info->name);
  97. return buf;
  98. }
  99. ii++;
  100. }
  101. } else {
  102. if (info->maxOutputChannels) {
  103. if (idx == ii) {
  104. strcpy(buf, info->name);
  105. return buf;
  106. }
  107. ii++;
  108. }
  109. }
  110. }
  111. return NULL;
  112. }
  113. static void show_audio_dev()
  114. {
  115. int icnt, ocnt;
  116. int rc = audio_get_dev_count(&icnt, &ocnt);
  117. if (rc == 0) {
  118. int i;
  119. char tmp[128];
  120. printf("audio input devices(%d):\n", icnt);
  121. for (i = 0; i < icnt; ++i) {
  122. audio_get_dev_name(tmp, true, i);
  123. printf("%d = %s\n", i, tmp);
  124. }
  125. printf("audio output devices(%d):\n", ocnt);
  126. for (i = 0; i < ocnt; ++i) {
  127. audio_get_dev_name(tmp, false, i);
  128. printf("%d = %s\n", i, tmp);
  129. }
  130. printf("\n");
  131. }
  132. }
  133. static int Bin2Str(unsigned char *x, int xlen, char *str, int str_size)
  134. {
  135. static const char *hex2char = "0123456789ABCDEF";
  136. int i, k = 0;
  137. if (str_size <= xlen * 2)
  138. return -1;
  139. for (i = 0; i < xlen; ++i) {
  140. int h = x[i] >> 4;
  141. int l = x[i] & 0xf;
  142. str[k++] = hex2char[h];
  143. str[k++] = hex2char[l];
  144. }
  145. str[k] = 0;
  146. return k;
  147. }
  148. //static int isSupportThisFormat(int iPixelFormat)
  149. //{
  150. // unsigned int i;
  151. // for (i = 0; i < sizeof(g_aiSupportedFormats) / sizeof(g_aiSupportedFormats[0]); i++)
  152. // {
  153. // if (g_aiSupportedFormats[i] == iPixelFormat)
  154. // return 1;
  155. // }
  156. // return 0;
  157. //}
  158. static void show_video_dev()
  159. {
  160. //uint32_t count = 0;
  161. //char device[20];
  162. //int fd = -1;
  163. //bool found = false;
  164. //int n = 0;
  165. //for (; n < 64; n++)
  166. //{
  167. // sprintf(device, "/dev/video%d", n);
  168. // if ((fd = open(device, O_RDONLY)) != -1)
  169. // {
  170. // count++;
  171. // // query device capabilities
  172. // struct v4l2_capability cap;
  173. // struct v4l2_fmtdesc tFmtDesc;
  174. // struct v4l2_format tV4l2Fmt;
  175. // int iPixelFormat = 0;
  176. // if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)
  177. // {
  178. // printf("error in querying the device capability for device %s. errno = %d.\n",device, errno);
  179. // close(fd);
  180. // continue;
  181. // }
  182. // //printf("device[%s] Name UTF8 is: %s\n", device, cap.card);
  183. // if (cap.bus_info[0] != 0) // may not available in all drivers
  184. // {
  185. // //printf("device[%s] UniqueId UTF8 is: %s\n", device, cap.bus_info);
  186. // }
  187. // if (cap.driver[0] != 0) // may not available in all drivers
  188. // {
  189. // //printf("device[%s] driver UTF8 is: %s\n", device, cap.driver);
  190. // }
  191. // //printf("capabilities is 0x%x\n", cap.capabilities);
  192. // if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
  193. // {
  194. // //printf("%s is not a video capture device\n", device);
  195. // continue;
  196. // }
  197. // /* ------------------------------------------------------------------ */
  198. // if (cap.capabilities & V4L2_CAP_STREAMING) {
  199. // //printf("%s supports streaming i/o\n", device);
  200. // }
  201. // if (cap.capabilities & V4L2_CAP_READWRITE) {
  202. // //printf("%s supports read i/o\n", device);
  203. // }
  204. // /* 查询支持的格式 */
  205. // memset(&tFmtDesc, 0, sizeof(tFmtDesc));
  206. // tFmtDesc.index = 0;
  207. // tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  208. // while ((ioctl(fd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) {
  209. // //if (isSupportThisFormat(tFmtDesc.pixelformat))
  210. // //printf("tFmtDesc.pixelformat == 0x:%x\n", tFmtDesc.pixelformat);
  211. // if(V4L2_PIX_FMT_YUYV == tFmtDesc.pixelformat || V4L2_PIX_FMT_RGB565 == tFmtDesc.pixelformat)
  212. // {
  213. // //printf("Support this format!\n");
  214. // iPixelFormat = tFmtDesc.pixelformat;
  215. // break;
  216. // }
  217. // //printf("Support this format +++!\n");
  218. // tFmtDesc.index++;
  219. // }
  220. // if (0 != iPixelFormat)
  221. // {
  222. // char strCameraName[MAX_PATH] = { 0 };
  223. // snprintf(strCameraName, MAX_PATH, "%s%s%s", cap.card,";",cap.bus_info);
  224. // printf("%s\n\n", strCameraName);
  225. // }
  226. // else {
  227. // //printf("can not support the format of this device[%s]\n\n", device);
  228. // continue;
  229. // }
  230. // /* 获取当前显示设备支持的分辨率 */
  231. // memset(&tV4l2Fmt, 0, sizeof(struct v4l2_format));
  232. // tV4l2Fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  233. // tV4l2Fmt.fmt.pix.pixelformat = iPixelFormat;
  234. // tV4l2Fmt.fmt.pix.width = 1920;
  235. // tV4l2Fmt.fmt.pix.height = 1080;
  236. // tV4l2Fmt.fmt.pix.field = V4L2_FIELD_ANY;
  237. // /* 如果驱动程序发现无法某些参数(比如分辨率),
  238. // * 它会调整这些参数, 并且返回给应用程序
  239. // */
  240. // if (ioctl(fd, VIDIOC_S_FMT, &tV4l2Fmt))
  241. // {
  242. // //printf("Unable to set format\n\n");
  243. // continue;
  244. // }
  245. // {
  246. // int iWidth = tV4l2Fmt.fmt.pix.width;
  247. // int iHeight = tV4l2Fmt.fmt.pix.height;
  248. // //printf("width is %d\nheight is %d\nformat is %d\n\n", iWidth, iHeight, iPixelFormat);
  249. // }
  250. // close(fd);
  251. // }
  252. //}
  253. int icount = get_cameracount();
  254. printf("video devices(%d):\n", icount);
  255. int inumber = 0;
  256. for (int i = 0; i < 64 && inumber < icount; ++i) {
  257. char strcamera[2*MAX_PATH] = { 0 };
  258. char strpath[MAX_PATH] = { 0 };
  259. if(0 == get_device_fullpathname(i, strcamera, 2*MAX_PATH))
  260. {
  261. printf("%d = %s\n", inumber++, strcamera);
  262. }
  263. }
  264. }
  265. static void __dummy_log_callback(const char *log)
  266. {
  267. }
  268. static int load_dll_functions()
  269. {
  270. int iret = -1;
  271. void* handle = NULL;
  272. char* error = NULL;
  273. handle = dlopen("./libmediadeviceinfo.so", RTLD_LAZY);
  274. if (NULL == handle)
  275. {
  276. printf("dlopen failed %s.\n", dlerror());
  277. return iret;
  278. }
  279. get_cameracount = (lpfn_get_cameracountfun)dlsym(handle, "rvc_videocap_get_device_count");
  280. if ((error = dlerror()) != NULL) {
  281. printf("%s\n", error);
  282. return iret;
  283. }
  284. get_videodevice_name = (lpfn_get_videodevice_namefun)dlsym(handle, "rvc_videocap_get_device_name");
  285. if ((error = dlerror()) != NULL) {
  286. printf("%s\n", error);
  287. return iret;
  288. }
  289. get_videodevice_info = (lpfn_get_videodevice_infofun)dlsym(handle, "rvc_videocap_get_device_info");
  290. if ((error = dlerror()) != NULL) {
  291. printf("%s\n", error);
  292. return iret;
  293. }
  294. get_device_fullpathname = (lpfn_get_videodevice_namefun)dlsym(handle, "rvc_videocap_get_device_fullpathname");
  295. if ((error = dlerror()) != NULL) {
  296. printf("%s\n", error);
  297. return iret;
  298. }
  299. get_videodeviceid = (lpfn_get_videodeviceid)dlsym(handle, "rvc_videocap_get_video_device_id");
  300. if ((error = dlerror()) != NULL) {
  301. printf("%s\n", error);
  302. return iret;
  303. }
  304. iret = 0;
  305. return iret;
  306. }
  307. static int app_init()
  308. {
  309. Pa_Initialize();
  310. //PaUtil_SetDebugPrintFunction(&__dummy_log_callback);
  311. int iret = load_dll_functions();
  312. return iret;
  313. }
  314. static void app_term()
  315. {
  316. Pa_Terminate();
  317. }
  318. static void device_list(bool in_direction)
  319. {
  320. snd_ctl_t* handle = NULL;
  321. int card = 0, err = 0, dev = 0, idx = 0;
  322. snd_ctl_card_info_t* info = NULL;
  323. snd_pcm_info_t* pcminfo = NULL;
  324. snd_ctl_card_info_alloca(&info);
  325. snd_pcm_info_alloca(&pcminfo);
  326. snd_pcm_stream_t instream = SND_PCM_STREAM_CAPTURE;
  327. if (!in_direction){
  328. instream = SND_PCM_STREAM_PLAYBACK;
  329. }
  330. card = -1;
  331. if (snd_card_next(&card) < 0 || card < 0) {
  332. printf("no soundcards found...\n");
  333. return;
  334. }
  335. printf("**** List of %s Hardware Devices ****\n",snd_pcm_stream_name(instream));
  336. while (card >= 0) {
  337. char name[32] = {0};
  338. sprintf(name, "hw:%d", card);
  339. if ((err = snd_ctl_open(&handle, name, 0)) < 0) {
  340. printf("control open (%i): %s\n", card, snd_strerror(err));
  341. goto next_card;
  342. }
  343. if ((err = snd_ctl_card_info(handle, info)) < 0) {
  344. printf("control hardware info (%i): %s\n", card, snd_strerror(err));
  345. snd_ctl_close(handle);
  346. goto next_card;
  347. }
  348. dev = -1;
  349. while (1) {
  350. unsigned int count = 0;
  351. if (snd_ctl_pcm_next_device(handle, &dev) < 0)
  352. printf("snd_ctl_pcm_next_device\n");
  353. if (dev < 0)
  354. break;
  355. snd_pcm_info_set_device(pcminfo, dev);
  356. snd_pcm_info_set_subdevice(pcminfo, 0);
  357. snd_pcm_info_set_stream(pcminfo, instream);
  358. if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
  359. if (err != -ENOENT)
  360. printf("control digital audio info (%i): %s\n", card, snd_strerror(err));
  361. continue;
  362. }
  363. printf("card %i: %s [%s], device %i: %s [%s]\n",
  364. card, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info),
  365. dev,
  366. snd_pcm_info_get_id(pcminfo),
  367. snd_pcm_info_get_name(pcminfo));
  368. //printf("%s\n",snd_ctl_card_info_get_name(info));
  369. count = snd_pcm_info_get_subdevices_count(pcminfo);
  370. //printf(" Subdevices: %i/%i\n",snd_pcm_info_get_subdevices_avail(pcminfo), count);
  371. for (idx = 0; idx < (int)count; idx++) {
  372. snd_pcm_info_set_subdevice(pcminfo, idx);
  373. if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
  374. printf("control digital audio playback info (%i): %s\n", card, snd_strerror(err));
  375. }
  376. else {
  377. //printf(" Subdevice #%i: %s\n",idx, snd_pcm_info_get_subdevice_name(pcminfo));
  378. }
  379. }
  380. }
  381. snd_ctl_close(handle);
  382. next_card:
  383. if (snd_card_next(&card) < 0) {
  384. printf("snd_card_next\n");
  385. break;
  386. }
  387. }
  388. }
  389. int main()
  390. {
  391. if (app_init() != 0) {
  392. printf("app init failed!\n");
  393. return -1;
  394. }
  395. show_audio_dev();
  396. show_video_dev();
  397. //getchar();
  398. app_term();
  399. printf("\n--------------------------------------------------------------\n");
  400. printf(" get audio device info from alsa. \n");
  401. printf("--------------------------------------------------------------\n");
  402. device_list(true);
  403. printf("--------------------------------------------------------------\n");
  404. device_list(false);
  405. return 0;
  406. }