[FFmpeg-user] Rescaling audio samples
JULIAN GARDNER
joolzg at btinternet.com
Fri Mar 27 23:46:24 CET 2015
Im hoping someone can help me here as I am stuck when trying to resample audio from rate to another rate, this is my own code and not withing ffmpeg's code, using ffmpeg libs
LONG MESSAGE WITH CODE
output Stream Information:
Output #0, mpegts, to 'a0.ts':
Stream #0:0: Video: h264 (libx264), yuv420p, 720x576, q=-1--1, 1300 kb/s, 25 tbn, 25 tbc
Stream #0:1: Audio: aac (libfaac), 48000 Hz, stereo, s16, 64 kb/s
Input Stream Information
Input #0, mpegts, from 'udp://225.176.5.178:50206?reuse&fifo_size=50000':
Duration: N/A, start: 62947.782956, bitrate: N/A
Program 1
Metadata:
service_name : 1458
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p, 720x288 [SAR 32:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 32000 Hz, stereo, fltp, 73 kb/s
My Conversion Code
static int write_audio_frame(AVFormatContext *out_context, OutputStream *out_stream)
{
inputStream *inputSource = inputs[0];
AVCodecContext *c;
AVPacket pkt = { 0 }; // data and size must be 0;
AVFrame *frame = NULL;
avPackets *here;
int ret;
int l;
int got_packet = 0;
av_init_packet(&pkt);
c = out_stream->st->codec;
// Get next available packet
here = inputSource->packets_list[AUDIO_INDEX];
if( here) {
int dst_nb_samples;
frame = here->frame;
frame->pts = out_stream->next_pts;
out_stream->next_pts += frame->nb_samples;
/* convert samples from native format to destination codec format, using the resampler */
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(inputSource->audio_swr_ctx, inputSource->audio_dec_ctx->sample_rate) + frame->nb_samples,
c->sample_rate, inputSource->audio_dec_ctx->sample_rate, AV_ROUND_UP);
// If i have this assert in it triggers all the time, but as my input is 32000 and my output is 48000 i would expect them to be different
//av_assert0(dst_nb_samples == frame->nb_samples);
// This gives "rescale_rnd 1024 to 1560"
printf( "rescale_rnd %d to %d\r\n", frame->nb_samples, dst_nb_samples);
// Reallocate the buffer if the size is biggert
if( dst_nb_samples>out_stream->audio_frame_size) {
av_frame_free(&ost->audio_frame);
out_stream->audio_frame = alloc_audio_frame(c->sample_fmt, c->channel_layout, c->sample_rate, dst_nb_samples);
out_stream->audio_frame_size = dst_nb_samples;
}
/* when we pass a frame to the encoder, it may keep a reference to it
* internally;
* make sure we do not overwrite it here
*/
ret = av_frame_make_writable(out_stream->audio_frame);
if (ret < 0)
exit(1);
/* convert to destination format */
ret = swr_convert(inputSource->audio_swr_ctx,
out_stream->audio_frame->data, dst_nb_samples,
(const uint8_t **)frame->data, frame->nb_samples);
if (ret < 0) {
fprintf(stderr, "Error while converting\n");
exit(1);
}
out_stream->audio_frame->pts = av_rescale_q(out_stream->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
out_stream->samples_count += dst_nb_samples;
// HERE IS THE FAILING CALL
ret = avcodec_encode_audio2(c, &pkt, out_stream->audio_frame, &got_packet);
if (ret < 0) {
fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
exit(1);
}
if (got_packet) {
ret = write_frame(out_context, &c->time_base, out_stream->st, &pkt);
if (ret < 0) {
fprintf(stderr, "Error while writing audio frame: %s\n",
av_err2str(ret));
exit(1);
}
}
inputSource->packets_list[AUDIO_INDEX] = here->next;
av_frame_free(&here->frame);
free( here);
}
}
return 0; //(frame || got_packet) ? 0 : 1;
}
//
Allocating the output audio buffer
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
uint64_t channel_layout,
int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
int ret;
if (!frame) {
fprintf(stderr, "Error allocating an audio frame\n");
exit(1);
}
// This code give "Allocating 1 3 48000 1024"
printf( "Allocating %d %d %d %d\n", sample_fmt, channel_layout, sample_rate, nb_samples);
frame->format = sample_fmt;
frame->channel_layout = channel_layout;
frame->sample_rate = sample_rate;
frame->nb_samples = nb_samples;
if (nb_samples) {
ret = av_frame_get_buffer(frame, 16);
if (ret < 0) {
fprintf(stderr, "Error allocating an audio buffer\n");
exit(1);
}
}
return frame;
}
After running my code i get this crash
rescale_rnd 1024 to 1536
[libfaac @ 0x7fb5500021a0] more samples than frame size (avcodec_encode_audio2)
Can anyone shed some light on why after converting from 1024 to 1536 samples the system crashes ithe the above error.
joolz
More information about the ffmpeg-user
mailing list