some comments in decode.c

I have spent some time to understand decodeParent(), which does a lot
of obfuscated magic...  I find it useful to help others to also
understand it, so I wrote a few comments.

git-svn-id: https://svn.musicpd.org/mpd/trunk@7259 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Max Kellermann 2008-04-12 04:12:26 +00:00 committed by Eric Wong
parent 7ee436b435
commit aaebd9ef2b

View File

@ -366,15 +366,20 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
int pause = 0; int pause = 0;
int quit = 0; int quit = 0;
unsigned int bbp = buffered_before_play; unsigned int bbp = buffered_before_play;
/** cross fading enabled for the current song? 0=must check;
1=enabled; -1=disabled */
int doCrossFade = 0; int doCrossFade = 0;
unsigned int crossFadeChunks = 0; unsigned int crossFadeChunks = 0;
unsigned int fadePosition; unsigned int fadePosition;
/** the position of the next cross-faded chunk in the next
song */
int nextChunk = -1; int nextChunk = -1;
unsigned int test; unsigned int test;
int decodeWaitedOn = 0; int decodeWaitedOn = 0;
static const char silence[CHUNK_SIZE]; static const char silence[CHUNK_SIZE];
double sizeToTime = 0.0; double sizeToTime = 0.0;
unsigned int end; unsigned int end;
/** the position of the first chunk in the next song */
int next = -1; int next = -1;
if (waitOnDecode(pc, dc, cb, &decodeWaitedOn) < 0) if (waitOnDecode(pc, dc, cb, &decodeWaitedOn) < 0)
@ -412,6 +417,7 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
if (decodeWaitedOn) { if (decodeWaitedOn) {
if(dc->state!=DECODE_STATE_START && if(dc->state!=DECODE_STATE_START &&
dc->error==DECODE_ERROR_NOERROR) { dc->error==DECODE_ERROR_NOERROR) {
/* the decoder is ready and ok */
decodeWaitedOn = 0; decodeWaitedOn = 0;
if(openAudioDevice(&(cb->audioFormat))<0) { if(openAudioDevice(&(cb->audioFormat))<0) {
char tmp[MPD_PATH_MAX]; char tmp[MPD_PATH_MAX];
@ -438,12 +444,15 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
cb->audioFormat.sampleRate; cb->audioFormat.sampleRate;
} }
else if(dc->state!=DECODE_STATE_START) { else if(dc->state!=DECODE_STATE_START) {
/* the decoder failed */
pc->errored_song = pc->current_song; pc->errored_song = pc->current_song;
pc->error = PLAYER_ERROR_FILE; pc->error = PLAYER_ERROR_FILE;
quitDecode(pc,dc); quitDecode(pc,dc);
return; return;
} }
else { else {
/* the decoder is not yet ready; wait
some more */
player_sleep(); player_sleep();
continue; continue;
} }
@ -452,6 +461,8 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
if (dc->state == DECODE_STATE_STOP && if (dc->state == DECODE_STATE_STOP &&
pc->queueState == PLAYER_QUEUE_FULL && pc->queueState == PLAYER_QUEUE_FULL &&
pc->queueLockState == PLAYER_QUEUE_UNLOCKED) { pc->queueLockState == PLAYER_QUEUE_UNLOCKED) {
/* the decoder has finished the current song;
make it decode the next song */
next = cb->end; next = cb->end;
dc->start = 1; dc->start = 1;
pc->queueState = PLAYER_QUEUE_DECODE; pc->queueState = PLAYER_QUEUE_DECODE;
@ -460,6 +471,9 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
} }
if (next >= 0 && doCrossFade == 0 && !dc->start && if (next >= 0 && doCrossFade == 0 && !dc->start &&
dc->state != DECODE_STATE_START) { dc->state != DECODE_STATE_START) {
/* enable cross fading in this song? if yes,
calculate how many chunks will be required
for it */
nextChunk = -1; nextChunk = -1;
if (isCurrentAudioFormat(&(cb->audioFormat))) { if (isCurrentAudioFormat(&(cb->audioFormat))) {
doCrossFade = 1; doCrossFade = 1;
@ -469,6 +483,9 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
audioFormat)); audioFormat));
if (!crossFadeChunks if (!crossFadeChunks
|| pc->crossFade >= dc->totalTime) { || pc->crossFade >= dc->totalTime) {
/* cross fading is disabled or
the next song is too
short */
doCrossFade = -1; doCrossFade = -1;
} }
} else } else
@ -489,7 +506,13 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
(cb->begin > next && (cb->begin > next &&
(fadePosition = next - cb->begin + (fadePosition = next - cb->begin +
buffered_chunks) <= crossFadeChunks))) { buffered_chunks) <= crossFadeChunks))) {
/* perform cross fade */
if (nextChunk < 0) { if (nextChunk < 0) {
/* beginning of the cross fade
- adjust crossFadeChunks
which might be bigger than
the remaining number of
chunks in the old song */
crossFadeChunks = fadePosition; crossFadeChunks = fadePosition;
} }
test = end; test = end;
@ -516,12 +539,21 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
= cb->chunkSize[nextChunk]; = cb->chunkSize[nextChunk];
} }
} else { } else {
/* there are not enough
decoded chunks yet */
if (dc->state == DECODE_STATE_STOP) { if (dc->state == DECODE_STATE_STOP) {
/* the decoder isn't
running, abort
cross fading */
doCrossFade = -1; doCrossFade = -1;
} else } else
/* wait for the
decoder */
continue; continue;
} }
} }
/* play the current chunk */
pc->elapsedTime = cb->times[cb->begin]; pc->elapsedTime = cb->times[cb->begin];
pc->bitRate = cb->bitRate[cb->begin]; pc->bitRate = cb->bitRate[cb->begin];
pcm_volumeChange(cb->chunks + cb->begin * pcm_volumeChange(cb->chunks + cb->begin *
@ -541,7 +573,12 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
cb->begin++; cb->begin++;
player_wakeup_decoder_nb(); player_wakeup_decoder_nb();
} else if (cb->begin != end && cb->begin == next) { } else if (cb->begin != end && cb->begin == next) {
/* at the beginning of a new song */
if (doCrossFade == 1 && nextChunk >= 0) { if (doCrossFade == 1 && nextChunk >= 0) {
/* the cross-fade is finished; skip
the section which was cross-faded
(and thus already played) */
nextChunk = cb->begin + crossFadeChunks; nextChunk = cb->begin + crossFadeChunks;
test = end; test = end;
if (end < cb->begin) if (end < cb->begin)
@ -553,6 +590,8 @@ static void decodeParent(PlayerControl * pc, DecoderControl * dc, OutputBuffer *
advanceOutputBufferTo(cb, nextChunk); advanceOutputBufferTo(cb, nextChunk);
} }
} }
/* wait for the decoder to work on the new song */
while (pc->queueState == PLAYER_QUEUE_DECODE || while (pc->queueState == PLAYER_QUEUE_DECODE ||
pc->queueLockState == PLAYER_QUEUE_LOCKED) { pc->queueLockState == PLAYER_QUEUE_LOCKED) {
processDecodeInput(pc, dc, cb, processDecodeInput(pc, dc, cb,