[pulseaudio-discuss] [PATCH 52/56] bluetooth: Create I/O thread function for BlueZ 5 cards
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Thu Jul 25 02:42:23 PDT 2013
On Thu, 2013-07-25 at 12:29 +0300, Tanu Kaskinen wrote:
> > +/* Run from IO thread */
> > +static int a2dp_process_push(struct userdata *u) {
> > + int ret = 0;
> > + pa_memchunk memchunk;
> > +
> > + pa_assert(u);
> > + pa_assert(u->profile == PROFILE_A2DP_SOURCE);
> > + pa_assert(u->source);
> > + pa_assert(u->read_smoother);
> > +
> > + memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
> > + memchunk.index = memchunk.length = 0;
> > +
> > + for (;;) {
> > + bool found_tstamp = false;
> > + pa_usec_t tstamp;
> > + struct sbc_info *sbc_info;
> > + struct rtp_header *header;
> > + struct rtp_payload *payload;
> > + const void *p;
> > + void *d;
> > + ssize_t l;
> > + size_t to_write, to_decode;
> > +
> > + a2dp_prepare_buffer(u);
> > +
> > + sbc_info = &u->sbc_info;
> > + header = sbc_info->buffer;
> > + payload = (struct rtp_payload*) ((uint8_t*) sbc_info->buffer + sizeof(*header));
> > +
> > + l = pa_read(u->stream_fd, sbc_info->buffer, sbc_info->buffer_size, &u->stream_write_type);
>
> The code assumes later that what we read here is exactly one complete
> rtp packet, nothing more, nothing less. I don't understand how such
> assumption can be done. I think we should parse the rtp header to find
> the packet boundary, and buffer any incomplete packets for later
> reading. Or perhaps recvmsg() should be used (I guess that's needed also
> for reading the timestamp, which is currently a TODO item).
Correction: I don't think we need recvmsg() for reading the timestamp,
because I don't know what the socket timestamp would be useful for. The
RTP timestamp is what matters.
> Phew, this one took long.
I forgot to mention: I would like these two comments to be added on top
of a2dp_process_render() and a2dp_process_push(), respectively:
/* This function renders write_block_size amount of data, encodes it and writes
* it to stream_fd. The return value can be either 1, 0 or -1. 1 means
* a successful write. 0 means EAGAIN, so nothing was written, but the caller
* should retry after polling. -1 means error, and the caller is expected to
* release the transport and reset write_memchunk and write_index.
*
* If write_block_size changes when write_memchunk.memblock is non-NULL (i.e.
* after EAGAIN has occurred), write_memchunk must be reset, because this
* function assumes that the memchunk length is exactly write_block_size!
* FIXME: Resetting write_memchunk causes audio loss, so some other way to
* handle this would be preferable. */
/* This function reads as much data from stream_fd as possible
* (sbc_info.buffer_size at most, though). The read data is assumed to be
* exactly one complete RTP packet (FIXME: invalid assumption). The read RTP
* packet is decoded and posted to the source. The return value can be either
* the number of bytes that were read from stream_fd, 0 or -1. 0 means EAGAIN,
* so nothing was read, but the caller should retry after polling. -1 means
* error, and the caller is expected to release the transport and reset
* read_index and read_smoother. */
--
Tanu
More information about the pulseaudio-discuss
mailing list