Recherche avancée

Médias (1)

Mot : - Tags -/Christian Nold

Autres articles (71)

  • 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.

  • Modifier la date de publication

    21 juin 2013, par

    Comment changer la date de publication d’un média ?
    Il faut au préalable rajouter un champ "Date de publication" dans le masque de formulaire adéquat :
    Administrer > Configuration des masques de formulaires > Sélectionner "Un média"
    Dans la rubrique "Champs à ajouter, cocher "Date de publication "
    Cliquer en bas de la page sur Enregistrer

  • 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 ;

Sur d’autres sites (10876)

  • Transcode of H.264 to VP8 using libav* has incorrect frame rate

    17 avril 2014, par Kevin Watson

    I’ve so far failed to get the correct output frame rate when transcoding H.264 to VP8 with the libav* libraries. I created a functioning encode of Sintel.2010.720p.mkv as WebM (VP8/Vorbis) using a modification of the transcoding.c example in the FFmpeg source. Unfortunately the resulting file is 48 fps unlike the 24 fps of the original and the output of the ffmpeg command I’m trying to mimic.

    I noticed ffprobe produces a tbc of double the fps for this and other H.264 videos, while the tbc of the resulting VP8 stream produced by the ffmpeg command is the default 1000. The stock transcoding.c example copies the time base of the decoder to the encoder AVCodecContext, which is 1/48. Running the ffmpeg command through gdb it looks like the time base of the AVCodecContext is set to 1/24, but making that change alone only causes the resulting video to be slowed to twice the duration at 24 fps.

    I can create a usable video, but the frame rate doubles. When the output frame rate is the correct 24 fps, the video is smooth but slowed to half speed.

    Here is my modification of the example.

    /*
     * Copyright (c) 2010 Nicolas George
     * Copyright (c) 2011 Stefano Sabatini
     * Copyright (c) 2014 Andrey Utkin
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */

    /**
     * @file
     * API example for demuxing, decoding, filtering, encoding and muxing
     * @example doc/examples/transcoding.c
     */

    #include <libavcodec></libavcodec>avcodec.h>
    #include <libavformat></libavformat>avformat.h>
    #include <libavfilter></libavfilter>avfiltergraph.h>
    #include <libavfilter></libavfilter>avcodec.h>
    #include <libavfilter></libavfilter>buffersink.h>
    #include <libavfilter></libavfilter>buffersrc.h>
    #include <libavutil></libavutil>opt.h>
    #include <libavutil></libavutil>pixdesc.h>

    #define STATS_LOG "stats.log"

    static AVFormatContext *ifmt_ctx;
    static AVFormatContext *ofmt_ctx;
    typedef struct FilteringContext {
      AVFilterContext *buffersink_ctx;
      AVFilterContext *buffersrc_ctx;
      AVFilterGraph *filter_graph;
    } FilteringContext;
    static FilteringContext *filter_ctx;

    static int open_input_file(const char *filename) {
      int ret;
      unsigned int i;

      ifmt_ctx = NULL;
      if ((ret = avformat_open_input(&amp;ifmt_ctx, filename, NULL, NULL)) &lt; 0) {
    av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
    return ret;
      }

      if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) &lt; 0) {
    av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
    return ret;
      }

      for (i = 0; i &lt; ifmt_ctx->nb_streams; i++) {
    AVStream *stream;
    AVCodecContext *codec_ctx;
    stream = ifmt_ctx->streams[i];
    codec_ctx = stream->codec;
    /* Reencode video &amp; audio and remux subtitles etc. */
    if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
        || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
      /* Open decoder */
      ret = avcodec_open2(codec_ctx,
                  avcodec_find_decoder(codec_ctx->codec_id), NULL);
      if (ret &lt; 0) {
        av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
        return ret;
      }
    }
      }

      av_dump_format(ifmt_ctx, 0, filename, 0);
      return 0;
    }

    static int init_output_context(char* filename) {
      int ret;
      ofmt_ctx = NULL;

      avformat_alloc_output_context2(&amp;ofmt_ctx, NULL, NULL, filename);
      if (!ofmt_ctx) {
    av_log(NULL, AV_LOG_ERROR, "Could not create output context\n");
    return AVERROR_UNKNOWN;
      }

      return 0;
    }

    static int init_webm_encoders(int audioBitRate, int crf, int videoMaxBitRate, int threads,
                  char* quality, int speed, int pass, char* stats) {
      AVStream *out_stream;
      AVStream *in_stream;
      AVCodecContext *dec_ctx, *enc_ctx;
      AVCodec *encoder;
      int ret;
      unsigned int i;

      for (i = 0; i &lt; ifmt_ctx->nb_streams; i++) {
    in_stream = ifmt_ctx->streams[i];
    dec_ctx = in_stream->codec;
    if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO || dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {

      AVDictionary *opts = NULL;
      if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
        encoder = avcodec_find_encoder(AV_CODEC_ID_VP8);
        out_stream = avformat_new_stream(ofmt_ctx, encoder);
        if (!out_stream) {
          av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
          return AVERROR_UNKNOWN;
        }

        enc_ctx = out_stream->codec;
        enc_ctx->height = dec_ctx->height;
        enc_ctx->width = dec_ctx->width;
        enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
        /* take first format from list of supported formats */
        enc_ctx->pix_fmt = encoder->pix_fmts[0];
        /* video time_base can be set to whatever is handy and supported by encoder */
        enc_ctx->time_base = dec_ctx->time_base;
        /* enc_ctx->time_base.num = 1; */
        /* enc_ctx->time_base.den = 24; */

        enc_ctx->bit_rate = videoMaxBitRate;
        enc_ctx->thread_count = threads;
        switch (pass) {
        case 1:
          enc_ctx->flags |= CODEC_FLAG_PASS1;
          break;
        case 2:
          enc_ctx->flags |= CODEC_FLAG_PASS2;
          if (stats) {
        enc_ctx->stats_in = stats;
          }
          break;
        }

        char crfString[3];
        snprintf(crfString, 3, "%d", crf);
        av_dict_set(&amp;opts, "crf", crfString, 0);
        av_dict_set(&amp;opts, "quality", quality, 0);
        char speedString[3];
        snprintf(speedString, 3, "%d", speed);
        av_dict_set(&amp;opts, "speed", speedString, 0);
      } else {
        encoder = avcodec_find_encoder(AV_CODEC_ID_VORBIS);
        out_stream = avformat_new_stream(ofmt_ctx, encoder);
        if (!out_stream) {
          av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
          return AVERROR_UNKNOWN;
        }

        /* in_stream = ifmt_ctx->streams[i]; */
        /* dec_ctx = in_stream->codec; */
        enc_ctx = out_stream->codec;
        /* encoder = out_stream->codec->codec; */

        enc_ctx->sample_rate = dec_ctx->sample_rate;
        enc_ctx->channel_layout = dec_ctx->channel_layout;
        enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
        /* take first format from list of supported formats */
        enc_ctx->sample_fmt = encoder->sample_fmts[0];
        enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
        enc_ctx->bit_rate = audioBitRate;
      }

      /* Open codec with the set options */
      ret = avcodec_open2(enc_ctx, encoder, &amp;opts);
      if (ret &lt; 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
        return ret;
      }
      int unused = av_dict_count(opts);
      if (unused > 0) {
        av_log(NULL, AV_LOG_WARNING, "%d unused options\n", unused);
      }
      /* } else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) { */
    } else {
      av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
      return AVERROR_INVALIDDATA;
    } /* else { */
      /*   /\* if this stream must be remuxed *\/ */
      /*   ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec, */
      /*                ifmt_ctx->streams[i]->codec); */
      /*   if (ret &lt; 0) { */
      /*   av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n"); */
      /*   return ret; */
      /*   } */
      /* } */

    if (ofmt_ctx->oformat->flags &amp; AVFMT_GLOBALHEADER)
      enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
      }

      return 0;
    }

    static int open_output_file(const char *filename) {
      int ret;

      av_dump_format(ofmt_ctx, 0, filename, 1);

      if (!(ofmt_ctx->oformat->flags &amp; AVFMT_NOFILE)) {
    ret = avio_open(&amp;ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Could not open output file &#39;%s&#39;", filename);
      return ret;
    }
      }

      /* init muxer, write output file header */
      ret = avformat_write_header(ofmt_ctx, NULL);
      if (ret &lt; 0) {
    av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
    return ret;
      }

      return 0;
    }

    static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
               AVCodecContext *enc_ctx, const char *filter_spec) {
      char args[512];
      int ret = 0;
      AVFilter *buffersrc = NULL;
      AVFilter *buffersink = NULL;
      AVFilterContext *buffersrc_ctx = NULL;
      AVFilterContext *buffersink_ctx = NULL;
      AVFilterInOut *outputs = avfilter_inout_alloc();
      AVFilterInOut *inputs  = avfilter_inout_alloc();
      AVFilterGraph *filter_graph = avfilter_graph_alloc();

      if (!outputs || !inputs || !filter_graph) {
    ret = AVERROR(ENOMEM);
    goto end;
      }

      if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
    buffersrc = avfilter_get_by_name("buffer");
    buffersink = avfilter_get_by_name("buffersink");
    if (!buffersrc || !buffersink) {
      av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
      ret = AVERROR_UNKNOWN;
      goto end;
    }

    snprintf(args, sizeof(args),
         "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
         dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
         dec_ctx->time_base.num, dec_ctx->time_base.den,
         dec_ctx->sample_aspect_ratio.num,
         dec_ctx->sample_aspect_ratio.den);

    ret = avfilter_graph_create_filter(&amp;buffersrc_ctx, buffersrc, "in",
                       args, NULL, filter_graph);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
      goto end;
    }

    ret = avfilter_graph_create_filter(&amp;buffersink_ctx, buffersink, "out",
                       NULL, NULL, filter_graph);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
      goto end;
    }

    ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
                 (uint8_t*)&amp;enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),
                 AV_OPT_SEARCH_CHILDREN);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
      goto end;
    }
      } else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
    buffersrc = avfilter_get_by_name("abuffer");
    buffersink = avfilter_get_by_name("abuffersink");
    if (!buffersrc || !buffersink) {
      av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
      ret = AVERROR_UNKNOWN;
      goto end;
    }

    if (!dec_ctx->channel_layout)
      dec_ctx->channel_layout =
        av_get_default_channel_layout(dec_ctx->channels);
    snprintf(args, sizeof(args),
         "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
         dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
         av_get_sample_fmt_name(dec_ctx->sample_fmt),
         dec_ctx->channel_layout);
    ret = avfilter_graph_create_filter(&amp;buffersrc_ctx, buffersrc, "in",
                       args, NULL, filter_graph);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
      goto end;
    }

    ret = avfilter_graph_create_filter(&amp;buffersink_ctx, buffersink, "out",
                       NULL, NULL, filter_graph);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
      goto end;
    }

    ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",
                 (uint8_t*)&amp;enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),
                 AV_OPT_SEARCH_CHILDREN);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
      goto end;
    }

    ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
                 (uint8_t*)&amp;enc_ctx->channel_layout,
                 sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
      goto end;
    }

    ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
                 (uint8_t*)&amp;enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate),
                 AV_OPT_SEARCH_CHILDREN);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
      goto end;
    }
      } else {
    ret = AVERROR_UNKNOWN;
    goto end;
      }

      /* Endpoints for the filter graph. */
      outputs->name       = av_strdup("in");
      outputs->filter_ctx = buffersrc_ctx;
      outputs->pad_idx    = 0;
      outputs->next       = NULL;

      inputs->name       = av_strdup("out");
      inputs->filter_ctx = buffersink_ctx;
      inputs->pad_idx    = 0;
      inputs->next       = NULL;

      if (!outputs->name || !inputs->name) {
    ret = AVERROR(ENOMEM);
    goto end;
      }

      if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,
                      &amp;inputs, &amp;outputs, NULL)) &lt; 0)
    goto end;

      if ((ret = avfilter_graph_config(filter_graph, NULL)) &lt; 0)
    goto end;

      /* Fill FilteringContext */
      fctx->buffersrc_ctx = buffersrc_ctx;
      fctx->buffersink_ctx = buffersink_ctx;
      fctx->filter_graph = filter_graph;

     end:
      avfilter_inout_free(&amp;inputs);
      avfilter_inout_free(&amp;outputs);

      return ret;
    }

    static int init_filters(enum AVCodecID audioCodec) {
      const char *filter_spec;
      unsigned int i;
      int ret;
      filter_ctx = av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));
      if (!filter_ctx)
    return AVERROR(ENOMEM);

      for (i = 0; i &lt; ifmt_ctx->nb_streams; i++) {
    filter_ctx[i].buffersrc_ctx  = NULL;
    filter_ctx[i].buffersink_ctx = NULL;
    filter_ctx[i].filter_graph   = NULL;
    /* Skip streams that are neither audio nor video */
    if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO
          || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
      continue;


    if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
      filter_spec = "null"; /* passthrough (dummy) filter for video */
    else
      /* TODO: make this more general */
      if (audioCodec == AV_CODEC_ID_VORBIS) {
        filter_spec = "asetnsamples=n=64";
      } else {
        /* filter_spec = "null"; /\* passthrough (dummy) filter for audio *\/ */
        filter_spec = "fps=24";
        /* filter_spec = "settb=expr=1/24"; */
      }
    ret = init_filter(&amp;filter_ctx[i], ifmt_ctx->streams[i]->codec,
              ofmt_ctx->streams[i]->codec, filter_spec);
    if (ret)
      return ret;
      }
      return 0;
    }

    static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) {
      int ret;
      int got_frame_local;
      AVPacket enc_pkt;
      int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
    (ifmt_ctx->streams[stream_index]->codec->codec_type ==
     AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;

      if (!got_frame)
    got_frame = &amp;got_frame_local;

      /* av_log(NULL, AV_LOG_INFO, "Encoding frame\n"); */
      /* encode filtered frame */
      enc_pkt.data = NULL;
      enc_pkt.size = 0;
      av_init_packet(&amp;enc_pkt);
      ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &amp;enc_pkt,
             filt_frame, got_frame);
      av_frame_free(&amp;filt_frame);
      if (ret &lt; 0)
    return ret;
      if (!(*got_frame))
    return 0;

      /* prepare packet for muxing */
      enc_pkt.stream_index = stream_index;
      enc_pkt.dts = av_rescale_q_rnd(enc_pkt.dts,
                     ofmt_ctx->streams[stream_index]->codec->time_base,
                     ofmt_ctx->streams[stream_index]->time_base,
                     AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
      enc_pkt.pts = av_rescale_q_rnd(enc_pkt.pts,
                     ofmt_ctx->streams[stream_index]->codec->time_base,
                     ofmt_ctx->streams[stream_index]->time_base,
                     AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
      enc_pkt.duration = av_rescale_q(enc_pkt.duration,
                      ofmt_ctx->streams[stream_index]->codec->time_base,
                      ofmt_ctx->streams[stream_index]->time_base);

      /* av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); */
      /* mux encoded frame */
      ret = av_interleaved_write_frame(ofmt_ctx, &amp;enc_pkt);
      return ret;
    }

    static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) {
      int ret;
      AVFrame *filt_frame;

      /* av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n"); */
      /* push the decoded frame into the filtergraph */
      ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
                     frame, 0);
      if (ret &lt; 0) {
    av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
    return ret;
      }

      /* pull filtered frames from the filtergraph */
      while (1) {
    filt_frame = av_frame_alloc();
    if (!filt_frame) {
      ret = AVERROR(ENOMEM);
      break;
    }
    /* av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n"); */
    ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
                      filt_frame);
    if (ret &lt; 0) {
      /* if no more frames for output - returns AVERROR(EAGAIN)
       * if flushed and no more frames for output - returns AVERROR_EOF
       * rewrite retcode to 0 to show it as normal procedure completion
       */
      if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
        ret = 0;
      av_frame_free(&amp;filt_frame);
      break;
    }

    filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
    ret = encode_write_frame(filt_frame, stream_index, NULL);
    if (ret &lt; 0)
      break;
      }

      return ret;
    }

    static int flush_encoder(unsigned int stream_index) {
      int ret;
      int got_frame;

      if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &amp;
        CODEC_CAP_DELAY))
    return 0;

      while (1) {
    av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
    ret = encode_write_frame(NULL, stream_index, &amp;got_frame);
    if (ret &lt; 0)
      break;
    if (!got_frame)
      return 0;
      }
      return ret;
    }

    static int transcode() {
      int ret;
      AVPacket packet = { .data = NULL, .size = 0 };
      AVFrame *frame = NULL;
      enum AVMediaType type;
      unsigned int stream_index;
      unsigned int i;
      int got_frame;
      int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);

      /* read all packets */
      while (1) {
    if ((ret = av_read_frame(ifmt_ctx, &amp;packet)) &lt; 0)
      break;
    stream_index = packet.stream_index;
    type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
    av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
       stream_index);

    if (filter_ctx[stream_index].filter_graph) {
      av_log(NULL, AV_LOG_DEBUG, "Going to reencode&amp;filter the frame\n");
      frame = av_frame_alloc();
      if (!frame) {
        ret = AVERROR(ENOMEM);
        break;
      }
      packet.dts = av_rescale_q_rnd(packet.dts,
                    ifmt_ctx->streams[stream_index]->time_base,
                    ifmt_ctx->streams[stream_index]->codec->time_base,
                    AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
      packet.pts = av_rescale_q_rnd(packet.pts,
                    ifmt_ctx->streams[stream_index]->time_base,
                    ifmt_ctx->streams[stream_index]->codec->time_base,
                    AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
      dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
        avcodec_decode_audio4;
      ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
             &amp;got_frame, &amp;packet);
      if (ret &lt; 0) {
        av_frame_free(&amp;frame);
        av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
        break;
      }

      if (got_frame) {
        frame->pts = av_frame_get_best_effort_timestamp(frame);
        ret = filter_encode_write_frame(frame, stream_index);
        av_frame_free(&amp;frame);
        if (ret &lt; 0)
          goto end;
      } else {
        av_frame_free(&amp;frame);
      }
    } else {
      /* remux this frame without reencoding */
      packet.dts = av_rescale_q_rnd(packet.dts,
                    ifmt_ctx->streams[stream_index]->time_base,
                    ofmt_ctx->streams[stream_index]->time_base,
                    AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
      packet.pts = av_rescale_q_rnd(packet.pts,
                    ifmt_ctx->streams[stream_index]->time_base,
                    ofmt_ctx->streams[stream_index]->time_base,
                    AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);

      ret = av_interleaved_write_frame(ofmt_ctx, &amp;packet);
      if (ret &lt; 0)
        goto end;
    }
    av_free_packet(&amp;packet);
      }

      /* flush filters and encoders */
      for (i = 0; i &lt; ifmt_ctx->nb_streams; i++) {
    /* flush filter */
    if (!filter_ctx[i].filter_graph)
      continue;
    ret = filter_encode_write_frame(NULL, i);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n");
      goto end;
    }

    /* flush encoder */
    ret = flush_encoder(i);
    if (ret &lt; 0) {
      av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
      goto end;
    }
      }

      av_write_trailer(ofmt_ctx);

      // Retrieve and store the first instance of codec statistics
      // TODO: less naive, deal with multiple instances of statistics
      for (i = 0; i &lt; ofmt_ctx->nb_streams; i++) {
    AVCodecContext* codec = ofmt_ctx->streams[i]->codec;
    if ((codec->flags &amp; CODEC_FLAG_PASS1) &amp;&amp; (codec->stats_out)){
      FILE* logfile = fopen(STATS_LOG, "wb");
      fprintf(logfile, "%s", codec->stats_out);
      if (fclose(logfile) &lt; 0) {
        av_log(NULL, AV_LOG_ERROR, "Error closing log file.\n");
      }
      break;
    }
      }

      av_log(NULL, AV_LOG_INFO, "output duration = %" PRId64 "\n", ofmt_ctx->duration);

     end:
      av_free_packet(&amp;packet);
      av_frame_free(&amp;frame);
      for (i = 0; i &lt; ifmt_ctx->nb_streams; i++) {
    avcodec_close(ifmt_ctx->streams[i]->codec);
    if (ofmt_ctx &amp;&amp; ofmt_ctx->nb_streams > i &amp;&amp; ofmt_ctx->streams[i] &amp;&amp; ofmt_ctx->streams[i]->codec)
      avcodec_close(ofmt_ctx->streams[i]->codec);
    if (filter_ctx &amp;&amp; filter_ctx[i].filter_graph)
      avfilter_graph_free(&amp;filter_ctx[i].filter_graph);
      }
      av_free(filter_ctx);
      avformat_close_input(&amp;ifmt_ctx);
      if (ofmt_ctx &amp;&amp; !(ofmt_ctx->oformat->flags &amp; AVFMT_NOFILE))
    avio_close(ofmt_ctx->pb);
      avformat_free_context(ofmt_ctx);

      if (ret &lt; 0)
    av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));

      return ret ? 1 : 0;
    }

    int TranscodeToWebM(char* inputPath, char* outputPath, int audioBitRate, int crf, int videoMaxBitRate, int threads,
            char* quality, int speed) {
      int ret;
      unsigned int pass;
      char* stats = NULL;

      av_register_all();
      avfilter_register_all();

      for (pass = 1; pass &lt;= 2; pass++) {
    if ((ret = open_input_file(inputPath)) &lt; 0)
      goto end;

    if ((ret = init_output_context(outputPath)) &lt; 0)
      goto end;

    if (pass == 2) {
      size_t stats_length;
      if (cmdutils_read_file(STATS_LOG, &amp;stats, &amp;stats_length) &lt; 0) {
        av_log(NULL, AV_LOG_ERROR, "Error reading stats file.\n");
        break;
      }
    }

    if ((ret = init_webm_encoders(audioBitRate, crf, videoMaxBitRate, threads, quality, speed, pass, stats)) &lt; 0)
      goto end;

    if ((ret = open_output_file(outputPath)) &lt; 0)
      goto end;

    if ((ret = init_filters(AV_CODEC_ID_VORBIS)) &lt; 0)
      goto end;

    if ((ret = transcode()) &lt; 0)
      goto end;
      }

      if (remove(STATS_LOG) != 0) {
    av_log(NULL, AV_LOG_ERROR, "Failed to remove %s\n", STATS_LOG);
      }

     end:
      if (ret &lt; 0) {
    av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
    return ret;
      }

      return 0;
    }

    Here is the output from the ffmpeg command I am trying to mimic.

    ffmpeg version N-62301-g59a5384 Copyright (c) 2000-2014 the FFmpeg developers
     built on Apr  9 2014 09:58:44 with gcc 4.8.2 (GCC) 20140206 (prerelease)
     configuration: --prefix=/opt/ffmpeg --extra-cflags=-I/opt/x264/include --extra-ldflags=-L/opt/x264/lib --extra-libs=-ldl --enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264
     libavutil      52. 75.100 / 52. 75.100
     libavcodec     55. 58.103 / 55. 58.103
     libavformat    55. 36.102 / 55. 36.102
     libavdevice    55. 11.100 / 55. 11.100
     libavfilter     4.  3.100 /  4.  3.100
     libswscale      2.  6.100 /  2.  6.100
     libswresample   0. 18.100 /  0. 18.100
     libpostproc    52.  3.100 / 52.  3.100
    Input #0, matroska,webm, from &#39;/mnt/scratch/test_source/Sintel.2010.720p.mkv&#39;:
     Metadata:
    encoder         : libebml v1.0.0 + libmatroska v1.0.0
    creation_time   : 2011-04-24 17:20:33
     Duration: 00:14:48.03, start: 0.000000, bitrate: 6071 kb/s
    Chapter #0.0: start 0.000000, end 103.125000
    Metadata:
     title           : Chapter 01
    Chapter #0.1: start 103.125000, end 148.667000
    Metadata:
     title           : Chapter 02
    Chapter #0.2: start 148.667000, end 349.792000
    Metadata:
     title           : Chapter 03
    Chapter #0.3: start 349.792000, end 437.208000
    Metadata:
     title           : Chapter 04
    Chapter #0.4: start 437.208000, end 472.075000
    Metadata:
     title           : Chapter 05
    Chapter #0.5: start 472.075000, end 678.833000
    Metadata:
     title           : Chapter 06
    Chapter #0.6: start 678.833000, end 744.083000
    Metadata:
     title           : Chapter 07
    Chapter #0.7: start 744.083000, end 888.032000
    Metadata:
     title           : Chapter 08
    Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709), 1280x544, SAR 1:1 DAR 40:17, 24 fps, 24 tbr, 1k tbn, 48 tbc
    Stream #0:1(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 640 kb/s
    Metadata:
     title           : AC3 5.1 @ 640 Kbps
    Stream #0:2(ger): Subtitle: subrip
    Stream #0:3(eng): Subtitle: subrip
    Stream #0:4(spa): Subtitle: subrip
    Stream #0:5(fre): Subtitle: subrip
    Stream #0:6(ita): Subtitle: subrip
    Stream #0:7(dut): Subtitle: subrip
    Stream #0:8(pol): Subtitle: subrip
    Stream #0:9(por): Subtitle: subrip
    Stream #0:10(rus): Subtitle: subrip
    Stream #0:11(vie): Subtitle: subrip
    [libvpx @ 0x24b74c0] v1.3.0
    Output #0, webm, to &#39;/mnt/scratch/test_out/Sintel.2010.720p.script.webm&#39;:
     Metadata:
    encoder         : Lavf55.36.102
    Chapter #0.0: start 0.000000, end 103.125000
    Metadata:
     title           : Chapter 01
    Chapter #0.1: start 103.125000, end 148.667000
    Metadata:
     title           : Chapter 02
    Chapter #0.2: start 148.667000, end 349.792000
    Metadata:
     title           : Chapter 03
    Chapter #0.3: start 349.792000, end 437.208000
    Metadata:
     title           : Chapter 04
    Chapter #0.4: start 437.208000, end 472.075000
    Metadata:
     title           : Chapter 05
    Chapter #0.5: start 472.075000, end 678.833000
    Metadata:
     title           : Chapter 06
    Chapter #0.6: start 678.833000, end 744.083000
    Metadata:
     title           : Chapter 07
    Chapter #0.7: start 744.083000, end 888.032000
    Metadata:
     title           : Chapter 08
    Stream #0:0(eng): Video: vp8 (libvpx), yuv420p, 1280x544 [SAR 1:1 DAR 40:17], q=-1--1, pass 2, 60000 kb/s, 1k tbn, 24 tbc
    Stream #0:1(eng): Audio: vorbis (libvorbis), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Metadata:
     title           : AC3 5.1 @ 640 Kbps
    Stream mapping:
     Stream #0:0 -> #0:0 (h264 -> libvpx)
     Stream #0:1 -> #0:1 (ac3 -> libvorbis)
    Press [q] to stop, [?] for help
    frame=21312 fps= 11 q=0.0 Lsize=  567191kB time=00:14:48.01 bitrate=5232.4kbits/s    
    video:537377kB audio:29266kB subtitle:0kB other streams:0kB global headers:7kB muxing overhead: 0.096885%
  • Revision 32596 : minuscules et fin pour aujourd’hui

    1er novembre 2009, par fil@… — Log

    minuscules et fin pour aujourd’hui

  • FFmpeg decoded video is garbled mess with no audio. How can I fix it ? [closed]

    14 septembre 2023, par Señor Tonto

    I am trying to use FFmpeg 6.0 (which seems to have a terrible lack of documentation) to decode a .mp4/.mov file & play its audio. I am testing this on a .mov file (I tried also with a .mp4, same result) of an old animation I found. This turns out as a garbled mess that looks like an old film movie with no audio. Now, I used some old tutorials & managed to with much trial get the code I have now, which is of course half-working. I am using SDL to output the video. I'm not sure if it's a problem on the SDL end or the FFmpeg end at the moment (but I'm sure the video is a mix of the two & the audio because of SDL) I would appreciate some help as there's very little documentation I can find that isn't outdated & the deprecated list on FFmpeg hardly helps when I need to fix API-related changes. Here's my code

    &#xA;

    LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {&#xA;    OPENFILENAME ofn;&#xA;&#xA;    wchar_t g_filePath[MAX_PATH] = L"";&#xA;    char szFile[MAX_PATH] = "";&#xA;    wchar_t wFile[MAX_PATH] = L"";&#xA;    char data[MAX_PATH];&#xA;    DWORD bytesRead = 0;&#xA;    BOOL bSuccess = FALSE;&#xA;    static int iVscrollPos, cyClient, cyChar, cxChar, cxCaps, iMaxVerticalScroll = 0, iNumLines = 0;&#xA;    HDC hdc;&#xA;    TEXTMETRIC tm;&#xA;    static int tabIndex;&#xA;    std::wstring filePath;&#xA;&#xA;    //FFmpeg variables&#xA;    static AVFormatContext* format_ctx = nullptr; &#xA;    static AVCodecContext* video_codec_ctx = nullptr;&#xA;    static AVCodecContext* audio_codec_ctx = nullptr;&#xA;    static AVFrame* video_frame = nullptr;&#xA;    static AVFrame* audio_frame = nullptr;&#xA;    static AVPacket packet;&#xA;    static struct SwsContext* sws_ctx = nullptr;&#xA;    static int video_stream_idx = -1;&#xA;    static int audio_stream_idx = -1;&#xA;    static int video_width = 0;&#xA;    static int video_height = 0;&#xA;    static HWND hVideoWnd = nullptr;&#xA;    static HDC hVideoDC = nullptr;&#xA;    static HBITMAP hVideoBitmap = nullptr;&#xA;&#xA;    switch (msg) {&#xA;    case WM_CREATE:&#xA;        break;&#xA;    case WM_SIZE:&#xA;        break;&#xA;    case WM_NOTIFY:&#xA;        //code for handling tab switching &amp; creating all content inside the tabs, currently half-working, perhaps give each tab a show &amp; update win call?&#xA;        if (((LPNMHDR)lParam)->code == TCN_SELCHANGE) {&#xA;            tabIndex = TabCtrl_GetCurSel(g_hWndTabs);&#xA;            if (tabIndex == 0) {&#xA;                DestroyWindow(openFileBtn);&#xA;                DestroyWindow(saveFileBtn);&#xA;                DestroyWindow(emboldenBtn);&#xA;                DestroyWindow(italiciseBtn);&#xA;                DestroyWindow(hEditControl);&#xA;                DestroyWindow(hScrollContainer);&#xA;&#xA;                //this code reloads table data &amp; reconstructs the table whenever the &#x27;table view&#x27; tab is opened,&#xA;                std::wifstream infile("tabledata.txt");&#xA;                while (numRows > 0) {&#xA;                    numRows--;&#xA;                }&#xA;                while (true) {&#xA;                    // Read in data for a row&#xA;                    wchar_t buf1[MAX_PATH], buf2[MAX_PATH], buf3[MAX_PATH];&#xA;                    if (!(infile >> buf1 >> buf2 >> buf3)) {&#xA;                        // End of file reached, break out of loop&#xA;                        break;&#xA;                    }&#xA;&#xA;                    // Create new row window for this row of data&#xA;                    HWND hRow = CreateWindowEx(0, L"STATIC", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | WS_BORDER,&#xA;                        startX, startY &#x2B; numRows * ROW_HEIGHT,&#xA;                        3 * CELL_WIDTH, ROW_HEIGHT,&#xA;                        g_hWndMain, nullptr, g_hInstance, nullptr);&#xA;&#xA;                    // Create cell edit controls within the new row&#xA;                    HWND hCell1 = CreateWindowEx(0, L"EDIT", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_BORDER,&#xA;                        0, 0, CELL_WIDTH, ROW_HEIGHT,&#xA;                        hRow, nullptr, g_hInstance, nullptr);&#xA;                    HWND hCell2 = CreateWindowEx(0, L"EDIT", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_BORDER,&#xA;                        CELL_WIDTH, 0, CELL_WIDTH, ROW_HEIGHT,&#xA;                        hRow, nullptr, g_hInstance, nullptr);&#xA;                    HWND hCell3 = CreateWindowEx(0, L"EDIT", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_BORDER,&#xA;                        2 * CELL_WIDTH, 0, CELL_WIDTH, ROW_HEIGHT,&#xA;                        hRow, nullptr, g_hInstance, nullptr);&#xA;&#xA;                    // Set the text of each cell edit control&#xA;                    SetWindowTextW(hCell1, buf1);&#xA;                    SetWindowTextW(hCell2, buf2);&#xA;                    SetWindowTextW(hCell3, buf3);&#xA;&#xA;                    // Update the row window&#xA;                    InvalidateRect(hRow, nullptr, TRUE);&#xA;                    UpdateWindow(hRow);&#xA;&#xA;                    numRows&#x2B;&#x2B;;&#xA;                }&#xA;&#xA;&#xA;&#xA;                tblHeaderOne = CreateWindow(L"STATIC", L"Header 1",&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | WS_BORDER,&#xA;                    0, 40, 110, 20,&#xA;                    g_hWndMain, (HMENU)CELL_1_ID, g_hInstance, NULL);&#xA;                InvalidateRect(tblHeaderOne, NULL, TRUE);&#xA;                UpdateWindow(tblHeaderOne);&#xA;&#xA;&#xA;                tblHeaderTwo = CreateWindow(L"STATIC", L"Header 2",&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | WS_BORDER,&#xA;                    110, 40, 110, 20,&#xA;                    g_hWndMain, (HMENU)CELL_2_ID, g_hInstance, NULL);&#xA;                InvalidateRect(tblHeaderTwo, NULL, TRUE);&#xA;                UpdateWindow(tblHeaderTwo);&#xA;&#xA;                tblHeaderThree = CreateWindow(L"STATIC", L"Header 3",&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | WS_BORDER,&#xA;                    220, 40, 110, 20,&#xA;                    g_hWndMain, (HMENU)CELL_3_ID, g_hInstance, NULL);&#xA;                InvalidateRect(tblHeaderThree, NULL, TRUE);&#xA;                UpdateWindow(tblHeaderThree);&#xA;&#xA;                // Create button to add new row&#xA;                addRowBtn = CreateWindow(L"BUTTON", L"Add Row",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    390, 40, 100, 30,&#xA;                    g_hWndMain, (HMENU)ADD_ROW_BTN, g_hInstance, NULL);&#xA;                InvalidateRect(addRowBtn, NULL, TRUE);&#xA;                UpdateWindow(addRowBtn);&#xA;&#xA;            }&#xA;            else if (tabIndex == 1) {&#xA;&#xA;                DestroyWindow(hRow);&#xA;                DestroyWindow(tableContainer);&#xA;                DestroyWindow(tblHeaderOne);&#xA;                DestroyWindow(tblHeaderTwo);&#xA;                DestroyWindow(tblHeaderThree);&#xA;                DestroyWindow(addRowBtn);&#xA;&#xA;&#xA;&#xA;                openFileBtn = CreateWindow(L"BUTTON", L"Open File",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    10, 40, 150, 25,&#xA;                    g_hWndMain, (HMENU)OPEN_FILE_BTN, NULL, NULL);&#xA;                InvalidateRect(openFileBtn, NULL, TRUE);&#xA;                UpdateWindow(openFileBtn);&#xA;&#xA;                saveFileBtn = CreateWindow(L"BUTTON", L"Save File",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    10, 80, 150, 25,&#xA;                    g_hWndMain, (HMENU)SAVE_FILE_BTN, nullptr, nullptr);&#xA;                InvalidateRect(saveFileBtn, NULL, TRUE);&#xA;                UpdateWindow(saveFileBtn);&#xA;&#xA;                hScrollContainer = CreateWindowEx(WS_EX_CLIENTEDGE, L"SCROLLBAR", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_VSCROLL | SBS_VERT,&#xA;                    170, 40, 600, 300,&#xA;                    g_hWndMain, (HMENU)SCROLL_CONTAINER, g_hInstance, NULL);&#xA;&#xA;&#xA;                hEditControl = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,&#xA;                    0, 0, 600, 300,&#xA;                    hScrollContainer, (HMENU)EDIT_CONTROL, g_hInstance, NULL);&#xA;                InvalidateRect(hEditControl, NULL, TRUE);&#xA;                UpdateWindow(hEditControl);&#xA;&#xA;                SetFocus(hEditControl);&#xA;&#xA;                SetScrollRange(hScrollContainer, SB_VERT, 0, 5, TRUE);&#xA;                SetScrollPos(hScrollContainer, SB_VERT, 0, TRUE);&#xA;&#xA;                // Add embolden button&#xA;                emboldenBtn = CreateWindow(L"BUTTON", L"Embolden",&#xA;                    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,&#xA;                    10, 120, 100, 25,&#xA;                    g_hWndMain, (HMENU)EMBOLDEN_BTN, nullptr, nullptr);&#xA;                InvalidateRect(emboldenBtn, NULL, TRUE);&#xA;                UpdateWindow(emboldenBtn);&#xA;&#xA;                // Add italicise button&#xA;                italiciseBtn = CreateWindow(L"BUTTON", L"Italicise",&#xA;                    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,&#xA;                    10, 150, 100, 25,&#xA;                    g_hWndMain, (HMENU)ITALICISE_BTN, nullptr, nullptr);&#xA;                InvalidateRect(italiciseBtn, NULL, TRUE);&#xA;                UpdateWindow(italiciseBtn);&#xA;            }&#xA;            else if (tabIndex == 2) {&#xA;                DestroyWindow(hRow);&#xA;                DestroyWindow(tableContainer);&#xA;                DestroyWindow(tblHeaderOne);&#xA;                DestroyWindow(tblHeaderTwo);&#xA;                DestroyWindow(tblHeaderThree);&#xA;                DestroyWindow(addRowBtn);&#xA;                DestroyWindow(openFileBtn);&#xA;                DestroyWindow(saveFileBtn);&#xA;                DestroyWindow(emboldenBtn);&#xA;                DestroyWindow(italiciseBtn);&#xA;                DestroyWindow(hEditControl);&#xA;                DestroyWindow(hScrollContainer);&#xA;&#xA;                // Create container for player&#xA;                hWMPContainer = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", nullptr,&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | SS_GRAYFRAME,&#xA;                    50, 50, 700, 400,&#xA;                    g_hWndMain, nullptr, g_hInstance, nullptr);&#xA;&#xA;                // Create Open .mp4/.mov button&#xA;                OpenMp4Btn = CreateWindow(L"BUTTON", L"Open .mp4/.mov",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    50, 460, 150, 30,&#xA;                    g_hWndMain, (HMENU)FILEMENU_OPEN_FILE_BTN, nullptr, nullptr);&#xA;                InvalidateRect(OpenMp4Btn, nullptr, TRUE);&#xA;                UpdateWindow(OpenMp4Btn);&#xA;&#xA;&#xA;                // Create play/pause button&#xA;                hPlayBtn = CreateWindow(L"BUTTON", L"Play",&#xA;                    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,&#xA;                    350, 460, 100, 30,&#xA;                    g_hWndMain, nullptr, g_hInstance, nullptr);&#xA;                InvalidateRect(hPlayBtn, nullptr, TRUE);&#xA;                UpdateWindow(hPlayBtn);&#xA;&#xA;            }&#xA;        }&#xA;        return DefWindowProc(hwnd, msg, wParam, lParam);&#xA;        break;&#xA;    case WM_MOUSEWHEEL:&#xA;        //also WIP, will be developed after WM_VSCROLL is established&#xA;        break;&#xA;    case WM_VSCROLL:&#xA;        //to be developed 9516555&#xA;    case WM_PAINT:&#xA;        break;&#xA;    case WM_COMMAND:&#xA;        //all commands passed to the window through buttons, menus, forms, etc.&#xA;        if (HIWORD(wParam) == BN_CLICKED) {&#xA;            if ((HWND)lParam == addRowBtn) {&#xA;                const wchar_t* ROW_CLASS_NAME = L"Row Window";&#xA;                WNDCLASS rowWc{};&#xA;                rowWc.hInstance = g_hInstance;&#xA;                rowWc.lpszClassName = ROW_CLASS_NAME;&#xA;                rowWc.hCursor = LoadCursor(nullptr, IDC_ARROW);&#xA;                rowWc.hbrBackground = (HBRUSH)COLOR_WINDOW;&#xA;                rowWc.lpfnWndProc = AddRowDlgProc;&#xA;                RegisterClass(&amp;rowWc);&#xA;&#xA;                hWnd = CreateWindow(ROW_CLASS_NAME, L"Row Window",&#xA;                    WS_OVERLAPPEDWINDOW,&#xA;                    CW_USEDEFAULT, CW_USEDEFAULT,&#xA;                    250, 200,&#xA;                    nullptr, nullptr, nullptr, nullptr);&#xA;&#xA;                // Create text box controls&#xA;                hWndCell1Label = CreateWindowW(&#xA;                    L"STATIC", L"Cell 1:",&#xA;                    WS_CHILD | WS_VISIBLE | SS_LEFT,&#xA;                    10, 10, 50, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell1Edit = CreateWindowW(&#xA;                    L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,&#xA;                    65, 10, 100, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell2Label = CreateWindowW(&#xA;                    L"STATIC", L"Cell 2:",&#xA;                    WS_CHILD | WS_VISIBLE | SS_LEFT,&#xA;                    10, 40, 50, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell2Edit = CreateWindowW(&#xA;                    L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,&#xA;                    65, 40, 100, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;                hWndCell3Label = CreateWindowW(&#xA;                    L"STATIC", L"Cell 3:",&#xA;                    WS_CHILD | WS_VISIBLE | SS_LEFT,&#xA;                    10, 70, 50, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell3Edit = CreateWindowW(&#xA;                    L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,&#xA;                    65, 70, 100, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                // Create OK and Cancel button controls&#xA;                hWndOkButton = CreateWindowW(&#xA;                    L"BUTTON", L"OK",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    40, 110, 50, 25,&#xA;                    hWnd, (HMENU)IDOK, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCancelButton = CreateWindowW(&#xA;                    L"BUTTON", L"Cancel",&#xA;                    WS_CHILD | WS_VISIBLE,&#xA;                    100, 110, 50, 25,&#xA;                    hWnd, (HMENU)IDCANCEL, g_hInstance, NULL);&#xA;&#xA;&#xA;                ShowWindow(hWnd, SW_SHOW);&#xA;                UpdateWindow(hWnd);&#xA;&#xA;                MSG msg{};&#xA;                while (GetMessage(&amp;msg, nullptr, 0, 0)) {&#xA;                    TranslateMessage(&amp;msg);&#xA;                    DispatchMessage(&amp;msg);&#xA;                }&#xA;&#xA;            }&#xA;            if ((HWND)lParam == openFileBtn) {&#xA;                // Open File button clicked, show open file dialoge and load the selected file into the edit control&#xA;                OPENFILENAME ofn = { };&#xA;                WCHAR szFile[MAX_PATH] = L"";&#xA;                ofn.lStructSize = sizeof(OPENFILENAME);&#xA;                ofn.hwndOwner = hWnd;&#xA;                ofn.lpstrFilter = L"Text files\0*.txt\0All files\0*.*\0";&#xA;                ofn.lpstrFile = szFile;&#xA;                ofn.nMaxFile = MAX_PATH;&#xA;                ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;&#xA;                if (GetOpenFileName(&amp;ofn)) {&#xA;                    // Read file and set text of edit box&#xA;                    std::ifstream infile(ofn.lpstrFile, std::ios::in | std::ios::binary);&#xA;                    if (infile) {&#xA;                        std::wstring text((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>());&#xA;                        SetWindowText(hEditControl, text.c_str());&#xA;                        filePath = ofn.lpstrFile;&#xA;                    }&#xA;                }&#xA;            }&#xA;            if ((HWND)lParam == saveFileBtn) {&#xA;                if (!filePath.empty()) {&#xA;                    std::wofstream outfile(filePath, std::ios::out | std::ios::binary); // use std::wofstream instead of std::ofstream&#xA;                    if (outfile) {&#xA;                        int textLength = GetWindowTextLength(hEditControl);&#xA;                        if (textLength != 0) {&#xA;                            wchar_t* textBuffer = new wchar_t[textLength &#x2B; 1];&#xA;                            GetWindowTextW(hEditControl, textBuffer, textLength &#x2B; 1);&#xA;                            outfile.write(textBuffer, textLength * sizeof(wchar_t));&#xA;                            delete[] textBuffer;&#xA;                        }&#xA;                    }&#xA;                    outfile.close();&#xA;                    MessageBox(NULL, L"File saved successfully!", L"File save", MB_OK);&#xA;                }&#xA;&#xA;            }&#xA;            //The following are not currently working due to an issue in connecting to the edit box for char type manipulation&#xA;            if ((HWND)lParam == emboldenBtn) {&#xA;&#xA;            }&#xA;            if ((HWND)lParam == italiciseBtn) {&#xA;&#xA;            }&#xA;            //cannot or failed to open video file &#xA;            if ((HWND)lParam == OpenMp4Btn) {&#xA;                OPENFILENAMEA ofn = {};&#xA;                ofn.lStructSize = sizeof(ofn);&#xA;                ofn.hwndOwner = hwnd;&#xA;                ofn.lpstrFilter = "Video Files (*.mp4;*.mov)\0*.mp4;*.mov\0All Files (*.*)\0*.*\0";&#xA;                char szFile[MAX_PATH] = {};&#xA;                ofn.lpstrFile = szFile;&#xA;                ofn.nMaxFile = MAX_PATH;&#xA;                ofn.lpstrTitle = "Open Video File";&#xA;                ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;&#xA;                if (GetOpenFileNameA(&amp;ofn)) {&#xA;                    // Initialize SDL&#xA;                    SDL_Init(SDL_INIT_VIDEO);&#xA;&#xA;                    // Open the selected video file&#xA;                    AVFormatContext* format_ctx = nullptr;&#xA;                    if (avformat_open_input(&amp;format_ctx, szFile, nullptr, nullptr) != 0) {&#xA;                        // Error handling&#xA;                    }&#xA;&#xA;                    // Retrieve stream information&#xA;                    if (avformat_find_stream_info(format_ctx, nullptr) &lt; 0) {&#xA;                        // Error handling&#xA;                    }&#xA;&#xA;                    // Find the video and audio streams&#xA;                    int video_stream_idx = av_find_best_stream(format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);&#xA;                    int audio_stream_idx = av_find_best_stream(format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);&#xA;&#xA;                    // Open the video and audio codecs&#xA;                    AVCodecContext* video_codec_ctx = avcodec_alloc_context3(nullptr);&#xA;                    avcodec_parameters_to_context(video_codec_ctx, format_ctx->streams[video_stream_idx]->codecpar);&#xA;                    AVCodec* video_codec = const_cast(avcodec_find_decoder(video_codec_ctx->codec_id));&#xA;                    if (avcodec_open2(video_codec_ctx, video_codec, nullptr) &lt; 0) {&#xA;                        // Error handling&#xA;                    }&#xA;&#xA;                    AVCodecContext* audio_codec_ctx = avcodec_alloc_context3(nullptr);&#xA;                    avcodec_parameters_to_context(audio_codec_ctx, format_ctx->streams[audio_stream_idx]->codecpar);&#xA;                    AVCodec* audio_codec = const_cast(avcodec_find_decoder(audio_codec_ctx->codec_id));&#xA;                    if (avcodec_open2(audio_codec_ctx, audio_codec, nullptr) &lt; 0) {&#xA;                        // Error handling&#xA;                    }&#xA;                    // Allocate memory for the video and audio frames&#xA;                    AVFrame* video_frame = av_frame_alloc();&#xA;                    AVFrame* audio_frame = av_frame_alloc();&#xA;&#xA;                    // Create a window for displaying the video frames&#xA;                    SDL_Window* window = SDL_CreateWindow("Video Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, video_codec_ctx->width, video_codec_ctx->height, SDL_WINDOW_SHOWN);&#xA;&#xA;                    // Create a renderer for displaying the video frames&#xA;                    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);&#xA;&#xA;                    // Create a texture for displaying the video frames&#xA;                    SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STREAMING, video_codec_ctx->width, video_codec_ctx->height);&#xA;&#xA;                    // Create a scaling context for converting the video frames to RGB&#xA;                    SwsContext* sws_ctx = sws_getContext(video_codec_ctx->width, video_codec_ctx->height, video_codec_ctx->pix_fmt,&#xA;                        video_codec_ctx->width, video_codec_ctx->height, AV_PIX_FMT_BGR24,&#xA;                        SWS_BILINEAR, nullptr, nullptr, nullptr);&#xA;&#xA;                    // Decode and display the video frames&#xA;                    AVPacket packet;&#xA;                    while (av_read_frame(format_ctx, &amp;packet) >= 0) {&#xA;                        if (packet.stream_index == video_stream_idx) {&#xA;                            avcodec_send_packet(video_codec_ctx, &amp;packet);&#xA;                            while (avcodec_receive_frame(video_codec_ctx, video_frame) == 0) {&#xA;                                sws_scale(sws_ctx, video_frame->data, video_frame->linesize, 0, video_codec_ctx->height,&#xA;                                    video_frame->data, video_frame->linesize);&#xA;                                SDL_UpdateTexture(texture, NULL, video_frame->data[0], video_frame->linesize[0]);&#xA;                                SDL_RenderClear(renderer);&#xA;                                SDL_RenderCopy(renderer, texture, NULL, NULL);&#xA;                                SDL_RenderPresent(renderer);&#xA;                            }&#xA;                        }&#xA;                        av_packet_unref(&amp;packet);&#xA;                    }&#xA;&#xA;                    // Free the allocated memory and close the codecs&#xA;                    av_frame_free(&amp;video_frame);&#xA;                    av_frame_free(&amp;audio_frame);&#xA;                    avcodec_free_context(&amp;video_codec_ctx);&#xA;                    avcodec_free_context(&amp;audio_codec_ctx);&#xA;                    avformat_close_input(&amp;format_ctx);&#xA;&#xA;                    // Destroy the window, renderer, and texture&#xA;                    SDL_DestroyTexture(texture);&#xA;                    SDL_DestroyRenderer(renderer);&#xA;                    SDL_DestroyWindow(window);&#xA;&#xA;                    // Quit SDL&#xA;                    SDL_Quit();&#xA;                }&#xA;            }&#xA;        }&#xA;        break;&#xA;    case WM_DESTROY:&#xA;        //code that executes on window destruction&#xA;        PostQuitMessage(0);&#xA;        return 0;&#xA;    default:&#xA;        return DefWindowProc(hwnd, msg, wParam, lParam);&#xA;    }&#xA;}&#xA;</char></char>

    &#xA;

    I am doing this on MVSC2022 in a C++ win32 application if it's relevant, I will attach some images of the video : some of the videosome more of the videoA screenshot of the output screen

    &#xA;