mirror of https://git.ffmpeg.org/ffmpeg.git
Add sample format converter to FFmpeg (adds -sample_fmt option)
Originally committed as revision 14512 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
2879c75ff3
commit
a79db0f7c4
58
ffmpeg.c
58
ffmpeg.c
|
@ -257,6 +257,8 @@ typedef struct AVOutputStream {
|
|||
/* audio only */
|
||||
int audio_resample;
|
||||
ReSampleContext *resample; /* for audio resampling */
|
||||
int reformat_pair;
|
||||
AVAudioConvert *reformat_ctx;
|
||||
AVFifoBuffer fifo; /* for compression: one audio fifo per codec */
|
||||
FILE *logfile;
|
||||
} AVOutputStream;
|
||||
|
@ -513,6 +515,7 @@ static void do_audio_out(AVFormatContext *s,
|
|||
uint8_t *buftmp;
|
||||
static uint8_t *audio_buf = NULL;
|
||||
static uint8_t *audio_out = NULL;
|
||||
static uint8_t *audio_out2 = NULL;
|
||||
const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE;
|
||||
|
||||
int size_out, frame_bytes, ret;
|
||||
|
@ -541,6 +544,26 @@ static void do_audio_out(AVFormatContext *s,
|
|||
}
|
||||
}
|
||||
|
||||
#define MAKE_SFMT_PAIR(a,b) ((a)+SAMPLE_FMT_NB*(b))
|
||||
if (dec->sample_fmt!=enc->sample_fmt &&
|
||||
MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt)!=ost->reformat_pair) {
|
||||
if (!audio_out2)
|
||||
audio_out2 = av_malloc(audio_out_size);
|
||||
if (!audio_out2)
|
||||
av_exit(1);
|
||||
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",
|
||||
avcodec_get_sample_fmt_name(dec->sample_fmt),
|
||||
avcodec_get_sample_fmt_name(enc->sample_fmt));
|
||||
av_exit(1);
|
||||
}
|
||||
ost->reformat_pair=MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);
|
||||
}
|
||||
|
||||
if(audio_sync_method){
|
||||
double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts
|
||||
- av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);
|
||||
|
@ -599,6 +622,22 @@ static void do_audio_out(AVFormatContext *s,
|
|||
size_out = size;
|
||||
}
|
||||
|
||||
if (dec->sample_fmt!=enc->sample_fmt) {
|
||||
const void *ibuf[6]= {buftmp};
|
||||
void *obuf[6]= {audio_out2};
|
||||
int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
|
||||
int ostride[6]= {av_get_bits_per_sample_format(enc->sample_fmt)/8};
|
||||
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");
|
||||
return;
|
||||
}
|
||||
buftmp = audio_out2;
|
||||
/* FIXME: existing code assume that size_out equals framesize*channels*2
|
||||
remove this legacy cruft */
|
||||
size_out = len*2;
|
||||
}
|
||||
|
||||
/* now encode as many frames as possible */
|
||||
if (enc->frame_size > 1) {
|
||||
/* output resampled raw samples */
|
||||
|
@ -1726,6 +1765,7 @@ static int av_encode(AVFormatContext **output_files,
|
|||
case CODEC_TYPE_AUDIO:
|
||||
if (av_fifo_init(&ost->fifo, 1024))
|
||||
goto fail;
|
||||
ost->reformat_pair = MAKE_SFMT_PAIR(SAMPLE_FMT_NONE,SAMPLE_FMT_NONE);
|
||||
ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
|
||||
icodec->request_channels = codec->channels;
|
||||
ist->decoding_needed = 1;
|
||||
|
@ -2162,6 +2202,8 @@ static int av_encode(AVFormatContext **output_files,
|
|||
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);
|
||||
av_free(ost);
|
||||
}
|
||||
}
|
||||
|
@ -2763,6 +2805,7 @@ static void opt_input_file(const char *filename)
|
|||
ap->width = frame_width + frame_padleft + frame_padright;
|
||||
ap->height = frame_height + frame_padtop + frame_padbottom;
|
||||
ap->pix_fmt = frame_pix_fmt;
|
||||
// ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat
|
||||
ap->channel = video_channel;
|
||||
ap->standard = video_standard;
|
||||
ap->video_codec_id = find_codec_or_die(video_codec_name, CODEC_TYPE_VIDEO, 0);
|
||||
|
@ -2827,6 +2870,7 @@ static void opt_input_file(const char *filename)
|
|||
//fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
|
||||
audio_channels = enc->channels;
|
||||
audio_sample_rate = enc->sample_rate;
|
||||
audio_sample_fmt = enc->sample_fmt;
|
||||
if(audio_disable)
|
||||
ic->streams[i]->discard= AVDISCARD_ALL;
|
||||
break;
|
||||
|
@ -3109,6 +3153,7 @@ static void new_audio_stream(AVFormatContext *oc)
|
|||
st->stream_copy = 1;
|
||||
audio_enc->channels = audio_channels;
|
||||
} else {
|
||||
AVCodec *codec;
|
||||
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO);
|
||||
|
||||
set_context_opts(audio_enc, avctx_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
|
||||
|
@ -3116,6 +3161,7 @@ static void new_audio_stream(AVFormatContext *oc)
|
|||
if (audio_codec_name)
|
||||
codec_id = find_codec_or_die(audio_codec_name, CODEC_TYPE_AUDIO, 1);
|
||||
audio_enc->codec_id = codec_id;
|
||||
codec = avcodec_find_encoder(codec_id);
|
||||
|
||||
if (audio_qscale > QSCALE_NONE) {
|
||||
audio_enc->flags |= CODEC_FLAG_QSCALE;
|
||||
|
@ -3123,6 +3169,17 @@ static void new_audio_stream(AVFormatContext *oc)
|
|||
}
|
||||
audio_enc->thread_count = thread_count;
|
||||
audio_enc->channels = audio_channels;
|
||||
audio_enc->sample_fmt = audio_sample_fmt;
|
||||
|
||||
if(codec && codec->sample_fmts){
|
||||
const enum SampleFormat *p= codec->sample_fmts;
|
||||
for(; *p!=-1; p++){
|
||||
if(*p == audio_enc->sample_fmt)
|
||||
break;
|
||||
}
|
||||
if(*p == -1)
|
||||
audio_enc->sample_fmt = codec->sample_fmts[0];
|
||||
}
|
||||
}
|
||||
audio_enc->sample_rate = audio_sample_rate;
|
||||
audio_enc->time_base= (AVRational){1, audio_sample_rate};
|
||||
|
@ -3793,6 +3850,7 @@ static const OptionDef options[] = {
|
|||
{ "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, //
|
||||
{ "newaudio", OPT_AUDIO, {(void*)opt_new_audio_stream}, "add a new audio stream to the current output stream" },
|
||||
{ "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" },
|
||||
{ "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_sample_fmt}, "set sample format, 'list' as argument shows all the sample formats supported", "format" },
|
||||
|
||||
/* subtitle options */
|
||||
{ "sn", OPT_BOOL | OPT_SUBTITLE, {(void*)&subtitle_disable}, "disable subtitle" },
|
||||
|
|
Loading…
Reference in New Issue