Recherche avancée

Médias (1)

Mot : - Tags -/bug

Autres articles (67)

  • Mise à jour de la version 0.1 vers 0.2

    24 juin 2013, par

    Explications des différents changements notables lors du passage de la version 0.1 de MediaSPIP à la version 0.3. Quelles sont les nouveautés
    Au niveau des dépendances logicielles Utilisation des dernières versions de FFMpeg (>= v1.2.1) ; Installation des dépendances pour Smush ; Installation de MediaInfo et FFprobe pour la récupération des métadonnées ; On n’utilise plus ffmpeg2theora ; On n’installe plus flvtool2 au profit de flvtool++ ; On n’installe plus ffmpeg-php qui n’est plus maintenu au (...)

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

  • Ecrire une actualité

    21 juin 2013, par

    Présentez les changements dans votre MédiaSPIP ou les actualités de vos projets sur votre MédiaSPIP grâce à la rubrique actualités.
    Dans le thème par défaut spipeo de MédiaSPIP, les actualités sont affichées en bas de la page principale sous les éditoriaux.
    Vous pouvez personnaliser le formulaire de création d’une actualité.
    Formulaire de création d’une actualité Dans le cas d’un document de type actualité, les champs proposés par défaut sont : Date de publication ( personnaliser la date de publication ) (...)

Sur d’autres sites (13217)

  • Working with ffmpeg in Xamarin Android

    20 avril 2017, par Ahmed Mujtaba

    I’m building an android app using Xamarin. The requirement of the app is to capture video from the camera and encode the video to send it across to a server. Initially I was using an encoder library on the server side to encode recorded video but it was proving to be extremely unreliable and inefficient specially for large sized video files. I have posted my issues on another thread here I then decided to encode the video on the client side and then send it to the server. I’ve found encoding to be a bit complicated and there isn’t much information available on how this can be done so I search for the only way I knew how to encode a video that is by using ffmpeg codec. I’ve found some solutions. There’s a project on github that demonstrates how ffmpeg is used inside a Xamarin android project. However running the solution doesn’t give any output. The project has a binary ffmpeg file which is installed to the phone directory using the code below :

    _ffmpegBin = InstallBinary(XamarinAndroidFFmpeg.Resource.Raw.ffmpeg, "ffmpeg", false);

    Below is the example code for encoding video into different set of outputs :

               _workingDirectory = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
           var sourceMp4 = "cat1.mp4";
           var destinationPathAndFilename = System.IO.Path.Combine (_workingDirectory, "cat1_out.mp4");
           var destinationPathAndFilename2 = System.IO.Path.Combine (_workingDirectory, "cat1_out2.mp4");
           var destinationPathAndFilename4 = System.IO.Path.Combine (_workingDirectory, "cat1_out4.wav");
           if (File.Exists (destinationPathAndFilename))
               File.Delete (destinationPathAndFilename);
           CreateSampleFile(Resource.Raw.cat1, _workingDirectory, sourceMp4);


           var ffmpeg = new FFMpeg (this, _workingDirectory);

           var sourceClip = new Clip (System.IO.Path.Combine(_workingDirectory, sourceMp4));

           var result = ffmpeg.GetInfo (sourceClip);

           var br = System.Environment.NewLine;

           // There are callbacks based on Standard Output and Standard Error when ffmpeg binary is running as a process:

           var onComplete = new MyCommand ((_) => {
               RunOnUiThread(() =>_logView.Append("DONE!" + br + br));
           });

           var onMessage = new MyCommand ((message) => {
               RunOnUiThread(() =>_logView.Append(message + br + br));
           });

           var callbacks = new FFMpegCallbacks (onComplete, onMessage);

           // 1. The idea of this first test is to show that video editing is possible via FFmpeg:
           // It results in a 150x150 movie that eventually zooms on a cat ear. This is desaturated, and there's a fade in.

           var filters = new List<videofilter> ();
           filters.Add (new FadeVideoFilter ("in", 0, 100));
           filters.Add(new CropVideoFilter("150","150","0","0"));
           filters.Add(new ColorVideoFilter(1.0m, 1.0m, 0.0m, 0.5m, 1.0m, 1.0m, 1.0m, 1.0m));
           var outputClip = new Clip (destinationPathAndFilename) { videoFilter = VideoFilter.Build (filters)  };
           outputClip.H264_CRF = "18"; // It's the quality coefficient for H264 - Default is 28. I think 18 is pretty good.
           ffmpeg.ProcessVideo(sourceClip, outputClip, true, new FFMpegCallbacks(onComplete, onMessage));

           //2. This is a similar version version in command line only:
           string[] cmds = new string[] {
               "-y",
               "-i",
               sourceClip.path,
               "-strict",
               "-2",
               "-vf",
               "mp=eq2=1:1.68:0.3:1.25:1:0.96:1",
               destinationPathAndFilename2,
               "-acodec",
               "copy",
           };
           ffmpeg.Execute (cmds, callbacks);

           // 3. This lists codecs:
           string[] cmds3 = new string[] {
               "-codecs",
           };
           ffmpeg.Execute (cmds, callbacks);

           // 4. This convers to WAV
           // Note that the cat movie just has some silent house noise.
           ffmpeg.ConvertToWaveAudio(sourceClip, destinationPathAndFilename4, 44100, 2, callbacks, true);
    </videofilter>

    I have tried different commands but no output file is generated. I have tried to use another project found here but this one has the same issue. I don’t get any errors but no output file is generated. I’m really hoping someone can help me find a way I can manage to use ffmpeg in my project or some way to compress video to transport it to the server.

    I will really appreciate if someone can point me to the right direction.

  • FFmpeg - capture a flv stream and re-stream it to youtube

    27 juin 2023, par Noob Pwn

    is it possible to use FFmpeg to capture a flv stream and re-stream it to youtube as live stream

    &#xA;

    i expect someone show me the best configuration considering i am using a low resource 1 GB ram and 2 gb as storage cloud computer

    &#xA;

  • FFmpeg invalid data found when processing input with D3D11VA and DXVA2 hw acceleration

    6 mai 2023, par grill2010

    I'm currently porting my Android streaming app to Windows and for decoding the h264 video stream I use FFmpeg with possible hardware acceleration. Last two weeks I was reading a lot of documentation and studied a lot of examples on the internet. For my project I use JavaCV which is internally using FFmpeg 5.1.2. On Windows I support D3D11VA, DXVA2 and Cuvid for hardware acceleration (and software decoding as fallback). During testing I noticed that I get some strange artefacts when using D3D11VA or DXVA2 hw acceleration. Upon further investigation I saw that I receive a lot of

    &#xA;

    "Invalid data found when processing input"

    &#xA;

    errors when calling avcodec_send_packet. It seems this error only occurs on certain key frames. The error is reproducable all the time. The software decoder or cuvid decoder has absolutely no problem to process and to decode such a frame, so not sure why there should be an invalid data in the frame ? I played around a lot with the decoder configuration but nothing seems to help and at that point I think this is definitely not normal behaviour.

    &#xA;

    I provided a reproducable example which can be downloaded from here. All the important part is in the App.java class. In addition an example of the code was posted below. The example is trying to decode a key frame. The keyframe data with sps and pps is read from a file in the resource folder of the project.

    &#xA;

    To run the project just perform a .\gradlew build and afterwards a .\gradlew run. If you run the example the last log message shown in the terminal should be "SUCESS with HW decoding". The hardware decoder can be changed via the HW_DEVICE_TYPE variable in the App.java class. To disable hw acceleration just set the USE_HW_ACCEL to false.

    &#xA;

    For me everything seems to be correct and I have no idea what could be wrong with the code. I looked a lot on the internet to find the root cause of the issue and I did not really found a solution but other sources which are related to (maybe) the same problem

    &#xA;

    https://www.mail-archive.com/libav-user@ffmpeg.org/...

    &#xA;

    https://stackoverflow.com/questions/67307397/ffmpeg-...

    &#xA;

    I also found another streaming app on Windows which can use D3D11VA and DXVA2 hardware acceleration called Chiaki (it requires a PS4 or a PS5) which seems to have the exact same problem. I used the build provided here. It will fail to decode certain key frames as well when hardware acceleration with D3D11VA or DXVA2 is selected (e.g. the first key frame received by the stream). Chiaki can output the seemingly faulty frame but this is also possible with my example by setting the USE_AV_EF_EXPLODE to false.

    &#xA;

    Are there any ffmpeg gurus around that can check what's the problem with D3D11VA or DXVA2 ? Anything else that needs to be done to make the D3D11VA and DXVA2 hardware decoder work ? I'm now completly out of ideas and I'm not even sure if this is fixable.

    &#xA;

    I have Windows 11 installed on my test machine, and I have the latest Nvidea drivers installed.

    &#xA;

    Edit : here is a shrinked complete example of my project (keyframe file which includes sps and pps can be downloaded from here. It's a hex string file and can be decoded with the provided HexUtil class)

    &#xA;

    import javafx.application.Application;&#xA;import javafx.scene.Scene;&#xA;import javafx.scene.layout.Pane;&#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.javacpp.BytePointer;&#xA;import org.bytedeco.javacpp.IntPointer;&#xA;import org.bytedeco.javacv.FFmpegLogCallback;&#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.AV_EF_EXPLODE;&#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;    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;            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.setLevel(AV_LOG_QUIET);&#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;&#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;&#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 == 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;    /*** video processing ***/&#xA;    /************************/&#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 * 4)) {&#xA;            final byte[] frameData = AVTestFrames.h264KeyTestFrame;&#xA;&#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;            final AVFrame avFrame = av_frame_alloc();&#xA;&#xA;            final int err = avcodec_send_packet(this.m_VideoDecoderCtx, pkt); // this will fail with D3D11VA and DXVA2&#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;                    av_frame_unref(decodedFrame);&#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;                    av_frame_unref(decodedFrame);&#xA;                }&#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;        } 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;    public static final class HexUtil {&#xA;        private static final char[] hexArray = "0123456789ABCDEF".toCharArray();&#xA;&#xA;        private HexUtil() {&#xA;        }&#xA;&#xA;        public static String hexlify(final byte[] bytes) {&#xA;            final char[] hexChars = new char[bytes.length * 2];&#xA;&#xA;            for (int j = 0; j &lt; bytes.length; &#x2B;&#x2B;j) {&#xA;                final int v = bytes[j] &amp; 255;&#xA;                hexChars[j * 2] = HexUtil.hexArray[v >>> 4];&#xA;                hexChars[j * 2 &#x2B; 1] = HexUtil.hexArray[v &amp; 15];&#xA;            }&#xA;&#xA;            return new String(hexChars);&#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;&#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;                        inputStream = null;&#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;</boolean>

    &#xA;

    The build gradle of the project looks like this

    &#xA;

    plugins {&#xA;    id &#x27;application&#x27;&#xA;    id &#x27;org.openjfx.javafxplugin&#x27; version &#x27;0.0.13&#x27;&#xA;}&#xA;&#xA;group &#x27;com.test.example&#x27;&#xA;version &#x27;1.0.0&#x27;&#xA;&#xA;repositories {&#xA;    mavenCentral()&#xA;    mavenLocal()&#xA;    maven { url &#x27;https://jitpack.io&#x27; }&#xA;}&#xA;&#xA;dependencies {&#xA;    implementation group: &#x27;org.bytedeco&#x27;, name: &#x27;javacv-platform&#x27;, version: &#x27;1.5.8&#x27;&#xA;    implementation group: &#x27;com.github.oshi&#x27;, name: &#x27;oshi-core&#x27;, version: &#x27;3.4.3&#x27;&#xA;    implementation &#x27;org.tinylog:tinylog-api:2.1.0&#x27;&#xA;    implementation &#x27;org.tinylog:tinylog-impl:2.1.0&#x27;&#xA;    implementation &#x27;org.jcodec:jcodec:0.2.5&#x27;&#xA;}&#xA;&#xA;test {&#xA;    useJUnitPlatform()&#xA;}&#xA;&#xA;javafx {&#xA;    version = &#x27;17.0.6&#x27;&#xA;    modules = [&#x27;javafx.graphics&#x27;, &#x27;javafx.controls&#x27;, &#x27;javafx.fxml&#x27;, &#x27;javafx.base&#x27;]&#xA;}&#xA;&#xA;mainClassName = &#x27;com.test.example.App&#x27;&#xA;

    &#xA;