At Wed, 24 Jul 2013 11:43:58 -0400 (EDT), Alan Stern wrote:
On Wed, 24 Jul 2013, Takashi Iwai wrote:
I don't understand. Consider a simple playback example. Suppose the user wants to keep the latency low, so he requests 2 periods per buffer. snd-usb-audio ignores this value and decides to use 10 URBs, which is equivalent to setting the buffer size to 10 periods.
You don't have to fill all 10 URBs to start the stream...
Maybe you don't have to, but it looks the driver does just that. From snd_usb_endpoint_start():
if (snd_usb_endpoint_implicit_feedback_sink(ep)) { for (i = 0; i < ep->nurbs; i++) { struct snd_urb_ctx *ctx = ep->urb + i; list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); }
return 0;
}
for (i = 0; i < ep->nurbs; i++) { struct urb *urb = ep->urb[i].urb;
if (snd_BUG_ON(!urb)) goto __error; if (usb_pipeout(ep->pipe)) { prepare_outbound_urb(ep, urb->context); } else { prepare_inbound_urb(ep, urb->context); } err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { snd_printk(KERN_ERR "cannot submit urb %d, error %d: %s\n", i, err, usb_error_string(err)); goto __error; } set_bit(i, &ep->active_mask);
}
In this case, I'm particularly considering what happens when snd_usb_endpoint_implicit_feedback_sink(ep) is false.
Besides, what's the reason for allocating 10 URBs if you're not going to submit more than 2 of them at a time?
I don't know how you deduced 10 urbs in your example, but in general, ep->nurbs is calculated so that the driver can hold at least two ep->periods (i.e. double buffer). The USB audio driver has essentially two buffers: an internal hardware buffer via URBs and an intermediate buffer via vmalloc. The latter is exposed to user-space and its content is copied to the URBs appropriately via complete callbacks.
Due to this design, we just need two periods for URB buffers, ideally, no matter how many periods are used in the latter buffer specified by user. That's why no buffer_size is needed in ep->nurbs estimation. The actual calculation is, however, a bit more complicated to achieve enough fine-grained updates but yet not too big buffer size. I guess this can be simplified / improved.
Takashi