[Libav-user] Adding AMR frames to audio stream of video file

Paul B Mahol onemda at gmail.com
Thu Jul 2 10:14:54 CEST 2015


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 Franç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 à 10:40, adev dev <androiddevmar11 at gmail.com> a écrit :
>>
>>> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20150702/887db676/attachment.html>


More information about the Libav-user mailing list