NxPlayer: Fix some error handling, update comments, more debug output
This commit is contained in:
parent
6671be97cc
commit
cd546421d1
@ -1,9 +1,16 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/system/nxplayer/nxplayer.c
|
* apps/system/nxplayer/nxplayer.c
|
||||||
*
|
*
|
||||||
|
* Developed by:
|
||||||
|
*
|
||||||
* Copyright (C) 2013 Ken Pettit. All rights reserved.
|
* Copyright (C) 2013 Ken Pettit. All rights reserved.
|
||||||
* Author: Ken Pettit <pettitkd@gmail.com>
|
* 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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
@ -487,11 +494,18 @@ static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer,
|
|||||||
struct audio_buf_desc_s bufdesc;
|
struct audio_buf_desc_s bufdesc;
|
||||||
int ret;
|
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)
|
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. */
|
/* Read data into the buffer. */
|
||||||
@ -508,6 +522,9 @@ static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer,
|
|||||||
* event.
|
* event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
audvdbg("Closing audio file, nbytes=%d readerr=%d\n",
|
||||||
|
pBuf->nbytes, readerror);
|
||||||
|
|
||||||
fclose(pPlayer->fileFd);
|
fclose(pPlayer->fileFd);
|
||||||
pPlayer->fileFd = NULL;
|
pPlayer->fileFd = NULL;
|
||||||
|
|
||||||
@ -518,7 +535,7 @@ static int nxplayer_enqueuebuffer(FAR struct nxplayer_s *pPlayer,
|
|||||||
DEBUGASSERT(errcode > 0);
|
DEBUGASSERT(errcode > 0);
|
||||||
|
|
||||||
auddbg("ERROR: fread failed: %d\n", errcode);
|
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);
|
DEBUGASSERT(errcode > 0);
|
||||||
|
|
||||||
auddbg("ERROR: AUDIOIOC_ENQUEUEBUFFER ioctl failed: %d\n", errcode);
|
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;
|
struct audio_buf_desc_s buf_desc;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
uint8_t running = true;
|
uint8_t running = true;
|
||||||
uint8_t playing = true;
|
uint8_t streaming = true;
|
||||||
#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
|
#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
|
||||||
struct ap_buffer_info_s buf_info;
|
struct ap_buffer_info_s buf_info;
|
||||||
FAR struct ap_buffer_s** pBuffers;
|
FAR struct ap_buffer_s** pBuffers;
|
||||||
@ -580,7 +605,7 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
|
|||||||
int x;
|
int x;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
auddbg("Entry\n");
|
audvdbg("Entry\n");
|
||||||
|
|
||||||
/* Query the audio device for it's preferred buffer size / qty */
|
/* 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)
|
(unsigned long) &buf_info)) != OK)
|
||||||
{
|
{
|
||||||
/* Driver doesn't report it's buffer size. Use our default. */
|
/* Driver doesn't report it's buffer size. Use our default. */
|
||||||
|
|
||||||
buf_info.buffer_size = CONFIG_AUDIO_BUFFER_NUMBYTES;
|
buf_info.buffer_size = CONFIG_AUDIO_BUFFER_NUMBYTES;
|
||||||
buf_info.nbuffers = CONFIG_AUDIO_NUM_BUFFERS;
|
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;
|
buf_desc.numbytes = CONFIG_AUDIO_BUFFER_NUMBYTES;
|
||||||
#endif
|
#endif
|
||||||
buf_desc.u.ppBuffer = &pBuffers[x];
|
buf_desc.u.ppBuffer = &pBuffers[x];
|
||||||
|
|
||||||
ret = ioctl(pPlayer->devFd, AUDIOIOC_ALLOCBUFFER,
|
ret = ioctl(pPlayer->devFd, AUDIOIOC_ALLOCBUFFER,
|
||||||
(unsigned long) &buf_desc);
|
(unsigned long) &buf_desc);
|
||||||
if (ret != sizeof(buf_desc))
|
if (ret != sizeof(buf_desc))
|
||||||
{
|
{
|
||||||
/* Buffer alloc Operation not supported or error allocating! */
|
/* 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;
|
running = false;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
@ -667,13 +694,18 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
playing = false;
|
/* We are no longer streaming data from the file */
|
||||||
|
|
||||||
|
streaming = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
audvdbg("%d buffers queued, running=%d streaming=%d\n",
|
||||||
|
x, running, streaming);
|
||||||
|
|
||||||
/* Start the audio device */
|
/* Start the audio device */
|
||||||
|
|
||||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||||
@ -682,6 +714,7 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
|
|||||||
#else
|
#else
|
||||||
ret = ioctl(pPlayer->devFd, AUDIOIOC_START, 0);
|
ret = ioctl(pPlayer->devFd, AUDIOIOC_START, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* Error starting the audio stream! */
|
/* Error starting the audio stream! */
|
||||||
@ -693,21 +726,31 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
|
|||||||
|
|
||||||
pPlayer->state = NXPLAYER_STATE_PLAYING;
|
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
|
#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
|
||||||
(void)nxplayer_setvolume(pPlayer, pPlayer->volume);
|
(void)nxplayer_setvolume(pPlayer, pPlayer->volume);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
|
#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
|
||||||
nxplayer_setbalance(pPlayer, pPlayer->balance);
|
nxplayer_setbalance(pPlayer, pPlayer->balance);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_AUDIO_EXCLUDE_TONE
|
#ifndef CONFIG_AUDIO_EXCLUDE_TONE
|
||||||
nxplayer_setbass(pPlayer, pPlayer->bass);
|
nxplayer_setbass(pPlayer, pPlayer->bass);
|
||||||
nxplayer_settreble(pPlayer, pPlayer->treble);
|
nxplayer_settreble(pPlayer, pPlayer->treble);
|
||||||
#endif
|
#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)
|
while (running)
|
||||||
{
|
{
|
||||||
/* Wait for a signal either from the Audio driver that it needs
|
/* 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? */
|
/* Interrupted by a signal? What to do? */
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform operation based on message id */
|
/* 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 */
|
/* An audio buffer is being dequeued by the driver */
|
||||||
|
|
||||||
case AUDIO_MSG_DEQUEUE:
|
case AUDIO_MSG_DEQUEUE:
|
||||||
/* Read data from the file directly into this buffer
|
/* Read data from the file directly into this buffer and
|
||||||
* and re-enqueue it.
|
* 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);
|
ret = nxplayer_enqueuebuffer(pPlayer, msg.u.pPtr);
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
/* Out of data. Stay in the loop until the
|
/* Out of data. Stay in the loop until the device sends
|
||||||
* device sends us a COMPLETE message, but stop
|
* us a COMPLETE message, but stop trying to play more
|
||||||
* trying to play more data.
|
* data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
playing = false;
|
streaming = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -756,19 +801,22 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
|
|||||||
case AUDIO_MSG_STOP:
|
case AUDIO_MSG_STOP:
|
||||||
/* Send a stop message to the device */
|
/* Send a stop message to the device */
|
||||||
|
|
||||||
|
audvdbg("Stopping!\n");
|
||||||
|
|
||||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||||
ioctl(pPlayer->devFd, AUDIOIOC_STOP,
|
ioctl(pPlayer->devFd, AUDIOIOC_STOP,
|
||||||
(unsigned long) pPlayer->session);
|
(unsigned long) pPlayer->session);
|
||||||
#else
|
#else
|
||||||
ioctl(pPlayer->devFd, AUDIOIOC_STOP, 0);
|
ioctl(pPlayer->devFd, AUDIOIOC_STOP, 0);
|
||||||
#endif
|
#endif
|
||||||
playing = false;
|
streaming = false;
|
||||||
running = false;
|
running = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Message indicating the playback is complete */
|
/* Message indicating the playback is complete */
|
||||||
|
|
||||||
case AUDIO_MSG_COMPLETE:
|
case AUDIO_MSG_COMPLETE:
|
||||||
|
audvdbg("Play complete\n");
|
||||||
running = false;
|
running = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -782,6 +830,8 @@ static void *nxplayer_playthread(pthread_addr_t pvarg)
|
|||||||
/* Release our audio buffers and unregister / release the device */
|
/* Release our audio buffers and unregister / release the device */
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
|
audvdbg("Clean-up and exit\n");
|
||||||
|
|
||||||
/* Unregister the message queue and release the session */
|
/* Unregister the message queue and release the session */
|
||||||
|
|
||||||
ioctl(pPlayer->devFd, AUDIOIOC_UNREGISTERMQ, (unsigned long) pPlayer->mq);
|
ioctl(pPlayer->devFd, AUDIOIOC_UNREGISTERMQ, (unsigned long) pPlayer->mq);
|
||||||
@ -799,7 +849,7 @@ err_out:
|
|||||||
#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
|
#ifdef CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS
|
||||||
if (pBuffers != NULL)
|
if (pBuffers != NULL)
|
||||||
{
|
{
|
||||||
auddbg("Freeing buffers\n");
|
audvdbg("Freeing buffers\n");
|
||||||
for (x = 0; x < buf_info.nbuffers; x++)
|
for (x = 0; x < buf_info.nbuffers; x++)
|
||||||
{
|
{
|
||||||
/* Fill in the buffer descriptor struct to issue a free request */
|
/* Fill in the buffer descriptor struct to issue a free request */
|
||||||
@ -816,7 +866,7 @@ err_out:
|
|||||||
free(pBuffers);
|
free(pBuffers);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
auddbg("Freeing buffers\n");
|
audvdbg("Freeing buffers\n");
|
||||||
for (x = 0; x < CONFIG_AUDIO_NUM_BUFFERS; x++)
|
for (x = 0; x < CONFIG_AUDIO_NUM_BUFFERS; x++)
|
||||||
{
|
{
|
||||||
/* Fill in the buffer descriptor struct to issue a free request */
|
/* Fill in the buffer descriptor struct to issue a free request */
|
||||||
@ -851,7 +901,7 @@ err_out:
|
|||||||
|
|
||||||
nxplayer_release(pPlayer);
|
nxplayer_release(pPlayer);
|
||||||
|
|
||||||
auddbg("Exit\n");
|
audvdbg("Exit\n");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1459,9 +1509,9 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer,
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
auddbg("==============================\n");
|
audvdbg("==============================\n");
|
||||||
auddbg("Playing file %s\n", pFilename);
|
audvdbg("Playing file %s\n", pFilename);
|
||||||
auddbg("==============================\n");
|
audvdbg("==============================\n");
|
||||||
|
|
||||||
/* Test that the specified file exists */
|
/* 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 */
|
/* Hmmm, it's some unknown / unsupported type */
|
||||||
|
|
||||||
auddbg("BERROR: Unsupported format: %d \n", filefmt);
|
auddbg("ERROR: Unsupported format: %d \n", filefmt);
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
goto err_out_nodev;
|
goto err_out_nodev;
|
||||||
}
|
}
|
||||||
@ -1609,7 +1659,7 @@ int nxplayer_playfile(FAR struct nxplayer_s *pPlayer,
|
|||||||
(pthread_addr_t) pPlayer);
|
(pthread_addr_t) pPlayer);
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
auddbg("Error %d creating playthread\n", ret);
|
auddbg("ERROR: Failed to create playthread: %d\n", ret);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1735,9 +1785,12 @@ void nxplayer_release(FAR struct nxplayer_s* pPlayer)
|
|||||||
|
|
||||||
while ((ret = sem_wait(&pPlayer->sem)) != OK)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1749,11 +1802,15 @@ void nxplayer_release(FAR struct nxplayer_s* pPlayer)
|
|||||||
sem_post(&pPlayer->sem);
|
sem_post(&pPlayer->sem);
|
||||||
pthread_join(pPlayer->playId, &value);
|
pthread_join(pPlayer->playId, &value);
|
||||||
pPlayer->playId = 0;
|
pPlayer->playId = 0;
|
||||||
|
|
||||||
while ((ret = sem_wait(&pPlayer->sem)) != OK)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1790,9 +1847,12 @@ void nxplayer_reference(FAR struct nxplayer_s* pPlayer)
|
|||||||
|
|
||||||
while ((ret = sem_wait(&pPlayer->sem)) != OK)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1826,9 +1886,12 @@ void nxplayer_detach(FAR struct nxplayer_s* pPlayer)
|
|||||||
|
|
||||||
while ((ret = sem_wait(&pPlayer->sem)) != OK)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user