Write function size question in Audiotrack
When I saw the audio of the Audiotrack::write function when I looked at the relevant part of "Understanding Android" recently, I had some questions about the size of the operation.
The complete code for the function is as follows:
ssize_t audiotrack::write (const void* buffer, size_t usersize)
{
if (msharedbuffer!= 0) return invalid_operation;
if (mistimed) return invalid_operation;
if (ssize_t (Usersize) < 0) {
Sanity-check:user is most-likely passing an error code, and it would
Make is the return value ambiguous (actualsize vs error).
Aloge ("Audiotrack::write (buffer=%p, size=%u (%d)"),
Buffer, usersize, usersize);
return bad_value;
}
ALOGV ("Write%p:%d bytes, mactive=%d", this, usersize, mactive);
if (usersize = = 0) {
return 0;
}
Acquire a strong reference on the Imemory and iaudiotrack then that they cannot to be destroyed
While we are accessing the CBLK
Mlock.lock ();
SP audiotrack = maudiotrack;
SP imem = mcblkmemory;
Mlock.unlock ();
ssize_t written = 0;
Const int8_t *SRC = (const int8_t *) buffer;
Buffer Audiobuffer;
size_t Framesz = Framesize ();
do {
Audiobuffer.framecount = Usersize/framesz;
status_t err = Obtainbuffer (&audiobuffer,-1);
if (Err < 0) {
Out of buffers, return #bytes written
if (err = = status_t (no_more_buffers))
Break
return ssize_t (ERR);
}
size_t Towrite;
if (Mformat = = Audio_format_pcm_8_bit &&! ( Mflags & Audio_output_flag_direct)) {
Divide capacity by 2 to take expansion in account
Towrite = audiobuffer.size>>1;
Memcpy_to_i16_from_u8 (audiobuffer.i16, (const uint8_t *) SRC, towrite);
} else {
// !!! Question Point!!!
Towrite = audiobuffer.size;
memcpy (audiobuffer.i8, SRC, towrite);
src = towrite;
}
Usersize-= Towrite;
Written + = Towrite;
ReleaseBuffer (&audiobuffer);
while (Usersize >= Framesz);
return written;
}
The question point is the question point identified in the code above.
Since Audiobuffer is called Obtainbuffer, the copy data here takes into account only the size of the Audiobuffer, not the size of the source data src, if the size of the audiobuffer is greater than the SRC size, Wouldn't it be copy to invalid data?
Unless the size of the Audiobuffer has a certain relationship with the size of SRC.
Look at the implementation of the Obtainbuffer (only the relevant parts are listed):
status_t Audiotrack::obtainbuffer (buffer* audiobuffer, int32_t waitcount)
{
Automutex Lock (Mlock);
...
audio_track_cblk_t* cblk = mcblk;
Attention point 1
uint32_t framesreq = audiobuffer->framecount;
...
Audiobuffer->framecount = 0;
audiobuffer->size = 0;
uint32_t framesavail = cblk->framesavailable ();
...
Cblk->lock.unlock ();
if (Framesavail = = 0) {
Cblk->lock.lock ();
Goto Start_loop_here;
while (Framesavail = = 0) {
Looping attempts to get writable space
...
Read the server Count again
Start_loop_here:
Framesavail = cblk->framesavailable_l ();
}
Cblk->lock.unlock ();
}
Cblk->waittimems = 0;
Attention Point 2
if (Framesreq > Framesavail) {
Framesreq = Framesavail;
}
uint32_t u = cblk->user;
uint32_t bufferend = cblk->userbase + cblk->framecount;
Attention Point 3
if (Framesreq > Bufferend-u) {
Framesreq = Bufferend-u;
}
Audiobuffer->flags = mmuted? buffer::mute:0;
Audiobuffer->channelcount = Mchannelcount;
Audiobuffer->framecount = Framesreq;
Attention Point 4
Audiobuffer->size = Framesreq * cblk->framesize;
if (AUDIO_IS_LINEAR_PCM (Mformat)) {
Audiobuffer->format = Audio_format_pcm_16_bit;
} else {
Audiobuffer->format = Mformat;
}
Audiobuffer->raw = (int8_t *) cblk->buffer (U);
active = mactive;
Return active? status_t (No_error): status_t (STOPPED);
}
From the above 4 points of concern, we know that the size of audiobuffer from the Framesreq, that is, audiobuffer->framecount, of course, the middle design to a more adaptive treatment.
From the realization of the function audiotrack::write, Audiobuffer->framecount is calculated according to the size of SRC:
Audiobuffer.framecount = Usersize/framesz;
In other words, the size of the Audiobuffer eventually comes from the size of SRC.
And according to the above attention point 2, 3 processing, we know that the size of audiobuffer is less than or equal to src size.
So there's no need to worry about that before.