c语言的版本到处都有,pascal的不好找,只能自己翻译。
- //use it like:
- //AudioResampling(aCodecCtx, frame, AV_SAMPLE_FMT_S16, frame.channels, frame.sample_rate, audio_buf0);
- function AudioResampling(audio_dec_ctx: PAVCodecContext; pAudioDecodeFrame: pAVFrame;
- out_sample_fmt: TAVSampleFormat; out_channels: integer; out_sample_rate: integer; out_buf: pbyte): integer;
- var
- swr_ctx: pSwrContext = nil;
- data_size: integer = 0;
- ret: integer = 0;
- src_ch_layout: int64;
- dst_ch_layout: int64;
- dst_nb_channels: integer = 0;
- dst_linesize: integer = 0;
- src_nb_samples: integer = 0;
- dst_nb_samples: integer = 0;
- max_dst_nb_samples: integer = 0;
- dst_data: ppbyte = nil;
- resampled_data_size: integer = 0;
- begin
- Result := -1;
- src_ch_layout := audio_dec_ctx.channel_layout;
- dst_ch_layout := AV_CH_LAYOUT_STEREO;
- swr_ctx := swr_alloc();
- if swr_ctx = nil then
- begin
- consolelog('swr_alloc error');
- exit;
- end;
- if audio_dec_ctx.channels = av_get_channel_layout_nb_channels(audio_dec_ctx.channel_layout) then
- src_ch_layout := audio_dec_ctx.channel_layout
- else
- src_ch_layout := av_get_default_channel_layout(audio_dec_ctx.channels);
- if out_channels = 1 then
- begin
- dst_ch_layout := AV_CH_LAYOUT_MONO;
- //consolelog('dst_ch_layout: AV_CH_LAYOUT_MONO');
- end
- else if out_channels = 2 then
- begin
- dst_ch_layout := AV_CH_LAYOUT_STEREO;
- //consolelog('dst_ch_layout: AV_CH_LAYOUT_STEREO');
- end
- else
- begin
- dst_ch_layout := AV_CH_LAYOUT_SURROUND;
- //consolelog('dst_ch_layout: AV_CH_LAYOUT_SURROUND');
- end;
- if src_ch_layout <= 0 then
- begin
- consolelog('src_ch_layout error');
- exit;
- end;
- src_nb_samples := pAudioDecodeFrame.nb_samples;
- if src_nb_samples <= 0 then
- begin
- consolelog('src_nb_samples error');
- exit;
- end;
- av_opt_set_int(swr_ctx, 'in_channel_layout', src_ch_layout, 0);
- av_opt_set_int(swr_ctx, 'in_sample_rate', audio_dec_ctx.sample_rate, 0);
- av_opt_set_sample_fmt(swr_ctx, 'in_sample_fmt', audio_dec_ctx.sample_fmt, 0);
- av_opt_set_int(swr_ctx, 'out_channel_layout', dst_ch_layout, 0);
- av_opt_set_int(swr_ctx, 'out_sample_rate', out_sample_rate, 0);
- av_opt_set_sample_fmt(swr_ctx, 'out_sample_fmt', out_sample_fmt, 0);
- if swr_init(swr_ctx) < 0 then
- begin
- consolelog('Failed to initialize the resampling context');
- exit;
- end;
- dst_nb_samples := av_rescale_rnd(src_nb_samples, out_sample_rate, audio_dec_ctx.sample_rate, AV_ROUND_UP);
- max_dst_nb_samples := dst_nb_samples;
- if max_dst_nb_samples <= 0 then
- begin
- consolelog('av_rescale_rnd error');
- exit;
- end;
- dst_nb_channels := av_get_channel_layout_nb_channels(dst_ch_layout);
- ret := av_samples_alloc_array_and_samples(@dst_data, @dst_linesize, dst_nb_channels,
- dst_nb_samples, out_sample_fmt, 0);
- if ret < 0 then
- begin
- consolelog('av_samples_alloc_array_and_samples error');
- exit;
- end;
- dst_nb_samples := av_rescale_rnd(swr_get_delay(swr_ctx, audio_dec_ctx.sample_rate) +
- src_nb_samples, out_sample_rate, audio_dec_ctx.sample_rate, AV_ROUND_UP);
- if dst_nb_samples <= 0 then
- begin
- consolelog('av_rescale_rnd error ');
- exit;
- end;
- if dst_nb_samples > max_dst_nb_samples then
- begin
- av_free(dst_data^);
- ret := av_samples_alloc(dst_data, @dst_linesize, dst_nb_channels, dst_nb_samples,
- out_sample_fmt, 1);
- max_dst_nb_samples := dst_nb_samples;
- end;
- if swr_ctx <> nil then
- begin
- ret := swr_convert(swr_ctx, dst_data, dst_nb_samples, pAudioDecodeFrame.Data, pAudioDecodeFrame.nb_samples);
- if (ret < 0) then
- begin
- consolelog('swr_convert error');
- exit;
- end;
- resampled_data_size := av_samples_get_buffer_size(@dst_linesize, dst_nb_channels, ret,
- out_sample_fmt, 1);
- if (resampled_data_size < 0) then
- begin
- consolelog('av_samples_get_buffer_size error');
- exit;
- end;
- end
- else
- begin
- consolelog('swr_ctx null error');
- exit;
- end;
- move(dst_data^^, out_buf^, resampled_data_size);
- if (dst_data <> nil) then
- begin
- av_freep(@dst_data^);
- end;
- av_freep(@dst_data);
- dst_data := nil;
- if swr_ctx <> nil then
- begin
- swr_free(@swr_ctx);
- end;
- Result := resampled_data_size;
- end;
复制代码 |