<div dir="ltr"><div><div>I am trying to read an RTP audio stream, and encode it into a FLAC file. </div><div>However, when I am reading the stream, I get this error: </div><div><br></div><div>    [libvorbis @ 028b1520] more samples than frame size (avcodec_encode_audio2)</div><div>    </div><div>During debug mode, it seems the frame_size of my input and output codec context are mismatched:</div><div><br></div><div>    inCodecCtx->frame_size = 1152;</div><div>    outCodecCtx->frame_size = 64;</div><div>    </div><div>I tried to write 1152 to outCodecCtx->frame_size, but it gets overwritten with 64 at `avcodec_open2()`. Why can't I set the frame_size to match the input frame_size? Should I create an additional output frame to copy the contents over in a loop?</div><div><br></div><div>I'd really appreciate it if you could help me some help or suggestions.</div><div><br></div><div>Here is my source:</div><div>    </div><div>    // </div><div>    // Test with this command: ffmpeg -re -f lavfi -i aevalsrc="atan(t/2)*sin(400*2*PI*t)" -ar 16000 -c:a pcm_s16be -f rtp rtp://<a href="http://127.0.0.1:8554">127.0.0.1:8554</a></div><div>    // ffmpeg -f dshow -i audio="Microphone (High Definition Audio Device)" -ar 16000 -c:a pcm_s16be -ac 1 -f rtp rtp://<a href="http://127.0.0.1:8554">127.0.0.1:8554</a></div><div>    // Working code</div><div><br></div><div>    #include "stdafx.h"</div><div>    #include <math.h></div><div>    extern "C"</div><div>    {</div><div>    #include <libavutil/opt.h></div><div>    #include <libavcodec/avcodec.h></div><div>    #include <libavutil/channel_layout.h></div><div>    #include <libavutil/common.h></div><div>    #include <libavutil/imgutils.h></div><div>    #include <libavutil/mathematics.h></div><div>    #include <libavutil/samplefmt.h></div><div>    #include <libavformat/avformat.h></div><div>    }</div><div><br></div><div>    #define AUDIO_INBUF_SIZE 20480</div><div><br></div><div>    #define ERRBUFFLEN 200</div><div>    char errbuf[ERRBUFFLEN];</div><div>    #define av_err2str(ret) av_strerror(ret, errbuf, ERRBUFFLEN)</div><div>    const int samp_rate = 16000;</div><div>    int count = 0;</div><div>    // Callback function</div><div>    int _ffmpeg_interrupt_fcn(void* ptr)</div><div>    {</div><div>        int &r = *((int*)ptr);</div><div>        //double &r = *((double*)ptr);</div><div>        r += 1;</div><div>        printf("Interrupted! %d\n", r);</div><div>        if (r > 30) return 1;</div><div>        return 0;</div><div>    }</div><div><br></div><div>    static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)</div><div>    {</div><div>        /* rescale output packet timestamp values from codec to stream timebase */</div><div>        av_packet_rescale_ts(pkt, *time_base, st->time_base);</div><div>        pkt->stream_index = st->index;</div><div><br></div><div>        /* Write the compressed frame to the media file. */</div><div>    #ifdef DEBUG_PACKET</div><div>        log_packet(fmt_ctx, pkt);</div><div>    #endif</div><div>        return av_interleaved_write_frame(fmt_ctx, pkt);</div><div>    }</div><div><br></div><div>    /*</div><div>    * Audio decoding.</div><div>    */</div><div>    static void audio_decode_example(const char *outfilename, const char *filename)</div><div>    {</div><div>        int len;</div><div>        FILE *f, *outfile;</div><div>        uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];</div><div>        AVPacket inpkt, outpkt;</div><div>        </div><div>        AVCodec *inCodec = NULL;</div><div>        AVCodecContext *inCodecCtx = NULL;</div><div>        AVFrame *decoded_frame = NULL;</div><div>        AVFormatContext *inFormatCtx = NULL;</div><div><br></div><div>        AVCodec *outCodec = NULL;</div><div>        AVCodecContext *outCodecCtx = NULL;</div><div>        AVFormatContext *outFormatCtx = NULL;</div><div>        AVStream * outAudioStream = NULL;</div><div>        </div><div>        </div><div>        int ret;</div><div><br></div><div>        av_init_packet(&inpkt);</div><div><br></div><div>        AVDictionary *d = NULL;           // "create" an empty dictionary</div><div>        av_dict_set(&d, "protocol_whitelist", "file,udp,rtp", 0); // add an entry</div><div><br></div><div>        // Open video file</div><div>        ret = avformat_open_input(&inFormatCtx, filename, NULL, &d);</div><div>        if (ret <0)</div><div>        {</div><div>            printf_s("Failed: cannot open input.\n");</div><div>            av_strerror(ret, errbuf, ERRBUFFLEN);</div><div>            fprintf(stderr, "avformat_open_input() fail: %s\n", errbuf);</div><div>            exit(1);</div><div>        }</div><div><br></div><div>        printf_s("Retrieve stream information.\n");</div><div>        ret = avformat_find_stream_info(inFormatCtx, NULL);</div><div>        if (ret <0)</div><div>        {</div><div>            printf_s("Failed: cannot find stream.\n");</div><div>            av_strerror(ret, errbuf, ERRBUFFLEN);</div><div>            fprintf(stderr, "avformat_find_stream_info() fail: %s\n", errbuf);</div><div>            exit(1);</div><div>        }</div><div><br></div><div>        av_dump_format(inFormatCtx, 0, filename, 0);</div><div><br></div><div>        int stream_idx = -1;</div><div><br></div><div>        for (int i = 0; i < inFormatCtx->nb_streams; i++)</div><div>            if (inFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {</div><div>                stream_idx = i;</div><div>                break;</div><div>            }</div><div>        if (stream_idx == -1)</div><div>        {</div><div>            fprintf(stderr, "Video stream not found\n");</div><div>            exit(1);</div><div>        }</div><div><br></div><div>        inCodec = avcodec_find_decoder(inFormatCtx->streams[stream_idx]->codec->codec_id);</div><div>        if (!inCodec) {</div><div>            fprintf(stderr, "Codec not found\n");</div><div>            exit(1);</div><div>        }</div><div><br></div><div>        inCodecCtx = avcodec_alloc_context3(inCodec);</div><div>        if (!inCodecCtx) {</div><div>            fprintf(stderr, "Could not allocate audio codec context\n");</div><div>            exit(1);</div><div>        }</div><div>        </div><div>        inCodecCtx->channels = 1;</div><div><br></div><div>        ret = avcodec_open2(inCodecCtx, inCodec, NULL);</div><div>        if (ret < 0) {</div><div>            fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));</div><div>            exit(1);</div><div>        }</div><div><br></div><div>        // Set output</div><div>        ret = avformat_alloc_output_context2(&outFormatCtx, NULL, NULL, outfilename);</div><div>        if (!outFormatCtx || ret < 0)</div><div>        {</div><div>            fprintf(stderr, "Could not allocate output context");</div><div>        }</div><div>        outFormatCtx->flags |= AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS;</div><div>        outFormatCtx->audio_codec_id = AV_CODEC_ID_FLAC;</div><div><br></div><div>        // Find the codec.</div><div>        outCodec = avcodec_find_encoder(outFormatCtx->oformat->audio_codec);</div><div>        if (outCodec == NULL) {</div><div>            fprintf(stderr, "Codec not found\n");</div><div>            return;</div><div>        }</div><div><br></div><div>        // Add stream to pFormatCtx</div><div>        outAudioStream = avformat_new_stream(outFormatCtx, outCodec);</div><div>        if (!outAudioStream)</div><div>        {</div><div>            fprintf(stderr, "Cannot add new video stream\n");</div><div>            return;</div><div>        }</div><div><br></div><div>        outAudioStream->id = outFormatCtx->nb_streams - 1;</div><div>        outCodecCtx = outAudioStream->codec;</div><div>        outCodecCtx->sample_rate = samp_rate;</div><div>        outCodecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;</div><div>        outCodecCtx->channels = 1;</div><div>        outCodecCtx->frame_size = 1152;</div><div><br></div><div>        if (outFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)</div><div>            outCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;</div><div><br></div><div>        // Open the codec.</div><div>        if (avcodec_open2(outCodecCtx, outCodec, NULL) < 0)</div><div>        {</div><div>            fprintf(stderr, "Cannot open audio codec\n");</div><div>            return;</div><div>        }</div><div><br></div><div>        if (avio_open2(&outFormatCtx->pb, outfilename, AVIO_FLAG_WRITE, NULL, NULL) < 0)</div><div>        {</div><div>            av_strerror(ret, errbuf, ERRBUFFLEN);</div><div>            fprintf(stderr, "avio_open2 fail: %s\n", errbuf);</div><div>            return;</div><div>        }</div><div><br></div><div>        // Write file header.</div><div>        ret = avformat_write_header(outFormatCtx, NULL);</div><div>        if (ret < 0)</div><div>        {</div><div>            fprintf(stderr, "error writing header");</div><div>            return;</div><div>        }</div><div><br></div><div>        // Set callback</div><div>        inFormatCtx->interrupt_callback.callback = _ffmpeg_interrupt_fcn;</div><div>        inFormatCtx->interrupt_callback.opaque = &count;</div><div><br></div><div>        /**************************************************************</div><div>        *    Input Code Ctx Frame size: 1152</div><div>        *    Output Code Ctx Frame size: 64        </div><div>        **************************************************************/</div><div>        printf("Input Code Ctx Frame size: %d\n", inCodecCtx->frame_size);</div><div>        printf("Output Code Ctx Frame size: %d\n", inCodecCtx->frame_size);</div><div>        </div><div>        int got_packet = 0;</div><div><br></div><div>        while (av_read_frame(inFormatCtx, &inpkt) == 0) {</div><div>            int i, ch;</div><div>            int got_frame = 0;</div><div><br></div><div>            if (!decoded_frame) {</div><div>                if (!(decoded_frame = av_frame_alloc())) {</div><div>                    fprintf(stderr, "Could not allocate audio frame\n");</div><div>                    exit(1);</div><div>                }</div><div>            }</div><div>            len = avcodec_decode_audio4(inCodecCtx, decoded_frame, &got_frame, &inpkt);</div><div>            if (len < 0) {</div><div>                fprintf(stderr, "Error while decoding\n");</div><div>                exit(1);</div><div>            }</div><div>            if (got_frame) {</div><div>                printf("Packet size: %d\n", decoded_frame->pkt_size);</div><div>                printf("Frame samples: %d\n", decoded_frame->nb_samples);</div><div>                got_packet = 0;</div><div>                av_init_packet(&outpkt);</div><div>                int error = avcodec_encode_audio2(outCodecCtx, &outpkt, decoded_frame, &got_packet);</div><div><br></div><div>                if (!error && got_packet > 0)</div><div>                {</div><div>                    // Write packet with frame.</div><div>                    ret = write_frame(outFormatCtx, &outCodecCtx->time_base, outAudioStream, &outpkt);</div><div><br></div><div>                }</div><div>                av_packet_unref(&outpkt);</div><div><br></div><div>            }</div><div>            count = 0;</div><div>        }</div><div><br></div><div>        // Flush remaining encoded data</div><div>        while (1)</div><div>        {</div><div>            got_packet = 0;</div><div>            // Encode frame to packet.</div><div>            int error = avcodec_encode_audio2(outCodecCtx, &outpkt, NULL, &got_packet);</div><div><br></div><div>            if (!error && got_packet > 0)</div><div>            {</div><div>                av_init_packet(&outpkt);</div><div>                // Write packet with frame.</div><div>                ret = write_frame(outFormatCtx, &outCodecCtx->time_base, outAudioStream, &outpkt);</div><div><br></div><div>                av_packet_unref(&outpkt);</div><div>            }</div><div>            else</div><div>            {</div><div>                break;</div><div>            }</div><div>        }</div><div><br></div><div>        av_write_trailer(outFormatCtx);</div><div>        avcodec_close(outAudioStream->codec); // codecCtx</div><div>        avio_close(outFormatCtx->pb);</div><div>        avformat_free_context(outFormatCtx);</div><div><br></div><div>        avcodec_close(inCodecCtx);</div><div>        av_free(inCodecCtx);</div><div>        av_frame_free(&decoded_frame);</div><div>    }</div><div><br></div><div>    int main(int argc, char **argv)</div><div>    {</div><div>        const char *output_type;</div><div><br></div><div>        av_register_all();</div><div>        avformat_network_init(); // for network streaming</div><div><br></div><div>        audio_decode_example("test.flac", "test.sdp");</div><div><br></div><div>        return 0;</div><div>    }</div><div><span class="Apple-tab-span" style="white-space:pre">    </span></div><div>Cheers, </div><div>ytan</div></div><div><br></div></div>