[Libav-user] Adding AMR frames to audio stream of video file
Paul B Mahol
onemda at gmail.com
Thu Jul 2 12:12:53 CEST 2015
On 7/2/15, adev dev <androiddevmar11 at gmail.com> wrote:
> I was not clear enough. Sound is not bad quality. It is damaged. Please
> have a look on video file which I uploaded to YouTube:
>
> https://www.youtube.com/watch?v=1UcGQwvtr9s
>
> Video length is 4 seconds. Adding this sound makes it longer to 17 seconds.
> Looks like some parameters are wrong. Yes, AMR is recorded in mono so
> sample format converting is not needed. Thanks for help.
And sound is damaged when listening straight from recording?
>
>
> On 2 July 2015 at 10:14, Paul B Mahol <onemda at gmail.com> wrote:
>
>>
>> Dana 2. 7. 2015. 07:58 osoba "adev dev" <androiddevmar11 at gmail.com>
>> napisala je:
>>
>> >
>> > Hi,
>> > thanks for answer.
>> >
>> > I cannot increase sound bitrate. I am using Android MediaRecorder and
>> AMR codec for recording audio. AMR is needed because I am doing Chrome
>> version where AAC codec is not working. This AMR codec at least in
>> Android
>> can only record with maximum bitrate 23600. It is not much but sound
>> should
>> be good. Now my result is that sound is totally crappy. There are strange
>> pulses and if I record speech it is impossible to recognise words.
>> >
>> > I wonder what else could be the problem. When I am adding AAC files to
>> output video it is working correctly. Decoding AMR files and encoding
>> them
>> again to AAC is not working. For the first glance it looks that AMR
>> decoding is not working correctly. Or the frame is in format (not planar)
>> and this makes problem. What do you think?
>> >
>> > This is how I read frames and decode them:
>> >
>> > static void encodeSoundNext(JNIEnv * env, jobject this) {
>> >
>> > if (input_context == NULL)
>> > return;
>> >
>> > int samples_size;
>> >
>> > frameRead = 0;
>> > char index = 0;
>> >
>> > AVFrame *decoded_frame = NULL;
>> >
>> > int input_audio_stream_index = get_stream_index(input_context,
>> AVMEDIA_TYPE_AUDIO);
>> >
>> > while (frameRead >= 0) {
>> >
>> > AVPacket in_packet;
>> >
>> > index++;
>> >
>> > frameRead = av_read_frame(input_context, &in_packet);
>> > if (frameRead < 0) {
>> > trackCompressionFinished = 1;
>> > avformat_close_input(&input_context);
>> >
>> > } else {
>> >
>> > if (decoded_frame == NULL) {
>> > if (!(decoded_frame = avcodec_alloc_frame())) {
>> > LOGE("out of memory");
>> > exit(1);
>> > }
>> > } else {
>> > avcodec_get_frame_defaults(decoded_frame);
>> > }
>> > int got_frame_ptr;
>> > samplesBytes = avcodec_decode_audio4(in_audio_st->codec,
>> > decoded_frame, &got_frame_ptr, &in_packet);
>> > if (samplesBytes < 0) {
>> > LOGE("Error occurred during decoding.");
>> > exit(1);
>> > break;
>> > }
>> >
>> > write_audio_frame(oc, audio_st, decoded_frame);
>> > av_free_packet(&in_packet);
>> >
>> > }
>> > }
>> >
>> > if (decoded_frame != NULL) {
>> > av_free(decoded_frame);
>> > decoded_frame = NULL;
>> > }
>> > }
>> >
>> >
>> > This is how I am encoding sound to AAC:
>> >
>> >
>> > static void write_audio_frame(AVFormatContext *oc, AVStream *st,
>> > const AVFrame *frame_to_encode) {
>> > AVCodecContext *c;
>> > AVPacket pkt;
>> > int got_packet_ptr = 0;
>> >
>> > av_init_packet(&pkt);
>> > c = st->codec;
>> > pkt.size = 0;
>> > pkt.data = NULL;
>> > int ret = avcodec_encode_audio2(c, &pkt, frame_to_encode,
>> &got_packet_ptr);
>> > if (ret < 0) {
>> > exit(1);
>> > }
>> > if (got_packet_ptr == 1) {
>> > if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE) {
>> > pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base,
>> > st->time_base);
>> > }
>> > pkt.flags |= AV_PKT_FLAG_KEY;
>> > pkt.stream_index = st->index;
>> > // write the compressed frame in the media file
>> > if (av_interleaved_write_frame(oc, &pkt) != 0) {
>> > LOGE("Error while writing audio frame.");
>> > exit(1);
>> > }
>> > }
>> > av_free_packet(&pkt);
>> > }
>> >
>> >
>> > Audio stream is added to video file in this way:
>> >
>> >
>> > static AVStream *add_audio_stream(AVFormatContext *oc, enum AVCodecID
>> codec_id) {
>> >
>> > AVCodecContext *c;
>> > AVStream *st;
>> >
>> > st = avformat_new_stream(oc, NULL);
>> >
>> > c = st->codec;
>> > if (!st) {
>> > LOGE("Could not alloc stream.");
>> > return NULL;
>> > }
>> >
>> > // AAC is expirimental in FFMPEG2.1
>> > c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
>> >
>> > c->codec_id = codec_id;
>> > c->codec_type = AVMEDIA_TYPE_AUDIO;
>> > c->bit_rate = 23600; // bitrate of the compressed sound (must be higher
>> for stereo)
>> >
>> > c->sample_rate = 16000;
>> > c->channels = 1;
>> > c->sample_fmt = AV_SAMPLE_FMT_FLT;
>> >
>> > if (oc->oformat->flags & AVFMT_GLOBALHEADER){
>> > c->flags |= CODEC_FLAG_GLOBAL_HEADER;
>> > }
>> >
>> > return st;
>> > }
>> >
>> > What I noticed so far is that when I am decoding AAC files and encoding
>> them again to audio stream in video files AAC frames has format
>> AV_SAMPLE_FMT_FLTP. AMR frames are in AV_SAMPLE_FMT_FLT format. Do you
>> think I have to convert some how from AV_SAMPLE_FMT_FLT to
>> AV_SAMPLE_FMT_FLTP?? Thanks for all hints.
>> >
>>
>> For mono, single channel, conversion is not needed. If recording is of
>> bad
>> quality encoding you can only use some other amr encoder.
>>
>> >
>> >
>> > On 1 July 2015 at 20:57, Talgorn Franc,ois-Xavier <
>> fxtalgorn-at-yahoo.fr at ffmpeg.org> wrote:
>> >>
>> >> Hi,
>> >>
>> >> I don't know about AMR codec but bitrate definitely impacts on final
>> quality.
>> >> Try to increase bitrate value: I had same poor quality problems with
>> MPEG4 encoding until I set the bitrate to width * height * 4.
>> >> Keep in mind that poor quality might comes from a wide bunch of
>> parameters used to initialize the codec.
>> >> As for example, this is how I initialize an MPEG4 codec (A]), for
>> clarity, in_ctx is initialized via the code in (B])
>> >>
>> >> Concerning the delay issue: I also faced such a problem. I solved it
>> using av_packet_rescale_ts() which relies on time_base, instead of
>> setting
>> timestamps myself manually.
>> >>
>> >> I hope this comments will help put you on the road to success :-)
>> >>
>> >> Good luck.
>> >>
>> >> A]
>> >> //codec found, now we param it
>> >> o_codec_ctx->codec_id=AV_CODEC_ID_MPEG4;
>> >> o_codec_ctx->bit_rate=in_ctx->picture_width *
>> in_ctx->picture_height * 4;
>> >>
>> o_codec_ctx->width=in_ctx->format_ctx->streams[in_ctx->video_stream_idx]->codec->width;
>> >>
>> o_codec_ctx->height=in_ctx->format_ctx->streams[in_ctx->video_stream_idx]->codec->height;
>> >> o_codec_ctx->time_base =
>> in_ctx->format_ctx->streams[in_ctx->video_stream_idx]->codec->time_base;
>> >> o_codec_ctx->ticks_per_frame =
>> in_ctx->format_ctx->streams[in_ctx->video_stream_idx]->codec->ticks_per_frame;
>> >> o_codec_ctx->sample_aspect_ratio =
>> in_ctx->format_ctx->streams[in_ctx->video_stream_idx]->codec->sample_aspect_ratio;
>> >>
>> o_codec_ctx->gop_size=in_ctx->format_ctx->streams[in_ctx->video_stream_idx]->codec->gop_size;
>> >> o_codec_ctx->pix_fmt=AV_PIX_FMT_YUV420P;
>> >>
>> >>
>> >>
>> >> B]
>> >> // register all formats and codecs
>> >> av_register_all();
>> >> avcodec_register_all();
>> >>
>> >> // open input file, and allocate format context
>> >> if (avformat_open_input(&in_fmt_ctx, filename, NULL, NULL) < 0)
>> >> {
>> >> fprintf(stderr, "Could not open source file %s\n", filename);
>> >> exit(1);
>> >> }
>> >>
>> >> // retrieve stream information
>> >> if (avformat_find_stream_info(in_fmt_ctx, NULL) < 0)
>> >> {
>> >> fprintf(stderr, "Could not find stream information\n");
>> >> exit(1);
>> >> }
>> >>
>> >> if (open_codec_context(&video_stream_idx, in_fmt_ctx,
>> AVMEDIA_TYPE_VIDEO, filename) >= 0)
>> >> {
>> >> video_stream = in_fmt_ctx->streams[video_stream_idx];
>> >> video_dec_ctx = video_stream->codec;
>> >> }
>> >>
>> >> if (open_codec_context(&audio_stream_idx, in_fmt_ctx,
>> AVMEDIA_TYPE_AUDIO, filename) >= 0) {
>> >> audio_stream = in_fmt_ctx->streams[audio_stream_idx];
>> >> audio_dec_ctx = audio_stream->codec;
>> >> }
>> >>
>> >> if (!video_stream) {
>> >> fprintf(stderr, "Could not find video stream in the input,
>> aborting\n");
>> >> avformat_close_input(&in_fmt_ctx);
>> >> exit(0);
>> >> }
>> >>
>> >> in_video_ctx->format_ctx=in_fmt_ctx;
>> >> in_video_ctx->filename=filename;
>> >> in_video_ctx->codec_name=(char *)
>> in_fmt_ctx->streams[video_stream_idx]->codec->codec->long_name;
>> >> in_video_ctx->video_stream_idx=video_stream_idx;
>> >> in_video_ctx->audio_stream_idx=audio_stream_idx;
>> >>
>> in_video_ctx->picture_width=in_fmt_ctx->streams[video_stream_idx]->codec->width;
>> >>
>> in_video_ctx->picture_height=in_fmt_ctx->streams[video_stream_idx]->codec->height;
>> >> in_video_ctx->nb_streams=in_fmt_ctx->nb_streams;
>> >>
>> >>
>> >>
>> >>
>> >> Le 1 juil. 2015 `a 10:40, adev dev <androiddevmar11 at gmail.com> a ecrit
>> >> :
>> >>
>> >>> I am compressing movies from bitmaps and audio files. With AAC files
>> it is working correctly. But when I have AMR_WB files sound is corrupted.
>> I
>> can recognise correct words in video file but it is delayed and with very
>> bad quality.
>> >>>
>> >>> My AMR files are recorded with parameters:
>> >>> - sampling rate: 16000,
>> >>> - bitrate: 23000.
>> >>>
>> >>> I am setting this parameters in audio stream which is added to video.
>> Sample format is set to AV_SAMPLE_FMT_FLT. When using other formats app
>> crashes with "Unsupported sample format".
>> >>>
>> >>> What needs to be done to correctly add AMR stream to video file? Do I
>> have to reencode it to AAC and add as AAC audio stream?? Thank you for
>> all
>> hints.
>> >>> _______________________________________________
>> >>> Libav-user mailing list
>> >>> Libav-user at ffmpeg.org
>> >>> http://ffmpeg.org/mailman/listinfo/libav-user
>> >>
>> >>
>> >>
>> >> _______________________________________________
>> >> Libav-user mailing list
>> >> Libav-user at ffmpeg.org
>> >> http://ffmpeg.org/mailman/listinfo/libav-user
>> >>
>> >
>> >
>> > _______________________________________________
>> > Libav-user mailing list
>> > Libav-user at ffmpeg.org
>> > http://ffmpeg.org/mailman/listinfo/libav-user
>> >
>>
>> _______________________________________________
>> Libav-user mailing list
>> Libav-user at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/libav-user
>>
>>
>
More information about the Libav-user
mailing list