NxPlayer: Fix some error handling, update comments, more debug output

This commit is contained in:
Gregory Nutt 2014-07-31 14:59:51 -06:00
parent 6671be97cc
commit cd546421d1

View File

@ -1,9 +1,16 @@
/****************************************************************************
* apps/system/nxplayer/nxplayer.c
*
* Developed by:
*
* Copyright (C) 2013 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
*
* With ongoing support:
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Greory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -487,11 +494,18 @@ static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer,
struct audio_buf_desc_s bufdesc;
int ret;
/* Validate the file is still open */
/* Validate the file is still open. It will be closed automatically when
* we encounter the end of file (or, perhaps, a read error that we cannot
* handle.
*/
if (pPlayer->fileFd == NULL)
{
return OK;
/* Return -ENODATA to indicate that there is nothing more to read from
* the file.
*/
return -ENODATA;
}
/* Read data into the buffer. */
@ -508,6 +522,9 @@ static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer,
* event.
*/
audvdbg("Closing audio file, nbytes=%d readerr=%d\n",
pBuf->nbytes, readerror);
fclose(pPlayer->fileFd);
pPlayer->fileFd = NULL;
@ -518,7 +535,7 @@ static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer,
DEBUGASSERT(errcode > 0);
auddbg("ERROR: fread failed: %d\n", errcode);
return errcode;
return -errcode;
}
}
@ -547,11 +564,19 @@ static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer,
DEBUGASSERT(errcode > 0);
auddbg("ERROR: AUDIOIOC_ENQUEUEBUFFER ioctl failed: %d\n", errcode);
return errcode;
return -errcode;
}
/* Return OK to indicate that we successfully read data from the file
* (and we are not yet at the end of file)
*/
return OK;
}
return OK;
/* Return -ENODATA if we are at the end of file */
return -ENODATA;
}
/****************************************************************************
@ -569,7 +594,7 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
struct audio_buf_desc_s buf_desc;
ssize_t size;
uint8_t running = true;
uint8_t playing = true;
uint8_t streaming = true;
#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
struct ap_buffer_info_s buf_info;
FAR struct ap_buffer_s** pBuffers;
@ -580,7 +605,7 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
int x;
int ret;
auddbg("Entry\n");
audvdbg("Entry\n");
/* Query the audio device for it's preferred buffer size / qty */
@ -589,6 +614,7 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
(unsigned long) &buf_info)) != OK)
{
/* Driver doesn't report it's buffer size. Use our default. */
buf_info.buffer_size = CONFIG_AUDIO_BUFFER_NUMBYTES;
buf_info.nbuffers = CONFIG_AUDIO_NUM_BUFFERS;
}
@ -634,13 +660,14 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
buf_desc.numbytes = CONFIG_AUDIO_BUFFER_NUMBYTES;
#endif
buf_desc.u.ppBuffer = &pBuffers[x];
ret = ioctl(pPlayer->devFd, AUDIOIOC_ALLOCBUFFER,
(unsigned long) &buf_desc);
(unsigned long) &buf_desc);
if (ret != sizeof(buf_desc))
{
/* Buffer alloc Operation not supported or error allocating! */
auddbg("nxplayer_playthread: can't alloc buffer %d\n", x);
auddbg("ERROR: Could not allocate buffer %d\n", x);
running = false;
goto err_out;
}
@ -667,13 +694,18 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
}
else
{
playing = false;
/* We are no longer streaming data from the file */
streaming = false;
}
break;
}
}
audvdbg("%d buffers queued, running=%d streaming=%d\n",
x, running, streaming);
/* Start the audio device */
#ifdef CONFIG_AUDIO_MULTI_SESSION
@ -682,6 +714,7 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
#else
ret = ioctl(pPlayer->devFd, AUDIOIOC_START, 0);
#endif
if (ret < 0)
{
/* Error starting the audio stream! */
@ -693,21 +726,31 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
pPlayer->state = NXPLAYER_STATE_PLAYING;
/* Set parameters such as volume, bass, etc. */
/* Set initial parameters such as volume, bass, etc.
* REVISIT: Shouldn't this actually be done BEFORE we start playing?
*/
#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
(void)nxplayer_setvolume(pPlayer, pPlayer->volume);
#endif
#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
nxplayer_setbalance(pPlayer, pPlayer->balance);
#endif
#ifndef CONFIG_AUDIO_EXCLUDE_TONE
nxplayer_setbass(pPlayer, pPlayer->bass);
nxplayer_settreble(pPlayer, pPlayer->treble);
#endif
/* Loop until we specifically break */
/* Loop until we specifically break. running == true means that we are
* still looping waiting for the playback to complete. All of the file
* data may have been sent (if streaming == false), but the playback is
* not complete until we get the AUDIO_MSG_COMPLETE (or AUDIO_MSG_STOP)
* message
*/
audvdbg("%s\n", running ? "Playing..." : "Not runnning");
while (running)
{
/* Wait for a signal either from the Audio driver that it needs
@ -723,6 +766,7 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
{
/* Interrupted by a signal? What to do? */
continue;
}
/* Perform operation based on message id */
@ -732,21 +776,22 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
/* An audio buffer is being dequeued by the driver */
case AUDIO_MSG_DEQUEUE:
/* Read data from the file directly into this buffer
* and re-enqueue it.
/* Read data from the file directly into this buffer and
* re-enqueue it. streaming == true means that we have
* not yet hit the end-of-file.
*/
if (playing)
if (streaming)
{
ret = nxplayer_enqueuebuffer(pPlayer, msg.u.pPtr);
if (ret != OK)
{
/* Out of data. Stay in the loop until the
* device sends us a COMPLETE message, but stop
* trying to play more data.
/* Out of data. Stay in the loop until the device sends
* us a COMPLETE message, but stop trying to play more
* data.
*/
playing = false;
streaming = false;
}
}
break;
@ -756,19 +801,22 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
case AUDIO_MSG_STOP:
/* Send a stop message to the device */
audvdbg("Stopping!\n");
#ifdef CONFIG_AUDIO_MULTI_SESSION
ioctl(pPlayer->devFd, AUDIOIOC_STOP,
(unsigned long) pPlayer->session);
#else
ioctl(pPlayer->devFd, AUDIOIOC_STOP, 0);
#endif
playing = false;
streaming = false;
running = false;
break;
/* Message indicating the playback is complete */
case AUDIO_MSG_COMPLETE:
audvdbg("Play complete\n");
running = false;
break;
@ -782,6 +830,8 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
/* Release our audio buffers and unregister / release the device */
err_out:
audvdbg("Clean-up and exit\n");
/* Unregister the message queue and release the session */
ioctl(pPlayer->devFd, AUDIOIOC_UNREGISTERMQ, (unsigned long) pPlayer->mq);
@ -799,7 +849,7 @@ err_out:
#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
if (pBuffers != NULL)
{
auddbg("Freeing buffers\n");
audvdbg("Freeing buffers\n");
for (x = 0; x < buf_info.nbuffers; x++)
{
/* Fill in the buffer descriptor struct to issue a free request */
@ -816,7 +866,7 @@ err_out:
free(pBuffers);
}
#else
auddbg("Freeing buffers\n");
audvdbg("Freeing buffers\n");
for (x = 0; x < CONFIG_AUDIO_NUM_BUFFERS; x++)
{
/* Fill in the buffer descriptor struct to issue a free request */
@ -851,7 +901,7 @@ err_out:
nxplayer_release(pPlayer);
auddbg("Exit\n");
audvdbg("Exit\n");
return NULL;
}
@ -1459,9 +1509,9 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer,
return -EBUSY;
}
auddbg("==============================\n");
auddbg("Playing file %s\n", pFilename);
auddbg("==============================\n");
audvdbg("==============================\n");
audvdbg("Playing file %s\n", pFilename);
audvdbg("==============================\n");
/* Test that the specified file exists */
@ -1519,7 +1569,7 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer,
{
/* Hmmm, it's some unknown / unsupported type */
auddbg("BERROR: Unsupported format: %d \n", filefmt);
auddbg("ERROR: Unsupported format: %d \n", filefmt);
ret = -ENOSYS;
goto err_out_nodev;
}
@ -1609,7 +1659,7 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer,
(pthread_addr_t) pPlayer);
if (ret != OK)
{
auddbg("Error %d creating playthread\n", ret);
auddbg("ERROR: Failed to create playthread: %d\n", ret);
goto err_out;
}
@ -1735,9 +1785,12 @@ void nxplayer_release(FAR struct nxplayer_s* pPlayer)
while ((ret = sem_wait(&pPlayer->sem)) != OK)
{
if (ret != -EINTR)
int errcode = errno;
DEBUGASSERT(errcode > 0);
if (errcode != EINTR)
{
auddbg("Error getting semaphore\n");
auddbg("ERROR: sem_wait failed: %d\n", errcode);
return;
}
}
@ -1749,11 +1802,15 @@ void nxplayer_release(FAR struct nxplayer_s* pPlayer)
sem_post(&pPlayer->sem);
pthread_join(pPlayer->playId, &value);
pPlayer->playId = 0;
while ((ret = sem_wait(&pPlayer->sem)) != OK)
{
if (ret != -EINTR)
int errcode = errno;
DEBUGASSERT(errcode > 0);
if (errcode != -EINTR)
{
auddbg("Error getting semaphore\n");
auddbg("ERROR: sem_wait failed: %d\n", errcode);
return;
}
}
@ -1790,9 +1847,12 @@ void nxplayer_reference(FAR struct nxplayer_s* pPlayer)
while ((ret = sem_wait(&pPlayer->sem)) != OK)
{
if (ret != -EINTR)
int errcode = errno;
DEBUGASSERT(errcode > 0);
if (errcode != -EINTR)
{
auddbg("Error getting semaphore\n");
auddbg("ERROR: sem_wait failed: %d\n", errcode);
return;
}
}
@ -1826,9 +1886,12 @@ void nxplayer_detach(FAR struct nxplayer_s* pPlayer)
while ((ret = sem_wait(&pPlayer->sem)) != OK)
{
if (ret != -EINTR)
int errcode = errno;
DEBUGASSERT(errcode > 0);
if (errcode != -EINTR)
{
auddbg("Error getting semaphore\n");
auddbg("ERROR: sem_wait failed: %d\n", errcode);
return;
}
}