Libav
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/attributes.h"
23 #include "libavutil/common.h"
24 #include "libavutil/mathematics.h"
25 #include "internal.h"
26 #include "audio_frame_queue.h"
27 
29 {
30  afq->avctx = avctx;
31  afq->next_pts = AV_NOPTS_VALUE;
32  afq->remaining_delay = avctx->delay;
33  afq->remaining_samples = avctx->delay;
34  afq->frame_queue = NULL;
35 }
36 
38 {
39  AudioFrame *f = afq->frame_queue;
40  if (f) {
41  afq->frame_queue = f->next;
42  f->next = NULL;
43  av_freep(&f);
44  }
45 }
46 
48 {
49  /* remove/free any remaining frames */
50  while (afq->frame_queue)
51  delete_next_frame(afq);
52  memset(afq, 0, sizeof(*afq));
53 }
54 
55 #ifdef DEBUG
56 static void af_queue_log_state(AudioFrameQueue *afq)
57 {
58  AudioFrame *f;
59  av_dlog(afq->avctx, "remaining delay = %d\n", afq->remaining_delay);
60  av_dlog(afq->avctx, "remaining samples = %d\n", afq->remaining_samples);
61  av_dlog(afq->avctx, "frames:\n");
62  f = afq->frame_queue;
63  while (f) {
64  av_dlog(afq->avctx, " [ pts=%9"PRId64" duration=%d ]\n",
65  f->pts, f->duration);
66  f = f->next;
67  }
68 }
69 #endif /* DEBUG */
70 
72 {
73  AudioFrame *new_frame;
74  AudioFrame *queue_end = afq->frame_queue;
75 
76  /* find the end of the queue */
77  while (queue_end && queue_end->next)
78  queue_end = queue_end->next;
79 
80  /* allocate new frame queue entry */
81  if (!(new_frame = av_malloc(sizeof(*new_frame))))
82  return AVERROR(ENOMEM);
83 
84  /* get frame parameters */
85  new_frame->next = NULL;
86  new_frame->duration = f->nb_samples;
87  if (f->pts != AV_NOPTS_VALUE) {
88  new_frame->pts = av_rescale_q(f->pts,
89  afq->avctx->time_base,
90  (AVRational){ 1, afq->avctx->sample_rate });
91  afq->next_pts = new_frame->pts + new_frame->duration;
92  } else {
93  new_frame->pts = AV_NOPTS_VALUE;
94  afq->next_pts = AV_NOPTS_VALUE;
95  }
96 
97  /* add new frame to the end of the queue */
98  if (!queue_end)
99  afq->frame_queue = new_frame;
100  else
101  queue_end->next = new_frame;
102 
103  /* add frame sample count */
104  afq->remaining_samples += f->nb_samples;
105 
106 #ifdef DEBUG
107  af_queue_log_state(afq);
108 #endif
109 
110  return 0;
111 }
112 
113 void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts,
114  int *duration)
115 {
116  int64_t out_pts = AV_NOPTS_VALUE;
117  int removed_samples = 0;
118 
119 #ifdef DEBUG
120  af_queue_log_state(afq);
121 #endif
122 
123  /* get output pts from the next frame or generated pts */
124  if (afq->frame_queue) {
125  if (afq->frame_queue->pts != AV_NOPTS_VALUE)
126  out_pts = afq->frame_queue->pts - afq->remaining_delay;
127  } else {
128  if (afq->next_pts != AV_NOPTS_VALUE)
129  out_pts = afq->next_pts - afq->remaining_delay;
130  }
131  if (pts) {
132  if (out_pts != AV_NOPTS_VALUE)
133  *pts = ff_samples_to_time_base(afq->avctx, out_pts);
134  else
135  *pts = AV_NOPTS_VALUE;
136  }
137 
138  /* if the delay is larger than the packet duration, we use up delay samples
139  for the output packet and leave all frames in the queue */
140  if (afq->remaining_delay >= nb_samples) {
141  removed_samples += nb_samples;
142  afq->remaining_delay -= nb_samples;
143  }
144  /* remove frames from the queue until we have enough to cover the
145  requested number of samples or until the queue is empty */
146  while (removed_samples < nb_samples && afq->frame_queue) {
147  removed_samples += afq->frame_queue->duration;
148  delete_next_frame(afq);
149  }
150  afq->remaining_samples -= removed_samples;
151 
152  /* if there are no frames left and we have room for more samples, use
153  any remaining delay samples */
154  if (removed_samples < nb_samples && afq->remaining_samples > 0) {
155  int add_samples = FFMIN(afq->remaining_samples,
156  nb_samples - removed_samples);
157  removed_samples += add_samples;
158  afq->remaining_samples -= add_samples;
159  }
160  if (removed_samples > nb_samples)
161  av_log(afq->avctx, AV_LOG_WARNING, "frame_size is too large\n");
162  if (duration)
163  *duration = ff_samples_to_time_base(afq->avctx, removed_samples);
164 }
This structure describes decoded (raw) audio or video data.
Definition: frame.h:135
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:129
AudioFrame * frame_queue
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
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:246
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1175
void av_freep(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
Initialize AudioFrameQueue.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:211
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:129
#define AVERROR(e)
Definition: error.h:43
int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
Add a frame to the queue.
AVCodecContext * avctx
void * av_malloc(size_t size) av_malloc_attrib 1(1)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
NULL
Definition: eval.c:55
#define av_cold
Definition: attributes.h:66
main external API structure.
Definition: avcodec.h:1050
rational number numerator/denominator
Definition: rational.h:43
static void delete_next_frame(AudioFrameQueue *afq)
common internal api header.
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:149
int delay
Codec delay.
Definition: avcodec.h:1212
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:179
#define FFMIN(a, b)
Definition: common.h:57
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:228
struct AudioFrame * next