|
|
@@ -1,470 +0,0 @@
|
|
|
-
|
|
|
-#include <stdio.h>
|
|
|
-#include <stdlib.h>
|
|
|
-
|
|
|
-#include <portaudio.h>
|
|
|
-
|
|
|
-//#include <pa_debugprint.h>
|
|
|
-
|
|
|
-#include <errno.h>
|
|
|
-#include <fcntl.h>
|
|
|
-#include <stdio.h>
|
|
|
-#include <stdlib.h>
|
|
|
-#include <sys/ioctl.h>
|
|
|
-#include <sys/stat.h>
|
|
|
-#include <unistd.h>
|
|
|
-#include <sys/types.h>
|
|
|
-#include <sys/stat.h>
|
|
|
-#include <fcntl.h>
|
|
|
-#include <sys/mman.h>
|
|
|
-#include <poll.h>
|
|
|
-#include <sys/ioctl.h>
|
|
|
-#include <string.h>
|
|
|
-#include <unistd.h>
|
|
|
-//v4l includes
|
|
|
-#include <linux/videodev2.h>
|
|
|
-#include <dlfcn.h>
|
|
|
-#include <alsa/asoundlib.h>
|
|
|
-
|
|
|
-#include "../libmediadeviceinfo/imediadeviceinfo.h"
|
|
|
-
|
|
|
-
|
|
|
-#ifndef MAX_STR_LEN
|
|
|
-#define MAX_STR_LEN 512
|
|
|
-#endif // !MAX_STR_LEN
|
|
|
-
|
|
|
-
|
|
|
-#ifndef MAX_PATH
|
|
|
-#define MAX_PATH 260
|
|
|
-#endif // !MAX_PATH
|
|
|
-
|
|
|
-
|
|
|
-typedef int (*lpfn_get_cameracountfun)();
|
|
|
-typedef int (*lpfn_get_videodevice_namefun)(int device_id, char* buf, int len);
|
|
|
-typedef int (*lpfn_get_videodevice_infofun)(int device_id, char* namebuf, int namelen, char* pathbuf, int pathlen);
|
|
|
-typedef int (*lpfn_get_videodeviceid)(const char* dev_name);
|
|
|
-
|
|
|
-static lpfn_get_cameracountfun get_cameracount = NULL;
|
|
|
-static lpfn_get_videodevice_namefun get_videodevice_name = NULL;
|
|
|
-static lpfn_get_videodevice_infofun get_videodevice_info = NULL;
|
|
|
-static lpfn_get_videodevice_namefun get_device_fullpathname = NULL;
|
|
|
-static lpfn_get_videodeviceid get_videodeviceid = NULL;
|
|
|
-
|
|
|
-
|
|
|
-static int audio_translate_id(int in_direction, int idx)
|
|
|
-{
|
|
|
- int i, n, ii;
|
|
|
- //audio_log_set_func(NULL);
|
|
|
- n = Pa_GetDeviceCount();
|
|
|
- for (i = 0, ii = 0; i < n; ++i) {
|
|
|
- const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
|
|
|
- if (in_direction) {
|
|
|
- if (info->maxInputChannels) {
|
|
|
- if (ii == idx) {
|
|
|
- //audio_log_set_func(__audio_log_func);
|
|
|
- return i;
|
|
|
- }
|
|
|
- ii++;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (info->maxOutputChannels) {
|
|
|
- if (ii == idx) {
|
|
|
- //audio_log_set_func(__audio_log_func);
|
|
|
- return i;
|
|
|
- }
|
|
|
- ii++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //audio_log_set_func(__audio_log_func);
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int audio_get_dev_count(int *in_cnt, int *out_cnt)
|
|
|
-{
|
|
|
- int i;
|
|
|
- int icnt = 0, ocnt = 0;
|
|
|
- int cnt = Pa_GetDeviceCount();
|
|
|
- printf("\n\ndevice count is %d.\n", cnt);
|
|
|
- for (i = 0; i < cnt; ++i) {
|
|
|
- const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
|
|
|
- if (info->maxInputChannels)
|
|
|
- icnt ++;
|
|
|
- if (info->maxOutputChannels)
|
|
|
- ocnt ++;
|
|
|
- }
|
|
|
- if (in_cnt)
|
|
|
- *in_cnt = icnt;
|
|
|
- if (out_cnt)
|
|
|
- *out_cnt = ocnt;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static char *audio_get_dev_name(char *buf, bool in_direction, int idx)
|
|
|
-{
|
|
|
- int cnt = Pa_GetDeviceCount();
|
|
|
- int ii, i;
|
|
|
- for (i = 0, ii = 0; i < cnt; ++i) {
|
|
|
- const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
|
|
|
- if (in_direction) {
|
|
|
- if (info->maxInputChannels) {
|
|
|
- if (idx == ii) {
|
|
|
- strcpy(buf, info->name);
|
|
|
- return buf;
|
|
|
- }
|
|
|
- ii++;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (info->maxOutputChannels) {
|
|
|
- if (idx == ii) {
|
|
|
- strcpy(buf, info->name);
|
|
|
- return buf;
|
|
|
- }
|
|
|
- ii++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-static void show_audio_dev()
|
|
|
-{
|
|
|
- int icnt, ocnt;
|
|
|
- int rc = audio_get_dev_count(&icnt, &ocnt);
|
|
|
- if (rc == 0) {
|
|
|
- int i;
|
|
|
- char tmp[128];
|
|
|
- printf("audio input devices(%d):\n", icnt);
|
|
|
- for (i = 0; i < icnt; ++i) {
|
|
|
- audio_get_dev_name(tmp, true, i);
|
|
|
- printf("%d = %s\n", i, tmp);
|
|
|
- }
|
|
|
- printf("audio output devices(%d):\n", ocnt);
|
|
|
- for (i = 0; i < ocnt; ++i) {
|
|
|
- audio_get_dev_name(tmp, false, i);
|
|
|
- printf("%d = %s\n", i, tmp);
|
|
|
- }
|
|
|
- printf("\n");
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-static int Bin2Str(unsigned char *x, int xlen, char *str, int str_size)
|
|
|
-{
|
|
|
- static const char *hex2char = "0123456789ABCDEF";
|
|
|
- int i, k = 0;
|
|
|
- if (str_size <= xlen * 2)
|
|
|
- return -1;
|
|
|
- for (i = 0; i < xlen; ++i) {
|
|
|
- int h = x[i] >> 4;
|
|
|
- int l = x[i] & 0xf;
|
|
|
- str[k++] = hex2char[h];
|
|
|
- str[k++] = hex2char[l];
|
|
|
- }
|
|
|
- str[k] = 0;
|
|
|
- return k;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-//static int isSupportThisFormat(int iPixelFormat)
|
|
|
-//{
|
|
|
-// unsigned int i;
|
|
|
-// for (i = 0; i < sizeof(g_aiSupportedFormats) / sizeof(g_aiSupportedFormats[0]); i++)
|
|
|
-// {
|
|
|
-// if (g_aiSupportedFormats[i] == iPixelFormat)
|
|
|
-// return 1;
|
|
|
-// }
|
|
|
-// return 0;
|
|
|
-//}
|
|
|
-
|
|
|
-static void show_video_dev()
|
|
|
-{
|
|
|
-
|
|
|
- //uint32_t count = 0;
|
|
|
- //char device[20];
|
|
|
- //int fd = -1;
|
|
|
- //bool found = false;
|
|
|
- //int n = 0;
|
|
|
- //for (; n < 64; n++)
|
|
|
- //{
|
|
|
- // sprintf(device, "/dev/video%d", n);
|
|
|
- // if ((fd = open(device, O_RDONLY)) != -1)
|
|
|
- // {
|
|
|
- // count++;
|
|
|
- // // query device capabilities
|
|
|
- // struct v4l2_capability cap;
|
|
|
- // struct v4l2_fmtdesc tFmtDesc;
|
|
|
- // struct v4l2_format tV4l2Fmt;
|
|
|
- // int iPixelFormat = 0;
|
|
|
- // if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)
|
|
|
- // {
|
|
|
- // printf("error in querying the device capability for device %s. errno = %d.\n",device, errno);
|
|
|
- // close(fd);
|
|
|
- // continue;
|
|
|
- // }
|
|
|
- // //printf("device[%s] Name UTF8 is: %s\n", device, cap.card);
|
|
|
- // if (cap.bus_info[0] != 0) // may not available in all drivers
|
|
|
- // {
|
|
|
- // //printf("device[%s] UniqueId UTF8 is: %s\n", device, cap.bus_info);
|
|
|
- // }
|
|
|
-
|
|
|
- // if (cap.driver[0] != 0) // may not available in all drivers
|
|
|
- // {
|
|
|
- // //printf("device[%s] driver UTF8 is: %s\n", device, cap.driver);
|
|
|
- // }
|
|
|
-
|
|
|
- // //printf("capabilities is 0x%x\n", cap.capabilities);
|
|
|
-
|
|
|
- // if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
|
|
|
- // {
|
|
|
- // //printf("%s is not a video capture device\n", device);
|
|
|
- // continue;
|
|
|
- // }
|
|
|
- // /* ------------------------------------------------------------------ */
|
|
|
-
|
|
|
- // if (cap.capabilities & V4L2_CAP_STREAMING) {
|
|
|
- // //printf("%s supports streaming i/o\n", device);
|
|
|
- // }
|
|
|
-
|
|
|
- // if (cap.capabilities & V4L2_CAP_READWRITE) {
|
|
|
- // //printf("%s supports read i/o\n", device);
|
|
|
- // }
|
|
|
-
|
|
|
- // /* 查询支持的格式 */
|
|
|
- // memset(&tFmtDesc, 0, sizeof(tFmtDesc));
|
|
|
- // tFmtDesc.index = 0;
|
|
|
- // tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
- // while ((ioctl(fd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) {
|
|
|
- // //if (isSupportThisFormat(tFmtDesc.pixelformat))
|
|
|
- // //printf("tFmtDesc.pixelformat == 0x:%x\n", tFmtDesc.pixelformat);
|
|
|
- // if(V4L2_PIX_FMT_YUYV == tFmtDesc.pixelformat || V4L2_PIX_FMT_RGB565 == tFmtDesc.pixelformat)
|
|
|
- // {
|
|
|
- // //printf("Support this format!\n");
|
|
|
- // iPixelFormat = tFmtDesc.pixelformat;
|
|
|
- // break;
|
|
|
- // }
|
|
|
- // //printf("Support this format +++!\n");
|
|
|
- // tFmtDesc.index++;
|
|
|
- // }
|
|
|
-
|
|
|
- // if (0 != iPixelFormat)
|
|
|
- // {
|
|
|
- // char strCameraName[MAX_PATH] = { 0 };
|
|
|
- // snprintf(strCameraName, MAX_PATH, "%s%s%s", cap.card,";",cap.bus_info);
|
|
|
- // printf("%s\n\n", strCameraName);
|
|
|
- // }
|
|
|
- // else {
|
|
|
- // //printf("can not support the format of this device[%s]\n\n", device);
|
|
|
- // continue;
|
|
|
- // }
|
|
|
-
|
|
|
-
|
|
|
- // /* 获取当前显示设备支持的分辨率 */
|
|
|
- // memset(&tV4l2Fmt, 0, sizeof(struct v4l2_format));
|
|
|
- // tV4l2Fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
|
- // tV4l2Fmt.fmt.pix.pixelformat = iPixelFormat;
|
|
|
- // tV4l2Fmt.fmt.pix.width = 1920;
|
|
|
- // tV4l2Fmt.fmt.pix.height = 1080;
|
|
|
- // tV4l2Fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
|
|
-
|
|
|
- // /* 如果驱动程序发现无法某些参数(比如分辨率),
|
|
|
- // * 它会调整这些参数, 并且返回给应用程序
|
|
|
- // */
|
|
|
- // if (ioctl(fd, VIDIOC_S_FMT, &tV4l2Fmt))
|
|
|
- // {
|
|
|
- // //printf("Unable to set format\n\n");
|
|
|
- // continue;
|
|
|
- // }
|
|
|
- // {
|
|
|
- // int iWidth = tV4l2Fmt.fmt.pix.width;
|
|
|
- // int iHeight = tV4l2Fmt.fmt.pix.height;
|
|
|
-
|
|
|
- // //printf("width is %d\nheight is %d\nformat is %d\n\n", iWidth, iHeight, iPixelFormat);
|
|
|
- // }
|
|
|
-
|
|
|
- // close(fd);
|
|
|
- // }
|
|
|
- //}
|
|
|
-
|
|
|
- int icount = get_cameracount();
|
|
|
- printf("video devices(%d):\n", icount);
|
|
|
-
|
|
|
- int inumber = 0;
|
|
|
- for (int i = 0; i < 64 && inumber < icount; ++i) {
|
|
|
- char strcamera[2*MAX_PATH] = { 0 };
|
|
|
- char strpath[MAX_PATH] = { 0 };
|
|
|
-
|
|
|
- if(0 == get_device_fullpathname(i, strcamera, 2*MAX_PATH))
|
|
|
- {
|
|
|
- printf("%d = %s\n", inumber++, strcamera);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void __dummy_log_callback(const char *log)
|
|
|
-{
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-static int load_dll_functions()
|
|
|
-{
|
|
|
- int iret = -1;
|
|
|
-
|
|
|
- void* handle = NULL;
|
|
|
- char* error = NULL;
|
|
|
- handle = dlopen("./libmediadeviceinfo.so", RTLD_LAZY);
|
|
|
- if (NULL == handle)
|
|
|
- {
|
|
|
- printf("dlopen failed %s.\n", dlerror());
|
|
|
- return iret;
|
|
|
- }
|
|
|
-
|
|
|
- get_cameracount = (lpfn_get_cameracountfun)dlsym(handle, "rvc_videocap_get_device_count");
|
|
|
- if ((error = dlerror()) != NULL) {
|
|
|
- printf("%s\n", error);
|
|
|
- return iret;
|
|
|
- }
|
|
|
-
|
|
|
- get_videodevice_name = (lpfn_get_videodevice_namefun)dlsym(handle, "rvc_videocap_get_device_name");
|
|
|
- if ((error = dlerror()) != NULL) {
|
|
|
- printf("%s\n", error);
|
|
|
- return iret;
|
|
|
- }
|
|
|
-
|
|
|
- get_videodevice_info = (lpfn_get_videodevice_infofun)dlsym(handle, "rvc_videocap_get_device_info");
|
|
|
- if ((error = dlerror()) != NULL) {
|
|
|
- printf("%s\n", error);
|
|
|
- return iret;
|
|
|
- }
|
|
|
-
|
|
|
- get_device_fullpathname = (lpfn_get_videodevice_namefun)dlsym(handle, "rvc_videocap_get_device_fullpathname");
|
|
|
- if ((error = dlerror()) != NULL) {
|
|
|
- printf("%s\n", error);
|
|
|
- return iret;
|
|
|
- }
|
|
|
-
|
|
|
- get_videodeviceid = (lpfn_get_videodeviceid)dlsym(handle, "rvc_videocap_get_video_device_id");
|
|
|
- if ((error = dlerror()) != NULL) {
|
|
|
- printf("%s\n", error);
|
|
|
- return iret;
|
|
|
- }
|
|
|
-
|
|
|
- iret = 0;
|
|
|
-
|
|
|
- return iret;
|
|
|
-}
|
|
|
-
|
|
|
-static int app_init()
|
|
|
-{
|
|
|
- Pa_Initialize();
|
|
|
- //PaUtil_SetDebugPrintFunction(&__dummy_log_callback);
|
|
|
- int iret = load_dll_functions();
|
|
|
-
|
|
|
- return iret;
|
|
|
-}
|
|
|
-
|
|
|
-static void app_term()
|
|
|
-{
|
|
|
- Pa_Terminate();
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void device_list(bool in_direction)
|
|
|
-{
|
|
|
- snd_ctl_t* handle = NULL;
|
|
|
- int card = 0, err = 0, dev = 0, idx = 0;
|
|
|
- snd_ctl_card_info_t* info = NULL;
|
|
|
- snd_pcm_info_t* pcminfo = NULL;
|
|
|
- snd_ctl_card_info_alloca(&info);
|
|
|
- snd_pcm_info_alloca(&pcminfo);
|
|
|
- snd_pcm_stream_t instream = SND_PCM_STREAM_CAPTURE;
|
|
|
- if (!in_direction){
|
|
|
- instream = SND_PCM_STREAM_PLAYBACK;
|
|
|
- }
|
|
|
-
|
|
|
- card = -1;
|
|
|
- if (snd_card_next(&card) < 0 || card < 0) {
|
|
|
- printf("no soundcards found...\n");
|
|
|
- return;
|
|
|
- }
|
|
|
- printf("**** List of %s Hardware Devices ****\n",snd_pcm_stream_name(instream));
|
|
|
- while (card >= 0) {
|
|
|
- char name[32] = {0};
|
|
|
- sprintf(name, "hw:%d", card);
|
|
|
- if ((err = snd_ctl_open(&handle, name, 0)) < 0) {
|
|
|
- printf("control open (%i): %s\n", card, snd_strerror(err));
|
|
|
- goto next_card;
|
|
|
- }
|
|
|
- if ((err = snd_ctl_card_info(handle, info)) < 0) {
|
|
|
- printf("control hardware info (%i): %s\n", card, snd_strerror(err));
|
|
|
- snd_ctl_close(handle);
|
|
|
- goto next_card;
|
|
|
- }
|
|
|
- dev = -1;
|
|
|
- while (1) {
|
|
|
- unsigned int count = 0;
|
|
|
- if (snd_ctl_pcm_next_device(handle, &dev) < 0)
|
|
|
- printf("snd_ctl_pcm_next_device\n");
|
|
|
- if (dev < 0)
|
|
|
- break;
|
|
|
- snd_pcm_info_set_device(pcminfo, dev);
|
|
|
- snd_pcm_info_set_subdevice(pcminfo, 0);
|
|
|
- snd_pcm_info_set_stream(pcminfo, instream);
|
|
|
- if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
|
|
|
- if (err != -ENOENT)
|
|
|
- printf("control digital audio info (%i): %s\n", card, snd_strerror(err));
|
|
|
- continue;
|
|
|
- }
|
|
|
- printf("card %i: %s [%s], device %i: %s [%s]\n",
|
|
|
- card, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info),
|
|
|
- dev,
|
|
|
- snd_pcm_info_get_id(pcminfo),
|
|
|
- snd_pcm_info_get_name(pcminfo));
|
|
|
- //printf("%s\n",snd_ctl_card_info_get_name(info));
|
|
|
- count = snd_pcm_info_get_subdevices_count(pcminfo);
|
|
|
- //printf(" Subdevices: %i/%i\n",snd_pcm_info_get_subdevices_avail(pcminfo), count);
|
|
|
- for (idx = 0; idx < (int)count; idx++) {
|
|
|
- snd_pcm_info_set_subdevice(pcminfo, idx);
|
|
|
- if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
|
|
|
- printf("control digital audio playback info (%i): %s\n", card, snd_strerror(err));
|
|
|
- }
|
|
|
- else {
|
|
|
- //printf(" Subdevice #%i: %s\n",idx, snd_pcm_info_get_subdevice_name(pcminfo));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- snd_ctl_close(handle);
|
|
|
- next_card:
|
|
|
- if (snd_card_next(&card) < 0) {
|
|
|
- printf("snd_card_next\n");
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int main()
|
|
|
-{
|
|
|
- if (app_init() != 0) {
|
|
|
- printf("app init failed!\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- show_audio_dev();
|
|
|
- show_video_dev();
|
|
|
-
|
|
|
- //getchar();
|
|
|
-
|
|
|
- app_term();
|
|
|
-
|
|
|
- printf("\n--------------------------------------------------------------\n");
|
|
|
- printf(" get audio device info from alsa. \n");
|
|
|
- printf("--------------------------------------------------------------\n");
|
|
|
-
|
|
|
- device_list(true);
|
|
|
- printf("--------------------------------------------------------------\n");
|
|
|
- device_list(false);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|