2 * Audio Interleaving functions
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/fifo.h"
25 #include "audiointerleave.h"
28 void ff_audio_interleave_close(AVFormatContext
*s
)
31 for (i
= 0; i
< s
->nb_streams
; i
++) {
32 AVStream
*st
= s
->streams
[i
];
33 AudioInterleaveContext
*aic
= st
->priv_data
;
35 if (st
->codec
->codec_type
== CODEC_TYPE_AUDIO
)
36 av_fifo_free(aic
->fifo
);
40 int ff_audio_interleave_init(AVFormatContext
*s
,
41 const int *samples_per_frame
,
46 if (!samples_per_frame
)
49 for (i
= 0; i
< s
->nb_streams
; i
++) {
50 AVStream
*st
= s
->streams
[i
];
51 AudioInterleaveContext
*aic
= st
->priv_data
;
53 if (st
->codec
->codec_type
== CODEC_TYPE_AUDIO
) {
54 aic
->sample_size
= (st
->codec
->channels
*
55 av_get_bits_per_sample(st
->codec
->codec_id
)) / 8;
56 if (!aic
->sample_size
) {
57 av_log(s
, AV_LOG_ERROR
, "could not compute sample size\n");
60 aic
->samples_per_frame
= samples_per_frame
;
61 aic
->samples
= aic
->samples_per_frame
;
62 aic
->time_base
= time_base
;
64 aic
->fifo_size
= 100* *aic
->samples
;
65 aic
->fifo
= av_fifo_alloc(100 * *aic
->samples
);
72 static int ff_interleave_new_audio_packet(AVFormatContext
*s
, AVPacket
*pkt
,
73 int stream_index
, int flush
)
75 AVStream
*st
= s
->streams
[stream_index
];
76 AudioInterleaveContext
*aic
= st
->priv_data
;
78 int size
= FFMIN(av_fifo_size(aic
->fifo
), *aic
->samples
* aic
->sample_size
);
79 if (!size
|| (!flush
&& size
== av_fifo_size(aic
->fifo
)))
82 av_new_packet(pkt
, size
);
83 av_fifo_generic_read(aic
->fifo
, pkt
->data
, size
, NULL
);
85 pkt
->dts
= pkt
->pts
= aic
->dts
;
86 pkt
->duration
= av_rescale_q(*aic
->samples
, st
->time_base
, aic
->time_base
);
87 pkt
->stream_index
= stream_index
;
88 aic
->dts
+= pkt
->duration
;
92 aic
->samples
= aic
->samples_per_frame
;
97 int ff_audio_rechunk_interleave(AVFormatContext
*s
, AVPacket
*out
, AVPacket
*pkt
, int flush
,
98 int (*get_packet
)(AVFormatContext
*, AVPacket
*, AVPacket
*, int),
99 int (*compare_ts
)(AVFormatContext
*, AVPacket
*, AVPacket
*))
104 AVStream
*st
= s
->streams
[pkt
->stream_index
];
105 AudioInterleaveContext
*aic
= st
->priv_data
;
106 if (st
->codec
->codec_type
== CODEC_TYPE_AUDIO
) {
107 unsigned new_size
= av_fifo_size(aic
->fifo
) + pkt
->size
;
108 if (new_size
> aic
->fifo_size
) {
109 if (av_fifo_realloc2(aic
->fifo
, new_size
) < 0)
111 aic
->fifo_size
= new_size
;
113 av_fifo_generic_write(aic
->fifo
, pkt
->data
, pkt
->size
, NULL
);
115 // rewrite pts and dts to be decoded time line position
116 pkt
->pts
= pkt
->dts
= aic
->dts
;
117 aic
->dts
+= pkt
->duration
;
118 ff_interleave_add_packet(s
, pkt
, compare_ts
);
123 for (i
= 0; i
< s
->nb_streams
; i
++) {
124 AVStream
*st
= s
->streams
[i
];
125 if (st
->codec
->codec_type
== CODEC_TYPE_AUDIO
) {
127 while (ff_interleave_new_audio_packet(s
, &new_pkt
, i
, flush
))
128 ff_interleave_add_packet(s
, &new_pkt
, compare_ts
);
132 return get_packet(s
, out
, pkt
, flush
);