Skip to content

Commit 904f391

Browse files
yangyaleiacassis
authored andcommitted
nuttx/audio: Add audio_try_enqueue
support upper driver check whether enqueue apb buffer to the lower driver Signed-off-by: yangyalei <yangyalei@xiaomi.com>
1 parent 928b936 commit 904f391

File tree

1 file changed

+73
-5
lines changed

1 file changed

+73
-5
lines changed

audio/audio.c

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <nuttx/config.h>
2828

29+
#include <sys/param.h>
2930
#include <sys/types.h>
3031
#include <sys/stat.h>
3132
#include <stdint.h>
@@ -66,6 +67,8 @@
6667
# define CONFIG_AUDIO_BUFFER_DEQUEUE_PRIO 1
6768
#endif
6869

70+
#define AUDIO_ENQUEUE_THRESHOLD 2
71+
6972
/****************************************************************************
7073
* Private Types
7174
****************************************************************************/
@@ -375,6 +378,66 @@ static inline int audio_getnstate(FAR struct audio_upperhalf_s *upper,
375378
return nstate;
376379
}
377380

381+
/****************************************************************************
382+
* Name: audio_try_enqueue
383+
*
384+
* Description:
385+
* Try enqueue audio buffer
386+
*
387+
****************************************************************************/
388+
389+
static int audio_try_enqueue(FAR struct audio_upperhalf_s *upper)
390+
{
391+
FAR struct audio_lowerhalf_s *lower = upper->dev;
392+
FAR struct audio_openpriv_s *priv;
393+
int ret = OK;
394+
395+
for (; ; )
396+
{
397+
uint32_t count = upper->status->head - upper->status->tail;
398+
bool ready = false;
399+
bool wait = false;
400+
401+
for (priv = upper->head; priv != NULL; priv = priv->flink)
402+
{
403+
if (priv->state == AUDIO_STATE_OPEN ||
404+
priv->state == AUDIO_STATE_PAUSED)
405+
{
406+
continue;
407+
}
408+
else if (priv->head > upper->status->head)
409+
{
410+
ready = true;
411+
}
412+
else if (priv->head < upper->status->head ||
413+
priv->head <= upper->status->tail)
414+
{
415+
priv->state = AUDIO_STATE_XRUN;
416+
}
417+
else
418+
{
419+
wait = true;
420+
}
421+
}
422+
423+
if (!ready || (wait && count > AUDIO_ENQUEUE_THRESHOLD))
424+
{
425+
return OK;
426+
}
427+
428+
ret = lower->ops->enqueuebuffer(
429+
lower, upper->apbs[upper->status->head % upper->periods]);
430+
if (ret < 0)
431+
{
432+
return ret;
433+
}
434+
435+
upper->status->head++;
436+
}
437+
438+
return ret;
439+
}
440+
378441
/****************************************************************************
379442
* Name: audio_configure
380443
*
@@ -756,7 +819,7 @@ static int audio_enqueuebuffer(FAR struct file *filep,
756819
FAR struct audio_lowerhalf_s *lower = upper->dev;
757820
FAR struct audio_openpriv_s *priv = filep->f_priv;
758821
irqstate_t flags;
759-
int ret;
822+
int ret = OK;
760823

761824
DEBUGASSERT(lower->ops->enqueuebuffer != NULL);
762825

@@ -774,12 +837,16 @@ static int audio_enqueuebuffer(FAR struct file *filep,
774837
}
775838
else
776839
{
777-
flags = spin_lock_irqsave(&upper->spinlock);
778-
priv->head += bufdesc->numbytes;
779-
spin_unlock_irqrestore(&upper->spinlock, flags);
840+
flags = spin_lock_irqsave_nopreempt(&upper->spinlock);
841+
upper->apbs[priv->head % upper->periods]->nbytes =
842+
MAX(upper->apbs[priv->head % upper->periods]->nbytes,
843+
bufdesc->numbytes);
844+
priv->head++;
845+
ret = audio_try_enqueue(upper);
846+
spin_unlock_irqrestore_nopreempt(&upper->spinlock, flags);
780847
}
781848

782-
return OK;
849+
return ret;
783850
}
784851

785852
/****************************************************************************
@@ -1319,6 +1386,7 @@ static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper,
13191386

13201387
flags = spin_lock_irqsave_nopreempt(&upper->spinlock);
13211388
upper->status->tail++;
1389+
audio_try_enqueue(upper);
13221390
for (priv = upper->head; priv != NULL; priv = priv->flink)
13231391
{
13241392
if (priv->fd > 0)

0 commit comments

Comments
 (0)