FFmpeg
Loading...
Searching...
No Matches
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 FFmpeg.
6 *
7 * FFmpeg 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 * FFmpeg 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 FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
24#include "libavutil/mem.h"
25#include "audio_frame_queue.h"
26#include "encode.h"
27#include "libavutil/avassert.h"
28
30{
31 afq->avctx = avctx;
32 afq->remaining_delay = avctx->initial_padding;
34 afq->output_delay = avctx->initial_padding;
35 afq->frame_count = 0;
36}
37
39{
40 if(afq->frame_count)
41 av_log(afq->avctx, AV_LOG_WARNING, "%d frames left in the queue on closing\n", afq->frame_count);
42 av_freep(&afq->frames);
43 memset(afq, 0, sizeof(*afq));
44}
45
47{
48 AudioFrame *new = av_fast_realloc(afq->frames, &afq->frame_alloc, sizeof(*afq->frames)*(afq->frame_count+1));
49 const AVFrameSideData *sd;
50 int nb_samples = f->nb_samples;
51
52 if(!new)
53 return AVERROR(ENOMEM);
54 afq->frames = new;
55 new += afq->frame_count;
56
57 sd = av_frame_side_data_get(f->side_data, f->nb_side_data, AV_FRAME_DATA_SKIP_SAMPLES);
58 if (sd && sd->size >= 10) {
59 int discard_padding = AV_RL32(sd->data + 4);
60 if (discard_padding > 0 && discard_padding < nb_samples)
61 nb_samples -= discard_padding;
62 }
63
64 /* get frame parameters */
65 new->duration = nb_samples;
66 new->duration += afq->remaining_delay;
67 if (f->pts != AV_NOPTS_VALUE) {
68 new->pts = av_rescale_q(f->pts,
69 afq->avctx->time_base,
70 (AVRational){ 1, afq->avctx->sample_rate });
71 new->pts -= afq->remaining_delay;
72 if(afq->frame_count && new[-1].pts >= new->pts)
73 av_log(afq->avctx, AV_LOG_WARNING, "Queue input is backward in time\n");
74 } else {
75 new->pts = AV_NOPTS_VALUE;
76 }
77 afq->remaining_delay = 0;
78
79 /* add frame sample count */
80 afq->remaining_samples += nb_samples;
81
82 afq->frame_count++;
83
84 return 0;
85}
86
88{
89 int64_t out_pts = AV_NOPTS_VALUE;
90 int frame_size = nb_samples;
91 int removed_samples = 0;
92 int i;
93
94 if (afq->frame_count || afq->frame_alloc) {
95 if (afq->frames->pts != AV_NOPTS_VALUE)
96 out_pts = afq->frames->pts;
97 }
98 if(!afq->frame_count)
99 av_log(afq->avctx, AV_LOG_WARNING, "Trying to remove %d samples, but the queue is empty\n", nb_samples);
100 if (pkt)
101 pkt->pts = ff_samples_to_time_base(afq->avctx, out_pts);
102
103 for(i=0; nb_samples && i<afq->frame_count; i++){
104 int n= FFMIN(afq->frames[i].duration, nb_samples);
105 afq->frames[i].duration -= n;
106 nb_samples -= n;
107 removed_samples += n;
108 if(afq->frames[i].pts != AV_NOPTS_VALUE)
109 afq->frames[i].pts += n;
110 }
111 afq->remaining_samples -= removed_samples;
112 i -= i && afq->frames[i-1].duration;
113 memmove(afq->frames, afq->frames + i, sizeof(*afq->frames) * (afq->frame_count - i));
114 afq->frame_count -= i;
115
116 if(nb_samples){
117 av_assert0(!afq->frame_count);
119 if(afq->frames && afq->frames[0].pts != AV_NOPTS_VALUE)
120 afq->frames[0].pts += nb_samples;
121 av_log(afq->avctx, AV_LOG_DEBUG, "Trying to remove %d more samples than there are in the queue\n", nb_samples);
122 }
123 if (pkt) {
124 int discard_padding = frame_size - removed_samples;
125 pkt->duration = ff_samples_to_time_base(afq->avctx, removed_samples);
126 if (afq->output_delay > 0 || discard_padding > 0) {
127 uint8_t *side_data =
129 if (!side_data)
130 return AVERROR(ENOMEM);
131 if (afq->output_delay) {
132 AV_WL32(side_data, FFMIN(afq->output_delay, removed_samples));
133 afq->output_delay -= removed_samples;
134 afq->output_delay = FFMAX(afq->output_delay, 0);
135 }
136 AV_WL32(side_data + 4, discard_padding);
137 }
138 }
139
140 return 0;
141}
av_cold void ff_af_queue_close(AudioFrameQueue *afq)
Close AudioFrameQueue.
av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
Initialize AudioFrameQueue.
int ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, AVPacket *pkt)
Remove frame(s) from the queue.
int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
Add a frame to the queue.
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
static av_always_inline int64_t ff_samples_to_time_base(const AVCodecContext *avctx, int64_t samples)
Rescale from sample rate to AVCodecContext.time_base.
Definition encode.h:96
static const uint8_t frame_size[4]
Definition g723_1.h:222
@ AV_PKT_DATA_SKIP_SAMPLES
Recommends skipping the specified number of samples.
Definition packet.h:153
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition packet.c:231
#define AVERROR(e)
Definition error.h:45
static const AVFrameSideData * av_frame_side_data_get(AVFrameSideData *const *sd, const int nb_sd, enum AVFrameSideDataType type)
Wrapper around av_frame_side_data_get_c() to workaround the limitation that for any type T the conver...
Definition frame.h:1196
@ AV_FRAME_DATA_SKIP_SAMPLES
Recommends skipping the specified number of samples.
Definition frame.h:109
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_WL32(p, v)
#define AV_RL32(p)
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
Memory handling functions.
main external API structure.
Definition avcodec.h:443
int initial_padding
Audio only.
Definition avcodec.h:1114
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avcodec.h:547
Structure to hold side data for an AVFrame.
Definition frame.h:327
size_t size
Definition frame.h:330
uint8_t * data
Definition frame.h:329
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
Rational number (pair of numerator and denominator).
Definition rational.h:58
AudioFrame * frames
AVCodecContext * avctx
#define av_freep(p)
#define av_log(a,...)