Recherche avancée

Médias (91)

Autres articles (103)

  • MediaSPIP 0.1 Beta version

    25 avril 2011, par

    MediaSPIP 0.1 beta is the first version of MediaSPIP proclaimed as "usable".
    The zip file provided here only contains the sources of MediaSPIP in its standalone version.
    To get a working installation, you must manually install all-software dependencies on the server.
    If you want to use this archive for an installation in "farm mode", you will also need to proceed to other manual (...)

  • MediaSPIP version 0.1 Beta

    16 avril 2011, par

    MediaSPIP 0.1 beta est la première version de MediaSPIP décrétée comme "utilisable".
    Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
    Pour avoir une installation fonctionnelle, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
    Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...)

  • Amélioration de la version de base

    13 septembre 2013

    Jolie sélection multiple
    Le plugin Chosen permet d’améliorer l’ergonomie des champs de sélection multiple. Voir les deux images suivantes pour comparer.
    Il suffit pour cela d’activer le plugin Chosen (Configuration générale du site > Gestion des plugins), puis de configurer le plugin (Les squelettes > Chosen) en activant l’utilisation de Chosen dans le site public et en spécifiant les éléments de formulaires à améliorer, par exemple select[multiple] pour les listes à sélection multiple (...)

Sur d’autres sites (10378)

  • Encoiding Video Frame Error with VAAPI encoding [on hold]

    26 octobre 2018, par Tcor5

    I’m attempting to convert one of the FFMPEG Muxing examples (https://ffmpeg.org/doxygen/2.8/muxing_8c.html) to use VAAPI hardware encoding, using https://www.ffmpeg.org/doxygen/trunk/vaapi_transcode_8c-example.html as an example.

    The problem is when I call avcodec_open2, it returns :
    Error encoding video frame : Input/output error

    I believe I have set up all the HW contexts and frames appropriately but it seems the encoding is failing due to an invalid VASurface ID.
    Does anyone have any tips on how to resolve/troubleshoot this ?

    Thanks

    This is the entire shell printout :

    [AVHWDeviceContext @ 0x55acd607dd40] Opened VA display via X11 display :0.
    [AVHWDeviceContext @ 0x55acd607dd40] libva: VA-API version 1.1.0
    [AVHWDeviceContext @ 0x55acd607dd40] libva: va_getDriverName() returns 0
    [AVHWDeviceContext @ 0x55acd607dd40] libva: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
    [AVHWDeviceContext @ 0x55acd607dd40] libva: Found init function __vaDriverInit_1_1
    [AVHWDeviceContext @ 0x55acd607dd40] libva: va_openDriver() returns 0
    [AVHWDeviceContext @ 0x55acd607dd40] Initialised VAAPI connection: version 1.1
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x32315659 -> yuv420p.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x30323449 -> yuv420p.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x3231564e -> nv12.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x32595559 -> yuyv422.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x59565955 -> uyvy422.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x48323234 -> yuv422p.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x58424752 -> rgb0.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x58524742 -> bgr0.
    [AVHWDeviceContext @ 0x55acd607dd40] Format 0x30313050 -> p010le.
    [AVHWDeviceContext @ 0x55acd607dd40] Matched "Intel i965 driver for Intel(R) Skylake - 2.1.0" as known driver "Intel i965 (Quick Sync)".
    [AVHWDeviceContext @ 0x55acd609dc40] Opened VA display via X11 display :0.
    [AVHWDeviceContext @ 0x55acd609dc40] libva: VA-API version 1.1.0
    [AVHWDeviceContext @ 0x55acd609dc40] libva: va_getDriverName() returns 0
    [AVHWDeviceContext @ 0x55acd609dc40] libva: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
    [AVHWDeviceContext @ 0x55acd609dc40] libva: Found init function __vaDriverInit_1_1
    [AVHWDeviceContext @ 0x55acd609dc40] libva: va_openDriver() returns 0
    [AVHWDeviceContext @ 0x55acd609dc40] Initialised VAAPI connection: version 1.1
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x32315659 -> yuv420p.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x30323449 -> yuv420p.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x3231564e -> nv12.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x32595559 -> yuyv422.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x59565955 -> uyvy422.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x48323234 -> yuv422p.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x58424752 -> rgb0.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x58524742 -> bgr0.
    [AVHWDeviceContext @ 0x55acd609dc40] Format 0x30313050 -> p010le.
    [AVHWDeviceContext @ 0x55acd609dc40] Matched "Intel i965 driver for Intel(R) Skylake - 2.1.0" as known driver "Intel i965 (Quick Sync)".
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000000.
    [AVHWFramesContext @ 0x55acd60bbb00] Direct mapping possible.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000001.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000002.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000003.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000004.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000005.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000006.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000007.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000008.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000009.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x400000a.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x400000b.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x400000c.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x400000d.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x400000e.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x400000f.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000010.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000011.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000012.
    [AVHWFramesContext @ 0x55acd60bbb00] Created surface 0x4000013.
    [h264_vaapi @ 0x55acd60ba3c0] Using nv12 as format of reconstructed frames.
    [AVHWFramesContext @ 0x55acd60bcec0] Created surface 0x4000014.
    [AVHWFramesContext @ 0x55acd60bcec0] Direct mapping possible.
    [AVHWFramesContext @ 0x55acd60bcec0] Created surface 0x4000015.
    [AVHWFramesContext @ 0x55acd60bcec0] Created surface 0x4000016.
    [AVHWFramesContext @ 0x55acd60bcec0] Created surface 0x4000017.
    [AVHWFramesContext @ 0x55acd60bcec0] Created surface 0x4000018.
    [AVHWFramesContext @ 0x55acd60bcec0] Created surface 0x4000019.
    [AVHWFramesContext @ 0x55acd60bcec0] Created surface 0x400001a.
    [h264_vaapi @ 0x55acd60ba3c0] Using variable-bitrate = 400000 bps.
    [h264_vaapi @ 0x55acd60ba3c0] Encode frame: 352x288 (0).
    [h264_vaapi @ 0x55acd60ba3c0] Pictures: IDR (0/0)
    [h264_vaapi @ 0x55acd60ba3c0] Issuing encode for pic 0/0 as type IDR.
    [h264_vaapi @ 0x55acd60ba3c0] No reference pictures.
    [h264_vaapi @ 0x55acd60ba3c0] Input surface is 0.
    [h264_vaapi @ 0x55acd60ba3c0] Recon surface is 0x400001a.
    [h264_vaapi @ 0x55acd60ba3c0] Allocated output buffer 0x8000000
    [h264_vaapi @ 0x55acd60ba3c0] Output buffer is 0x8000000.
    [h264_vaapi @ 0x55acd60ba3c0] Param buffer (27) is 0x8000001.
    [h264_vaapi @ 0x55acd60ba3c0] Param buffer (27) is 0x8000002.
    [h264_vaapi @ 0x55acd60ba3c0] Param buffer (27) is 0x8000003.
    [h264_vaapi @ 0x55acd60ba3c0] Param buffer (27) is 0x8000004.
    [h264_vaapi @ 0x55acd60ba3c0] Param buffer (22) is 0x8000005.
    [h264_vaapi @ 0x55acd60ba3c0] Param buffer (23) is 0x8000006.
    [h264_vaapi @ 0x55acd60ba3c0] Packed header buffer (1) is 0x8000007/0x8000008 (376 bits).
    [h264_vaapi @ 0x55acd60ba3c0] Packed header buffer (4) is 0x8000009/0x800000a (944 bits).
    [h264_vaapi @ 0x55acd60ba3c0] Packed header buffer (3) is 0x800000b/0x800000c (72 bits).
    [h264_vaapi @ 0x55acd60ba3c0] Param buffer (24) is 0x800000d.
    [h264_vaapi @ 0x55acd60ba3c0] Failed to begin picture encode issue: 6 (invalid VASurfaceID).
    [h264_vaapi @ 0x55acd60ba3c0] Encode failed: -5.
    Error encoding video frame: Input/output error

    This is the code that i’m using :

    #include
    #include
    #include
    #include

    #include <libavutil></libavutil>avassert.h>
    #include <libavutil></libavutil>channel_layout.h>
    #include <libavutil></libavutil>opt.h>
    #include <libavutil></libavutil>mathematics.h>
    #include <libavutil></libavutil>timestamp.h>
    #include <libavformat></libavformat>avformat.h>
    #include <libswscale></libswscale>swscale.h>
    #include <libswresample></libswresample>swresample.h>

    //HW Encoding
    #include <libavcodec></libavcodec>avcodec.h>
    #include <libavutil></libavutil>pixdesc.h>
    #include <libavutil></libavutil>hwcontext.h>

    #define STREAM_DURATION   10.0
    #define STREAM_FRAME_RATE 25 /* 25 images/s */
    /* default pix_fmt */
    #define STREAM_PIX_FMT    AV_PIX_FMT_VAAPI
    #define SCALE_FLAGS SWS_BICUBIC

    #define LINUX_LIVE_STREAM   // enables linux live stream
    #define MAX_NAME_LEN 256
    static AVBufferRef *hw_device_ctx = NULL; //HW Encoding
    // a wrapper around a single output AVStream
    typedef struct OutputStream {
       AVStream *st;
       AVCodecContext *enc;
       /* pts of the next frame that will be generated */
       int64_t next_pts;
       int samples_count;
       AVFrame *frame;
       AVFrame *tmp_frame;
       float t, tincr, tincr2;
       struct SwsContext *sws_ctx;
       struct SwrContext *swr_ctx;
    } OutputStream;


    static int set_hwframe_ctx(AVCodecContext *c, AVBufferRef *hw_device_ctx)
    {
       AVBufferRef *hw_frames_ref;
       AVHWFramesContext *frames_ctx = NULL;
       int err = 0;
       if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx))) {
           fprintf(stderr, "Failed to create VAAPI frame context.\n");
           return -1;
       }
       frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
       frames_ctx->format    = AV_PIX_FMT_VAAPI;
       frames_ctx->sw_format = AV_PIX_FMT_NV12;
       frames_ctx->width     = 352;
       frames_ctx->height    = 288;
       frames_ctx->initial_pool_size = 20;
       if ((err = av_hwframe_ctx_init(hw_frames_ref)) &lt; 0) {
           fprintf(stderr, "Failed to initialize VAAPI frame context."
                   "Error code: %s\n",av_err2str(err));
           av_buffer_unref(&amp;hw_frames_ref);
           return err;
       }
       c->hw_frames_ctx = av_buffer_ref(hw_frames_ref);
       if (!c->hw_frames_ctx)
           err = AVERROR(ENOMEM);
       return err;
    }

    /* Add an output stream. */
    static void add_stream(OutputStream *ost, AVFormatContext *oc,
                          AVCodec **codec,
                          enum AVCodecID codec_id)
    {
       AVCodecContext *c;
       int i;
       int ret; //HW Encoding
       const char *enc_name = "h264_vaapi";//HW encoding  
       //HW Encoding
       ret = av_hwdevice_ctx_create(&amp;hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0);
       if (ret &lt; 0) {
           fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(ret));
           return -1;
       }  
       *codec = avcodec_find_encoder_by_name(enc_name);//HW encoding codec
       if (!(*codec)) {
           fprintf(stderr, "Could not find encoder.\n");
           exit(1);
       }
       ost->st = avformat_new_stream(oc, NULL);
       if (!ost->st) {
           fprintf(stderr, "Could not allocate stream\n");
           exit(1);
       }
       ost->st->id = oc->nb_streams-1;
       c = avcodec_alloc_context3(*codec);
       if (!c) {
           fprintf(stderr, "Could not alloc an encoding context\n");
           exit(1);
       }
       ost->enc = c;
       switch ((*codec)->type) {

       case AVMEDIA_TYPE_VIDEO:
           c->codec_id = codec_id;
           c->bit_rate = 400000;
           /* Resolution must be a multiple of two. */
           c->width    = 352;
           c->height   = 288;
           ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
           c->time_base       = ost->st->time_base;
           c->gop_size      = 12;
           c->pix_fmt       = STREAM_PIX_FMT;
           if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
               c->max_b_frames = 2;
           }
           if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
               c->mb_decision = 2;
           }
       break;
       default:
           break;
       }
       if ((ret = set_hwframe_ctx(c, hw_device_ctx)) &lt; 0) {
           fprintf(stderr, "Failed to set hwframe context.\n");
           exit(1);
       }
       if (oc->oformat->flags &amp; AVFMT_GLOBALHEADER)
           c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
    }
    /* video output */
    static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
    {
       AVFrame *picture;
       int ret;
       picture = av_frame_alloc();
       if (!picture)
           return NULL;
       picture->format = AV_PIX_FMT_YUV420P;
       picture->width  = width;
       picture->height = height;
       printf ("pix_fmt = %d \n", pix_fmt);
       printf ("picture ->format (pix_fmt) = %d \n", picture->format);
       /* allocate the buffers for the frame data */
       ret = av_frame_get_buffer(picture, 32);
       if (ret &lt; 0) {
           fprintf(stderr, "Could not allocate frame data.\n");
           printf ("error : %d \n", ret);
           exit(1);
       }
       return picture;
    }

    static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
    {
       int ret;
       AVCodecContext *c = ost->enc;
       AVDictionary *opt = NULL;
       av_dict_copy(&amp;opt, opt_arg, 0);
       /* open the codec */
       ret = avcodec_open2(c, codec, &amp;opt);
       av_dict_free(&amp;opt);
       if (ret &lt; 0) {
           fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
           exit(1);
       }
       /* allocate and init a re-usable frame */
       printf ("line #%d\n", __LINE__);
       ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
       if (!ost->frame) {
           fprintf(stderr, "Could not allocate video frame\n");
           exit(1);
       }
       printf ("line #%d\n", __LINE__);
       /* If the output format is not YUV420P, then a temporary YUV420P
        * picture is needed too. It is then converted to the required
        * output format. */
       ost->tmp_frame = NULL;
       if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
           ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
           if (!ost->tmp_frame) {
               fprintf(stderr, "Could not allocate temporary picture\n");
               exit(1);
           }
       }
       /* copy the stream parameters to the muxer */
       ret = avcodec_parameters_from_context(ost->st->codecpar, c);
       if (ret &lt; 0) {
           fprintf(stderr, "Could not copy the stream parameters\n");
           exit(1);
       }
    }
    /* Prepare a dummy image. */
    static void fill_yuv_image(AVFrame *pict, int frame_index,
                              int width, int height)
    {
       int x, y, i;
       i = frame_index;  
       /* Y */
       for (y = 0; y &lt; height; y++)
           for (x = 0; x &lt; width; x++)
               pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
       /* Cb and Cr */
       for (y = 0; y &lt; height / 2; y++) {
           for (x = 0; x &lt; width / 2; x++) {
               pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
           }
       }
    }

    static AVFrame *get_video_frame(OutputStream *ost)
    {
       AVCodecContext *c = ost->enc;
       if (av_compare_ts(ost->next_pts, c->time_base,
                         STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
           return NULL;
       if (av_frame_make_writable(ost->frame) &lt; 0)
           exit(1);
       if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
           /* as we only generate a YUV420P picture, we must convert it
            * to the codec pixel format if needed */
           if (!ost->sws_ctx) {
               ost->sws_ctx = sws_getContext(c->width, c->height,
                                             AV_PIX_FMT_YUV420P,
                                             c->width, c->height,
                                             AV_PIX_FMT_NV12,
                                             SCALE_FLAGS, NULL, NULL, NULL);
               if (!ost->sws_ctx) {
                   fprintf(stderr,
                           "Could not initialize the conversion context\n");
                   exit(1);
               }
           }
           printf ("line #%d\n", __LINE__);
           fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
           printf ("line #%d\n", __LINE__);
           sws_scale(ost->sws_ctx, (const uint8_t * const *) ost->tmp_frame->data,
                     ost->tmp_frame->linesize, 0, c->height, ost->frame->data,
                     ost->frame->linesize);
           printf ("line #%d\n", __LINE__);
       } else {
           fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
       }
       printf ("line #%d\n", __LINE__);
       ost->frame->pts = ost->next_pts++;
       return ost->frame;
    }
    /*
    * encode one video frame and send it to the muxer
    * return 1 when encoding is finished, 0 otherwise
    */
    static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
    {
       int ret;
       AVCodecContext *c;
       AVFrame *frame;
       int got_packet = 0;
       AVPacket pkt = { 0 };
       AVStream *st;
       printf ("line #%d\n", __LINE__);
       c = ost->enc;
       printf ("line #%d\n", __LINE__);
       frame = get_video_frame(ost);
       printf ("line #%d\n", __LINE__);
       av_init_packet(&amp;pkt);
       /* encode the image */
       ret = avcodec_encode_video2(c, &amp;pkt, frame, &amp;got_packet);
       if (ret &lt; 0) {
           fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
           exit(1);
       }
       if (got_packet) {
           av_packet_rescale_ts(&amp;pkt, c->time_base, ost->st->time_base);
           pkt.stream_index = ost->st->index;
           ret = av_interleaved_write_frame(oc, &amp;pkt);
           } else {
                ret = 0;
           }
        if (ret &lt; 0) {
            fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
            exit(1);
        }
       return (frame || got_packet) ? 0 : 1;  
    }

    static void close_stream(AVFormatContext *oc, OutputStream *ost)
    {
       avcodec_free_context(&amp;ost->enc);
       av_frame_free(&amp;ost->frame);
       av_frame_free(&amp;ost->tmp_frame);
       sws_freeContext(ost->sws_ctx);
       swr_free(&amp;ost->swr_ctx);
    }

    /**************************************************************/
    /* media file output */
    int main(int argc, char **argv)
    {
       OutputStream video_st = { 0 }, audio_st = { 0 };
       const char *filename;
       AVOutputFormat *fmt;
       AVFormatContext *oc;
       AVCodec *video_codec, *enc_codec;
       int ret;
       int have_video = 0;
       int encode_video = 0;
       AVDictionary *opt = NULL;
       int i;
       av_log_set_level(AV_LOG_DEBUG); //Debug flag

       if (argc &lt; 2) {
           printf("usage: %s output_file\n"
                  "API example program to output a media file with libavformat.\n"
                  "This program generates a synthetic audio and video stream, encodes and\n"
                  "muxes them into a file named output_file.\n"
                  "The output format is automatically guessed according to the file extension.\n"
                  "Raw images can also be output by using '%%d' in the filename.\n"
                  "\n", argv[0]);
           return 1;
       }

       filename = argv[1];
       for (i = 2; i+1 &lt; argc; i+=2) {
           if (!strcmp(argv[i], "-flags") || !strcmp(argv[i], "-fflags"))
               av_dict_set(&amp;opt, argv[i]+1, argv[i+1], 0);
       }
       //HW Encoding
       ret = av_hwdevice_ctx_create(&amp;hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0);
       if (ret &lt; 0) {
           fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", av_err2str(ret));
           return -1;
       }
       if (!(video_codec = avcodec_find_encoder_by_name("h264_vaapi"))) {
           printf(stderr, "Could not find encoder h264_vaapi");
           ret = -1;
       }
       /* allocate the output media context */
       avformat_alloc_output_context2(&amp;oc, NULL, NULL, filename);
       if (!oc) {
           printf("Could not deduce output format from file extension: using MPEG.\n");
           avformat_alloc_output_context2(&amp;oc, NULL, "mpeg", filename);
       }
       if (!oc)
           return 1;

       fmt = oc->oformat;
       /* Add the audio and video streams using the default format codecs
        * and initialize the codecs. */
       if (fmt->video_codec != AV_CODEC_ID_NONE) {
           add_stream(&amp;video_st, oc, &amp;video_codec, fmt->video_codec);
           have_video = 1;
           encode_video = 1;
       }

       /* Now that all the parameters are set, we can open the audio and
        * video codecs and allocate the necessary encode buffers. */
       if (have_video)
           open_video(oc, video_codec, &amp;video_st, opt);
       av_dump_format(oc, 0, filename, 1);
       /* open the output file, if needed */
       if (!(fmt->flags &amp; AVFMT_NOFILE)) {
           ret = avio_open(&amp;oc->pb, filename, AVIO_FLAG_WRITE);
           if (ret &lt; 0) {
               fprintf(stderr, "Could not open '%s': %s\n", filename,
                       av_err2str(ret));
               return 1;
           }
       }

       /* Write the stream header, if any. */
       ret = avformat_write_header(oc, &amp;opt);
       if (ret &lt; 0) {
           fprintf(stderr, "Error occurred when opening output file: %s\n",
                   av_err2str(ret));
           return 1;
       }
       printf ("line #%d\n", __LINE__);
       while (encode_video) {
           /* select the stream to encode */
           if (encode_video &amp;&amp;
               (av_compare_ts(video_st.next_pts, video_st.enc->time_base,
                                               video_st.next_pts, video_st.enc->time_base) &lt;= 0)) {
               printf ("line #%d\n", __LINE__);
               encode_video = !write_video_frame(oc, &amp;video_st);
               printf ("line #%d\n", __LINE__);
           }
       }
       av_write_trailer(oc);
       /* Close each codec. */
       if (have_video)
           close_stream(oc, &amp;video_st);
       if (!(fmt->flags &amp; AVFMT_NOFILE))
           /* Close the output file. */
           avio_closep(&amp;oc->pb);
       /* free the stream */
       avformat_free_context(oc);
       av_buffer_unref(&amp;hw_device_ctx);
       return 0;
    }
  • ffmpeg live stream recording stops on stream interrupt

    3 septembre 2018, par Anton Antonov

    I have to record live stream with ffmmpeg. It is easy. Here is my command line :

    ffmpeg -i /source/address> -s 320x240 -r 25 -c:v libx264 -g 125 -vb 300000 -maxrate 400000 -bufsize 600000 -profile:v baseline -deinterlace -preset veryfast -ac 2 -ar 48000 -c:a libfdk_aac -b:a 64000 -f mp4 to/dst/file>

    But my task is to make ffmpeg to stop and exit when live stream is stopped.

    Is there easy way to do this ?

  • FFMPEG libav gdigrab capturing with wrong colors

    7 mars 2018, par user1496491

    I’m capturing screen with code below, and it gets me the picture with wrong colors.

    Screenshot

    The picture on left is raw data which I assumed in ARGB the picture in right is encoded as YUV. I’ve tried different formats, the pictures slighly changing, but it’s never looks ow it should be. In what format gdigrab gives its output ? What’s the right way to encode it ?

    #include "MainWindow.h"

    #include <qguiapplication>
    #include <qlabel>
    #include <qscreen>
    #include <qtimer>
    #include <qlayout>
    #include <qimage>
    #include <qtconcurrent></qtconcurrent>QtConcurrent>
    #include <qthreadpool>

    #include "ScreenCapture.h"

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    {
       resize(800, 600);

       label = new QLabel();
       label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

       auto layout = new QHBoxLayout();
       layout->addWidget(label);

       auto widget = new QWidget();
       widget->setLayout(layout);
       setCentralWidget(widget);

       init();
       initOutFile();
       collectFrame();
    }

    MainWindow::~MainWindow()
    {
       avformat_close_input(&amp;inputFormatContext);
       avformat_free_context(inputFormatContext);

       QThreadPool::globalInstance()->waitForDone();
    }

    void MainWindow::init()
    {

       av_register_all();
       avcodec_register_all();
       avdevice_register_all();

       auto screen = QGuiApplication::screens()[1];
       QRect geometry = screen->geometry();

       inputFormatContext = avformat_alloc_context();

       AVDictionary* options = NULL;
       av_dict_set(&amp;options, "framerate", "30", NULL);
       av_dict_set(&amp;options, "offset_x", QString::number(geometry.x()).toLatin1().data(), NULL);
       av_dict_set(&amp;options, "offset_y", QString::number(geometry.y()).toLatin1().data(), NULL);
       av_dict_set(&amp;options, "preset", "ultrafast", NULL);
       av_dict_set(&amp;options, "probesize", "10MB", NULL);
       av_dict_set(&amp;options, "pix_fmt", "yuv420p", NULL);
       av_dict_set(&amp;options, "video_size", QString(QString::number(geometry.width()) + "x" + QString::number(geometry.height())).toLatin1().data(), NULL);

       AVInputFormat* inputFormat = av_find_input_format("gdigrab");
       avformat_open_input(&amp;inputFormatContext, "desktop", inputFormat, &amp;options);

    //    AVDictionary* options = NULL;
    //    av_dict_set(&amp;options, "framerate", "30", NULL);
    //    av_dict_set(&amp;options, "preset", "ultrafast", NULL);
    //    av_dict_set(&amp;options, "vcodec", "h264", NULL);
    //    av_dict_set(&amp;options, "s", "1280x720", NULL);
    //    av_dict_set(&amp;options, "crf", "0", NULL);
    //    av_dict_set(&amp;options, "rtbufsize", "100M", NULL);

    //    AVInputFormat *format = av_find_input_format("dshow");
    //    avformat_open_input(&amp;inputFormatContext, "video=screen-capture-recorder", format, &amp;options);

       av_dict_free(&amp;options);
       avformat_find_stream_info(inputFormatContext, NULL);

       videoStreamIndex = av_find_best_stream(inputFormatContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);

       inputCodec = avcodec_find_decoder(inputFormatContext->streams[videoStreamIndex]->codecpar->codec_id);
       if(!inputCodec) qDebug() &lt;&lt; "Не найден кодек входящего потока!";

       inputCodecContext = avcodec_alloc_context3(inputCodec);
       inputCodecContext->codec_id = inputCodec->id;

       avcodec_parameters_to_context(inputCodecContext, inputFormatContext->streams[videoStreamIndex]->codecpar);

       if(avcodec_open2(inputCodecContext, inputCodec, NULL)) qDebug() &lt;&lt; "Не удалось открыть входной кодек!";
    }

    void MainWindow::initOutFile()
    {
       const char* filename = "C:/Temp/output.mp4";

       if(avformat_alloc_output_context2(&amp;outFormatContext, NULL, NULL, filename) &lt; 0) qDebug() &lt;&lt; "Не удалось создать выходной контекст!";

       outCodec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
       if(!outCodec) qDebug() &lt;&lt; "Не удалось найти кодек!";

       videoStream = avformat_new_stream(outFormatContext, outCodec);
       videoStream->time_base = {1, 30};

       const AVPixelFormat* pixelFormat = outCodec->pix_fmts;
       while (*pixelFormat != AV_PIX_FMT_NONE)
       {
           qDebug() &lt;&lt; "OUT_FORMAT" &lt;&lt; av_get_pix_fmt_name(*pixelFormat);
           ++pixelFormat;
       }

       outCodecContext = videoStream->codec;
       outCodecContext->bit_rate = 400000;
       outCodecContext->width = inputCodecContext->width;
       outCodecContext->height = inputCodecContext->height;
       outCodecContext->time_base = videoStream->time_base;
       outCodecContext->gop_size = 10;
       outCodecContext->max_b_frames = 1;
       outCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;

       if (outFormatContext->oformat->flags &amp; AVFMT_GLOBALHEADER) outCodecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;

       if(avcodec_open2(outCodecContext, outCodec, NULL)) qDebug() &lt;&lt; "Не удалось открыть выходной кодек!";

       swsContext = sws_getContext(inputCodecContext->width,
                                   inputCodecContext->height,
    //                                inputCodecContext->pix_fmt,
                                   AV_PIX_FMT_ABGR,
                                   outCodecContext->width,
                                   outCodecContext->height,
                                   outCodecContext->pix_fmt,
                                   SWS_BICUBIC, NULL, NULL, NULL);

       if(avio_open(&amp;outFormatContext->pb, filename, AVIO_FLAG_WRITE) &lt; 0) qDebug() &lt;&lt; "Не удалось открыть файл!";
       if(avformat_write_header(outFormatContext, NULL) &lt; 0) qDebug() &lt;&lt; "Не удалось записать заголовок!";
    }

    void MainWindow::collectFrame()
    {
       AVFrame* inFrame = av_frame_alloc();
       inFrame->format = inputCodecContext->pix_fmt;
       inFrame->width = inputCodecContext->width;
       inFrame->height = inputCodecContext->height;

       int size = av_image_alloc(inFrame->data, inFrame->linesize, inFrame->width, inFrame->height, inputCodecContext->pix_fmt, 1);
       qDebug() &lt;&lt; size;

       AVFrame* outFrame = av_frame_alloc();
       outFrame->format = outCodecContext->pix_fmt;
       outFrame->width = outCodecContext->width;
       outFrame->height = outCodecContext->height;

       qDebug() &lt;&lt; av_image_alloc(outFrame->data, outFrame->linesize, outFrame->width, outFrame->height, outCodecContext->pix_fmt, 1);

       AVPacket packet;
       av_init_packet(&amp;packet);

       av_read_frame(inputFormatContext, &amp;packet);
    //    while(av_read_frame(inputFormatContext, &amp;packet) >= 0)
    //    {
           if(packet.stream_index == videoStream->index)
           {

               memcpy(inFrame->data[0], packet.data, size);

               sws_scale(swsContext, inFrame->data, inFrame->linesize, 0, inputCodecContext->height, outFrame->data, outFrame->linesize);

               QImage image(inFrame->data[0], inFrame->width, inFrame->height, QImage::Format_ARGB32);
               label->setPixmap(QPixmap::fromImage(image).scaled(label->size(), Qt::KeepAspectRatio));

               AVPacket outPacket;
               av_init_packet(&amp;outPacket);

               int encodeResult = avcodec_receive_packet(outCodecContext, &amp;outPacket);
               while(encodeResult == AVERROR(EAGAIN))
               {
                   if(avcodec_send_frame(outCodecContext, outFrame)) qDebug() &lt;&lt; "Ошибка отправки фрейма на кодирование!";

                   encodeResult = avcodec_receive_packet(outCodecContext, &amp;outPacket);
               }
               if(encodeResult != 0) qDebug() &lt;&lt; "Ошибка во время кодирования!" &lt;&lt; encodeResult;

               if(outPacket.pts != AV_NOPTS_VALUE) outPacket.pts = av_rescale_q(outPacket.pts, videoStream->codec->time_base, videoStream->time_base);
               if(outPacket.dts != AV_NOPTS_VALUE) outPacket.dts = av_rescale_q(outPacket.dts, videoStream->codec->time_base, videoStream->time_base);

               av_write_frame(outFormatContext, &amp;outPacket);

               av_packet_unref(&amp;outPacket);
           }
    //    }

       av_packet_unref(&amp;packet);

       av_write_trailer(outFormatContext);
       avio_close(outFormatContext->pb);
    }
    </qthreadpool></qimage></qlayout></qtimer></qscreen></qlabel></qguiapplication>