audiointerleave.c
Go to the documentation of this file.
1 /*
2  * Audio Interleaving functions
3  *
4  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/fifo.h"
24 #include "libavutil/mathematics.h"
25 #include "avformat.h"
26 #include "audiointerleave.h"
27 #include "internal.h"
28 
30 {
31  int i;
32  for (i = 0; i < s->nb_streams; i++) {
33  AVStream *st = s->streams[i];
35 
37  av_fifo_free(aic->fifo);
38  }
39 }
40 
42  const int *samples_per_frame,
43  AVRational time_base)
44 {
45  int i;
46 
47  if (!samples_per_frame)
48  return -1;
49 
50  if (!time_base.num) {
51  av_log(s, AV_LOG_ERROR, "timebase not set for audio interleave\n");
52  return -1;
53  }
54  for (i = 0; i < s->nb_streams; i++) {
55  AVStream *st = s->streams[i];
57 
58  if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
59  aic->sample_size = (st->codec->channels *
61  if (!aic->sample_size) {
62  av_log(s, AV_LOG_ERROR, "could not compute sample size\n");
63  return -1;
64  }
65  aic->samples_per_frame = samples_per_frame;
66  aic->samples = aic->samples_per_frame;
67  aic->time_base = time_base;
68 
69  aic->fifo_size = 100* *aic->samples;
70  aic->fifo= av_fifo_alloc(100 * *aic->samples);
71  }
72  }
73 
74  return 0;
75 }
76 
78  int stream_index, int flush)
79 {
80  AVStream *st = s->streams[stream_index];
82 
83  int size = FFMIN(av_fifo_size(aic->fifo), *aic->samples * aic->sample_size);
84  if (!size || (!flush && size == av_fifo_size(aic->fifo)))
85  return 0;
86 
87  if (av_new_packet(pkt, size) < 0)
88  return AVERROR(ENOMEM);
89  av_fifo_generic_read(aic->fifo, pkt->data, size, NULL);
90 
91  pkt->dts = pkt->pts = aic->dts;
92  pkt->duration = av_rescale_q(*aic->samples, st->time_base, aic->time_base);
93  pkt->stream_index = stream_index;
94  aic->dts += pkt->duration;
95 
96  aic->samples++;
97  if (!*aic->samples)
98  aic->samples = aic->samples_per_frame;
99 
100  return size;
101 }
102 
104  int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int),
105  int (*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *))
106 {
107  int i;
108 
109  if (pkt) {
110  AVStream *st = s->streams[pkt->stream_index];
112  if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
113  unsigned new_size = av_fifo_size(aic->fifo) + pkt->size;
114  if (new_size > aic->fifo_size) {
115  if (av_fifo_realloc2(aic->fifo, new_size) < 0)
116  return -1;
117  aic->fifo_size = new_size;
118  }
119  av_fifo_generic_write(aic->fifo, pkt->data, pkt->size, NULL);
120  } else {
121  int ret;
122  // rewrite pts and dts to be decoded time line position
123  pkt->pts = pkt->dts = aic->dts;
124  aic->dts += pkt->duration;
125  ret = ff_interleave_add_packet(s, pkt, compare_ts);
126  if (ret < 0)
127  return ret;
128  }
129  pkt = NULL;
130  }
131 
132  for (i = 0; i < s->nb_streams; i++) {
133  AVStream *st = s->streams[i];
134  if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
135  AVPacket new_pkt;
136  int ret;
137  while ((ret = ff_interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) {
138  ret = ff_interleave_add_packet(s, &new_pkt, compare_ts);
139  if (ret < 0)
140  return ret;
141  }
142  if (ret < 0)
143  return ret;
144  }
145  }
146 
147  return get_packet(s, out, NULL, flush);
148 }
const char * s
Definition: avisynth_c.h:668
const int * samples
current samples per frame, pointer to samples_per_frame
int num
numerator
Definition: rational.h:44
const int * samples_per_frame
must be 0-terminated
void * priv_data
Definition: avformat.h:663
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Format I/O context.
Definition: avformat.h:944
static AVPacket pkt
Definition: demuxing.c:56
int ff_audio_interleave_init(AVFormatContext *s, const int *samples_per_frame, AVRational time_base)
AVStream ** streams
Definition: avformat.h:992
uint8_t * data
unsigned fifo_size
size of currently allocated FIFO
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:73
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
static int ff_interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt, int stream_index, int flush)
int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush, int(*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int), int(*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *))
Rechunk audio PCM packets per AudioInterleaveContext->samples_per_frame and interleave them correctly...
int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, int(*compare)(AVFormatContext *, AVPacket *, AVPacket *))
Add packet to AVFormatContext->packet_buffer list, determining its interleaved position using compare...
Definition: mux.c:536
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int size
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
uint64_t dts
current dts
static void flush(AVCodecContext *avctx)
AVRational time_base
time base of output audio packets
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
enum AVMediaType codec_type
enum AVCodecID codec_id
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
a very simple circular buffer FIFO implementation
synthesis window for stochastic i
rational number numerator/denominator
Definition: rational.h:43
int sample_size
size of one sample all channels included
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
Main libavformat public API header.
int av_fifo_size(AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
void ff_audio_interleave_close(AVFormatContext *s)
static int get_packet(URLContext *s, int for_header)
Interact with the server by receiving and sending RTMP packets until there is some significant data (...
Definition: rtmpproto.c:2122
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
int channels
number of audio channels
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:679
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...