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:
parent
7ee436b435
commit
aaebd9ef2b
39
src/decode.c
39
src/decode.c
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user