Recherche avancée

Médias (1)

Mot : - Tags -/ticket

Autres articles (53)

  • Configurer la prise en compte des langues

    15 novembre 2010, par

    Accéder à la configuration et ajouter des langues prises en compte
    Afin de configurer la prise en compte de nouvelles langues, il est nécessaire de se rendre dans la partie "Administrer" du site.
    De là, dans le menu de navigation, vous pouvez accéder à une partie "Gestion des langues" permettant d’activer la prise en compte de nouvelles langues.
    Chaque nouvelle langue ajoutée reste désactivable tant qu’aucun objet n’est créé dans cette langue. Dans ce cas, elle devient grisée dans la configuration et (...)

  • Personnaliser en ajoutant son logo, sa bannière ou son image de fond

    5 septembre 2013, par

    Certains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;

  • 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

Sur d’autres sites (7009)

  • Encoding YUV file (uncompressed video) to mp4 playable file using H264 encoding with ffmpeg c++ (NOT command line)

    20 avril 2023, par devprog

    My goal is to encode a yuv file to a playable mp4 file (can be played with VLC) with ffmpeg c++ code.

    


    First I have a source_1920x1080p30.mpg video (compressed) file.
Using ffmpeg CLI I created output_test.yuv file.
ffmpeg -i source_1920x1080p30.mpg -c:v rawvideo -pix_fmt yuv420p output_test.yuv

    


    I used ffplay -f rawvideo -pixel_format yuv420p -video_size 1920x1080 output_test.yuv which played well.
Also used ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1920x1080 -r 30 -i output_test.yuv -c:v libx264 vid.mp4
and the new vid.mp4 was playble.
So I have good yuv file.

    


    I want to encode this output_test.yuv YUV file with ffmpeg by code.
I tested the ffmpeg site encode example ffmpeg site encode example and it was running good.

    


    In that example, the frames are self made inside the code - But I want that the input would be my YUV file.

    


    Becasue I used ffmpeg CLI to convert YUV to mp4 (as noted above) I am sure it can be done by code - but I dont how..

    


    So, I tried to add to their example the use of the methods :
avformat_open_input() & avformat_find_stream_info()

    


    #include &#xA;#include &#xA;#include &#xA;&#xA;extern "C" {&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA; &#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>imgutils.h>&#xA;} &#xA;// ffmpeg method.&#xA;static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,&#xA;                   FILE *outfile)&#xA;{&#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;        fprintf(stderr, "Error sending a frame for encoding\n");&#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;        fwrite(pkt->data, 1, pkt->size, outfile);&#xA;        av_packet_unref(pkt);&#xA;    }&#xA;}&#xA;&#xA;int main(int argc, char **argv)&#xA;{&#xA;    &#xA;    int ret;&#xA;    char errbuf[100];&#xA;&#xA;    AVFormatContext* ifmt_ctx = avformat_alloc_context();&#xA;&#xA;    AVDictionary* options = NULL;&#xA;    //av_dict_set(&amp;options, "framerate", "30", 0);&#xA;    av_dict_set(&amp;options, "video_size", "1920x1080", 0);&#xA;    av_dict_set(&amp;options,"pixel_format", "yuv420p",0);&#xA;    av_dict_set(&amp;options, "vcodec", "rawvideo", 0);&#xA;&#xA;    if ((ret = avformat_open_input(&amp;ifmt_ctx, "output_test.yuv", NULL, &amp;options)) &lt; 0) {&#xA;        av_strerror(ret, errbuf, sizeof(errbuf));&#xA;        fprintf(stderr, "Unable to open err=%s\n", errbuf);&#xA;    }&#xA;&#xA;    const AVCodec *pCodec = avcodec_find_decoder(AV_CODEC_ID_RAWVIDEO); //Get pointer to rawvideo codec.&#xA;&#xA;    AVCodecContext *pCodecContext = avcodec_alloc_context3(pCodec); //Allocate codec context.&#xA;&#xA;    //Fill the codec context based on the values from the codec parameters.&#xA;    AVStream *vid_stream = ifmt_ctx->streams[0];&#xA;    avcodec_parameters_to_context(pCodecContext, vid_stream->codecpar);&#xA;&#xA;    avcodec_open2(pCodecContext, pCodec, NULL); //Open the codec&#xA;&#xA;    //Allocate memory for packet and frame&#xA;    AVPacket *pPacket = av_packet_alloc();&#xA;    AVFrame *pFrame = av_frame_alloc();&#xA;&#xA;    // For output use:&#xA;    &#xA;    const char *filename, *codec_name;&#xA;    const AVCodec *codec;&#xA;    AVCodecContext *c= NULL;&#xA;    int i, x, y;&#xA;    FILE *f;&#xA;    // origin ffmpeg code - AVFrame *frame;&#xA;    AVPacket *pkt;&#xA;    uint8_t endcode[] = { 0, 0, 1, 0xb7 };&#xA; &#xA;    if (argc &lt;= 2) {&#xA;        fprintf(stderr, "Usage: %s <output file="file"> <codec>\n", argv[0]);&#xA;        exit(0);&#xA;    }&#xA;    filename = argv[1];&#xA;    codec_name = argv[2];&#xA; &#xA;    /* find the mpeg1video encoder */&#xA;    codec = avcodec_find_encoder_by_name(codec_name);&#xA;    if (!codec) {&#xA;        fprintf(stderr, "Codec &#x27;%s&#x27; not found\n", codec_name);&#xA;        exit(1);&#xA;    }&#xA; &#xA;    c = avcodec_alloc_context3(codec);&#xA;    if (!c) {&#xA;        fprintf(stderr, "Could not allocate video codec context\n");&#xA;        exit(1);&#xA;    }&#xA; &#xA;    pkt = av_packet_alloc();&#xA;    if (!pkt)&#xA;        exit(1);&#xA; &#xA;    /* put sample parameters */&#xA;    c->bit_rate = 400000;&#xA;    /* resolution must be a multiple of two */&#xA;    c->width = 352;&#xA;    c->height = 288;&#xA;    /* frames per second */&#xA;    c->time_base = (AVRational){1, 25};&#xA;    c->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;    c->gop_size = 10;&#xA;    c->max_b_frames = 1;&#xA;    c->pix_fmt = AV_PIX_FMT_YUV420P;&#xA; &#xA;    if (codec->id == AV_CODEC_ID_H264)&#xA;        av_opt_set(c->priv_data, "preset", "slow", 0);&#xA; &#xA;    /* open it */&#xA;    ret = avcodec_open2(c, 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;    f = fopen(filename, "wb");&#xA;    if (!f) {&#xA;        fprintf(stderr, "Could not open %s\n", filename);&#xA;        exit(1);&#xA;    }&#xA;// This is ffmpeg code that I removed   &#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->width  = c->width;&#xA;//    frame->height = c->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\n");&#xA;//        exit(1);&#xA;//    }&#xA;&#xA;    pFrame->format = c->pix_fmt;&#xA;    pFrame->width  = c->width;&#xA;    pFrame->height = c->height;&#xA;    &#xA;&#xA;    //Read video frames and pass through the decoder.&#xA;    //Note: Since the video is rawvideo, we don&#x27;t really have to pass it through the decoder.&#xA;    while (av_read_frame(ifmt_ctx, pPacket) >= 0) &#xA;    {&#xA;        //The video is not encoded - passing through the decoder is simply copy the data.&#xA;        avcodec_send_packet(pCodecContext, pPacket);    //Supply raw packet data as input to the "decoder".&#xA;        avcodec_receive_frame(pCodecContext, pFrame);   //Return decoded output data from the "decoder".&#xA;&#xA;        fflush(stdout);&#xA;// This is ffmpeg code that I removed  &#xA;//        /* Make sure the frame data is writable.&#xA;//           On the first round, the frame is fresh from av_frame_get_buffer()&#xA;//           and therefore we know it is writable.&#xA;//           But on the next rounds, encode() will have called&#xA;//           avcodec_send_frame(), and the codec may have kept a reference to&#xA;//           the frame in its internal structures, that makes the frame&#xA;//           unwritable.&#xA;//           av_frame_make_writable() checks that and allocates a new buffer&#xA;//           for the frame only if necessary.&#xA;//         */&#xA;//        ret = av_frame_make_writable(frame);&#xA;//        if (ret &lt; 0)&#xA;//            exit(1);&#xA;// &#xA;//        /* Prepare a dummy image.&#xA;//           In real code, this is where you would have your own logic for&#xA;//           filling the frame. FFmpeg does not care what you put in the&#xA;//           frame.&#xA;//         */&#xA;//        /* Y */&#xA;//        for (y = 0; y &lt; c->height; y&#x2B;&#x2B;) {&#xA;//            for (x = 0; x &lt; c->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; c->height/2; y&#x2B;&#x2B;) {&#xA;//            for (x = 0; x &lt; c->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;        pFrame->pts = i;&#xA; &#xA;        /* encode the image */&#xA;        encode(c, pFrame, pkt, f);&#xA;    }&#xA; &#xA;    /* flush the encoder */&#xA;    encode(c, NULL, pkt, f);&#xA; &#xA;    /* Add sequence end code to have a real MPEG file.&#xA;       It makes only sense because this tiny examples writes packets&#xA;       directly. This is called "elementary stream" and only works for some&#xA;       codecs. To create a valid file, you usually need to write packets&#xA;       into a proper file format or protocol; see mux.c.&#xA;     */&#xA;    if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)&#xA;        fwrite(endcode, 1, sizeof(endcode), f);&#xA;    fclose(f);&#xA; &#xA;    avcodec_free_context(&amp;c);&#xA;    av_frame_free(&amp;pFrame);&#xA;    av_packet_free(&amp;pkt);&#xA; &#xA;    return 0;&#xA;}&#xA;</codec></output>

    &#xA;

    EDIT : I added combined code of ffmpeg and reading/decoding from YUV file according @Rotem (thanks). Frame from decoder pushed right to encode() method of ffmpeg. The out video was not good... Should I manipulate the YUV input frame before send it to encode() method ? if yes how to do it ?

    &#xA;

  • FFmpeg avcodec_open2 throws -22 ("Invalid Argument")

    14 avril 2023, par stupidbutseeking

    I got stuck trying to write a simple video conversion using C++ and ffmpeg.

    &#xA;

    When trying to convert a video using FFmpeg, calling avcodec_open2 fails with the code "-22" which seems to be an "Invalid Argument"-error.

    &#xA;

    I can't figure out why it fails, nor what the invalid argument is. In the following snippet I create the output codec and pass its context the information from the source (code further down below).

    &#xA;

    The check for the "outputCodec" works and does not throw an error. As far as I know an "AVDictionary"-argument is optional. So I guess the reason for the error is the context.

    &#xA;

        const AVCodec* outputCodec = avcodec_find_encoder_by_name(codecName.c_str());&#xA;&#xA;    if (!outputCodec)&#xA;    {&#xA;        std::cout &lt;&lt; "Zielformat-Codec nicht gefunden" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    AVCodecContext* outputCodecContext = avcodec_alloc_context3(outputCodec);&#xA;    outputCodecContext->bit_rate = bitRate;&#xA;    outputCodecContext->width = inputCodecContext->width;&#xA;    outputCodecContext->height = inputCodecContext->height;&#xA;    outputCodecContext->pix_fmt = outputCodec->pix_fmts[0];&#xA;    outputCodecContext->time_base = inputCodecContext->time_base;&#xA;&#xA;    **int errorCode = avcodec_open2(outputCodecContext, outputCodec, NULL); //THIS RETURNS -22**&#xA;    if (errorCode != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim &#xD6;ffnen des Zielformat-Codecs" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;

    &#xA;

    Here is the code for getting the input file & context :

    &#xA;

        std::string inputFilename = "input_video.mp4";&#xA;    std::string outputFilename = "output.avi";&#xA;    std::string codecName = "mpeg4";&#xA;    int bitRate = 400000;&#xA;&#xA;    AVFormatContext* inputFormatContext = NULL;&#xA;    if (avformat_open_input(&amp;inputFormatContext, inputFilename.c_str(), NULL, NULL) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim &#xD6;ffnen der Eingabedatei" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    [Do Video Stream Search)&#xA;&#xA;    AVCodecParameters* inputCodecParameters = inputFormatContext->streams[videoStreamIndex]->codecpar;&#xA;    const AVCodec* inputCodec = avcodec_find_decoder(inputCodecParameters->codec_id);&#xA;    AVCodecContext* inputCodecContext = avcodec_alloc_context3(inputCodec);&#xA;    if (avcodec_parameters_to_context(inputCodecContext, inputCodecParameters) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim Setzen des Eingabecodecs" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;    if (avcodec_open2(inputCodecContext, inputCodec, NULL) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim &#xD6;ffnen des Eingabecodecs" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;

    &#xA;

    The purpose was simply to get started with ffmpeg in an own C++ project.

    &#xA;

    If it is of any need, I downloaded the ffmpeg libs from here. I used the gpl shared ones. The architecture is win x64. I referenced them through the project properties (additional libraries and so on).

    &#xA;

    I tried to convert a .mp4 video to an .avi video with an "mpeg4" compression.&#xA;I also tried other compressions like "libx264" but none worked.

    &#xA;

    I searched for the problem on stackoverflow but could not find the exact same problem. While its purpose is different this post is about the same error code when calling avcodec_open2. But its solution is not working for me. I inspected the watch for the "outputContext" while running the code and the codec_id, codec_type and format is set. I use the time_base from the input file. According to my understanding, this should be equal to the source. So I can not find out what I am missing.

    &#xA;

    Thanks in advance and sorry for my english.

    &#xA;

    And for completion, here is the whole method :

    &#xA;

    int TestConvert()&#xA;{&#xA;    std::string inputFilename = "input_video.mp4";&#xA;    std::string outputFilename = "output.avi";&#xA;    std::string codecName = "mpeg4";&#xA;    int bitRate = 400000;&#xA;&#xA;    AVFormatContext* inputFormatContext = NULL;&#xA;    if (avformat_open_input(&amp;inputFormatContext, inputFilename.c_str(), NULL, NULL) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim &#xD6;ffnen der Eingabedatei" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    int videoStreamIndex = -1;&#xA;    for (unsigned int i = 0; i &lt; inputFormatContext->nb_streams; i&#x2B;&#x2B;)&#xA;    {&#xA;        if (inputFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)&#xA;        {&#xA;            videoStreamIndex = i;&#xA;            break;&#xA;        }&#xA;    }&#xA;&#xA;    AVCodecParameters* inputCodecParameters = inputFormatContext->streams[videoStreamIndex]->codecpar;&#xA;    const AVCodec* inputCodec = avcodec_find_decoder(inputCodecParameters->codec_id);&#xA;    AVCodecContext* inputCodecContext = avcodec_alloc_context3(inputCodec);&#xA;    if (avcodec_parameters_to_context(inputCodecContext, inputCodecParameters) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim Setzen des Eingabecodecs" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;    if (avcodec_open2(inputCodecContext, inputCodec, NULL) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim &#xD6;ffnen des Eingabecodecs" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    const AVCodec* outputCodec = avcodec_find_encoder_by_name(codecName.c_str());&#xA;&#xA;    if (!outputCodec)&#xA;    {&#xA;        std::cout &lt;&lt; "Zielformat-Codec nicht gefunden" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    AVCodecContext* outputCodecContext = avcodec_alloc_context3(outputCodec);&#xA;    outputCodecContext->bit_rate = bitRate;&#xA;    outputCodecContext->width = inputCodecContext->width;&#xA;    outputCodecContext->height = inputCodecContext->height;&#xA;    outputCodecContext->pix_fmt = outputCodec->pix_fmts[0];&#xA;    outputCodecContext->time_base = inputCodecContext->time_base;&#xA;&#xA;    int errorCode = avcodec_open2(outputCodecContext, outputCodec, NULL);&#xA;    if (errorCode != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim &#xD6;ffnen des Zielformat-Codecs" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    AVFormatContext* outputFormatContext = NULL;&#xA;    if (avformat_alloc_output_context2(&amp;outputFormatContext, NULL, NULL, outputFilename.c_str()) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim Erstellen des Ausgabe-Formats" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    AVStream* outputVideoStream = avformat_new_stream(outputFormatContext, outputCodec);&#xA;    if (outputVideoStream == NULL)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim Hinzuf&#xFC;gen des Video-Streams zum Ausgabe-Format" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;    outputVideoStream->id = outputFormatContext->nb_streams - 1;&#xA;    AVCodecParameters* outputCodecParameters = outputVideoStream->codecpar;&#xA;    if (avcodec_parameters_from_context(outputCodecParameters, outputCodecContext) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim Setzen des Ausgabe-Codecs" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    if (!(outputFormatContext->oformat->flags &amp; AVFMT_NOFILE))&#xA;    {&#xA;        if (avio_open(&amp;outputFormatContext->pb, outputFilename.c_str(), AVIO_FLAG_WRITE) != 0)&#xA;        {&#xA;            std::cout &lt;&lt; "Fehler beim &#xD6;ffnen der Ausgabedatei" &lt;&lt; std::endl;&#xA;            return -1;&#xA;        }&#xA;    }&#xA;&#xA;    if (avformat_write_header(outputFormatContext, NULL) != 0)&#xA;    {&#xA;        std::cout &lt;&lt; "Fehler beim Schreiben des Ausgabe-Formats in die Ausgabedatei" &lt;&lt; std::endl;&#xA;        return -1;&#xA;    }&#xA;&#xA;    AVPacket packet;&#xA;    int response;&#xA;    AVFrame* frame = av_frame_alloc();&#xA;    AVFrame* outputFrame = av_frame_alloc();&#xA;    while (av_read_frame(inputFormatContext, &amp;packet) == 0)&#xA;    {&#xA;        if (packet.stream_index == videoStreamIndex)&#xA;        {&#xA;            response = avcodec_send_packet(inputCodecContext, &amp;packet);&#xA;            while (response >= 0)&#xA;            {&#xA;                response = avcodec_receive_frame(inputCodecContext, frame);&#xA;                if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)&#xA;                {&#xA;                    break;&#xA;                }&#xA;                else if (response &lt; 0)&#xA;                {&#xA;                    std::cout &lt;&lt; "Fehler beim Dekodieren des Video-Pakets" &lt;&lt; std::endl;&#xA;                    return -1;&#xA;                }&#xA;&#xA;                struct SwsContext* swsContext = sws_getContext(inputCodecContext->width, inputCodecContext->height, inputCodecContext->pix_fmt, outputCodecContext->width, outputCodecContext->height, outputCodecContext->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL); if (!swsContext)&#xA;                {&#xA;                    std::cout &lt;&lt; "Fehler beim Erstellen des SwsContext" &lt;&lt; std::endl;&#xA;                    return -1;&#xA;                }&#xA;                sws_scale(swsContext, frame->data, frame->linesize, 0, inputCodecContext->height, outputFrame->data, outputFrame->linesize);&#xA;                sws_freeContext(swsContext);&#xA;&#xA;                outputFrame->pts = frame->pts;&#xA;                outputFrame->pkt_dts = frame->pkt_dts;&#xA;                //outputFrame->pkt_duration = frame->pkt_duration;&#xA;                response = avcodec_send_frame(outputCodecContext, outputFrame);&#xA;                while (response >= 0)&#xA;                {&#xA;                    response = avcodec_receive_packet(outputCodecContext, &amp;packet);&#xA;                    if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)&#xA;                    {&#xA;                        break;&#xA;                    }&#xA;                    else if (response &lt; 0)&#xA;                    {&#xA;                        std::cout &lt;&lt; "Fehler beim Kodieren des Ausgabe-Frames" &lt;&lt; std::endl;&#xA;                        return -1;&#xA;                    }&#xA;&#xA;                    packet.stream_index = outputVideoStream->id;&#xA;                    av_packet_rescale_ts(&amp;packet, outputCodecContext->time_base, outputVideoStream->time_base);&#xA;                    if (av_interleaved_write_frame(outputFormatContext, &amp;packet) != 0)&#xA;                    {&#xA;                        std::cout &lt;&lt; "Fehler beim Schreiben des Ausgabe-Pakets" &lt;&lt; std::endl;&#xA;                        return -1;&#xA;                    }&#xA;                    av_packet_unref(&amp;packet);&#xA;                }&#xA;            }&#xA;        }&#xA;        av_packet_unref(&amp;packet);&#xA;    }&#xA;&#xA;    av_write_trailer(outputFormatContext);&#xA;    avcodec_free_context(&amp;inputCodecContext);&#xA;    avcodec_free_context(&amp;outputCodecContext);&#xA;    avformat_close_input(&amp;inputFormatContext);&#xA;    avformat_free_context(inputFormatContext);&#xA;    avformat_free_context(outputFormatContext);&#xA;    av_frame_free(&amp;frame);&#xA;    av_frame_free(&amp;outputFrame);&#xA;&#xA;    return 0;&#xA;&#xA;}&#xA;

    &#xA;

  • Sending raw h264 video and aac audio frames to an RTMP server using ffmpeg

    7 décembre 2022, par codeimpaler

    I am receiving raw h264 and aac audio frames from an even driven source. I am trying to send these frames to an rtmp server. &#xA;I started working from the ffmpeg example muxing.c which successfully sends a custom stream to the rtmp server. I figure I just need to replace their frame data with my own.I found this suggestion online. I have tried How to pack raw h264 stream to flv container and send over rtmp using ffmpeg (not command) &#xA;and&#xA;How to publish selfmade stream with ffmpeg and c++ to rtmp server ?&#xA;and a few other suggestions but none have worked for me. &#xA;I have tried to directly memcpy my byte buffer but my code keeps failing&#xA;at ret = avcodec_encode_video2(c, &pkt, frame, &got_packet).&#xA;Specifically, I get an invalid access error.&#xA;For a little more context, anytime I receive a frame (which is event driven), void RTMPWriter::WriteVideoFrame(...) is called. Assume the constructor has already been called before the first frame is received. &#xA;I am not that familiar with ffmpeg and there could be several things wrong with the code. Any input will be really appreciated.

    &#xA;&#xA;

        #define STREAM_FRAME_RATE 25 /* 25 images/s */&#xA;    #define STREAM_PIX_FMT    AV_PIX_FMT_YUV420P /* default pix_fmt */&#xA;    #define SCALE_FLAGS SWS_BICUBIC&#xA;    RTMPWriter::RTMPWriter()&#xA;      : seenKeyFrame(false),&#xA;        video_st({ 0 }), &#xA;        audio_st({ 0 }),&#xA;        have_video(0), &#xA;        have_audio(0)&#xA;    {&#xA;&#xA;        const char *filename;&#xA;        AVCodec *audio_codec = NULL, *video_codec = NULL;&#xA;        int ret;&#xA;&#xA;        int encode_video = 0, encode_audio = 0;&#xA;        AVDictionary *opt = NULL;&#xA;        int i;&#xA;&#xA;        /* Initialize libavcodec, and register all codecs and formats. */&#xA;        av_register_all();&#xA;&#xA;        avformat_network_init();&#xA;&#xA;       String^ StreamURL = "StreamURL";&#xA;       String^ out_uri = safe_cast(ApplicationData::Current->LocalSettings->Values->Lookup(StreamURL));&#xA;       std::wstring out_uriW(out_uri->Begin());&#xA;       std::string out_uriA(out_uriW.begin(), out_uriW.end());&#xA;       filename = out_uriA.c_str();  &#xA;&#xA;       /* allocate the output media context */&#xA;       avformat_alloc_output_context2(&amp;oc, NULL, "flv", filename);&#xA;       if (!oc)&#xA;       {&#xA;           OutputDebugString(L"Could not deduce output format from file extension: using MPEG.\n");&#xA;           avformat_alloc_output_context2(&amp;oc, NULL, "mpeg", filename);&#xA;       }&#xA;       if (!oc)&#xA;       {&#xA;           OutputDebugString(L"Could not allocate  using MPEG.\n");&#xA;       }&#xA;&#xA;&#xA;       fmt = oc->oformat;&#xA;&#xA;       /* Add the audio and video streams using the default format codecs&#xA;       * and initialize the codecs. */&#xA;       if (fmt->video_codec != AV_CODEC_ID_NONE) {&#xA;           add_stream(&amp;video_st, oc, &amp;video_codec, fmt->video_codec);&#xA;           have_video = 1;&#xA;           encode_video = 1;&#xA;       }&#xA;       if (fmt->audio_codec != AV_CODEC_ID_NONE) {&#xA;           add_stream(&amp;audio_st, oc, &amp;audio_codec, fmt->audio_codec);&#xA;           have_audio = 1;&#xA;           encode_audio = 1;&#xA;       }&#xA;&#xA;       /* Now that all the parameters are set, we can open the audio and&#xA;        * video codecs and allocate the necessary encode buffers. */&#xA;       if (have_video)&#xA;       {&#xA;           open_video(oc, video_codec, &amp;video_st, opt);&#xA;       }&#xA;&#xA;       if (have_audio)&#xA;       {&#xA;           open_audio(oc, audio_codec, &amp;audio_st, opt);&#xA;       }&#xA;&#xA;       av_dump_format(oc, 0, filename, 1);&#xA;&#xA;       /* open the output file, if needed */&#xA;       if (!(fmt->flags &amp; AVFMT_NOFILE))&#xA;       {&#xA;           ret = avio_open(&amp;oc->pb, filename, AVIO_FLAG_WRITE);&#xA;           if (ret &lt; 0)&#xA;           {&#xA;               OutputDebugString(L"Could not open ");&#xA;               OutputDebugString(out_uri->Data());&#xA;           }&#xA;       }&#xA;&#xA;       /* Write the stream header, if any. */&#xA;       ret = avformat_write_header(oc, &amp;opt);&#xA;       if (ret &lt; 0)&#xA;       {&#xA;           OutputDebugString(L"Error occurred when writing stream header \n");&#xA;       }&#xA;&#xA;    }&#xA;&#xA;    void RTMPWriter::WriteVideoFrame(&#xA;        boolean isKeyFrame,&#xA;        boolean hasDiscontinuity,&#xA;        UINT64 frameId,&#xA;        UINT32 videoBufferLength,&#xA;        BYTE *videoBytes)&#xA;    {&#xA;&#xA;        int ret;&#xA;        AVCodecContext *c;&#xA;        AVFrame* frame;&#xA;        int got_packet = 0;&#xA;        AVPacket pkt = { 0 };&#xA;&#xA;        c = video_st.enc;&#xA;&#xA;        frame = get_video_frame(videoBufferLength, videoBytes);&#xA;&#xA;        /* encode the image */&#xA;        ret = avcodec_encode_video2(c, &amp;pkt, frame, &amp;got_packet);&#xA;        if (ret &lt; 0) {&#xA;             OutputDebugString(L"Error encoding video frame: \n")&#xA;        }&#xA;&#xA;        if (got_packet) &#xA;        {&#xA;            ret = write_frame(oc, &amp;c->time_base, video_st.st, &amp;pkt);&#xA;        }&#xA;        else {&#xA;            ret = 0;&#xA;        }&#xA;&#xA;        if (ret &lt; 0) {&#xA;             OutputDebugString(L"Error while writing video frame: %s\n");&#xA;        }&#xA;    }&#xA;&#xA;    AVFrame * RTMPWriter::get_video_frame(&#xA;       UINT32 videoBufferLength,&#xA;       BYTE *videoBytes)&#xA;    {&#xA;        AVCodecContext *c = video_st.enc;&#xA;&#xA;        if (c->pix_fmt != AV_PIX_FMT_YUV420P) {&#xA;            /* as we only generate a YUV420P picture, we must convert it&#xA;            * to the codec pixel format if needed */&#xA;            if (!video_st.sws_ctx) {&#xA;                video_st.sws_ctx = sws_getContext(c->width, c->height,&#xA;                    AV_PIX_FMT_YUV420P,&#xA;                    c->width, c->height,&#xA;                    c->pix_fmt,&#xA;                    SCALE_FLAGS, NULL, NULL, NULL);&#xA;                if (!video_st.sws_ctx) {&#xA;                    fprintf(stderr,&#xA;                        "Could not initialize the conversion context\n");&#xA;                        exit(1);&#xA;                }&#xA;            }&#xA;            fill_yuv_image(video_st.tmp_frame, video_st.next_pts, c->width, c->height, videoBufferLength, videoBytes);&#xA;            sws_scale(video_st.sws_ctx,&#xA;            (const uint8_t * const *)video_st.tmp_frame->data, video_st.tmp_frame->linesize,&#xA;            0, c->height, video_st.frame->data, video_st.frame->linesize);&#xA;        }&#xA;        else {&#xA;            fill_yuv_image(video_st.frame, video_st.next_pts, c->width, c->height, videoBufferLength, videoBytes);&#xA;        }&#xA;&#xA;        video_st.frame->pts = video_st.next_pts&#x2B;&#x2B;;&#xA;&#xA;        return video_st.frame;&#xA;    }&#xA;&#xA;    /* Prepare a dummy image. */&#xA;    void  RTMPWriter::fill_yuv_image(&#xA;         AVFrame *pict, &#xA;         int frame_index,&#xA;         int width, &#xA;         int height, &#xA;         UINT32 videoBufferLength,&#xA;         BYTE *videoBytes)&#xA;    {&#xA;        //int x, y, i, ret;&#xA;&#xA;        /* when we pass a frame to the encoder, it may keep a reference to it&#xA;        * internally;&#xA;        * make sure we do not overwrite it here&#xA;        */&#xA;        ret = av_frame_make_writable(pict);&#xA;        if (ret &lt; 0) &#xA;        {&#xA;             OutputDebugString(L"Unable to make piture writable");&#xA;        }&#xA;&#xA;        memcpy(pict->data, videoBytes, videoBufferLength);&#xA;&#xA;        //i = frame_index;&#xA;&#xA;        ///* Y */&#xA;        //for (y = 0; y &lt; height; y&#x2B;&#x2B;)&#xA;        //  for (x = 0; x &lt; width; x&#x2B;&#x2B;)&#xA;        //      pict->data[0][y * pict->linesize[0] &#x2B; x] = x &#x2B; y &#x2B; i * 3;&#xA;&#xA;        ///* Cb and Cr */&#xA;        //for (y = 0; y &lt; height / 2; y&#x2B;&#x2B;) {&#xA;        //  for (x = 0; x &lt; width / 2; x&#x2B;&#x2B;) {&#xA;        //      pict->data[1][y * pict->linesize[1] &#x2B; x] = 128 &#x2B; y &#x2B; i * 2;&#xA;        //      pict->data[2][y * pict->linesize[2] &#x2B; x] = 64 &#x2B; x &#x2B; i * 5;&#xA;        //  }&#xA;        //}&#xA;    }&#xA;&#xA;    void RTMPWriter::WriteAudioFrame()&#xA;    {&#xA;&#xA;    }&#xA;&#xA;    /* Add an output stream. */&#xA;    void  RTMPWriter::add_stream(&#xA;        OutputStream *ost, &#xA;        AVFormatContext *oc,&#xA;        AVCodec **codec,&#xA;        enum AVCodecID codec_id)&#xA;   {&#xA;    AVCodecContext *c;&#xA;    int i;&#xA;&#xA;    /* find the encoder */&#xA;    *codec = avcodec_find_encoder(codec_id);&#xA;    if (!(*codec)) {&#xA;        OutputDebugString(L"Could not find encoder for &#x27;%s&#x27;\n");&#xA;        //avcodec_get_name(codec_id));&#xA;        exit(1);&#xA;    }&#xA;&#xA;    ost->st = avformat_new_stream(oc, NULL);&#xA;    if (!ost->st) {&#xA;        OutputDebugString(L"Could not allocate stream\n");&#xA;        exit(1);&#xA;    }&#xA;    ost->st->id = oc->nb_streams - 1;&#xA;    c = avcodec_alloc_context3(*codec);&#xA;    if (!c) {&#xA;        OutputDebugString(L"Could not alloc an encoding context\n");&#xA;        exit(1);&#xA;    }&#xA;    ost->enc = c;&#xA;&#xA;    switch ((*codec)->type) {&#xA;    case AVMEDIA_TYPE_AUDIO:&#xA;        c->sample_fmt = (*codec)->sample_fmts ?&#xA;            (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;&#xA;        c->bit_rate = 64000;&#xA;        c->sample_rate = 44100;&#xA;        if ((*codec)->supported_samplerates) {&#xA;            c->sample_rate = (*codec)->supported_samplerates[0];&#xA;            for (i = 0; (*codec)->supported_samplerates[i]; i&#x2B;&#x2B;) {&#xA;                if ((*codec)->supported_samplerates[i] == 44100)&#xA;                    c->sample_rate = 44100;&#xA;            }&#xA;        }&#xA;        c->channels = av_get_channel_layout_nb_channels(c->channel_layout);&#xA;        c->channel_layout = AV_CH_LAYOUT_STEREO;&#xA;        if ((*codec)->channel_layouts) {&#xA;            c->channel_layout = (*codec)->channel_layouts[0];&#xA;            for (i = 0; (*codec)->channel_layouts[i]; i&#x2B;&#x2B;) {&#xA;                if ((*codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO)&#xA;                    c->channel_layout = AV_CH_LAYOUT_STEREO;&#xA;            }&#xA;        }&#xA;        c->channels = av_get_channel_layout_nb_channels(c->channel_layout);&#xA;        ost->st->time_base = /*(AVRational)*/{ 1, c->sample_rate };&#xA;        break;&#xA;&#xA;    case AVMEDIA_TYPE_VIDEO:&#xA;        c->codec_id = codec_id;&#xA;&#xA;        c->bit_rate = 400000;&#xA;        /* Resolution must be a multiple of two. */&#xA;        c->width = 352;&#xA;        c->height = 288;&#xA;        /* timebase: This is the fundamental unit of time (in seconds) in terms&#xA;        * of which frame timestamps are represented. For fixed-fps content,&#xA;        * timebase should be 1/framerate and timestamp increments should be&#xA;        * identical to 1. */&#xA;        ost->st->time_base = /*(AVRational)*/{ 1, STREAM_FRAME_RATE };&#xA;        c->time_base = ost->st->time_base;&#xA;&#xA;        c->gop_size = 12; /* emit one intra frame every twelve frames at most */&#xA;        c->pix_fmt = STREAM_PIX_FMT;&#xA;            if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {&#xA;                /* just for testing, we also add B-frames */&#xA;                c->max_b_frames = 2;&#xA;            }&#xA;            if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {&#xA;                /* Needed to avoid using macroblocks in which some coeffs overflow.&#xA;                * This does not happen with normal video, it just happens here as&#xA;                * the motion of the chroma plane does not match the luma plane. */&#xA;                c->mb_decision = 2;&#xA;            }&#xA;            break;&#xA;&#xA;        default:&#xA;            break;&#xA;        }&#xA;&#xA;         /* Some formats want stream headers to be separate. */&#xA;        if (oc->oformat->flags &amp; AVFMT_GLOBALHEADER)&#xA;            c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;&#xA;    }&#xA;&#xA;AVFrame * RTMPWriter::alloc_audio_frame(&#xA;    enum AVSampleFormat sample_fmt,&#xA;    uint64_t channel_layout,&#xA;    int sample_rate, int nb_samples)&#xA;{&#xA;    AVFrame *frame = av_frame_alloc();&#xA;    int ret;&#xA;&#xA;    if (!frame) {&#xA;        OutputDebugString(L"Error allocating an audio frame\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    frame->format = sample_fmt;&#xA;    frame->channel_layout = channel_layout;&#xA;    frame->sample_rate = sample_rate;&#xA;    frame->nb_samples = nb_samples;&#xA;&#xA;    if (nb_samples) {&#xA;        ret = av_frame_get_buffer(frame, 0);&#xA;        if (ret &lt; 0) {&#xA;            OutputDebugString(L"Error allocating an audio buffer\n");&#xA;            exit(1);&#xA;        }&#xA;    }&#xA;&#xA;        return frame;&#xA;    }&#xA;&#xA;&#xA;&#xA;&#xA;void  RTMPWriter::open_audio(&#xA;    AVFormatContext *oc, &#xA;    AVCodec *codec, &#xA;    OutputStream *ost, &#xA;    AVDictionary *opt_arg)&#xA;{&#xA;    AVCodecContext *c;&#xA;    int nb_samples;&#xA;    int ret;&#xA;    AVDictionary *opt = NULL;&#xA;&#xA;    c = ost->enc;&#xA;&#xA;    /* open it */&#xA;    av_dict_copy(&amp;opt, opt_arg, 0);&#xA;    ret = avcodec_open2(c, codec, &amp;opt);&#xA;    av_dict_free(&amp;opt);&#xA;    if (ret &lt; 0) {&#xA;        OutputDebugString(L"Could not open audio codec: %s\n");// , av_err2str(ret));&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* init signal generator */&#xA;    ost->t = 0;&#xA;    ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;&#xA;    /* increment frequency by 110 Hz per second */&#xA;    ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;&#xA;&#xA;    if (c->codec->capabilities &amp; AV_CODEC_CAP_VARIABLE_FRAME_SIZE)&#xA;        nb_samples = 10000;&#xA;    else&#xA;        nb_samples = c->frame_size;&#xA;&#xA;    ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout,&#xA;        c->sample_rate, nb_samples);&#xA;    ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,&#xA;        c->sample_rate, nb_samples);&#xA;&#xA;    /* copy the stream parameters to the muxer */&#xA;    ret = avcodec_parameters_from_context(ost->st->codecpar, c);&#xA;    if (ret &lt; 0) {&#xA;        OutputDebugString(L"Could not copy the stream parameters\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* create resampler context */&#xA;    ost->swr_ctx = swr_alloc();&#xA;    if (!ost->swr_ctx) {&#xA;        OutputDebugString(L"Could not allocate resampler context\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* set options */&#xA;    av_opt_set_int(ost->swr_ctx, "in_channel_count", c->channels, 0);&#xA;    av_opt_set_int(ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);&#xA;    av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);&#xA;    av_opt_set_int(ost->swr_ctx, "out_channel_count", c->channels, 0);&#xA;    av_opt_set_int(ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);&#xA;    av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);&#xA;&#xA;    /* initialize the resampling context */&#xA;    if ((ret = swr_init(ost->swr_ctx)) &lt; 0) {&#xA;        OutputDebugString(L"Failed to initialize the resampling context\n");&#xA;        exit(1);&#xA;    }&#xA;}&#xA;&#xA;int RTMPWriter::write_frame(&#xA;    AVFormatContext *fmt_ctx, &#xA;    const AVRational *time_base, &#xA;    AVStream *st, &#xA;    AVPacket *pkt)&#xA;{&#xA;    /* rescale output packet timestamp values from codec to stream timebase */&#xA;    av_packet_rescale_ts(pkt, *time_base, st->time_base);&#xA;    pkt->stream_index = st->index;&#xA;&#xA;    /* Write the compressed frame to the media file. */&#xA;    //log_packet(fmt_ctx, pkt);&#xA;    OutputDebugString(L"Actually sending video frame: %s\n");&#xA;    return av_interleaved_write_frame(fmt_ctx, pkt);&#xA;}&#xA;&#xA;&#xA;AVFrame  *RTMPWriter::alloc_picture(&#xA;    enum AVPixelFormat pix_fmt, &#xA;    int width, &#xA;    int height)&#xA;{&#xA;    AVFrame *picture;&#xA;    int ret;&#xA;&#xA;    picture = av_frame_alloc();&#xA;    if (!picture)&#xA;        return NULL;&#xA;&#xA;    picture->format = pix_fmt;&#xA;    picture->width = width;&#xA;    picture->height = height;&#xA;&#xA;    /* allocate the buffers for the frame data */&#xA;    ret = av_frame_get_buffer(picture, 32);&#xA;    if (ret &lt; 0) {&#xA;        fprintf(stderr, "Could not allocate frame data.\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    return picture;&#xA;}&#xA;&#xA;void RTMPWriter::open_video(&#xA;    AVFormatContext *oc, &#xA;    AVCodec *codec, &#xA;    OutputStream *ost, &#xA;    AVDictionary *opt_arg)&#xA;{&#xA;    int ret;&#xA;    AVCodecContext *c = ost->enc;&#xA;    AVDictionary *opt = NULL;&#xA;&#xA;    av_dict_copy(&amp;opt, opt_arg, 0);&#xA;&#xA;    /* open the codec */&#xA;    ret = avcodec_open2(c, codec, &amp;opt);&#xA;    av_dict_free(&amp;opt);&#xA;    if (ret &lt; 0) {&#xA;        OutputDebugString(L"Could not open video codec: %s\n");// , av_err2str(ret));&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* allocate and init a re-usable frame */&#xA;    ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);&#xA;    if (!ost->frame) {&#xA;        OutputDebugString(L"Could not allocate video frame\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* If the output format is not YUV420P, then a temporary YUV420P&#xA;    * picture is needed too. It is then converted to the required&#xA;    * output format. */&#xA;    ost->tmp_frame = NULL;&#xA;    if (c->pix_fmt != AV_PIX_FMT_YUV420P) {&#xA;        ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);&#xA;        if (!ost->tmp_frame) {&#xA;            OutputDebugString(L"Could not allocate temporary picture\n");&#xA;            exit(1);&#xA;        }&#xA;    }&#xA;&#xA;    /* copy the stream parameters to the muxer */&#xA;    ret = avcodec_parameters_from_context(ost->st->codecpar, c);&#xA;    if (ret &lt; 0) {&#xA;        OutputDebugString(L"Could not copy the stream parameters\n");&#xA;        exit(1);&#xA;    }&#xA;}&#xA;&#xA;void RTMPWriter::close_stream(AVFormatContext *oc, OutputStream *ost)&#xA;{&#xA;    avcodec_free_context(&amp;ost->enc);&#xA;    av_frame_free(&amp;ost->frame);&#xA;    av_frame_free(&amp;ost->tmp_frame);&#xA;    sws_freeContext(ost->sws_ctx);&#xA;    swr_free(&amp;ost->swr_ctx);&#xA;}&#xA;&#xA;RTMPWriter::~RTMPWriter()&#xA;{&#xA;    av_write_trailer(oc);&#xA;    /* Close each codec. */&#xA;    if (have_video)&#xA;        close_stream(oc, &amp;video_st);&#xA;    if (have_audio)&#xA;        close_stream(oc, &amp;audio_st);&#xA;&#xA;    if (!(fmt->flags &amp; AVFMT_NOFILE))&#xA;        /* Close the output file. */&#xA;        avio_closep(&amp;oc->pb);&#xA;&#xA;    /* free the stream */&#xA;    avformat_free_context(oc);&#xA;}&#xA;

    &#xA;