Permalink
..
Failed to load latest commit information.
platform Update version in the `pom.xml` files to 1.4.4-SNAPSHOT Oct 16, 2018
src/main Release version 1.4.3 Oct 15, 2018
COPYING.GPLv2 * Added presets for PGR FlyCapture 1.7 Mar 23, 2014
COPYING.GPLv3 * Added presets for PGR FlyCapture 1.7 Mar 23, 2014
COPYING.LGPLv2.1 * Added presets for PGR FlyCapture 1.7 Mar 23, 2014
COPYING.LGPLv3 * Added presets for PGR FlyCapture 1.7 Mar 23, 2014
COPYING.lame * Add Speex and OpenSSL in the `cppbuild.sh` for FFmpeg to support c… Nov 16, 2014
COPYING.mfx * Upgrade presets for FFmpeg 3.4.1 Dec 11, 2017
COPYING.opencore-amr * Add OpenCORE AMR-NB and AMR-WB in the `cppbuild.sh` script for FFm… Dec 23, 2014
COPYING.opus * Upgrade presets for FFmpeg 3.4 and its dependencies Oct 22, 2017
COPYING.speex * Add Speex and OpenSSL in the `cppbuild.sh` for FFmpeg to support c… Nov 16, 2014
COPYING.x264 * Add Speex and OpenSSL in the `cppbuild.sh` for FFmpeg to support c… Nov 16, 2014
COPYING.x265 Update version in `pom.xml` files to 0.11-SNAPSHOT Feb 28, 2015
COPYRIGHT.nv Add missing license files for OpenCV, FFmpeg, HDF5, and Leptonica Aug 3, 2018
LICENSE.TXT * Upgrade presets for FFmpeg 3.4 and its dependencies Oct 22, 2017
LICENSE.lame * Add Speex and OpenSSL in the `cppbuild.sh` for FFmpeg to support c… Nov 16, 2014
LICENSE.libvpx * Add libvpx in the `cppbuild.sh` script for FFmpeg to support the W… Jun 13, 2015
LICENSE.md * Upgrade presets for FFmpeg 4.0 and its dependencies Apr 23, 2018
LICENSE.opencore-amr * Add OpenCORE AMR-NB and AMR-WB in the `cppbuild.sh` script for FFm… Dec 23, 2014
LICENSE.openh264 Release version 1.1 Oct 25, 2015
LICENSE.openssl * Add Speex and OpenSSL in the `cppbuild.sh` for FFmpeg to support c… Nov 16, 2014
LICENSE.zlib Add missing license files for OpenCV, FFmpeg, HDF5, and Leptonica Aug 3, 2018
README.md Release version 1.4.3 Oct 15, 2018
cppbuild.sh Fix build for FFmpeg with GCC 8.x on Windows Sep 6, 2018
ffmpeg-macosx.patch * Upgrade presets for FFmpeg 4.0 and its dependencies Apr 23, 2018
ffmpeg.patch * Upgrade presets for FFmpeg 4.0 and its dependencies Apr 23, 2018
lame.patch * Enable Intel QSV acceleration via libmfx for FFmpeg (pull #485) Dec 5, 2017
libvpx-android.patch * Fix build for FFmpeg on `android-x86` and `android-x86_64` platfor… Apr 2, 2018
libvpx-linux-arm.patch * Fix FFmpeg build of libvpx with Linux on ARM (issue #586) Jul 14, 2018
pom.xml Update version in the `pom.xml` files to 1.4.4-SNAPSHOT Oct 16, 2018
x264-android.patch * Upgrade presets for FFmpeg 4.0.2 and its dependencies Aug 10, 2018
x265-android.patch * Add builds for `android-arm64` and `android-x86_64` platforms (issue Feb 25, 2018

README.md

JavaCPP Presets for FFmpeg

Introduction

This directory contains the JavaCPP Presets module for:

Please refer to the parent README.md file for more detailed information about the JavaCPP Presets.

Documentation

Java API documentation is available here:

Sample Usage

Here is a simple example of FFmpeg ported to Java from this C source file:

We can use Maven 3 to download and install automatically all the class files as well as the native binaries. To run this sample code, after creating the pom.xml and src/main/java/ReadFewFrame.java source files below, simply execute on the command line:

 $ mvn compile exec:java -Dexec.args="myvideofile.mpg"

The pom.xml build file

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.bytedeco.javacpp-presets.ffmpeg</groupId>
    <artifactId>readfewframe</artifactId>
    <version>1.4.3</version>
    <properties>
        <exec.mainClass>ReadFewFrame</exec.mainClass>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>4.0.2-1.4.3</version>
        </dependency>
    </dependencies>
</project>

The src/main/java/ReadFewFrame.java source file

import java.io.*;
import org.bytedeco.javacpp.*;
import static org.bytedeco.javacpp.avcodec.*;
import static org.bytedeco.javacpp.avformat.*;
import static org.bytedeco.javacpp.avutil.*;
import static org.bytedeco.javacpp.swscale.*;

public class ReadFewFrame {
    /**
    * Write image data using simple image format ppm
    * @see https://en.wikipedia.org/wiki/Netpbm_format
    */
    static void save_frame(AVFrame pFrame, int width, int height, int f_idx) throws IOException {
        // Open file
        String szFilename = String.format("frame%d_.ppm", f_idx);
        OutputStream pFile = new FileOutputStream(szFilename);

        // Write header
        pFile.write(String.format("P6\n%d %d\n255\n", width, height).getBytes());

        // Write pixel data
        BytePointer data = pFrame.data(0);
        byte[] bytes = new byte[width * 3];
        int l = pFrame.linesize(0);
        for(int y = 0; y < height; y++) {
            data.position(y * l).get(bytes);
            pFile.write(bytes);
        }

        // Close file
        pFile.close();
    }

    public static void main(String[] args) throws Exception {
        System.out.println("Read few frame and write to image");
        if (args.length < 1) {
            System.out.println("Missing input video file");
            System.exit(-1);
        }
        int ret = -1, i = 0, v_stream_idx = -1;
        String vf_path = args[0];
        AVFormatContext fmt_ctx = new AVFormatContext(null);
        AVPacket pkt = new AVPacket();

        ret = avformat_open_input(fmt_ctx, vf_path, null, null);
        if (ret < 0) {
            System.out.printf("Open video file %s failed \n", vf_path);
            throw new IllegalStateException();
        }

        // i dont know but without this function, sws_getContext does not work
        if (avformat_find_stream_info(fmt_ctx, (PointerPointer)null) < 0) {
            System.exit(-1);
        }

        av_dump_format(fmt_ctx, 0, args[0], 0);

        for (i = 0; i < fmt_ctx.nb_streams(); i++) {
            if (fmt_ctx.streams(i).codecpar().codec_type() == AVMEDIA_TYPE_VIDEO) {
                v_stream_idx = i;
                break;
            }
        }
        if (v_stream_idx == -1) {
            System.out.println("Cannot find video stream");
            throw new IllegalStateException();
        } else {
            System.out.printf("Video stream %d with resolution %dx%d\n", v_stream_idx,
                    fmt_ctx.streams(i).codecpar().width(),
                    fmt_ctx.streams(i).codecpar().height());
        }

        AVCodecContext codec_ctx = avcodec_alloc_context3(null);
        avcodec_parameters_to_context(codec_ctx, fmt_ctx.streams(v_stream_idx).codecpar());

        AVCodec codec = avcodec_find_decoder(codec_ctx.codec_id());
        if (codec == null) {
            System.out.println("Unsupported codec for video file");
            throw new IllegalStateException();
        }
        ret = avcodec_open2(codec_ctx, codec, (PointerPointer)null);
        if (ret < 0) {
            System.out.println("Can not open codec");
            throw new IllegalStateException();
        }

        AVFrame frm = av_frame_alloc();

        // Allocate an AVFrame structure
        AVFrame pFrameRGB = av_frame_alloc();
        if (pFrameRGB == null) {
            System.exit(-1);
        }

        // Determine required buffer size and allocate buffer
        int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx.width(),
                        codec_ctx.height(), 1);
        BytePointer buffer = new BytePointer(av_malloc(numBytes));

        SwsContext sws_ctx = sws_getContext(
                codec_ctx.width(),
                codec_ctx.height(),
                codec_ctx.pix_fmt(),
                codec_ctx.width(),
                codec_ctx.height(),
                AV_PIX_FMT_RGB24,
                SWS_BILINEAR,
                null,
                null,
                (DoublePointer)null
            );

        if (sws_ctx == null) {
            System.out.println("Can not use sws");
            throw new IllegalStateException();
        }

        av_image_fill_arrays(pFrameRGB.data(), pFrameRGB.linesize(),
                buffer, AV_PIX_FMT_RGB24, codec_ctx.width(), codec_ctx.height(), 1);

        i = 0;
        int ret1 = -1, ret2 = -1, fi = -1;
        while (av_read_frame(fmt_ctx, pkt) >= 0) {
            if (pkt.stream_index() == v_stream_idx) {
                ret1 = avcodec_send_packet(codec_ctx, pkt);
                ret2 = avcodec_receive_frame(codec_ctx, frm);
                System.out.printf("ret1 %d ret2 %d\n", ret1, ret2);
                // avcodec_decode_video2(codec_ctx, frm, fi, pkt);
            }
            // if not check ret2, error occur [swscaler @ 0x1cb3c40] bad src image pointers
            // ret2 same as fi
            // if (fi && ++i <= 5) {
            if (ret2 >= 0 && ++i <= 5) {
                sws_scale(
                        sws_ctx,
                        frm.data(),
                        frm.linesize(),
                        0,
                        codec_ctx.height(),
                        pFrameRGB.data(),
                        pFrameRGB.linesize()
                    );

                save_frame(pFrameRGB, codec_ctx.width(), codec_ctx.height(), i);
                // save_frame(frm, codec_ctx.width(), codec_ctx.height(), i);
            }
            av_packet_unref(pkt);
            if (i >= 5) {
                break;
            }
        }

        av_frame_free(frm);

        avcodec_close(codec_ctx);
        avcodec_free_context(codec_ctx);

        avformat_close_input(fmt_ctx);
        System.out.println("Shutdown");
        System.exit(0);
    }
}