1
0
mirror of http://mpg123.de/trunk/.git synced 2025-10-25 04:37:34 +03:00

More communicative buffer and normalized usage of which.

No nastly killing or SIGSTOP anymore; buffer either plays or waits for commands, including termination.
This fixes the terminal behaviour with track skip and seek when stopped:
The buffer can be resynced while being stopped, so no forced restart of playback on track skip anymore.

The only nagging usability issue remaining with the buffer is the inability to seek while playing.
Refilling of the buffer effects in fast-forward only.



git-svn-id: svn://scm.orgis.org/mpg123/trunk@1251 35dc7657-300d-0410-a2e5-dc2837fedb53
This commit is contained in:
thor
2007-12-08 01:16:09 +00:00
parent a4934f6b77
commit d71a40ee46
9 changed files with 150 additions and 64 deletions

View File

@@ -44,16 +44,22 @@ void real_buffer_ignore_lowmem(void)
xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_WAKEUP);
}
void real_buffer_end(void)
void real_buffer_end(int rude)
{
if (!buffermem)
return;
xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_TERMINATE);
xfermem_putcmd(buffermem->fd[XF_WRITER], rude ? XF_CMD_ABORT : XF_CMD_TERMINATE);
}
void real_buffer_resync(void)
{
buffer_sig(SIGINT, TRUE);
if(buffermem->justwait)
{
buffermem->wakeme[XF_WRITER] = TRUE;
xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_RESYNC);
xfermem_getcmd(buffermem->fd[XF_WRITER], TRUE);
}
else buffer_sig(SIGINT, TRUE);
}
void real_plain_buffer_resync(void)
@@ -68,12 +74,18 @@ void real_buffer_reset(void)
void real_buffer_start(void)
{
buffer_sig(SIGCONT, FALSE);
if(buffermem->justwait)
{
debug("ending buffer's waiting");
buffermem->justwait = FALSE;
xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_WAKEUP);
}
}
void real_buffer_stop(void)
void real_buffer_stop()
{
buffer_sig(SIGSTOP, FALSE);
buffermem->justwait = TRUE;
buffer_sig(SIGINT, TRUE);
}
extern int buffer_pid;
@@ -142,14 +154,25 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
for (;;) {
if (intflag) {
debug("handle intflag... flushing");
intflag = FALSE;
if (param.outmode == DECODE_AUDIO)
ao->flush(ao);
xf->readindex = xf->freeindex;
if (xf->wakeme[XF_WRITER])
xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
if (param.outmode == DECODE_AUDIO) ao->flush(ao);
/* Either prepare for waiting or empty buffer now. */
if(!xf->justwait) xf->readindex = xf->freeindex;
else
{
int cmd;
debug("Prepare for waiting; draining command queue. (There's a lot of wakeup commands pending, usually.)");
do
{
cmd = xfermem_getcmd(my_fd, FALSE);
/* debug1("drain: %i", cmd); */
} while(cmd > 0);
}
if(xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
}
if (usr1flag) {
debug("handling usr1flag");
usr1flag = FALSE;
/* close and re-open in order to flush
* the device's internal buffer before
@@ -182,19 +205,19 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
if(preload < outburst)
preload = outburst;
}
if(bytes < preload) {
debug1("bytes: %i", bytes);
if(xf->justwait || bytes < preload) {
int cmd;
if (done && !bytes) {
break;
}
if(!done) {
if(xf->justwait || !done) {
/* Don't spill into errno check below. */
errno = 0;
cmd = xfermem_block(XF_READER, xf);
debug1("got %i", cmd);
switch(cmd) {
/* More input pending. */
@@ -205,23 +228,34 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
*/
case XF_CMD_WAKEUP:
break; /* Proceed playing. */
case XF_CMD_TERMINATE:
/* Proceed playing without
* blocking any further.
*/
done=TRUE;
case XF_CMD_ABORT: /* Immediate end, discard buffer contents. */
return; /* Cleanup happens outside of buffer_loop()*/
case XF_CMD_TERMINATE: /* Graceful end, playing stuff in buffer and then return. */
debug("going to terminate");
done = TRUE;
break;
case XF_CMD_RESYNC:
debug("ordered resync");
if (param.outmode == DECODE_AUDIO) ao->flush(ao);
xf->readindex = xf->freeindex;
if (xf->wakeme[XF_WRITER]) xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
continue;
break;
case -1:
if(errno==EINTR) /* Got signal, handle it at top of loop... */
if(intflag || usr1flag) /* Got signal, handle it at top of loop... */
{
debug("buffer interrupted");
continue;
}
if(errno)
perror("Yuck! Error in buffer handling... or somewhere unexpected.");
error1("Yuck! Error in buffer handling... or somewhere unexpected: %s", strerror(errno));
done = TRUE;
xf->readindex = xf->freeindex;
xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE);
break;
default:
fprintf(stderr, "\nEh!? Received unknown command 0x%x in buffer process. Tell Daniel!\n", cmd);
fprintf(stderr, "\nEh!? Received unknown command 0x%x in buffer process.\n", cmd);
}
}
}
@@ -229,7 +263,7 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
* audio settings. We do not want to lower the preload mark
* just yet!
*/
if (!bytes)
if (xf->justwait || !bytes)
continue;
preload = outburst; /* set preload to lower mark */
if (bytes > xf->size - xf->readindex)
@@ -238,6 +272,7 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
bytes = outburst;
/* Could change that to use flush_output.... need to capture return value, then. */
debug("write");
if (param.outmode == DECODE_FILE)
bytes = write(OutputDescriptor, xf->data + xf->readindex, bytes);
else if (param.outmode == DECODE_AUDIO)
@@ -246,7 +281,7 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
if(bytes < 0) {
bytes = 0;
if(errno != EINTR) {
if(!intflag && !usr1flag) {
perror("Ouch ... error while writing audio data: ");
/*
* done==TRUE tells writer process to stop
@@ -261,6 +296,7 @@ void buffer_loop(audio_output_t *ao, sigset_t *oldsigset)
xf->readindex = xf->freeindex;
xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE);
}
else debug("buffer interrupted");
}
xf->readindex = (xf->readindex + bytes) % xf->size;