summaryrefslogtreecommitdiff
path: root/ffmpeg.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-09-19 06:13:30 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-09-19 07:04:17 +0200
commitb5875b91113a0f3de6ad61e9ff8b74b81de94760 (patch)
treeb33f19a81ebe0d3145368f0d6494f4f4aab75aba /ffmpeg.c
parent53e37840bf205a24c3b3ad6d838805dc54a905bf (diff)
Add libswresample.
Similar to libswscale this does resampling and format convertion, just for audio instead of video. changing sampling rate, sample formats, channel layouts and sample packing all in one with a very simple public interface. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'ffmpeg.c')
-rw-r--r--ffmpeg.c83
1 files changed, 29 insertions, 54 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index b887abd7f5..6da97d24ae 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -45,6 +45,7 @@
#include "libavutil/avstring.h"
#include "libavutil/libm.h"
#include "libavformat/os_support.h"
+#include "libswresample/swresample.h"
#include "libavformat/ffm.h" // not public API
@@ -229,15 +230,14 @@ typedef struct OutputStream {
/* audio only */
int audio_resample;
- ReSampleContext *resample; /* for audio resampling */
int resample_sample_fmt;
int resample_channels;
int resample_sample_rate;
- int reformat_pair;
- AVAudioConvert *reformat_ctx;
AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */
FILE *logfile;
+ struct SwrContext *swr;
+
#if CONFIG_AVFILTER
AVFilterContext *output_video_filter;
AVFilterContext *input_video_filter;
@@ -843,14 +843,15 @@ need_realloc:
exit_program(1);
}
- if (enc->channels != dec->channels)
+ if (enc->channels != dec->channels
+ || enc->sample_fmt != dec->sample_fmt)
ost->audio_resample = 1;
resample_changed = ost->resample_sample_fmt != dec->sample_fmt ||
ost->resample_channels != dec->channels ||
ost->resample_sample_rate != dec->sample_rate;
- if ((ost->audio_resample && !ost->resample) || resample_changed) {
+ if ((ost->audio_resample && !ost->swr) || resample_changed) {
if (resample_changed) {
av_log(NULL, AV_LOG_INFO, "Input stream #%d.%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n",
ist->file_index, ist->st->index,
@@ -859,24 +860,29 @@ need_realloc:
ost->resample_sample_fmt = dec->sample_fmt;
ost->resample_channels = dec->channels;
ost->resample_sample_rate = dec->sample_rate;
- if (ost->resample)
- audio_resample_close(ost->resample);
+ swr_free(&ost->swr);
}
/* if audio_sync_method is >1 the resampler is needed for audio drift compensation */
if (audio_sync_method <= 1 &&
ost->resample_sample_fmt == enc->sample_fmt &&
ost->resample_channels == enc->channels &&
ost->resample_sample_rate == enc->sample_rate) {
- ost->resample = NULL;
+ //ost->swr = NULL;
ost->audio_resample = 0;
} else {
- if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
- fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");
- ost->resample = av_audio_resample_init(enc->channels, dec->channels,
- enc->sample_rate, dec->sample_rate,
- enc->sample_fmt, dec->sample_fmt,
- 16, 10, 0, 0.8);
- if (!ost->resample) {
+ ost->swr = swr_alloc2(ost->swr,
+ enc->channel_layout, enc->sample_fmt, enc->sample_rate,
+ dec->channel_layout, dec->sample_fmt, dec->sample_rate,
+ 0, NULL);
+ av_set_int(ost->swr, "ich", dec->channels);
+ av_set_int(ost->swr, "och", enc->channels);
+ if(audio_sync_method>1) av_set_int(ost->swr, "flags", SWR_FLAG_RESAMPLE);
+ if(ost->swr && swr_init(ost->swr) < 0){
+ fprintf(stderr, "swr_init() failed\n");
+ swr_free(&ost->swr);
+ }
+
+ if (!ost->swr) {
fprintf(stderr, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n",
dec->channels, dec->sample_rate,
enc->channels, enc->sample_rate);
@@ -885,21 +891,7 @@ need_realloc:
}
}
-#define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))
- if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt &&
- MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt)!=ost->reformat_pair) {
- if (ost->reformat_ctx)
- av_audio_convert_free(ost->reformat_ctx);
- ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1,
- dec->sample_fmt, 1, NULL, 0);
- if (!ost->reformat_ctx) {
- fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
- av_get_sample_fmt_name(dec->sample_fmt),
- av_get_sample_fmt_name(enc->sample_fmt));
- exit_program(1);
- }
- ost->reformat_pair=MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);
- }
+ av_assert0(ost->audio_resample || dec->sample_fmt==enc->sample_fmt);
if(audio_sync_method){
double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts
@@ -941,7 +933,7 @@ need_realloc:
if(verbose > 2)
fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
// fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
- av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
+ swr_compensate(ost->swr, comp, enc->sample_rate);
}
}
}else
@@ -950,30 +942,15 @@ need_realloc:
if (ost->audio_resample) {
buftmp = audio_buf;
- size_out = audio_resample(ost->resample,
- (short *)buftmp, (short *)buf,
- size / (dec->channels * isize));
+ size_out = swr_convert(ost->swr, ( uint8_t*[]){buftmp}, audio_buf_size / (enc->channels * osize),
+ (const uint8_t*[]){buf }, size / (dec->channels * isize));
size_out = size_out * enc->channels * osize;
} else {
buftmp = buf;
size_out = size;
}
- if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt) {
- const void *ibuf[6]= {buftmp};
- void *obuf[6]= {audio_buf};
- int istride[6]= {isize};
- int ostride[6]= {osize};
- int len= size_out/istride[0];
- if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
- printf("av_audio_convert() failed\n");
- if (exit_on_error)
- exit_program(1);
- return;
- }
- buftmp = audio_buf;
- size_out = len*osize;
- }
+ av_assert0(ost->audio_resample || dec->sample_fmt==enc->sample_fmt);
/* now encode as many frames as possible */
if (enc->frame_size > 1) {
@@ -2133,7 +2110,6 @@ static int transcode_init(OutputFile *output_files, int nb_output_files,
if (!ost->fifo) {
return AVERROR(ENOMEM);
}
- ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);
if (!codec->sample_rate) {
codec->sample_rate = icodec->sample_rate;
}
@@ -2149,6 +2125,8 @@ static int transcode_init(OutputFile *output_files, int nb_output_files,
if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
codec->channel_layout = 0;
ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
+ ost->audio_resample |= codec->sample_fmt != icodec->sample_fmt
+ || codec->channel_layout != icodec->channel_layout;
icodec->request_channels = codec->channels;
ist->decoding_needed = 1;
ost->encoding_needed = 1;
@@ -2679,10 +2657,7 @@ static int transcode(OutputFile *output_files, int nb_output_files,
av_free(ost->forced_kf_pts);
if (ost->video_resample)
sws_freeContext(ost->img_resample_ctx);
- if (ost->resample)
- audio_resample_close(ost->resample);
- if (ost->reformat_ctx)
- av_audio_convert_free(ost->reformat_ctx);
+ swr_free(&ost->swr);
av_dict_free(&ost->opts);
}
}