usb camera mbox使用时出现“cannot get freq at ep”

来源:互联网 发布:centos 安装nginx 编辑:程序博客网 时间:2024/06/17 22:36

         在项目中遇到一个usb摄像头无法正常录音的问题,而其他usb camera都可以正常工作。因此查询这个usb camera在录音的时候有什么不同的地方,发现用这个usb camera录音的时候总是打印 “cannot get freq at ep 0x84 ", 在kernel中grep了一把,是sound/usb/clock.c中打印的一句warning: 


static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,                     struct usb_host_interface *alts,                     struct audioformat *fmt, int rate){     struct usb_device *dev = chip->dev;     unsigned int ep;     unsigned char data[3];     int err, crate;     ep = get_endpoint(alts, 0)->bEndpointAddress;     /* if endpoint doesn't have sampling rate control, bail out */     if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))          return 0;     data[0] = rate;     data[1] = rate >> 8;     data[2] = rate >> 16;     if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,                       USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,                       UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,                       data, sizeof(data), 1000)) < 0) {          snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",                  dev->devnum, iface, fmt->altsetting, rate, ep);          return err;     }     if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,                       USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,                       UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,                       data, sizeof(data), 1000)) < 0) {          snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",                  dev->devnum, iface, fmt->altsetting, ep);          return 0; /* some devices don't support reading */     }     crate = data[0] | (data[1] << 8) | (data[2] << 16);     if (crate != rate) {          snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);          // runtime->rate = crate;     }     return 0;}

虽然usb_audio功能在平台实现了,但是对usb的知识还是有所欠缺,因此向google求助。


http://comments.gmane.org/gmane.linux.alsa.user/36523


在这个讨论交流里我了解问题大概是usb camera 本身的firmware 有buggy, 只要将其对应的mixer设置正确就可以了。


因此我在串口中输入了命令:


tinymix -D 1root@android:/proc/asound # tinymix -D 1                                      Number of controls: 2ctl     type    num     name                                     value0       BOOL    1       Mic Capture Switch                       On1       INT     1       Mic Capture Volume                       8191

然后再去录音就可以正常录音了,因此看了一下tinymix -D 1所走的code流程:


int main(int argc, char **argv){    struct mixer *mixer;    int card = 0;    if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {        argv++;        if (argv[1]) {            card = atoi(argv[1]);            argv++;            argc -= 2;        } else {            argc -= 1;        }    }    mixer = mixer_open(card);    if (!mixer) {        fprintf(stderr, "Failed to open mixer\n");        return EXIT_FAILURE;    }    if (argc == 1)        tinymix_list_controls(mixer);    else if (argc == 2)        tinymix_detail_control(mixer, atoi(argv[1]), 1);    else if (argc == 3)        tinymix_set_value(mixer, atoi(argv[1]), argv[2]);    else        printf("Usage: tinymix [-D card] [control id] [value to set]\n");    mixer_close(mixer);    return 0;}

因此我在usb_audio的HAL层也去做了相同的操作:


<strong>capture:</strong>static int adev_open_input_stream(struct audio_hw_device *dev,                                  audio_io_handle_t handle,                                  audio_devices_t devices,                                  struct audio_config *config,                                  struct audio_stream_in **stream_in){     …………     …………    struct mixer *usb_mixer;     …………    usb_mixer = mixer_open(adev->card);    if (!usb_mixer) {        ALOGE("Unable to open the mixer, aborting.");        goto err_open;    }       …………err_open:    …………    mixer_close(usb_mixer);    …………    return ret;}
<strong>playback:</strong>static int adev_open_output_stream(struct audio_hw_device *dev,                                   audio_io_handle_t handle,                                   audio_devices_t devices,                                   audio_output_flags_t flags,                                   struct audio_config *config,                                   struct audio_stream_out **stream_out){    …………    struct mixer *usb_mixer;    …………    usb_mixer = mixer_open(adev->card);    if (!usb_mixer) {        ALOGE("Unable to open the mixer, aborting.");        goto err_open;    }     …………err_open:    mixer_close(usb_mixer);   …………    return ret;}

*********************************欢迎各位交流指正********************************************************


0 0
原创粉丝点击