Recherche avancée

Médias (91)

Autres articles (97)

  • Personnaliser les catégories

    21 juin 2013, par

    Formulaire de création d’une catégorie
    Pour ceux qui connaissent bien SPIP, une catégorie peut être assimilée à une rubrique.
    Dans le cas d’un document de type catégorie, les champs proposés par défaut sont : Texte
    On peut modifier ce formulaire dans la partie :
    Administration > Configuration des masques de formulaire.
    Dans le cas d’un document de type média, les champs non affichés par défaut sont : Descriptif rapide
    Par ailleurs, c’est dans cette partie configuration qu’on peut indiquer le (...)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

  • Des sites réalisés avec MediaSPIP

    2 mai 2011, par

    Cette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
    Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page.

Sur d’autres sites (16631)

  • FFmpeg:A General error in an external library occurred when using FFmpeg6.1's avcodec_send_frame

    4 janvier 2024, par MMingY

    I have the same code that can successfully push streams (rtmp) in the environment, but in the Android environment, I fail with an error message. The error message method is avcodec_send_frame in ffmpeg6.1. By the way, I compiled the FFmpeg library on Android myself, and I downloaded the official package for Win11. I will provide the code for Android and Win11 below.

    


    android :

    


    static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,

                   AVFormatContext *outFormatCtx) {
    int ret;

    /* send the frame to the encoder */
    if (frame)
        LOGE2("Send frame %ld\n", frame->pts);

    ret = avcodec_send_frame(enc_ctx, frame);
    if (ret < 0) {
        char errbuf[AV_ERROR_MAX_STRING_SIZE];
        av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
        LOGE2("Error sending a frame for encoding ,%s\n", errbuf);
//        exit(1);
        return;
    }

    while (ret >= 0) {
        ret = avcodec_receive_packet(enc_ctx, pkt);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            return;
        else if (ret < 0) {
            fprintf(stderr, "Error during encoding\n");
            exit(1);
        }

        printf("Write packet (size=%5d)\n", pkt->pts);
        /*    ret = av_interleaved_write_frame(outFormatCtx, pkt);
            if (ret < 0) {
                LOGE2("write frame err=%s", av_err2str(ret));
                break;
            }*/
//        printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
        av_write_frame(outFormatCtx, pkt); // Write the packet to the RTMP stream
        av_packet_unref(pkt);
    }
}

PUSHER_FUNC(int, testPush, jstring yuvPath, jstring outputPath) {
    const char *yvu_path = env->GetStringUTFChars(yuvPath, JNI_FALSE);
    const char *output_path = env->GetStringUTFChars(outputPath, JNI_FALSE);
    const char *rtmp_url = output_path;
    const AVCodec *codec;
    AVCodecContext *codecContext = NULL;
    AVFormatContext *outFormatCtx;
    int ret = 0;
    AVStream *outStream;
    AVFrame *frame;
    AVPacket *pkt;
    int i, x, y;
    avformat_network_init();

    codec = avcodec_find_encoder(AV_CODEC_ID_H264);
//    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
//    codec = avcodec_find_encoder(AV_CODEC_ID_H265);
    if (!codec) {
        LOGE2("JNI Error finding H.264 encoder");
        return -1;
    }
    codecContext = avcodec_alloc_context3(codec);
    if (!codecContext) {
        fprintf(stderr, "Could not allocate video codec context\n");
        return -1;
    }

    /* Allocate the output context */
    outFormatCtx = avformat_alloc_context();
    if (!outFormatCtx) {
        fprintf(stderr, "Could not allocate output context\n");
        return -1;
    }

    /* Open the RTMP output */
    const AVOutputFormat *ofmt = av_guess_format("flv", NULL, NULL);
//    const AVOutputFormat *ofmt = av_guess_format("mpegts", NULL, NULL);
//    const AVOutputFormat *ofmt = av_guess_format("mp4", NULL, NULL);
    if (!ofmt) {
        fprintf(stderr, "Could not find output format\n");
        return -1;
    }
    outFormatCtx->oformat = ofmt;
    outFormatCtx->url = av_strdup(rtmp_url);
    /* Add a video stream */
    outStream = avformat_new_stream(outFormatCtx, codec);
    if (!outStream) {
        fprintf(stderr, "Could not allocate stream\n");
        return -1;
    }
    outStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    outStream->codecpar->codec_id = codec->id;
    outStream->codecpar->width = 352;
    outStream->codecpar->height = 288;

    /* Set the output URL */
    av_dict_set(&outFormatCtx->metadata, "url", rtmp_url, 0);

    pkt = av_packet_alloc();
    if (!pkt)
        return -1;

    /* ... (rest of the setup code) ... */
/* put sample parameters */
    codecContext->bit_rate = 400000;
    /* resolution must be a multiple of two */
    codecContext->width = 352;
    codecContext->height = 288;
    /* frames per second */
    codecContext->time_base = (AVRational) {1, 25};
    codecContext->framerate = (AVRational) {25, 1};

    /* emit one intra frame every ten frames
     * check frame pict_type before passing frame
     * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
     * then gop_size is ignored and the output of encoder
     * will always be I frame irrespective to gop_size
     */
    codecContext->gop_size = 10;
    codecContext->max_b_frames = 1;
    codecContext->pix_fmt = AV_PIX_FMT_YUV420P;

    if (codec->id == AV_CODEC_ID_H264)
        av_opt_set(codecContext->priv_data, "preset", "slow", 0);

    /* open it */
    ret = avcodec_open2(codecContext, codec, NULL);
    if (ret < 0) {
        LOGE2("JNI Error opening codec eer%s", av_err2str(ret));
        return ret;
    }

    avcodec_parameters_to_context(codecContext, outStream->codecpar);

    if (avio_open(&outFormatCtx->pb, rtmp_url, AVIO_FLAG_WRITE)) {
        fprintf(stderr, "Could not open output\n");
        return ret;
    }
    /* Write the header */
    if (avformat_write_header(outFormatCtx, NULL) != 0) {
        fprintf(stderr, "Error occurred when opening output\n");
        return ret;
    }

    frame = av_frame_alloc();
    if (!frame) {
        fprintf(stderr, "Could not allocate video frame\n");
        return -1;
    }
    frame->format = codecContext->pix_fmt;
    frame->format = AV_PIX_FMT_YUV420P;
    frame->format = 0;
    frame->width = codecContext->width;
    frame->height = codecContext->height;

    ret = av_frame_get_buffer(frame, 0);
    if (ret < 0) {
        fprintf(stderr, "Could not allocate the video frame data ,%s\n", av_err2str(ret));
        return ret;
    }

    /*  FILE *yuv_file = fopen(yvu_path, "rb");
      if (yuv_file == NULL) {
          LOGE2("cannot open h264 file");
          return -1;
      }*/

    /* encode 1 second of video */
    for (i = 0; i < 25000; i++) {
//    for (i = 0; i < 25; i++) {
//        fflush(stdout);

        /* make sure the frame data is writable */
        ret = av_frame_make_writable(frame);
        if (ret < 0)
            exit(1);

        /* prepare a dummy image */
        /* Y */
        for (y = 0; y < codecContext->height; y++) {
            for (x = 0; x < codecContext->width; x++) {
                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
            }
        }

        /* Cb and Cr */
        for (y = 0; y < codecContext->height / 2; y++) {
            for (x = 0; x < codecContext->width / 2; x++) {
                frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
                frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
            }
        }

        frame->pts = i;

        /* encode the image */
        encode(codecContext, frame, pkt, outFormatCtx);
    }

//    fclose(yuv_file);

    /* flush the encoder */
    encode(codecContext, NULL, pkt, outFormatCtx);

    /* Write the trailer */
    av_write_trailer(outFormatCtx);

    /* Close the output */
    avformat_free_context(outFormatCtx);

    avcodec_free_context(&codecContext);
    av_frame_free(&frame);
    av_packet_free(&pkt);
}


    


    win11:

    


    #include &#xA;#include &#xA;#include &#xA;&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>imgutils.h>&#xA;#include <libavutil></libavutil>time.h>&#xA;&#xA;static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,&#xA;                   AVFormatContext *outFormatCtx) {&#xA;    int ret;&#xA;&#xA;    /* send the frame to the encoder */&#xA;    if (frame)&#xA;        printf("Send frame %3"PRId64"\n", frame->pts);&#xA;&#xA;    ret = avcodec_send_frame(enc_ctx, frame);&#xA;    if (ret &lt; 0) {&#xA;        char errbuf[AV_ERROR_MAX_STRING_SIZE];&#xA;        av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);&#xA;        fprintf(stderr, "Error sending a frame for encoding ,%s\n", errbuf);&#xA;        exit(1);&#xA;    }&#xA;&#xA;    while (ret >= 0) {&#xA;        ret = avcodec_receive_packet(enc_ctx, pkt);&#xA;        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)&#xA;            return;&#xA;        else if (ret &lt; 0) {&#xA;            fprintf(stderr, "Error during encoding\n");&#xA;            exit(1);&#xA;        }&#xA;&#xA;        printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);&#xA;        av_write_frame(outFormatCtx, pkt); // Write the packet to the RTMP stream&#xA;        av_packet_unref(pkt);&#xA;    }&#xA;}&#xA;&#xA;int main(int argc, char **argv) {&#xA;    av_log_set_level(AV_LOG_DEBUG);&#xA;    const char *rtmp_url, *codec_name;&#xA;    const AVCodec *codec;&#xA;    AVCodecContext *codecContext = NULL;&#xA;    int i, ret, x, y;&#xA;    AVFormatContext *outFormatCtx;&#xA;    AVStream *st;&#xA;    AVFrame *frame;&#xA;    AVPacket *pkt;&#xA;    uint8_t endcode[] = {0, 0, 1, 0xb7};&#xA;&#xA;    if (argc &lt;= 3) {&#xA;        fprintf(stderr, "Usage: %s <rtmp url="url"> <codec>\n", argv[0]);&#xA;        exit(0);&#xA;    }&#xA;    rtmp_url = argv[1];&#xA;    codec_name = argv[2];&#xA;    avformat_network_init();&#xA;    /* find the mpeg1video encoder */&#xA;//    codec = avcodec_find_encoder_by_name(codec_name);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_VP9);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_H264);&#xA;    codec = avcodec_find_encoder(AV_CODEC_ID_H264);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_AV1);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_H265);&#xA;    if (!codec) {&#xA;        fprintf(stderr, "Codec &#x27;%s&#x27; not found\n", codec_name);&#xA;        exit(1);&#xA;    }&#xA;    codecContext = avcodec_alloc_context3(codec);&#xA;    if (!codecContext) {&#xA;        fprintf(stderr, "Could not allocate video codec context\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* Allocate the output context */&#xA;    outFormatCtx = avformat_alloc_context();&#xA;    if (!outFormatCtx) {&#xA;        fprintf(stderr, "Could not allocate output context\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* Open the RTMP output */&#xA;    const AVOutputFormat *ofmt = av_guess_format("flv", NULL, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("MKV", NULL, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("rtmp", NULL, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("mpegts", NULL, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("mp4", NULL, NULL);&#xA;    if (!ofmt) {&#xA;        fprintf(stderr, "Could not find output format\n");&#xA;        exit(1);&#xA;    }&#xA;    outFormatCtx->oformat = ofmt;&#xA;    outFormatCtx->url = av_strdup(rtmp_url);&#xA;    /* Add a video stream */&#xA;    st = avformat_new_stream(outFormatCtx, codec);&#xA;    if (!st) {&#xA;        fprintf(stderr, "Could not allocate stream\n");&#xA;        exit(1);&#xA;    }&#xA;    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;    st->codecpar->codec_id = codec->id;&#xA;    st->codecpar->width = 352;&#xA;    st->codecpar->height = 288;&#xA;//    st->codecpar = c;&#xA;//    st->codecpar->format = AV_PIX_FMT_YUV420P;&#xA;    // Set video stream parameters&#xA;//    st->codecpar->framerate = (AVRational){25, 1};&#xA;&#xA;    /* Set the output URL */&#xA;    av_dict_set(&amp;outFormatCtx->metadata, "url", rtmp_url, 0);&#xA;&#xA;&#xA;    pkt = av_packet_alloc();&#xA;    if (!pkt)&#xA;        exit(1);&#xA;&#xA;    /* ... (rest of the setup code) ... */&#xA;/* put sample parameters */&#xA;    codecContext->bit_rate = 400000;&#xA;    /* resolution must be a multiple of two */&#xA;    codecContext->width = 352;&#xA;    codecContext->height = 288;&#xA;    /* frames per second */&#xA;    codecContext->time_base = (AVRational) {1, 25};&#xA;    codecContext->framerate = (AVRational) {25, 1};&#xA;&#xA;    /* emit one intra frame every ten frames&#xA;     * check frame pict_type before passing frame&#xA;     * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I&#xA;     * then gop_size is ignored and the output of encoder&#xA;     * will always be I frame irrespective to gop_size&#xA;     */&#xA;    codecContext->gop_size = 10;&#xA;    codecContext->max_b_frames = 1;&#xA;    codecContext->pix_fmt = AV_PIX_FMT_YUV420P;&#xA;&#xA;    if (codec->id == AV_CODEC_ID_H264)&#xA;        av_opt_set(codecContext->priv_data, "preset", "slow", 0);&#xA;&#xA;    /* open it */&#xA;    ret = avcodec_open2(codecContext, codec, NULL);&#xA;    if (ret &lt; 0) {&#xA;        fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));&#xA;        exit(1);&#xA;    }&#xA;&#xA;    avcodec_parameters_to_context(codecContext, st->codecpar);&#xA;&#xA;    if (avio_open(&amp;outFormatCtx->pb, rtmp_url, AVIO_FLAG_WRITE)) {&#xA;        fprintf(stderr, "Could not open output\n");&#xA;        exit(1);&#xA;    }&#xA;    /* Write the header */&#xA;    if (avformat_write_header(outFormatCtx, NULL) != 0) {&#xA;        fprintf(stderr, "Error occurred when opening output\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    frame = av_frame_alloc();&#xA;    if (!frame) {&#xA;        fprintf(stderr, "Could not allocate video frame\n");&#xA;        exit(1);&#xA;    }&#xA;//    frame->format = c->pix_fmt;&#xA;//    frame->format = AV_PIX_FMT_YUV420P;&#xA;    frame->format = 0;&#xA;    frame->width = codecContext->width;&#xA;    frame->height = codecContext->height;&#xA;&#xA;    ret = av_frame_get_buffer(frame, 0);&#xA;    if (ret &lt; 0) {&#xA;        fprintf(stderr, "Could not allocate the video frame data ,%s\n", av_err2str(ret));&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* encode 1 second of video */&#xA;    for (i = 0; i &lt; 2500; i&#x2B;&#x2B;) {&#xA;        /* ... (rest of the encoding loop) ... */&#xA;        fflush(stdout);&#xA;&#xA;        /* make sure the frame data is writable */&#xA;        ret = av_frame_make_writable(frame);&#xA;        if (ret &lt; 0)&#xA;            exit(1);&#xA;&#xA;        /* prepare a dummy image */&#xA;        /* Y */&#xA;        for (y = 0; y &lt; codecContext->height; y&#x2B;&#x2B;) {&#xA;            for (x = 0; x &lt; codecContext->width; x&#x2B;&#x2B;) {&#xA;                frame->data[0][y * frame->linesize[0] &#x2B; x] = x &#x2B; y &#x2B; i * 3;&#xA;            }&#xA;        }&#xA;&#xA;        /* Cb and Cr */&#xA;        for (y = 0; y &lt; codecContext->height / 2; y&#x2B;&#x2B;) {&#xA;            for (x = 0; x &lt; codecContext->width / 2; x&#x2B;&#x2B;) {&#xA;                frame->data[1][y * frame->linesize[1] &#x2B; x] = 128 &#x2B; y &#x2B; i * 2;&#xA;                frame->data[2][y * frame->linesize[2] &#x2B; x] = 64 &#x2B; x &#x2B; i * 5;&#xA;            }&#xA;        }&#xA;&#xA;        frame->pts = i;&#xA;&#xA;        /* encode the image */&#xA;        encode(codecContext, frame, pkt, outFormatCtx);&#xA;    }&#xA;&#xA;    /* flush the encoder */&#xA;    encode(codecContext, NULL, pkt, outFormatCtx);&#xA;&#xA;    /* Write the trailer */&#xA;    av_write_trailer(outFormatCtx);&#xA;&#xA;    /* Close the output */&#xA;    avformat_free_context(outFormatCtx);&#xA;&#xA;    avcodec_free_context(&amp;codecContext);&#xA;    av_frame_free(&amp;frame);&#xA;    av_packet_free(&amp;pkt);&#xA;&#xA;    return 0;&#xA;}&#xA;</codec></rtmp>

    &#xA;

    I suspect it's an issue with the ffmpeg library I compiled, so I searched for a step to compile ffmpeg on GitHub, but the package it compiled still has the same problem. I don't know what to do now.

    &#xA;

  • Problems with outputting stream format as RTMP via FFmpeg C-API

    9 janvier 2024, par dongrixinyu

    I am using FFmpeg's C API to push video streams rtmp://.... into an SRS server.
    &#xA;The input stream is an MP4 file named juren-30s.mp4.
    &#xA;The output stream is also an MP4 file named juren-30s-5.mp4.

    &#xA;

    My piece of code (see further down) works fine when used in the following steps :
    &#xA;mp4 -> demux -> decode -> rgb images -> encode -> mux -> mp4.

    &#xA;

    Problem :

    &#xA;

    When I changed the output stream to an online RTMP url named rtmp://ip:port/live/stream_nb_23 (just an example, you can change it according to your server and rules.)

    &#xA;

    result : This code would be corrupted mp4 -> rtmp(flv).

    &#xA;

    What I've tried :

    &#xA;

    Changing the output format
    &#xA;I changed the output format param to become flv when I initialized the avformat_alloc_output_context2. But this didn't help.

    &#xA;

    Debugging the output
    &#xA;When I executed ffprobe rtmp://ip:port/live/xxxxxxx, I got the following errors and did not know why :

    &#xA;

    [h264 @ 0x55a925e3ba80] luma_log2_weight_denom 12 is out of range&#xA;[h264 @ 0x55a925e3ba80] Missing reference picture, default is 2&#xA;[h264 @ 0x55a925e3ba80] concealing 8003 DC, 8003 AC, 8003 MV errors in P frame&#xA;[h264 @ 0x55a925e3ba80] QP 4294966938 out of range&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;[h264 @ 0x55a925e3ba80] no frame!&#xA;[h264 @ 0x55a925e3ba80] luma_log2_weight_denom 21 is out of range&#xA;[h264 @ 0x55a925e3ba80] luma_log2_weight_denom 10 is out of range&#xA;[h264 @ 0x55a925e3ba80] chroma_log2_weight_denom 12 is out of range&#xA;[h264 @ 0x55a925e3ba80] Missing reference picture, default is 0&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;[h264 @ 0x55a925e3ba80] QP 4294967066 out of range&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;[h264 @ 0x55a925e3ba80] no frame!&#xA;[h264 @ 0x55a925e3ba80] QP 341 out of range&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;

    &#xA;

    I am confused about the difference between MP4 and RTMP of how to use FFmpeg C-API to produce a correct output stream format.

    &#xA;

    Besides, I also wanna learn how to convert video and audio streams into other formats using FFmpeg C-api, such as flv, ts, rtsp, etc.

    &#xA;

    Code to reproduce the problem :

    &#xA;

    &#xA;

    So how to make this code output to RTMP without getting issue of an unplayable video ?

    &#xA;

    #include &#xA;#include "libavformat/avformat.h"&#xA;int main()&#xA;{&#xA;    int ret = 0; int err;&#xA;&#xA;    //Open input file&#xA;    char filename[] = "juren-30s.mp4";&#xA;    AVFormatContext *fmt_ctx = avformat_alloc_context();&#xA;    if (!fmt_ctx) {&#xA;        printf("error code %d \n",AVERROR(ENOMEM));&#xA;        return ENOMEM;&#xA;    }&#xA;    if((err = avformat_open_input(&amp;fmt_ctx, filename,NULL,NULL)) &lt; 0){&#xA;        printf("can not open file %d \n",err);&#xA;        return err;&#xA;    }&#xA;&#xA;    //Open the decoder&#xA;    AVCodecContext *avctx = avcodec_alloc_context3(NULL);&#xA;    ret = avcodec_parameters_to_context(avctx, fmt_ctx->streams[0]->codecpar);&#xA;    if (ret &lt; 0){&#xA;        printf("error code %d \n",ret);&#xA;        return ret;&#xA;    }&#xA;    AVCodec *codec = avcodec_find_decoder(avctx->codec_id);&#xA;    if ((ret = avcodec_open2(avctx, codec, NULL)) &lt; 0) {&#xA;        printf("open codec faile %d \n",ret);&#xA;        return ret;&#xA;    }&#xA;&#xA;    //Open the output file container&#xA;    char filename_out[] = "juren-30s-5.mp4";&#xA;    AVFormatContext *fmt_ctx_out = NULL;&#xA;    err = avformat_alloc_output_context2(&amp;fmt_ctx_out, NULL, NULL, filename_out);&#xA;    if (!fmt_ctx_out) {&#xA;        printf("error code %d \n",AVERROR(ENOMEM));&#xA;        return ENOMEM;&#xA;    }&#xA;    //Add all the way to the container context&#xA;    AVStream *st = avformat_new_stream(fmt_ctx_out, NULL);&#xA;    st->time_base = fmt_ctx->streams[0]->time_base;&#xA;&#xA;    AVCodecContext *enc_ctx = NULL;&#xA;    &#xA;    AVPacket *pt = av_packet_alloc();&#xA;    AVFrame *frame = av_frame_alloc();&#xA;    AVPacket *pkt_out = av_packet_alloc();&#xA;&#xA;    int frame_num = 0; int read_end = 0;&#xA;    &#xA;    for(;;){&#xA;        if( 1 == read_end ){ break;}&#xA;&#xA;        ret = av_read_frame(fmt_ctx, pkt);&#xA;        //Skip and do not process audio packets&#xA;        if( 1 == pkt->stream_index ){&#xA;            av_packet_unref(pt);&#xA;            continue;&#xA;        }&#xA;&#xA;        if ( AVERROR_EOF == ret) {&#xA;            //After reading the file, the data and size of pkt should be null at this time&#xA;            avcodec_send_packet(avctx, NULL);&#xA;        }else {&#xA;            if( 0 != ret){&#xA;                printf("read error code %d \n",ret);&#xA;                return ENOMEM;&#xA;            }else{&#xA;                retry:&#xA;                if (avcodec_send_packet(avctx, pkt) == AVERROR(EAGAIN)) {&#xA;                    printf("Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");&#xA;                    //Here you can consider sleeping for 0.1 seconds and returning EAGAIN. This is usually because there is a bug in ffmpeg&#x27;s internal API.&#xA;                    goto retry;&#xA;                }&#xA;                //Release the encoded data in pkt&#xA;                av_packet_unref(pt);&#xA;            }&#xA;&#xA;        }&#xA;&#xA;        //The loop keeps reading data from the decoder until there is no more data to read.&#xA;        for(;;){&#xA;            //Read AVFrame&#xA;            ret = avcodec_receive_frame(avctx, frame);&#xA;            /* Release the YUV data in the frame,&#xA;             * Since av_frame_unref is called in the avcodec_receive_frame function, the following code can be commented.&#xA;             * So we don&#x27;t need to manually unref this AVFrame&#xA;             * */&#xA;            //off_frame_unref(frame);&#xA;&#xA;            if( AVERROR(EAGAIN) == ret ){&#xA;                //Prompt EAGAIN means the decoder needs more AVPackets&#xA;                //Jump out of the first layer of for and let the decoder get more AVPackets&#xA;                break;&#xA;            }else if( AVERROR_EOF == ret ){&#xA;                /* The prompt AVERROR_EOF means that an AVPacket with both data and size NULL has been sent to the decoder before.&#xA;                 * Sending NULL AVPacket prompts the decoder to flush out all cached frames.&#xA;                 * Usually a NULL AVPacket is sent only after reading the input file, or when another video stream needs to be decoded with an existing decoder.&#xA;                 *&#xA;                 * */&#xA;&#xA;                /* Send null AVFrame to the encoder and let the encoder flush out the remaining data.&#xA;                 * */&#xA;                ret = avcodec_send_frame(enc_ctx, NULL);&#xA;                for(;;){&#xA;                    ret = avcodec_receive_packet(enc_ctx, pkt_out);&#xA;                    //It is impossible to return EAGAIN here, if there is any, exit directly.&#xA;                    if (ret == AVERROR(EAGAIN)){&#xA;                        printf("avcodec_receive_packet error code %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    &#xA;                    if ( AVERROR_EOF == ret ){ break; }&#xA;                    &#xA;                    //Encode the AVPacket, print some information first, and then write it to the file.&#xA;                    printf("pkt_out size : %d \n",pkt_out->size);&#xA;                    //Set the stream_index of AVPacket so that you know which stream it is.&#xA;                    pkt_out->stream_index = st->index;&#xA;                    //Convert the time base of AVPacket to the time base of the output stream.&#xA;                    pkt_out->pts = av_rescale_q_rnd(pkt_out->pts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->dts = av_rescale_q_rnd(pkt_out->dts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->duration = av_rescale_q_rnd(pkt_out->duration, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;&#xA;&#xA;                    ret = av_interleaved_write_frame(fmt_ctx_out, pkt_out);&#xA;                    if (ret &lt; 0) {&#xA;                        printf("av_interleaved_write_frame faile %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    av_packet_unref(pt_out);&#xA;                }&#xA;                av_write_trailer(fmt_ctx_out);&#xA;                //Jump out of the second layer of for, the file has been decoded.&#xA;                read_end = 1;&#xA;                break;&#xA;            }else if( ret >= 0 ){&#xA;                //Only when a frame is decoded can the encoder be initialized.&#xA;                if( NULL == enc_ctx ){&#xA;                    //Open the encoder and set encoding information.&#xA;                    AVCodec *encode = avcodec_find_encoder(AV_CODEC_ID_H264);&#xA;                    enc_ctx = avcodec_alloc_context3(encode);&#xA;                    enc_ctx->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;                    enc_ctx->bit_rate = 400000;&#xA;                    enc_ctx->framerate = avctx->framerate;&#xA;                    enc_ctx->gop_size = 30;&#xA;                    enc_ctx->max_b_frames = 10;&#xA;                    enc_ctx->profile = FF_PROFILE_H264_MAIN;&#xA;                   &#xA;                    /*&#xA;                     * In fact, the following information is also available in the container. You can also open the encoder directly in the container at the beginning.&#xA;                     * I took these encoder parameters from AVFrame because the difference in the container is final.&#xA;                     * Because the AVFrame you decoded may go through a filter, the information will be transformed after the filter, but this article does not use filters.&#xA;                     */&#xA;                     &#xA;                    //The time base of the encoder should be the time base of AVFrame, because AVFrame is the input. The time base of AVFrame is the time base of the stream.&#xA;                    enc_ctx->time_base = fmt_ctx->streams[0]->time_base;&#xA;                    enc_ctx->width = fmt_ctx->streams[0]->codecpar->width;&#xA;                    enc_ctx->height = fmt_ctx->streams[0]->codecpar->height;&#xA;                    enc_ctx->sample_aspect_ratio = st->sample_aspect_ratio = frame->sample_aspect_ratio;&#xA;                    enc_ctx->pix_fmt = frame->format;&#xA;                    enc_ctx->color_range            = frame->color_range;&#xA;                    enc_ctx->color_primaries        = frame->color_primaries;&#xA;                    enc_ctx->color_trc              = frame->color_trc;&#xA;                    enc_ctx->colorspace             = frame->colorspace;&#xA;                    enc_ctx->chroma_sample_location = frame->chroma_location;&#xA;&#xA;                    /* Note that the value of this field_order is different for different videos. I have written it here.&#xA;                     * Because the video in this article is AV_FIELD_PROGRESSIVE&#xA;                     * The production environment needs to process different videos&#xA;                     */&#xA;                    enc_ctx->field_order = AV_FIELD_PROGRESSIVE;&#xA;&#xA;                    /* Now we need to copy the encoder parameters to the stream. When decoding, assign parameters from the stream to the decoder.&#xA;                     * Now let’s do it in reverse.&#xA;                     * */&#xA;                    ret = avcodec_parameters_from_context(st->codecpar,enc_ctx);&#xA;                    if (ret &lt; 0){&#xA;                        printf("error code %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    if ((ret = avcodec_open2(enc_ctx, encode, NULL)) &lt; 0) {&#xA;                        printf("open codec faile %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;&#xA;                    //Formally open the output file&#xA;                    if ((ret = avio_open2(&amp;fmt_ctx_out->pb, filename_out, AVIO_FLAG_WRITE,&amp;fmt_ctx_out->interrupt_callback,NULL)) &lt; 0) {&#xA;                        printf("avio_open2 fail %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;&#xA;                    //Write the file header first.&#xA;                    ret = avformat_write_header(fmt_ctx_out,NULL);&#xA;                    if (ret &lt; 0) {&#xA;                        printf("avformat_write_header fail %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;&#xA;                }&#xA;&#xA;                //Send AVFrame to the encoder, and then continuously read AVPacket&#xA;                ret = avcodec_send_frame(enc_ctx, frame);&#xA;                if (ret &lt; 0) {&#xA;                    printf("avcodec_send_frame fail %d \n",ret);&#xA;                    return ret;&#xA;                }&#xA;                for(;;){&#xA;                    ret = avcodec_receive_packet(enc_ctx, pkt_out);&#xA;                    if (ret == AVERROR(EAGAIN)){ break; }&#xA;                    &#xA;                    if (ret &lt; 0){&#xA;                    printf("avcodec_receive_packet fail %d \n",ret);&#xA;                    return ret;&#xA;                    }&#xA;                    &#xA;                    //Encode the AVPacket, print some information first, and then write it to the file.&#xA;                    printf("pkt_out size : %d \n",pkt_out->size);&#xA;&#xA;                    //Set the stream_index of AVPacket so that you know which stream it is.&#xA;                    pkt_out->stream_index = st->index;&#xA;                    &#xA;                    //Convert the time base of AVPacket to the time base of the output stream.&#xA;                    pkt_out->pts = av_rescale_q_rnd(pkt_out->pts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->dts = av_rescale_q_rnd(pkt_out->dts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->duration = av_rescale_q_rnd(pkt_out->duration, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;&#xA;                    ret = av_interleaved_write_frame(fmt_ctx_out, pkt_out);&#xA;                    if (ret &lt; 0) {&#xA;                        printf("av_interleaved_write_frame faile %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    av_packet_unref(pt_out);&#xA;                }&#xA;&#xA;            }&#xA;            else{ printf("other fail \n"); return ret;}&#xA;        }&#xA;    }&#xA;    &#xA;    av_frame_free(&amp;frame); av_packet_free(&amp;pt); av_packet_free(&amp;pkt_out);&#xA;    &#xA;    //Close the encoder and decoder.&#xA;    avcodec_close(avctx); avcodec_close(enc_ctx);&#xA;&#xA;    //Release container memory.&#xA;    avformat_free_context(fmt_ctx);&#xA;&#xA;    //Must adjust avio_closep, otherwise the data may not be written in, it will be 0kb&#xA;    avio_closep(&amp;fmt_ctx_out->pb);&#xA;    avformat_free_context(fmt_ctx_out);&#xA;    printf("done \n");&#xA;&#xA;    return 0;&#xA;}&#xA;

    &#xA;

    This problem has haunted over my head for about three weeks. I still have no idea where the key bug exists. Really appreciate it if any FFmpeg expert could help me.

    &#xA;

  • Problems with outputting stream format as RTMP about FFmpeg C-API

    27 novembre 2023, par dongrixinyu

    I am using FFmpeg's C API to push video streams rtmp://.... into an SRS server.
    &#xA;The input stream is an MP4 file named juren-30s.mp4.
    &#xA;The output stream is also an MP4 file named juren-30s-5.mp4.

    &#xA;

    My piece of code (see further down) works fine when used in the following steps :
    &#xA;mp4 -> demux -> decode -> rgb images -> encode -> mux -> mp4.

    &#xA;

    Problem :

    &#xA;

    When I changed the output stream to an online RTMP url named rtmp://ip:port/live/stream_nb_23 (just an example, you can change it according to your server and rules.)

    &#xA;

    result : This code would be corrupted mp4 -> rtmp(flv).

    &#xA;

    What I've tried :

    &#xA;

    Changing the output format
    &#xA;I changed the output format param to become flv when I initialized the avformat_alloc_output_context2. But this didn't help.

    &#xA;

    Debugging the output
    &#xA;When I executed ffprobe rtmp://ip:port/live/xxxxxxx, I got the following errors and did not know why :

    &#xA;

    [h264 @ 0x55a925e3ba80] luma_log2_weight_denom 12 is out of range&#xA;[h264 @ 0x55a925e3ba80] Missing reference picture, default is 2&#xA;[h264 @ 0x55a925e3ba80] concealing 8003 DC, 8003 AC, 8003 MV errors in P frame&#xA;[h264 @ 0x55a925e3ba80] QP 4294966938 out of range&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;[h264 @ 0x55a925e3ba80] no frame!&#xA;[h264 @ 0x55a925e3ba80] luma_log2_weight_denom 21 is out of range&#xA;[h264 @ 0x55a925e3ba80] luma_log2_weight_denom 10 is out of range&#xA;[h264 @ 0x55a925e3ba80] chroma_log2_weight_denom 12 is out of range&#xA;[h264 @ 0x55a925e3ba80] Missing reference picture, default is 0&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;[h264 @ 0x55a925e3ba80] QP 4294967066 out of range&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;[h264 @ 0x55a925e3ba80] no frame!&#xA;[h264 @ 0x55a925e3ba80] QP 341 out of range&#xA;[h264 @ 0x55a925e3ba80] decode_slice_header error&#xA;

    &#xA;

    I am confused about the difference between MP4 and RTMP of how to use FFmpeg C-API to produce a correct output stream format.

    &#xA;

    Besides, I also wanna learn how to convert video and audio streams into other formats using FFmpeg C-api, such as flv, ts, rtsp, etc.

    &#xA;

    Code to reproduce the problem :

    &#xA;

    &#xA;

    So how to make this code output to RTMP without getting issue of an unplayable video ?

    &#xA;

    #include &#xA;#include "libavformat/avformat.h"&#xA;int main()&#xA;{&#xA;    int ret = 0; int err;&#xA;&#xA;    //Open input file&#xA;    char filename[] = "juren-30s.mp4";&#xA;    AVFormatContext *fmt_ctx = avformat_alloc_context();&#xA;    if (!fmt_ctx) {&#xA;        printf("error code %d \n",AVERROR(ENOMEM));&#xA;        return ENOMEM;&#xA;    }&#xA;    if((err = avformat_open_input(&amp;fmt_ctx, filename,NULL,NULL)) &lt; 0){&#xA;        printf("can not open file %d \n",err);&#xA;        return err;&#xA;    }&#xA;&#xA;    //Open the decoder&#xA;    AVCodecContext *avctx = avcodec_alloc_context3(NULL);&#xA;    ret = avcodec_parameters_to_context(avctx, fmt_ctx->streams[0]->codecpar);&#xA;    if (ret &lt; 0){&#xA;        printf("error code %d \n",ret);&#xA;        return ret;&#xA;    }&#xA;    AVCodec *codec = avcodec_find_decoder(avctx->codec_id);&#xA;    if ((ret = avcodec_open2(avctx, codec, NULL)) &lt; 0) {&#xA;        printf("open codec faile %d \n",ret);&#xA;        return ret;&#xA;    }&#xA;&#xA;    //Open the output file container&#xA;    char filename_out[] = "juren-30s-5.mp4";&#xA;    AVFormatContext *fmt_ctx_out = NULL;&#xA;    err = avformat_alloc_output_context2(&amp;fmt_ctx_out, NULL, NULL, filename_out);&#xA;    if (!fmt_ctx_out) {&#xA;        printf("error code %d \n",AVERROR(ENOMEM));&#xA;        return ENOMEM;&#xA;    }&#xA;    //Add all the way to the container context&#xA;    AVStream *st = avformat_new_stream(fmt_ctx_out, NULL);&#xA;    st->time_base = fmt_ctx->streams[0]->time_base;&#xA;&#xA;    AVCodecContext *enc_ctx = NULL;&#xA;    &#xA;    AVPacket *pt = av_packet_alloc();&#xA;    AVFrame *frame = av_frame_alloc();&#xA;    AVPacket *pkt_out = av_packet_alloc();&#xA;&#xA;    int frame_num = 0; int read_end = 0;&#xA;    &#xA;    for(;;){&#xA;        if( 1 == read_end ){ break;}&#xA;&#xA;        ret = av_read_frame(fmt_ctx, pkt);&#xA;        //Skip and do not process audio packets&#xA;        if( 1 == pkt->stream_index ){&#xA;            av_packet_unref(pt);&#xA;            continue;&#xA;        }&#xA;&#xA;        if ( AVERROR_EOF == ret) {&#xA;            //After reading the file, the data and size of pkt should be null at this time&#xA;            avcodec_send_packet(avctx, NULL);&#xA;        }else {&#xA;            if( 0 != ret){&#xA;                printf("read error code %d \n",ret);&#xA;                return ENOMEM;&#xA;            }else{&#xA;                retry:&#xA;                if (avcodec_send_packet(avctx, pkt) == AVERROR(EAGAIN)) {&#xA;                    printf("Receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");&#xA;                    //Here you can consider sleeping for 0.1 seconds and returning EAGAIN. This is usually because there is a bug in ffmpeg&#x27;s internal API.&#xA;                    goto retry;&#xA;                }&#xA;                //Release the encoded data in pkt&#xA;                av_packet_unref(pt);&#xA;            }&#xA;&#xA;        }&#xA;&#xA;        //The loop keeps reading data from the decoder until there is no more data to read.&#xA;        for(;;){&#xA;            //Read AVFrame&#xA;            ret = avcodec_receive_frame(avctx, frame);&#xA;            /* Release the YUV data in the frame,&#xA;             * Since av_frame_unref is called in the avcodec_receive_frame function, the following code can be commented.&#xA;             * So we don&#x27;t need to manually unref this AVFrame&#xA;             * */&#xA;            //off_frame_unref(frame);&#xA;&#xA;            if( AVERROR(EAGAIN) == ret ){&#xA;                //Prompt EAGAIN means the decoder needs more AVPackets&#xA;                //Jump out of the first layer of for and let the decoder get more AVPackets&#xA;                break;&#xA;            }else if( AVERROR_EOF == ret ){&#xA;                /* The prompt AVERROR_EOF means that an AVPacket with both data and size NULL has been sent to the decoder before.&#xA;                 * Sending NULL AVPacket prompts the decoder to flush out all cached frames.&#xA;                 * Usually a NULL AVPacket is sent only after reading the input file, or when another video stream needs to be decoded with an existing decoder.&#xA;                 *&#xA;                 * */&#xA;&#xA;                /* Send null AVFrame to the encoder and let the encoder flush out the remaining data.&#xA;                 * */&#xA;                ret = avcodec_send_frame(enc_ctx, NULL);&#xA;                for(;;){&#xA;                    ret = avcodec_receive_packet(enc_ctx, pkt_out);&#xA;                    //It is impossible to return EAGAIN here, if there is any, exit directly.&#xA;                    if (ret == AVERROR(EAGAIN)){&#xA;                        printf("avcodec_receive_packet error code %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    &#xA;                    if ( AVERROR_EOF == ret ){ break; }&#xA;                    &#xA;                    //Encode the AVPacket, print some information first, and then write it to the file.&#xA;                    printf("pkt_out size : %d \n",pkt_out->size);&#xA;                    //Set the stream_index of AVPacket so that you know which stream it is.&#xA;                    pkt_out->stream_index = st->index;&#xA;                    //Convert the time base of AVPacket to the time base of the output stream.&#xA;                    pkt_out->pts = av_rescale_q_rnd(pkt_out->pts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->dts = av_rescale_q_rnd(pkt_out->dts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->duration = av_rescale_q_rnd(pkt_out->duration, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;&#xA;&#xA;                    ret = av_interleaved_write_frame(fmt_ctx_out, pkt_out);&#xA;                    if (ret &lt; 0) {&#xA;                        printf("av_interleaved_write_frame faile %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    av_packet_unref(pt_out);&#xA;                }&#xA;                av_write_trailer(fmt_ctx_out);&#xA;                //Jump out of the second layer of for, the file has been decoded.&#xA;                read_end = 1;&#xA;                break;&#xA;            }else if( ret >= 0 ){&#xA;                //Only when a frame is decoded can the encoder be initialized.&#xA;                if( NULL == enc_ctx ){&#xA;                    //Open the encoder and set encoding information.&#xA;                    AVCodec *encode = avcodec_find_encoder(AV_CODEC_ID_H264);&#xA;                    enc_ctx = avcodec_alloc_context3(encode);&#xA;                    enc_ctx->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;                    enc_ctx->bit_rate = 400000;&#xA;                    enc_ctx->framerate = avctx->framerate;&#xA;                    enc_ctx->gop_size = 30;&#xA;                    enc_ctx->max_b_frames = 10;&#xA;                    enc_ctx->profile = FF_PROFILE_H264_MAIN;&#xA;                   &#xA;                    /*&#xA;                     * In fact, the following information is also available in the container. You can also open the encoder directly in the container at the beginning.&#xA;                     * I took these encoder parameters from AVFrame because the difference in the container is final.&#xA;                     * Because the AVFrame you decoded may go through a filter, the information will be transformed after the filter, but this article does not use filters.&#xA;                     */&#xA;                     &#xA;                    //The time base of the encoder should be the time base of AVFrame, because AVFrame is the input. The time base of AVFrame is the time base of the stream.&#xA;                    enc_ctx->time_base = fmt_ctx->streams[0]->time_base;&#xA;                    enc_ctx->width = fmt_ctx->streams[0]->codecpar->width;&#xA;                    enc_ctx->height = fmt_ctx->streams[0]->codecpar->height;&#xA;                    enc_ctx->sample_aspect_ratio = st->sample_aspect_ratio = frame->sample_aspect_ratio;&#xA;                    enc_ctx->pix_fmt = frame->format;&#xA;                    enc_ctx->color_range            = frame->color_range;&#xA;                    enc_ctx->color_primaries        = frame->color_primaries;&#xA;                    enc_ctx->color_trc              = frame->color_trc;&#xA;                    enc_ctx->colorspace             = frame->colorspace;&#xA;                    enc_ctx->chroma_sample_location = frame->chroma_location;&#xA;&#xA;                    /* Note that the value of this field_order is different for different videos. I have written it here.&#xA;                     * Because the video in this article is AV_FIELD_PROGRESSIVE&#xA;                     * The production environment needs to process different videos&#xA;                     */&#xA;                    enc_ctx->field_order = AV_FIELD_PROGRESSIVE;&#xA;&#xA;                    /* Now we need to copy the encoder parameters to the stream. When decoding, assign parameters from the stream to the decoder.&#xA;                     * Now let’s do it in reverse.&#xA;                     * */&#xA;                    ret = avcodec_parameters_from_context(st->codecpar,enc_ctx);&#xA;                    if (ret &lt; 0){&#xA;                        printf("error code %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    if ((ret = avcodec_open2(enc_ctx, encode, NULL)) &lt; 0) {&#xA;                        printf("open codec faile %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;&#xA;                    //Formally open the output file&#xA;                    if ((ret = avio_open2(&amp;fmt_ctx_out->pb, filename_out, AVIO_FLAG_WRITE,&amp;fmt_ctx_out->interrupt_callback,NULL)) &lt; 0) {&#xA;                        printf("avio_open2 fail %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;&#xA;                    //Write the file header first.&#xA;                    ret = avformat_write_header(fmt_ctx_out,NULL);&#xA;                    if (ret &lt; 0) {&#xA;                        printf("avformat_write_header fail %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;&#xA;                }&#xA;&#xA;                //Send AVFrame to the encoder, and then continuously read AVPacket&#xA;                ret = avcodec_send_frame(enc_ctx, frame);&#xA;                if (ret &lt; 0) {&#xA;                    printf("avcodec_send_frame fail %d \n",ret);&#xA;                    return ret;&#xA;                }&#xA;                for(;;){&#xA;                    ret = avcodec_receive_packet(enc_ctx, pkt_out);&#xA;                    if (ret == AVERROR(EAGAIN)){ break; }&#xA;                    &#xA;                    if (ret &lt; 0){&#xA;                    printf("avcodec_receive_packet fail %d \n",ret);&#xA;                    return ret;&#xA;                    }&#xA;                    &#xA;                    //Encode the AVPacket, print some information first, and then write it to the file.&#xA;                    printf("pkt_out size : %d \n",pkt_out->size);&#xA;&#xA;                    //Set the stream_index of AVPacket so that you know which stream it is.&#xA;                    pkt_out->stream_index = st->index;&#xA;                    &#xA;                    //Convert the time base of AVPacket to the time base of the output stream.&#xA;                    pkt_out->pts = av_rescale_q_rnd(pkt_out->pts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->dts = av_rescale_q_rnd(pkt_out->dts, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;                    pkt_out->duration = av_rescale_q_rnd(pkt_out->duration, fmt_ctx->streams[0]->time_base, st->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);&#xA;&#xA;                    ret = av_interleaved_write_frame(fmt_ctx_out, pkt_out);&#xA;                    if (ret &lt; 0) {&#xA;                        printf("av_interleaved_write_frame faile %d \n",ret);&#xA;                        return ret;&#xA;                    }&#xA;                    av_packet_unref(pt_out);&#xA;                }&#xA;&#xA;            }&#xA;            else{ printf("other fail \n"); return ret;}&#xA;        }&#xA;    }&#xA;    &#xA;    av_frame_free(&amp;frame); av_packet_free(&amp;pt); av_packet_free(&amp;pkt_out);&#xA;    &#xA;    //Close the encoder and decoder.&#xA;    avcodec_close(avctx); avcodec_close(enc_ctx);&#xA;&#xA;    //Release container memory.&#xA;    avformat_free_context(fmt_ctx);&#xA;&#xA;    //Must adjust avio_closep, otherwise the data may not be written in, it will be 0kb&#xA;    avio_closep(&amp;fmt_ctx_out->pb);&#xA;    avformat_free_context(fmt_ctx_out);&#xA;    printf("done \n");&#xA;&#xA;    return 0;&#xA;}&#xA;

    &#xA;