<div dir="ltr"><div>Hi,</div><div>I don't know why I am not getting a reply to my previous e-mails, so I am trying again. Please let me know if they were there.<br></div><div><br></div><div>I have a pipeline of reader->decoder->encoder->writer where the codec parameters are the same on encoder and decoder. <br></div><div>The resultant file has audio that is distorted and considerably shorter than the file that was being read from. There are no messages returned from ffmpeg to indicate anything going wrong.<br></div><div><br></div><div>I've spent the last week looking into this and i've not got any further than at the start. Instead of posting my original code I thought i'd make a small representation of my code use  ffmpeg calls only.</div><div><br></div><div>What is it that I am missing? Are my e-mails getting through?<br></div><div>Thanks in advance.</div><div>Jon Noble<br></div><div><br></div><div>### The code ###<br></div><div><br></div><div>#include <assert.h><br>#include <libavformat/avformat.h><br>#include <libavcodec/avcodec.h><br>#include <stdio.h><br><br>const char* source = "/home/jon/Projects/Code/mediahandling/RegressionTests/ReferenceMedia/Audio/ogg/monotone.ogg";<br>const char* destination = "/tmp/vorbis.ogg";<br><br>AVFormatContext* d_ctx = NULL;<br>AVCodec* d_codec = NULL;<br>AVCodecParameters* d_codec_params =  NULL;<br>int d_stream_index = -1;<br>AVFrame* d_frame  = NULL;<br><br>AVFormatContext* e_ctx = NULL;<br>AVCodec* e_codec = NULL;<br>AVCodecContext* e_codec_ctx = NULL;<br>AVStream* e_stream = NULL;<br>AVFrame* e_frame = NULL;<br><br><br>int sample_count = 0;<br>int sample_rate = 0;<br><br>int open_source()<br>{    <br>    d_ctx = avformat_alloc_context();<br>    int code = avformat_open_input(&d_ctx, source, NULL, NULL);  <br>    assert(code >= 0);<br>    code = avformat_find_stream_info(d_ctx, NULL);<br>    assert(code >= 0);<br><br>    for (int i = 0; i < d_ctx->nb_streams; ++i) <br>    {<br>        AVCodecParameters* local = d_ctx->streams[i]->codecpar;<br>        assert(local != NULL);<br>        if (local->codec_type == AVMEDIA_TYPE_AUDIO) <br>        {<br>            sample_rate = local->sample_rate;<br>            d_stream_index = i;<br>            d_codec_params = local;<br>            d_codec = avcodec_find_decoder(local->codec_id);<br>            assert(d_codec != NULL);<br>            av_dump_format(d_ctx,i, source, 0);<br>            return 0;<br>        }<br>    }    <br>    return code;    <br>}<br><br>int setup_encoder()<br>{<br>    /* allocate the output media context */<br>    int ret = avformat_alloc_output_context2(&e_ctx, NULL, NULL, destination);<br>    assert(ret >= 0);<br><br>    AVOutputFormat *fmt = e_ctx->oformat;<br>    if (fmt->audio_codec != AV_CODEC_ID_NONE) <br>    {<br>        e_codec = avcodec_find_encoder(fmt->audio_codec);<br>        e_stream = avformat_new_stream(e_ctx, NULL);<br>        e_stream->id = e_ctx->nb_streams - 1;<br>        e_codec_ctx = avcodec_alloc_context3(e_codec);<br>        e_codec_ctx->sample_fmt = d_codec_params->format;<br>        e_codec_ctx->bit_rate = d_codec_params->bit_rate;<br>        e_codec_ctx->sample_rate = d_codec_params->sample_rate;<br>        e_codec_ctx->channels = d_codec_params->channels;<br>        e_codec_ctx->channel_layout = d_codec_params->channel_layout;<br>        e_stream->time_base = (AVRational) {1, e_codec_ctx->sample_rate};<br>        if (e_ctx->oformat->flags & AVFMT_GLOBALHEADER) <br>        {<br>            e_codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;<br>        }<br><br>        ret = avcodec_open2(e_codec_ctx, e_codec, NULL);<br>        assert(ret >= 0);<br>        ret = avcodec_parameters_from_context(e_stream->codecpar, e_codec_ctx);<br>        assert(ret >= 0);<br><br>        av_dump_format(e_ctx, 0, destination, 1);<br>        ret = avio_open(&e_ctx->pb, destination, AVIO_FLAG_WRITE);<br>        assert(ret >= 0);<br><br>        int64_t sample_count = 0;<br>        e_frame = av_frame_alloc();<br>        e_frame->format = d_codec_params->format;<br>        e_frame->channel_layout = d_codec_params->channel_layout;<br>        e_frame->sample_rate = d_codec_params->sample_rate;<br>        e_frame->nb_samples = e_codec_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE ? 10000 : e_codec_ctx->frame_size;<br>        ret = av_frame_get_buffer(e_frame, 0);<br>        assert(ret >= 0);<br>    }<br>    return ret;<br>}<br><br>int encode()<br>{<br>    assert(e_frame);<br>    assert(e_ctx);<br>    assert(e_codec_ctx);<br>    AVPacket pkt = { NULL, 0, 0 }; // data and size must be 0;<br>    av_init_packet(&pkt);<br><br>    int code = av_frame_make_writable(e_frame);<br>    assert(code >= 0);<br>    e_frame->pts = av_rescale_q(sample_count, (AVRational){1, sample_rate}, e_codec_ctx->time_base);<br>    e_frame->data[0] = d_frame->data[0];<br><br>    int got_packet;<br>    code = avcodec_encode_audio2(e_codec_ctx, &pkt, e_frame, &got_packet);<br>    assert(code >= 0);<br>    if (got_packet == 1) {<br>        av_packet_rescale_ts(&pkt, e_codec_ctx->time_base, e_stream->time_base);<br>        pkt.stream_index = e_stream->index;<br>        code = av_interleaved_write_frame(e_ctx, &pkt);<br>        assert(code >= 0);<br>    }<br>    sample_count += d_frame->nb_samples;<br>    return code;<br>}<br><br>int main()<br>{<br><br>    int code = open_source();  <br>    assert(code >= 0);<br>    assert(d_ctx != NULL);<br>    assert(d_codec != NULL);<br>    assert(d_codec_params != NULL);<br>    AVCodecContext* d_codec_context = avcodec_alloc_context3(d_codec);<br>    assert(d_codec_context != NULL);<br>    code = avcodec_parameters_to_context(d_codec_context, d_codec_params);<br>    assert(code >= 0);<br>    code = avcodec_open2(d_codec_context, d_codec, NULL);<br>    assert(code >= 0);<br>    d_frame = av_frame_alloc();<br>    AVPacket* d_packet = av_packet_alloc();<br><br>    code = setup_encoder();<br>    assert(code >= 0);<br><br>    code = avformat_write_header(e_ctx, NULL);<br>    assert(code >= 0);<br><br>    // read raw packets from stream<br>    while (av_read_frame(d_ctx, d_packet) >= 0)<br>    {<br>        if (d_packet->stream_index == d_stream_index) <br>        {<br>            // send packet to decoder<br>            code = avcodec_send_packet(d_codec_context, d_packet);<br>            assert(code >= 0);<br>            while (code >= 0) <br>            {<br>                code = avcodec_receive_frame(d_codec_context, d_frame);<br>                if (code == AVERROR(EAGAIN) || code == AVERROR_EOF) <br>                {<br>                    break;<br>                }<br>                assert(code >= 0);<br>                encode();<br>            }<br>        }<br>        av_packet_unref(d_packet);<br>    }<br><br>    av_frame_free(&e_frame);<br>    return code;<br>}</div><div><br></div><div>### STDOUT ###</div><div><br></div><div>[jon@jon-desktop ffmpegtest]$ ./a.out <br>Input #0, ogg, from '/home/jon/Projects/Code/mediahandling/RegressionTests/ReferenceMedia/Audio/ogg/monotone.ogg':<br>  Duration: 00:00:03.00, start: 0.000000, bitrate: 23 kb/s<br>    Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp, 96 kb/s<br>Output #0, ogg, to '/tmp/vorbis.ogg':<br>    Stream #0:0: Audio: vorbis, 44100 Hz, mono, fltp, 96 kb/s</div></div>