audio_frame_queue.c
Go to the documentation of this file.
1 /*
2  * Audio Frame Queue
3  * Copyright (c) 2012 Justin Ruggles
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/common.h"
23 #include "libavutil/mathematics.h"
24 #include "internal.h"
25 #include "audio_frame_queue.h"
26 
28 {
29  afq->avctx = avctx;
30  afq->next_pts = AV_NOPTS_VALUE;
31  afq->remaining_delay = avctx->delay;
32  afq->remaining_samples = avctx->delay;
33  afq->frame_queue = NULL;
34 }
35 
37 {
38  AudioFrame *f = afq->frame_queue;
39  if (f) {
40  afq->frame_queue = f->next;
41  f->next = NULL;
42  av_freep(&f);
43  }
44 }
45 
47 {
48  /* remove/free any remaining frames */
49  while (afq->frame_queue)
50  delete_next_frame(afq);
51  memset(afq, 0, sizeof(*afq));
52 }
53 
54 #ifdef DEBUG
55 static void af_queue_log_state(AudioFrameQueue *afq)
56 {
57  AudioFrame *f;
58  av_dlog(afq->avctx, "remaining delay = %d\n", afq->remaining_delay);
59  av_dlog(afq->avctx, "remaining samples = %d\n", afq->remaining_samples);
60  av_dlog(afq->avctx, "frames:\n");
61  f = afq->frame_queue;
62  while (f) {
63  av_dlog(afq->avctx, " [ pts=%9"PRId64" duration=%d ]\n",
64  f->pts, f->duration);
65  f = f->next;
66  }
67 }
68 #endif /* DEBUG */
69 
71 {
72  AudioFrame *new_frame;
73  AudioFrame *queue_end = afq->frame_queue;
74 
75  /* find the end of the queue */
76  while (queue_end && queue_end->next)
77  queue_end = queue_end->next;
78 
79  /* allocate new frame queue entry */
80  if (!(new_frame = av_malloc(sizeof(*new_frame))))
81  return AVERROR(ENOMEM);
82 
83  /* get frame parameters */
84  new_frame->next = NULL;
85  new_frame->duration = f->nb_samples;
86  if (f->pts != AV_NOPTS_VALUE) {
87  new_frame->pts = av_rescale_q(f->pts,
88  afq->avctx->time_base,
89  (AVRational){ 1, afq->avctx->sample_rate });
90  afq->next_pts = new_frame->pts + new_frame->duration;
91  } else {
92  new_frame->pts = AV_NOPTS_VALUE;
93  afq->next_pts = AV_NOPTS_VALUE;
94  }
95 
96  /* add new frame to the end of the queue */
97  if (!queue_end)
98  afq->frame_queue = new_frame;
99  else
100  queue_end->next = new_frame;
101 
102  /* add frame sample count */
103  afq->remaining_samples += f->nb_samples;
104 
105 #ifdef DEBUG
106  af_queue_log_state(afq);
107 #endif
108 
109  return 0;
110 }
111 
112 void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts,
113  int *duration)
114 {
115  int64_t out_pts = AV_NOPTS_VALUE;
116  int removed_samples = 0;
117 
118 #ifdef DEBUG
119  af_queue_log_state(afq);
120 #endif
121 
122  /* get output pts from the next frame or generated pts */
123  if (afq->frame_queue) {
124  if (afq->frame_queue->pts != AV_NOPTS_VALUE)
125  out_pts = afq->frame_queue->pts - afq->remaining_delay;
126  } else {
127  if (afq->next_pts != AV_NOPTS_VALUE)
128  out_pts = afq->next_pts - afq->remaining_delay;
129  }
130  if (pts) {
131  if (out_pts != AV_NOPTS_VALUE)
132  *pts = ff_samples_to_time_base(afq->avctx, out_pts);
133  else
134  *pts = AV_NOPTS_VALUE;
135  }
136 
137  /* if the delay is larger than the packet duration, we use up delay samples
138  for the output packet and leave all frames in the queue */
139  if (afq->remaining_delay >= nb_samples) {
140  removed_samples += nb_samples;
141  afq->remaining_delay -= nb_samples;
142  }
143  /* remove frames from the queue until we have enough to cover the
144  requested number of samples or until the queue is empty */
145  while (removed_samples < nb_samples && afq->frame_queue) {
146  removed_samples += afq->frame_queue->duration;
147  delete_next_frame(afq);
148  }
149  afq->remaining_samples -= removed_samples;
150 
151  /* if there are no frames left and we have room for more samples, use
152  any remaining delay samples */
153  if (removed_samples < nb_samples && afq->remaining_samples > 0) {
154  int add_samples = FFMIN(afq->remaining_samples,
155  nb_samples - removed_samples);
156  removed_samples += add_samples;
157  afq->remaining_samples -= add_samples;
158  }
159  if (removed_samples > nb_samples)
160  av_log(afq->avctx, AV_LOG_WARNING, "frame_size is too large\n");
161  if (duration)
162  *duration = ff_samples_to_time_base(afq->avctx, removed_samples);
163 }
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:61
This structure describes decoded (raw) audio or video data.
Definition: avcodec.h:989
AudioFrame * frame_queue
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
static int64_t duration
Definition: avplay.c:249
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1465
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:151
int64_t pts
presentation timestamp in time_base units (time when frame should be shown to user) If AV_NOPTS_VALUE...
Definition: avcodec.h:1088
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:122
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
Add a frame to the queue.
AVCodecContext * avctx
NULL
Definition: eval.c:52
int sample_rate
samples per second
Definition: avcodec.h:2104
main external API structure.
Definition: avcodec.h:1339
out nb_samples
rational number numerator/denominator
Definition: rational.h:43
static void delete_next_frame(AudioFrameQueue *afq)
common internal api header.
common internal and external API header
void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
Initialize AudioFrameQueue.
void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts, int *duration)
Remove frame(s) from the queue.
void ff_af_queue_close(AudioFrameQueue *afq)
Close AudioFrameQueue.
static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx, int64_t samples)
Rescale from sample rate to AVCodecContext.time_base.
Definition: internal.h:140
int delay
Codec delay.
Definition: avcodec.h:1497
int nb_samples
number of audio samples (per channel) described by this frame
Definition: avcodec.h:1042
struct AudioFrame * next