Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

277
LINES

< > BotCompany Repo | #1033823 // JavaCPP ffpmeg Encode H264 Demo [OK on Linux x64]

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Uses 16081K of libraries. Click here for Pure Java version (319L/3K).

1  
!7
2  
3  
// from https://github.com/vzhn/ffmpeg-java-samples/blob/master/src/main/java/EncodeAndMuxH264.java
4  
5  
/*lib 1400538
6  
lib 1400539
7  
lib 1400540
8  
lib 1400541
9  
lib 1400542
10  
lib 1400543*/
11  
lib 1400544 // javacpp ffmpeg examples for linux x64
12  
13  
p { EncodeAndMuxH264.main(args); }
14  
15  
import org.apache.commons.cli.CommandLine;
16  
import org.apache.commons.cli.DefaultParser;
17  
import org.apache.commons.cli.Option;
18  
import org.apache.commons.cli.Options;
19  
import org.apache.commons.cli.HelpFormatter;
20  
import org.apache.commons.cli.ParseException;
21  
import org.bytedeco.javacpp.*;
22  
23  
import java.awt.*;
24  
import java.awt.image.BufferedImage;
25  
import java.awt.image.DataBufferByte;
26  
27  
import static org.bytedeco.javacpp.avcodec.*;
28  
import static org.bytedeco.javacpp.avformat.*;
29  
import static org.bytedeco.javacpp.avutil.*;
30  
import static org.bytedeco.javacpp.swscale.sws_getContext;
31  
32  
sclass EncodeAndMuxH264 {
33  
    private final static String DEFAULT_FPS = "30";
34  
    private static final String DEFAULT_BITRATE = "400000";
35  
    private static final String DEFAULT_WIDTH = "640";
36  
    private static final String DEFAULT_HEIGHT = "320";
37  
    private static final String DEFAULT_GOP = "60";
38  
    private static final String DEFAULT_MAX_B_FRAMES = "12";
39  
    private static final String DEFAULT_N_FRAMES = "300";
40  
    private static final String DEFAULT_PROFILE = "baseline";
41  
    private static final String DEFAULT_FILE = "out.mkv";
42  
43  
    private AVFrame frame;
44  
    private AVFrame rgbFrame;
45  
    private swscale.SwsContext swsContext;
46  
    private BufferedImage image;
47  
    private AVCodecContext cc;
48  
    private int fps;
49  
    private int bitrate;
50  
    private int width;
51  
    private int height;
52  
    private int gopSize;
53  
    private int maxBFrames;
54  
    private int nFrames;
55  
    private String profile;
56  
    private AVCodec codec;
57  
    private AVFormatContext oc;
58  
    private AVOutputFormat fmt;
59  
    private String ofile;
60  
    private AVRational streamTimebase;
61  
    private AVRational codecTimebase;
62  
    private AVPacket pkt;
63  
64  
    private EncodeAndMuxH264() {}
65  
66  
    public static void main(String... argv) throws ParseException {
67  
        Options options = new Options();
68  
        options.addOption("help", false, "show help and exit");
69  
        options.addOption("fps", true, "fps");
70  
        options.addOption("bitrate", true, "bitrate");
71  
        options.addOption("width", true, "width");
72  
        options.addOption("height", true, "height");
73  
        options.addOption("gop", true, "gop");
74  
        options.addOption("max_b_frames", true, "max_b_frames");
75  
        options.addOption("n_frames", true, "number of frames");
76  
        options.addOption("profile", true, "h264 profile");
77  
        options.addOption("file", true, "output file name");
78  
        CommandLine cmd = new DefaultParser().parse(options, argv);
79  
        if (cmd.hasOption("help")) {
80  
            HelpFormatter helpFormatter = new HelpFormatter();
81  
            helpFormatter.printHelp("EncodeAndMuxH264 [options]", options);
82  
        } else {
83  
            System.out.println("options:");
84  
            EncodeAndMuxH264 instance = new EncodeAndMuxH264();
85  
            instance.fps = Integer.parseInt(getOption(cmd, "fps", DEFAULT_FPS));
86  
            instance.bitrate = Integer.parseInt(getOption(cmd, "bitrate", DEFAULT_BITRATE));
87  
            instance.width = Integer.parseInt(getOption(cmd,"width", DEFAULT_WIDTH));
88  
            instance.height = Integer.parseInt(getOption(cmd,"height", DEFAULT_HEIGHT));
89  
            instance.gopSize = Integer.parseInt(getOption(cmd,"gop", DEFAULT_GOP));
90  
            instance.maxBFrames = Integer.parseInt(getOption(cmd,"max_b_frames", DEFAULT_MAX_B_FRAMES));
91  
            instance.nFrames = Integer.parseInt(getOption(cmd,"n_frames", DEFAULT_N_FRAMES));
92  
            instance.profile = getOption(cmd,"profile", DEFAULT_PROFILE);
93  
            instance.ofile = getOption(cmd,"file", DEFAULT_FILE);
94  
95  
            instance.start();
96  
        }
97  
    }
98  
99  
    private static String getOption(CommandLine cmd, String key, String defaultValue) {
100  
        String v = cmd.getOptionValue(key, defaultValue);
101  
        System.out.println("\t" + key + " = \"" + v + "\"");
102  
        return v;
103  
    }
104  
105  
    private void start() {
106  
        allocCodecContext();
107  
108  
        AVPacket pkt = av_packet_alloc();
109  
110  
        allocFrame(cc);
111  
        allocRgbFrame(cc);
112  
        allocSwsContext();
113  
        allocOutputContext();
114  
115  
        encodeVideo(pkt);
116  
        writeDelayedFrames();
117  
118  
        av_write_trailer(oc);
119  
        free(cc, oc);
120  
    }
121  
122  
    private void writeDelayedFrames() {
123  
        sendFrame(null);
124  
    }
125  
126  
    private void encodeVideo(AVPacket pkt) {
127  
        for (int i = 0; i < nFrames; i++) {
128  
            frame.pts(avutil.av_rescale_q(i, codecTimebase, streamTimebase));
129  
130  
            drawFrame(i);
131  
            sendFrame(frame);
132  
        }
133  
    }
134  
135  
    private void sendFrame(AVFrame o) {
136  
        int r = avcodec.avcodec_send_frame(cc, o);
137  
        if (r == 0) {
138  
            receivePacket();
139  
        } else {
140  
            throw new RuntimeException("error: " + r);
141  
        }
142  
    }
143  
144  
    private void drawFrame(int n) {
145  
        Graphics gc = image.getGraphics();
146  
        gc.clearRect(0, 0, image.getWidth(), image.getHeight());
147  
        gc.setFont(gc.getFont().deriveFont(50f));
148  
        gc.drawString(String.format("pts: %d", n), 200, 200);
149  
        gc.dispose();
150  
151  
        DataBufferByte dataBufferByte = (DataBufferByte) image.getRaster().getDataBuffer();
152  
        rgbFrame.data(0).put(dataBufferByte.getData());
153  
154  
        swscale.sws_scale(
155  
            swsContext, rgbFrame.data(), rgbFrame.linesize(), 0,
156  
            frame.height(), frame.data(), frame.linesize()
157  
        );
158  
    }
159  
160  
    private void allocOutputContext() {
161  
        oc = new AVFormatContext();
162  
        pkt = new AVPacket();
163  
        int r = avformat_alloc_output_context2(oc, null, null, ofile);
164  
        if (r < 0) {
165  
            throw new RuntimeException("could not allocate output context");
166  
        }
167  
        fmt = oc.oformat();
168  
        AVStream st = avformat_new_stream(oc, codec);
169  
        avcodec_parameters_from_context(st.codecpar(), cc);
170  
        st.time_base(cc.time_base());
171  
172  
        av_dump_format(oc, 0, ofile, 1);
173  
174  
        /* open the output file, if needed */
175  
        PointerPointer pp = new PointerPointer(1);
176  
        try {
177  
            if (avio_open(pp, new BytePointer(ofile), AVIO_FLAG_WRITE) <0){
178  
                throw new RuntimeException("Could not open " + fmt);
179  
            }
180  
            oc.pb(new AVIOContext(pp.get()));
181  
        } finally {
182  
            pp.deallocate();
183  
        }
184  
185  
        /* Write the stream header, if any. */
186  
        if (avformat_write_header(oc, (AVDictionary) null) < 0) {
187  
            throw new RuntimeException("Error occurred when opening output file\n");
188  
        }
189  
190  
        streamTimebase = st.time_base();
191  
    }
192  
193  
    private void allocCodecContext() {
194  
        codecTimebase = new avutil.AVRational();
195  
        codecTimebase.num(1);
196  
        codecTimebase.den(fps);
197  
        codec = avcodec_find_encoder(AV_CODEC_ID_H264);
198  
        cc = avcodec_alloc_context3(codec);
199  
200  
        cc.bit_rate(bitrate);
201  
        cc.width(width);
202  
        cc.height(height);
203  
        cc.time_base(codecTimebase);
204  
        cc.gop_size(gopSize);
205  
        cc.max_b_frames(maxBFrames);
206  
        if (profile != null && !"".equals(profile)) {
207  
            av_opt_set(cc.priv_data(), "profile", profile, 0);
208  
        }
209  
210  
        cc.pix_fmt(avutil.AV_PIX_FMT_YUV420P);
211  
        cc.flags(cc.flags() | AV_CODEC_FLAG_GLOBAL_HEADER);
212  
        if (avcodec_open2(cc, codec, (AVDictionary) null) < 0) {
213  
            throw new RuntimeException("could not open codec");
214  
        }
215  
    }
216  
217  
    private void free(AVCodecContext cc, AVFormatContext oc) {
218  
        avcodec_close(cc);
219  
        avcodec_free_context(cc);
220  
        av_free(rgbFrame.data(0));
221  
        av_free(frame.data(0));
222  
        av_free(rgbFrame);
223  
        av_free(frame);
224  
225  
        avio_close(oc.pb());
226  
        av_free(oc);
227  
    }
228  
229  
    private void allocSwsContext() {
230  
        swsContext = sws_getContext(rgbFrame.width(), rgbFrame.height(), rgbFrame.format(),
231  
                frame.width(), frame.height(), frame.format(), swscale.SWS_BICUBIC,
232  
                null, null, (DoublePointer) null);
233  
234  
        if (swsContext.isNull()) {
235  
            throw new RuntimeException("Could not init sws context!");
236  
        }
237  
    }
238  
239  
    private void allocRgbFrame(AVCodecContext cc) {
240  
        image = new BufferedImage(cc.width(), cc.height(), BufferedImage.TYPE_3BYTE_BGR);
241  
242  
        rgbFrame = av_frame_alloc();
243  
        rgbFrame.format(AV_PIX_FMT_BGR24);
244  
        rgbFrame.width(cc.width());
245  
        rgbFrame.height(cc.height());
246  
        int ret = av_frame_get_buffer(rgbFrame, 32);
247  
        if (ret < 0) {
248  
            throw new RuntimeException("Could not allocate the video frame data");
249  
        }
250  
    }
251  
252  
    private void allocFrame(AVCodecContext cc) {
253  
        frame = av_frame_alloc();
254  
        frame.format(cc.pix_fmt());
255  
        frame.width(cc.width());
256  
        frame.height(cc.height());
257  
        int ret = av_frame_get_buffer(frame, 32);
258  
        if (ret < 0) {
259  
            throw new RuntimeException("Could not allocate the video frame data");
260  
        }
261  
    }
262  
263  
    private void receivePacket() {
264  
        int r;
265  
        while ((r = avcodec.avcodec_receive_packet(cc, pkt)) == 0) {
266  
            r = av_interleaved_write_frame(oc, pkt);
267  
            av_packet_unref(pkt);
268  
            if (r != 0) {
269  
                throw new RuntimeException("Error while writing video frame\n");
270  
            }
271  
        }
272  
273  
        if (r != AVERROR_EAGAIN() && r != AVERROR_EOF()) {
274  
            throw new RuntimeException("error");
275  
        }
276  
    }
277  
}

Author comment

Began life as a copy of #1033821

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033823
Snippet name: JavaCPP ffpmeg Encode H264 Demo [OK on Linux x64]
Eternal ID of this version: #1033823/4
Text MD5: ca049d66e323f8146d8a17ec126aa839
Transpilation MD5: c5d08aceccbd18027d08e4fe5bcec436
Author: stefan
Category: javax / gazelle v
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-01-06 19:17:12
Source code size: 9795 bytes / 277 lines
Pitched / IR pitched: No / No
Views / Downloads: 251 / 1012
Version history: 3 change(s)
Referenced in: [show references]