Recherche avancée

Médias (1)

Mot : - Tags -/punk

Autres articles (67)

  • Organiser par catégorie

    17 mai 2013, par

    Dans MédiaSPIP, une rubrique a 2 noms : catégorie et rubrique.
    Les différents documents stockés dans MédiaSPIP peuvent être rangés dans différentes catégories. On peut créer une catégorie en cliquant sur "publier une catégorie" dans le menu publier en haut à droite ( après authentification ). Une catégorie peut être rangée dans une autre catégorie aussi ce qui fait qu’on peut construire une arborescence de catégories.
    Lors de la publication prochaine d’un document, la nouvelle catégorie créée sera proposée (...)

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

  • Websites made ​​with MediaSPIP

    2 mai 2011, par

    This page lists some websites based on MediaSPIP.

Sur d’autres sites (10370)

  • FFmpeg downloading entire live stream when making a small clip

    6 février 2021, par stevendesu

    Setup

    


    I'm using FFmpeg to generate video clips from M3U8 videos. The command looks like this :

    


    ffmpeg -ss <start> -i &lt;1080p-chunklist-url> -c:v copy -c:a copy -t <duration> -f mp4 -y out.mp4&#xA;</duration></start>

    &#xA;

    For example, to create a 30-second clip starting at the 5-minute mark for a particular video, the command would be :

    &#xA;

    ffmpeg -ss 300 -i https://example.com/path/to/1080p/index.m3u8 -c:v copy -c:a copy -t 30 -f mp4 -y out.mp4&#xA;

    &#xA;

    Some caveats I'm already aware of :

    &#xA;

      &#xA;
    • If -ss comes after -i then FFmpeg will attempt to download the entire M3U8 instead of just the relevant TS files, and will parse the entire video contents looking for the exact timestamp. By putting -ss before -i FFmpeg uses "seek points", which with HLS videos means it looks at the M3U8 and only downloads relevant TS files
    • &#xA;

    • TS file boundaries function as "seek points" in HLS, so if a TS file starts at 4:51 and the next TS file starts at 5:01, this command will start the clip at 4:51 instead of 5:01 (it prefers the first seek point before the requested time)
    • &#xA;

    • The -t parameter sets an exact clip duration instead of an ending position, so in the above example of a clip starting at 4:51 the same clip would end at 5:21 instead of 5:30
    • &#xA;

    &#xA;

    In theory I can utilize -to instead of -t to specify an ending time of 5:30, however in practice this hasn't worked. Also in theory I can force -accurate_seeking to discard the contents from 4:51 to 5:00 and start the clip where I wanted it, but I learned this only works for transcodes and not transmux

    &#xA;

    Now to the meat of my problem :

    &#xA;

    Problem

    &#xA;

    When the M3U8 URL provided is a live stream (no #EXT-X-ENDLIST tag) then FFmpeg does not behave correctly. On FFmpeg versions 4.2.1 and earlier, it starts by downloading the TS file containing my clip segment, then proceeds to download every TS file in the M3U8 then hangs while waiting for new TS files to become available, downloading them as they appear - even hours after the end of the section I wanted to clip. On FFmpeg version 4.2.2 and later, I can create clips so long as they end before the second-to-last TS file. If the live stream currently has 20 minutes of video data and I create a clip from 19:30 - 19:40 (ending right at the start of the second-to-last TS file, assuming a 10-second TS file duration) then it will behave the same as 4.2.1 : waiting infinitely to download the entire video.

    &#xA;

    The "2 TS files from the end" rule I believe is related to FFmpeg's initial probe of the video to get stream data. In the aforementioned 20-minute long video, if I make a clip from 3:00 to 3:30 (well before the end of the stream) it will first download TS files 119 and 120 (19:40-19:50 and 19:50-20:00), then it displays a list of the streams in the video (audio, video, metadata), then it downloads TS files 19 - 21 (containing the actual data I want for my clip)

    &#xA;

    Is there a way to fix it so I can properly make clips of sections near the "end" of live M3U8s ?

    &#xA;

  • Using ffmpeg to combine small mp4 chunks ?

    20 mai 2015, par shiny formica

    I’m trying to convert batches of png images into a single mp4 x264 video using ffmpeg. The conversion, for reasons I won’t go into, converts groups of frames into short mp4 chunks and then I want to take those chunks and merge them into the final video at a specific fps (in this case 30fps).

    My understanding of ffmpeg and the x264 options is too limited, and while I can produce the individual mp4 chunks from the source png frames without trouble, the final merge always ends up duplicating and/or dropping frames especially with very short chunks (< 4 frames).

    The conversion from png to mp4 uses this command :

    ffmpeg -start_number 1001 -framerate 30 -f image2 -i 'intermediate.%d.png' -c:v libx264 -crf 1 -pix_fmt yuv420p -movflags +faststart -frames:v 4 -r 30 chunk.1.mp4 -y

    which appears to work as expected, I get a playable mp4 chunk of, in this case, 4 frames of the sequence of png images at 30fps. The length of each chunk can be anywhere from 1 frame to around 100 frames.

    When all the chunks are generated, I’ve been trying to use the concat demuxer to combine without re-encoding, placing all the source chunk paths in a file :

    concat.txt :

    file 'chunk.1.mp4'
    file 'chunk.2.mp4'
    file 'chunk.3.mp4'
    ...

    and then running this ffmpeg command :

    ffmpeg -f concat -i concat.txt -c:v copy merged.mp4 -y

    but it says this during the concatenation :

    [concat @ 0x315ff80] Estimating duration from bitrate, this may be inaccurate

    and the resulting mp4 has dropped/duplicated frames. So I tried adding duration info to the concat.txt file :

    file 'chunk.1.mp4'
    duration 0.133333
    file 'chunk.2.mp4'
    duration 0.133333
    file 'chunk.3.mp4'
    duration 0.066666

    in this case, two 4-frame/30fps chunks and one 2-frame/30fps chunk. Which gets rid of that estimation warning, but the result is still duplicating/dropping frames.

    I’m not sure where I’m going wrong here...what do I need to do either in the production of the short mp4 segments, or in the combination stage, to get a single mp4 at the right framerate with no duplicated or dropped frames ?

    As suggested, here’s the console output for the conversion from png->mp4 chunks :

    ffmpeg -loglevel verbose -start_number 1001 -framerate 30 -f image2 -i 'intermediate.%d.png' -c:v libx264 -crf 1 -pix_fmt yuv420p -movflags +faststart -frames:v 4 -r 30 chunk.1.mp4 -y
    ffmpeg version 2.5.4 Copyright (c) 2000-2015 the FFmpeg developers
     built on Feb 26 2015 10:23:42 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-3)
     configuration: --prefix=/dept/srd/vendor/ffmpeg/bundle.rhel6/ffmpeg2.5.4 --enable-static --enable-pthreads --enable-gpl --enable-version3 --disable-ffserver --disable-ffplay --disable-ffprobe --enable-x11grab --enable-nonfree --extra-cflags=-I/dept/srd/vendor/ffmpeg/extern/rhel6/include --extra-ldflags=-L/dept/srd/vendor/ffmpeg/extern/rhel6/lib --enable-libx264 --enable-fontconfig --enable-libfreetype --enable-swscale --enable-libmp3lame --enable-libfaac --disable-yasm
     libavutil      54. 15.100 / 54. 15.100
     libavcodec     56. 13.100 / 56. 13.100
     libavformat    56. 15.102 / 56. 15.102
     libavdevice    56.  3.100 / 56.  3.100
     libavfilter     5.  2.103 /  5.  2.103
     libswscale      3.  1.101 /  3.  1.101
     libswresample   1.  1.100 /  1.  1.100
     libpostproc    53.  3.100 / 53.  3.100
    Input #0, image2, from 'intermediate.%d.png':
     Duration: 00:00:00.27, start: 0.000000, bitrate: N/A
       Stream #0:0: Video: png, rgba, 1024x1024 (0x0), 30 fps, 30 tbr, 30 tbn, 30 tbc
    [graph 0 input from stream 0:0 @ 0x273e9c0] w:1024 h:1024 pixfmt:rgba tb:1/30 fr:30/1 sar:0/1 sws_param:flags=2
    [auto-inserted scaler 0 @ 0x2737ea0] w:iw h:ih flags:'0x4' interl:0
    [format @ 0x273ece0] auto-inserting filter 'auto-inserted scaler 0' between the filter 'Parsed_null_0' and the filter 'format'
    [auto-inserted scaler 0 @ 0x2737ea0] w:1024 h:1024 fmt:rgba sar:0/1 -> w:1024 h:1024 fmt:yuv420p sar:0/1 flags:0x4
    [libx264 @ 0x273c540] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
    [libx264 @ 0x273c540] profile High, level 3.2
    [libx264 @ 0x273c540] 264 - core 142 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=36 lookahead_threads=6 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to 'chunk.1.mp4':
     Metadata:
       encoder         : Lavf56.15.102
       Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 1024x1024, q=-1--1, 30 fps, 15360 tbn, 30 tbc
       Metadata:
         encoder         : Lavc56.13.100 libx264
    Stream mapping:
     Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
    Press [q] to stop, [?] for help
    No more output streams to write to, finishing.
    [mp4 @ 0x273baa0] Starting second pass: moving the moov atom to the beginning of the file
    frame=    4 fps=0.0 q=-1.0 Lsize=     197kB time=00:00:00.06 bitrate=24228.7kbits/s    
    video:196kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.439751%
    Input file #0 (intermediate.%d.png):
     Input stream #0:0 (video): 8 packets read (2341016 bytes); 5 frames decoded;
     Total: 8 packets (2341016 bytes) demuxed
    Output file #0 (chunk.3.mp4):
     Output stream #0:0 (video): 4 frames encoded; 4 packets muxed (201023 bytes);
     Total: 4 packets (201023 bytes) muxed
    [libx264 @ 0x273c540] frame I:1     Avg QP: 0.47  size:116049
    [libx264 @ 0x273c540] frame P:1     Avg QP: 2.29  size: 37932
    [libx264 @ 0x273c540] frame B:2     Avg QP: 2.37  size: 23184
    [libx264 @ 0x273c540] consecutive B-frames: 25.0%  0.0% 75.0%  0.0%
    [libx264 @ 0x273c540] mb I  I16..4: 80.0%  4.5% 15.5%
    [libx264 @ 0x273c540] mb P  I16..4:  0.2%  0.1%  0.4%  P16..4:  8.1%  3.6%  3.7%  0.0%  0.0%    skip:83.9%
    [libx264 @ 0x273c540] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  4.8%  1.2%  1.6%  direct: 4.3%  skip:88.1%  L0:38.6% L1:39.3% BI:22.1%
    [libx264 @ 0x273c540] 8x8 transform intra:4.6% inter:14.8%
    [libx264 @ 0x273c540] coded y,uvDC,uvAC intra: 20.7% 22.9% 22.8% inter: 8.7% 10.1% 10.0%
    [libx264 @ 0x273c540] i16 v,h,dc,p: 95%  1%  3%  1%
    [libx264 @ 0x273c540] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 21% 21% 22%  6%  6%  6%  7%  5%  6%
    [libx264 @ 0x273c540] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 17% 18%  7%  8%  7%  8%  6%  8%
    [libx264 @ 0x273c540] i8c dc,h,v,p: 89%  4%  4%  3%
    [libx264 @ 0x273c540] Weighted P-Frames: Y:0.0% UV:0.0%
    [libx264 @ 0x273c540] ref B L1: 89.5% 10.5%
    [libx264 @ 0x273c540] kb/s:12020.88

    as I said, this appears to produce a valid mp4 at 30fps with no duplicated or dropped frames from the input images.

    Here’s the output of the combine phase :

    ffmpeg -loglevel verbose -f concat -i concat.txt -c:v copy merged.mp4 -y
    ffmpeg version 2.5.4 Copyright (c) 2000-2015 the FFmpeg developers
     built on Feb 26 2015 10:23:42 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-3)
     configuration: --prefix=/dept/srd/vendor/ffmpeg/bundle.rhel6/ffmpeg2.5.4 --enable-static --enable-pthreads --enable-gpl --enable-version3 --disable-ffserver --disable-ffplay --disable-ffprobe --enable-x11grab --enable-nonfree --extra-cflags=-I/dept/srd/vendor/ffmpeg/extern/rhel6/include --extra-ldflags=-L/dept/srd/vendor/ffmpeg/extern/rhel6/lib --enable-libx264 --enable-fontconfig --enable-libfreetype --enable-swscale --enable-libmp3lame --enable-libfaac --disable-yasm
     libavutil      54. 15.100 / 54. 15.100
     libavcodec     56. 13.100 / 56. 13.100
     libavformat    56. 15.102 / 56. 15.102
     libavdevice    56.  3.100 / 56.  3.100
     libavfilter     5.  2.103 /  5.  2.103
     libswscale      3.  1.101 /  3.  1.101
     libswresample   1.  1.100 /  1.  1.100
     libpostproc    53.  3.100 / 53.  3.100
    Input #0, concat, from 'concat.txt':
     Duration: 00:00:00.67, start: 0.000000, bitrate: 2 kb/s
       Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1024x1024, 7791 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc
    Output #0, mp4, to 'merged.mp4':
     Metadata:
       encoder         : Lavf56.15.102
       Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1024x1024 (0x0), q=2-31, 7791 kb/s, 30 fps, 15360 tbn, 15360 tbc
    Stream mapping:
     Stream #0:0 -> #0:0 (copy)
    Press [q] to stop, [?] for help
    No more output streams to write to, finishing.
    frame=   20 fps=0.0 q=-1.0 Lsize=     748kB time=00:00:00.56 bitrate=10805.0kbits/s    
    video:746kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.141687%
    Input file #0 (concat.txt):
     Input stream #0:0 (video): 20 packets read (764361 bytes);
     Total: 20 packets (764361 bytes) demuxed
    Output file #0 (merged.mp4):
     Output stream #0:0 (video): 20 packets muxed (764361 bytes);
     Total: 20 packets (764361 bytes) muxed
  • Failed to decode h264 key frame with DXVA2.0 because returned buffer is to small

    16 mai 2023, par grill2010

    I hava a strange problem on Windows with DXVA2 h264 decoding. I recently figured out a ffmpeg decoding limitation for DXVA2 and D3D11VA on Windows and how to solve it, this solution completly fixes the problem with D3D11VA but DXVA2 still has some problems with certain keyframes. Upon further investigation it turned out that the decoding of these certain keyframes fail because the buffer returned from the IDirectXVideoDecoder_GetBuffer function was too small. FFmpeg is printing out these logs when the decoding fails :

    &#xA;

    Error: [h264 @ 0000028b2e5796c0] Buffer for type 5 was too small. size: 58752, dxva_size: 55296&#xA;Error: [h264 @ 0000028b2e5796c0] Failed to add bitstream or slice control buffer&#xA;Error: [h264 @ 0000028b2e5796c0] hardware accelerator failed to decode picture&#xA;

    &#xA;

    Why is this returned buffer too low ? What kind of factors inside ffmpeg do have an effect on this buffer size or is this a limitation of DXVA2 in general ? All other decoders like Cuvid, D3D11VA or the software decoder are not affected by this problem and can decode all keyframes.

    &#xA;

    I have an example javacv project on github that can reproduce the problem. I also provide the source code of the main class here. The keyframe example data with prepended SPS and PPS in hex form can be downloaded here.

    &#xA;

    import javafx.application.Application;&#xA;import javafx.scene.Scene;&#xA;import javafx.scene.layout.Pane;&#xA;import javafx.scene.layout.StackPane;&#xA;import javafx.stage.Stage;&#xA;import org.bytedeco.ffmpeg.avcodec.AVCodec;&#xA;import org.bytedeco.ffmpeg.avcodec.AVCodecContext;&#xA;import org.bytedeco.ffmpeg.avcodec.AVCodecHWConfig;&#xA;import org.bytedeco.ffmpeg.avcodec.AVPacket;&#xA;import org.bytedeco.ffmpeg.avutil.AVBufferRef;&#xA;import org.bytedeco.ffmpeg.avutil.AVDictionary;&#xA;import org.bytedeco.ffmpeg.avutil.AVFrame;&#xA;import org.bytedeco.ffmpeg.avutil.LogCallback;&#xA;import org.bytedeco.javacpp.BytePointer;&#xA;import org.bytedeco.javacpp.IntPointer;&#xA;import org.bytedeco.javacpp.Pointer;&#xA;import org.tinylog.Logger;&#xA;&#xA;import java.io.IOException;&#xA;import java.io.InputStream;&#xA;import java.nio.charset.StandardCharsets;&#xA;import java.util.Objects;&#xA;import java.util.function.Consumer;&#xA;&#xA;import static org.bytedeco.ffmpeg.avcodec.AVCodecContext.FF_THREAD_SLICE;&#xA;import static org.bytedeco.ffmpeg.global.avcodec.*;&#xA;import static org.bytedeco.ffmpeg.global.avutil.*;&#xA;&#xA;public class App extends Application {&#xA;&#xA;    /**** decoder variables ****/&#xA;&#xA;    private AVHWContextInfo hardwareContext;&#xA;&#xA;    private AVCodec decoder;&#xA;    private AVCodecContext m_VideoDecoderCtx;&#xA;&#xA;    private AVCodecContext.Get_format_AVCodecContext_IntPointer formatCallback;&#xA;&#xA;    private final int streamResolutionX = 1920;&#xA;    private final int streamResolutionY = 1080;&#xA;&#xA;    // AV_HWDEVICE_TYPE_CUDA // example works with cuda&#xA;    // AV_HWDEVICE_TYPE_DXVA2 // producing Invalid data found on keyframe&#xA;    // AV_HWDEVICE_TYPE_D3D11VA // producing Invalid data found on keyframe&#xA;    private static final int HW_DEVICE_TYPE = AV_HWDEVICE_TYPE_DXVA2;&#xA;&#xA;    private static final boolean USE_HW_ACCEL = true;&#xA;&#xA;    private static final boolean USE_AV_EF_EXPLODE = true;&#xA;&#xA;    public static void main(final String[] args) {&#xA;        //System.setProperty("prism.order", "d3d,sw");&#xA;        System.setProperty("prism.vsync", "false");&#xA;        Application.launch(App.class);&#xA;    }&#xA;&#xA;    @Override&#xA;    public void start(final Stage primaryStage) {&#xA;        final Pane dummyPane = new Pane();&#xA;        dummyPane.setStyle("-fx-background-color: black");&#xA;        final Scene scene = new Scene(dummyPane, this.streamResolutionX, this.streamResolutionY);&#xA;        primaryStage.setScene(scene);&#xA;        primaryStage.show();&#xA;        primaryStage.setMinWidth(480);&#xA;        primaryStage.setMinHeight(360);&#xA;&#xA;        this.initializeFFmpeg(result -> {&#xA;            if (!result) {&#xA;                Logger.error("FFmpeg could not be initialized correctly, terminating program");&#xA;                System.exit(1);&#xA;                return;&#xA;            }&#xA;            scene.setRoot(new StackPane());&#xA;            this.performTestFramesFeeding();&#xA;        });&#xA;    }&#xA;&#xA;    private void initializeFFmpeg(final Consumer<boolean> finishHandler) {&#xA;        FFmpegLogCallback.setLevel(AV_LOG_DEBUG); // Increase log level until the first frame is decoded&#xA;        FFmpegLogCallback.set();&#xA;        Pointer pointer = new Pointer((Pointer) null);&#xA;        AVCodec c;&#xA;        while ((c = av_codec_iterate(pointer)) != null) {&#xA;            if (av_codec_is_decoder(c) > 0)&#xA;                Logger.debug("{}:{} ", c.name().getString(), c.type());&#xA;        }&#xA;&#xA;        this.decoder = avcodec_find_decoder(AV_CODEC_ID_H264); // usually decoder name is h264 and without hardware support it&#x27;s yuv420p otherwise nv12&#xA;        if (this.decoder == null) {&#xA;            Logger.error("Unable to find decoder for format {}", "h264");&#xA;            finishHandler.accept(false);&#xA;            return;&#xA;        }&#xA;        Logger.info("Current decoder name: {}, {}", this.decoder.name().getString(), this.decoder.long_name().getString());&#xA;&#xA;        if (true) {&#xA;            for (; ; ) {&#xA;                this.m_VideoDecoderCtx = avcodec_alloc_context3(this.decoder);&#xA;                if (this.m_VideoDecoderCtx == null) {&#xA;                    Logger.error("Unable to find decoder for format AV_CODEC_ID_H264");&#xA;                    if (this.hardwareContext != null) {&#xA;                        this.hardwareContext.free();&#xA;                        this.hardwareContext = null;&#xA;                    }&#xA;                    continue;&#xA;                }&#xA;&#xA;                if (App.USE_HW_ACCEL) {&#xA;                    this.hardwareContext = this.createHardwareContext();&#xA;                    if (this.hardwareContext != null) {&#xA;                        Logger.info("Set hwaccel support");&#xA;                        this.m_VideoDecoderCtx.hw_device_ctx(this.hardwareContext.hwContext()); // comment to disable hwaccel&#xA;                    }&#xA;                } else {&#xA;                    Logger.info("Hwaccel manually disabled");&#xA;                }&#xA;&#xA;                // Always request low delay decoding&#xA;                this.m_VideoDecoderCtx.flags(this.m_VideoDecoderCtx.flags() | AV_CODEC_FLAG_LOW_DELAY);&#xA;&#xA;                // Allow display of corrupt frames and frames missing references&#xA;                this.m_VideoDecoderCtx.flags(this.m_VideoDecoderCtx.flags() | AV_CODEC_FLAG_OUTPUT_CORRUPT);&#xA;                this.m_VideoDecoderCtx.flags2(this.m_VideoDecoderCtx.flags2() | AV_CODEC_FLAG2_SHOW_ALL);&#xA;&#xA;                if (App.USE_AV_EF_EXPLODE) {&#xA;                    // Report decoding errors to allow us to request a key frame&#xA;                    this.m_VideoDecoderCtx.err_recognition(this.m_VideoDecoderCtx.err_recognition() | AV_EF_EXPLODE);&#xA;                }&#xA;&#xA;                // Enable slice multi-threading for software decoding&#xA;                if (this.m_VideoDecoderCtx.hw_device_ctx() == null) { // if not hw accelerated&#xA;                    this.m_VideoDecoderCtx.thread_type(this.m_VideoDecoderCtx.thread_type() | FF_THREAD_SLICE);&#xA;                    this.m_VideoDecoderCtx.thread_count(2/*AppUtil.getCpuCount()*/);&#xA;                } else {&#xA;                    // No threading for HW decode&#xA;                    this.m_VideoDecoderCtx.thread_count(1);&#xA;                }&#xA;&#xA;                this.m_VideoDecoderCtx.width(this.streamResolutionX);&#xA;                this.m_VideoDecoderCtx.height(this.streamResolutionY);&#xA;                this.m_VideoDecoderCtx.pix_fmt(this.getDefaultPixelFormat());&#xA;&#xA;                this.formatCallback = new AVCodecContext.Get_format_AVCodecContext_IntPointer() {&#xA;                    @Override&#xA;                    public int call(final AVCodecContext context, final IntPointer pixelFormats) {&#xA;                        final boolean hwDecodingSupported = context.hw_device_ctx() != null &amp;&amp; App.this.hardwareContext != null;&#xA;                        final int preferredPixelFormat = hwDecodingSupported ?&#xA;                                App.this.hardwareContext.hwConfig().pix_fmt() :&#xA;                                context.pix_fmt();&#xA;                        int i = 0;&#xA;                        while (true) {&#xA;                            final int currentSupportedFormat = pixelFormats.get(i&#x2B;&#x2B;);&#xA;                            System.out.println("Supported pixel formats " &#x2B; currentSupportedFormat);&#xA;                            if (currentSupportedFormat == AV_PIX_FMT_NONE) {&#xA;                                break;&#xA;                            }&#xA;                        }&#xA;&#xA;                        i = 0;&#xA;                        while (true) {&#xA;                            final int currentSupportedFormat = pixelFormats.get(i&#x2B;&#x2B;);&#xA;                            if (currentSupportedFormat == preferredPixelFormat) {&#xA;                                Logger.info("[FFmpeg]: pixel format in format callback is {}", currentSupportedFormat);&#xA;                                return currentSupportedFormat;&#xA;                            }&#xA;                            if (currentSupportedFormat == AV_PIX_FMT_NONE) {&#xA;                                break;&#xA;                            }&#xA;                        }&#xA;&#xA;                        i = 0;&#xA;                        while (true) { // try again and search for yuv&#xA;                            final int currentSupportedFormat = pixelFormats.get(i&#x2B;&#x2B;);&#xA;                            if (currentSupportedFormat == AV_PIX_FMT_YUV420P) {&#xA;                                Logger.info("[FFmpeg]: Not found in first match so use {}", AV_PIX_FMT_YUV420P);&#xA;                                return currentSupportedFormat;&#xA;                            }&#xA;                            if (currentSupportedFormat == AV_PIX_FMT_NONE) {&#xA;                                break;&#xA;                            }&#xA;                        }&#xA;&#xA;                        i = 0;&#xA;                        while (true) { // try again and search for nv12&#xA;                            final int currentSupportedFormat = pixelFormats.get(i&#x2B;&#x2B;);&#xA;                            if (currentSupportedFormat == AV_PIX_FMT_NV12) {&#xA;                                Logger.info("[FFmpeg]: Not found in second match so use {}", AV_PIX_FMT_NV12);&#xA;                                return currentSupportedFormat;&#xA;                            }&#xA;                            if (currentSupportedFormat == AV_PIX_FMT_NONE) {&#xA;                                break;&#xA;                            }&#xA;                        }&#xA;&#xA;                        Logger.info("[FFmpeg]: pixel format in format callback is using fallback {}", AV_PIX_FMT_NONE);&#xA;                        return AV_PIX_FMT_NONE;&#xA;                    }&#xA;                };&#xA;                this.m_VideoDecoderCtx.get_format(this.formatCallback);&#xA;&#xA;                final AVDictionary options = new AVDictionary(null);&#xA;                final int result = avcodec_open2(this.m_VideoDecoderCtx, this.decoder, options);&#xA;                if (result &lt; 0) {&#xA;                    Logger.error("avcodec_open2 was not successful");&#xA;                    finishHandler.accept(false);&#xA;                    return;&#xA;                }&#xA;                av_dict_free(options);&#xA;                break;&#xA;            }&#xA;        }&#xA;&#xA;        if (this.decoder == null || this.m_VideoDecoderCtx == null) {&#xA;            finishHandler.accept(false);&#xA;            return;&#xA;        }&#xA;        finishHandler.accept(true);&#xA;    }&#xA;&#xA;    private AVHWContextInfo createHardwareContext() {&#xA;        AVHWContextInfo result = null;&#xA;        for (int i = 0; ; i&#x2B;&#x2B;) {&#xA;            final AVCodecHWConfig config = avcodec_get_hw_config(this.decoder, i);&#xA;            if (config == null) {&#xA;                break;&#xA;            }&#xA;&#xA;            if ((config.methods() &amp; AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) &lt; 0) {&#xA;                continue;&#xA;            }&#xA;            final int device_type = config.device_type();&#xA;            if (device_type != App.HW_DEVICE_TYPE) {&#xA;                continue;&#xA;            }&#xA;            final AVBufferRef hw_context = av_hwdevice_ctx_alloc(device_type);&#xA;            if (hw_context == null || av_hwdevice_ctx_create(hw_context, device_type, (String) null, null, 0) &lt; 0) {&#xA;                Logger.error("HW accel not supported for type {}", device_type);&#xA;                av_free(config);&#xA;                av_free(hw_context);&#xA;            } else {&#xA;                Logger.info("HW accel created for type {}", device_type);&#xA;                result = new AVHWContextInfo(config, hw_context);&#xA;            }&#xA;            break;&#xA;        }&#xA;&#xA;        return result;&#xA;    }&#xA;&#xA;    @Override&#xA;    public void stop() {&#xA;        this.releaseNativeResources();&#xA;    }&#xA;&#xA;    /*****************************/&#xA;    /*** test frame processing ***/&#xA;    /*****************************/&#xA;    &#xA;    private void performTestFramesFeeding() {&#xA;        final AVPacket pkt = av_packet_alloc();&#xA;        if (pkt == null) {&#xA;            return;&#xA;        }&#xA;        try (final BytePointer bp = new BytePointer(65_535 * 15)) {&#xA;&#xA;&#xA;            for (int i = 0; i &lt; 1; i&#x2B;&#x2B;) {&#xA;                final byte[] frameData = AVTestFrames.h264KeyTestFrame;&#xA;&#xA;                bp.position(0);&#xA;&#xA;                bp.put(frameData);&#xA;                bp.limit(frameData.length);&#xA;&#xA;                pkt.data(bp);&#xA;                pkt.capacity(bp.capacity());&#xA;                pkt.size(frameData.length);&#xA;                pkt.position(0);&#xA;                pkt.limit(frameData.length);&#xA;                //pkt.flags(AV_PKT_FLAG_KEY);&#xA;                final AVFrame avFrame = av_frame_alloc();&#xA;                System.out.println("frameData.length " &#x2B; frameData.length);&#xA;&#xA;                final int err = avcodec_send_packet(this.m_VideoDecoderCtx, pkt); //fill_scaling_lists&#xA;                if (err &lt; 0) {&#xA;                    final BytePointer buffer = new BytePointer(512);&#xA;                    av_strerror(err, buffer, buffer.capacity());&#xA;                    final String string = buffer.getString();&#xA;                    System.out.println("Error on decoding test frame " &#x2B; err &#x2B; " message " &#x2B; string);&#xA;                    av_frame_free(avFrame);&#xA;                    return;&#xA;                }&#xA;&#xA;                final int result = avcodec_receive_frame(this.m_VideoDecoderCtx, avFrame);&#xA;                final AVFrame decodedFrame;&#xA;                if (result == 0) {&#xA;                    if (this.m_VideoDecoderCtx.hw_device_ctx() == null) {&#xA;                        decodedFrame = avFrame;&#xA;                        System.out.println("SUCESS with SW decoding");&#xA;                    } else {&#xA;                        final AVFrame hwAvFrame = av_frame_alloc();&#xA;                        if (av_hwframe_transfer_data(hwAvFrame, avFrame, 0) &lt; 0) {&#xA;                            System.out.println("Failed to transfer frame from hardware");&#xA;                            av_frame_unref(hwAvFrame);&#xA;                            decodedFrame = avFrame;&#xA;                        } else {&#xA;                            av_frame_unref(avFrame);&#xA;                            decodedFrame = hwAvFrame;&#xA;                            System.out.println("SUCESS with HW decoding");&#xA;                        }&#xA;                    }&#xA;&#xA;                    av_frame_unref(decodedFrame);&#xA;                } else {&#xA;                    final BytePointer buffer = new BytePointer(512);&#xA;                    av_strerror(result, buffer, buffer.capacity());&#xA;                    final String string = buffer.getString();&#xA;                    System.out.println("error " &#x2B; result &#x2B; " message " &#x2B; string);&#xA;                    av_frame_free(avFrame);&#xA;                }&#xA;            }&#xA;        } finally {&#xA;            if (pkt.stream_index() != -1) {&#xA;                av_packet_unref(pkt);&#xA;            }&#xA;            pkt.releaseReference();&#xA;        }&#xA;    }&#xA;&#xA;    final Object releaseLock = new Object();&#xA;    private volatile boolean released = false;&#xA;&#xA;    private void releaseNativeResources() {&#xA;        if (this.released) {&#xA;            return;&#xA;        }&#xA;        this.released = true;&#xA;        synchronized (this.releaseLock) {&#xA;            // Close the video codec&#xA;            if (this.m_VideoDecoderCtx != null) {&#xA;                avcodec_free_context(this.m_VideoDecoderCtx);&#xA;                this.m_VideoDecoderCtx = null;&#xA;            }&#xA;&#xA;            // close the format callback&#xA;            if (this.formatCallback != null) {&#xA;                this.formatCallback.close();&#xA;                this.formatCallback = null;&#xA;            }&#xA;&#xA;            // close hw context&#xA;            if (this.hardwareContext != null) {&#xA;                this.hardwareContext.free();&#xA;            }&#xA;        }&#xA;    }&#xA;&#xA;    private int getDefaultPixelFormat() {&#xA;        return AV_PIX_FMT_YUV420P; // Always return yuv420p here&#xA;    }&#xA;&#xA;&#xA;    /*********************/&#xA;    /*** inner classes ***/&#xA;    /*********************/&#xA;&#xA;    public static final class HexUtil {&#xA;&#xA;        private HexUtil() {&#xA;        }&#xA;&#xA;        public static byte[] unhexlify(final String argbuf) {&#xA;            final int arglen = argbuf.length();&#xA;            if (arglen % 2 != 0) {&#xA;                throw new RuntimeException("Odd-length string");&#xA;            } else {&#xA;                final byte[] retbuf = new byte[arglen / 2];&#xA;&#xA;                for (int i = 0; i &lt; arglen; i &#x2B;= 2) {&#xA;                    final int top = Character.digit(argbuf.charAt(i), 16);&#xA;                    final int bot = Character.digit(argbuf.charAt(i &#x2B; 1), 16);&#xA;                    if (top == -1 || bot == -1) {&#xA;                        throw new RuntimeException("Non-hexadecimal digit found");&#xA;                    }&#xA;&#xA;                    retbuf[i / 2] = (byte) ((top &lt;&lt; 4) &#x2B; bot);&#xA;                }&#xA;&#xA;                return retbuf;&#xA;            }&#xA;        }&#xA;    }&#xA;&#xA;    public static final class AVHWContextInfo {&#xA;        private final AVCodecHWConfig hwConfig;&#xA;        private final AVBufferRef hwContext;&#xA;&#xA;        private volatile boolean freed = false;&#xA;&#xA;        public AVHWContextInfo(final AVCodecHWConfig hwConfig, final AVBufferRef hwContext) {&#xA;            this.hwConfig = hwConfig;&#xA;            this.hwContext = hwContext;&#xA;        }&#xA;&#xA;        public AVCodecHWConfig hwConfig() {&#xA;            return this.hwConfig;&#xA;        }&#xA;&#xA;        public AVBufferRef hwContext() {&#xA;            return this.hwContext;&#xA;        }&#xA;&#xA;        public void free() {&#xA;            if (this.freed) {&#xA;                return;&#xA;            }&#xA;            this.freed = true;&#xA;            av_free(this.hwConfig);&#xA;            av_free(this.hwContext);&#xA;        }&#xA;&#xA;&#xA;        @Override&#xA;        public boolean equals(Object o) {&#xA;            if (this == o) return true;&#xA;            if (o == null || getClass() != o.getClass()) return false;&#xA;            AVHWContextInfo that = (AVHWContextInfo) o;&#xA;            return freed == that.freed &amp;&amp; Objects.equals(hwConfig, that.hwConfig) &amp;&amp; Objects.equals(hwContext, that.hwContext);&#xA;        }&#xA;&#xA;        @Override&#xA;        public int hashCode() {&#xA;            return Objects.hash(hwConfig, hwContext, freed);&#xA;        }&#xA;&#xA;        @Override&#xA;        public String toString() {&#xA;            return "AVHWContextInfo[" &#x2B;&#xA;                    "hwConfig=" &#x2B; this.hwConfig &#x2B; ", " &#x2B;&#xA;                    "hwContext=" &#x2B; this.hwContext &#x2B; &#x27;]&#x27;;&#xA;        }&#xA;    }&#xA;&#xA;    public static final class AVTestFrames {&#xA;&#xA;        private AVTestFrames() {&#xA;&#xA;        }&#xA;&#xA;        static {&#xA;            InputStream inputStream = null;&#xA;            try {&#xA;                inputStream = AVTestFrames.class.getClassLoader().getResourceAsStream("h264_test_key_frame.txt");&#xA;                final byte[] h264TestFrameBuffer = inputStream == null ? new byte[0] : inputStream.readAllBytes();&#xA;                final String h264TestFrame = new String(h264TestFrameBuffer, StandardCharsets.UTF_8);&#xA;                AVTestFrames.h264KeyTestFrame = HexUtil.unhexlify(h264TestFrame);&#xA;            } catch (final IOException e) {&#xA;                Logger.error(e, "Could not parse test frame");&#xA;            } finally {&#xA;                if (inputStream != null) {&#xA;                    try {&#xA;                        inputStream.close();&#xA;                    } catch (final IOException e) {&#xA;                        Logger.error(e, "Could not close test frame input stream");&#xA;                    }&#xA;                }&#xA;            }&#xA;        }&#xA;&#xA;        public static byte[] h264KeyTestFrame;&#xA;    }&#xA;&#xA;    public static class FFmpegLogCallback extends LogCallback {&#xA;&#xA;        private static final org.bytedeco.javacpp.tools.Logger logger = org.bytedeco.javacpp.tools.Logger.create(FFmpegLogCallback.class);&#xA;&#xA;        static final FFmpegLogCallback instance = new FFmpegLogCallback().retainReference();&#xA;&#xA;        public static FFmpegLogCallback getInstance() {&#xA;            return instance;&#xA;        }&#xA;&#xA;        /**&#xA;         * Calls {@code avutil.setLogCallback(getInstance())}.&#xA;         */&#xA;        public static void set() {&#xA;            setLogCallback(getInstance());&#xA;        }&#xA;&#xA;        /**&#xA;         * Returns {@code av_log_get_level()}.&#xA;         **/&#xA;        public static int getLevel() {&#xA;            return av_log_get_level();&#xA;        }&#xA;&#xA;        /**&#xA;         * Calls {@code av_log_set_level(level)}.&#xA;         **/&#xA;        public static void setLevel(int level) {&#xA;            av_log_set_level(level);&#xA;        }&#xA;&#xA;        @Override&#xA;        public void call(int level, BytePointer msg) {&#xA;            switch (level) {&#xA;                case AV_LOG_PANIC, AV_LOG_FATAL, AV_LOG_ERROR -> logger.error(msg.getString());&#xA;                case AV_LOG_WARNING -> logger.warn(msg.getString());&#xA;                case AV_LOG_INFO -> logger.info(msg.getString());&#xA;                case AV_LOG_VERBOSE, AV_LOG_DEBUG, AV_LOG_TRACE -> logger.debug(msg.getString());&#xA;                default -> {&#xA;                    assert false;&#xA;                }&#xA;            }&#xA;        }&#xA;    }&#xA;}&#xA;</boolean>

    &#xA;