Skip to content

Commit c518806

Browse files
author
Andrea Medeghini
committed
add example
1 parent 8e05370 commit c518806

13 files changed

Lines changed: 1516 additions & 345 deletions

File tree

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
/ffmpeg4java-windows/src/main/resources/ffmpeg4java.dll
2222
/ffmpeg4java-linux/src/main/resources/libffmpeg4java.so
2323
/ffmpeg4java-macos/src/main/resources/libffmpeg4java.dylib
24-
/ffmpeg4java-macos-examples/output.mov
25-
/ffmpeg4java-linux-examples/output.mov
26-
/ffmpeg4java-windows-examples/output.mov
24+
/ffmpeg4java-macos-examples/output.mp4
25+
/ffmpeg4java-linux-examples/output.mp4
26+
/ffmpeg4java-windows-examples/output.mp4

ffmpeg4java-linux-examples/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
<argument>-Djava.library.path=${project.build.directory}/lib</argument>
6666
<argument>com.nextbreakpoint.ffmpeg4java.linux.ConvertVideoMain</argument>
6767
<argument>sample.mpg</argument>
68-
<argument>output.mov</argument>
68+
<argument>output.mp4</argument>
6969
</arguments>
7070
</configuration>
7171
</execution>

ffmpeg4java-linux-examples/src/main/java/com/nextbreakpoint/ffmpeg4java/linux/ConvertVideoMain.java

Lines changed: 459 additions & 0 deletions
Large diffs are not rendered by default.

ffmpeg4java-linux-examples/src/main/java/com/nextbreakpoint/ffmpeg4java/linux/GenerateVideo.java

Lines changed: 0 additions & 62 deletions
This file was deleted.

ffmpeg4java-linux-test/src/test/java/com/nextbreakpoint/ffmpeg4java/linux/FFmpeg4JavaTest.java

Lines changed: 44 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import static com.nextbreakpoint.ffmpeg4java.linux.Libffmpeg_1.av_write_trailer;
4141
import static com.nextbreakpoint.ffmpeg4java.linux.Libffmpeg_1.avcodec_find_decoder;
4242
import static com.nextbreakpoint.ffmpeg4java.linux.Libffmpeg_1.avcodec_find_encoder;
43+
import static com.nextbreakpoint.ffmpeg4java.linux.Libffmpeg_1.avcodec_parameters_alloc;
4344
import static com.nextbreakpoint.ffmpeg4java.linux.Libffmpeg_1.avformat_alloc_context;
4445
import static com.nextbreakpoint.ffmpeg4java.linux.Libffmpeg_1.avformat_close_input;
4546
import static com.nextbreakpoint.ffmpeg4java.linux.Libffmpeg_1.avformat_find_stream_info;
@@ -112,10 +113,10 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
112113
try (var arena = Arena.ofConfined()) {
113114
var ppInputFormatCtx = NULL;
114115
var pInputCodecCtx = NULL;
115-
var pInputRGBFrame = NULL;
116-
var pInputYUVFrame = NULL;
117116
var pInputSwsContext = NULL;
117+
var pInputRGBFrame = NULL;
118118
var pInputRGBBuffer = NULL;
119+
var pInputTMPFrame = NULL;
119120
var pInputPacket = NULL;
120121

121122
try {
@@ -127,16 +128,16 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
127128
throw new RuntimeException(formatLoadVideoError(fileName, "Can't open file"));
128129
}
129130

130-
final var pFormatCtx = ppInputFormatCtx.get(C_POINTER, 0);
131+
final var pInputFormatCtx = ppInputFormatCtx.get(C_POINTER, 0);
131132

132-
if (avformat_find_stream_info(pFormatCtx, NULL) != 0) {
133+
if (avformat_find_stream_info(pInputFormatCtx, NULL) != 0) {
133134
throw new RuntimeException(formatLoadVideoError(fileName, "Can't find stream info"));
134135
}
135136

136-
av_dump_format(pFormatCtx, 0, pInputFileName, 0);
137+
av_dump_format(pInputFormatCtx, 0, pInputFileName, 0);
137138

138-
final int nbStreams = AVFormatContext.nb_streams(pFormatCtx);
139-
final var pInputStreams = AVFormatContext.streams(pFormatCtx);
139+
final int nbStreams = AVFormatContext.nb_streams(pInputFormatCtx);
140+
final var pInputStreams = AVFormatContext.streams(pInputFormatCtx);
140141

141142
var pInputCodecParameters = NULL;
142143
int videoStreamIndex = -1;
@@ -162,7 +163,7 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
162163
}
163164

164165
if (pInputCodec.equals(NULL)) {
165-
throw new RuntimeException(formatLoadVideoError(fileName, "Can't find codec"));
166+
throw new RuntimeException(formatLoadVideoError(fileName, "Can't find decoder"));
166167
}
167168

168169
pInputCodecCtx = avcodec_alloc_context3(pInputCodec);
@@ -176,7 +177,7 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
176177
}
177178

178179
if (avcodec_open2(pInputCodecCtx, pInputCodec, NULL) < 0) {
179-
throw new RuntimeException(formatLoadVideoError(fileName, "Can't open codec"));
180+
throw new RuntimeException(formatLoadVideoError(fileName, "Can't open decoder"));
180181
}
181182

182183
final int frameWidth = AVCodecContext.width(pInputCodecCtx);
@@ -190,14 +191,14 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
190191
}
191192

192193
pInputRGBFrame = av_frame_alloc();
193-
pInputYUVFrame = av_frame_alloc();
194+
pInputTMPFrame = av_frame_alloc();
194195

195196
if (pInputRGBFrame.equals(NULL)) {
196197
throw new RuntimeException(formatLoadVideoError(fileName, "Can't allocate RGB frame"));
197198
}
198199

199-
if (pInputYUVFrame.equals(NULL)) {
200-
throw new RuntimeException(formatLoadVideoError(fileName, "Can't allocate YUV frame"));
200+
if (pInputTMPFrame.equals(NULL)) {
201+
throw new RuntimeException(formatLoadVideoError(fileName, "Can't allocate TMP frame"));
201202
}
202203

203204
final int rgbByteSize = av_image_get_buffer_size(AV_PIX_FMT_RGB24(), frameWidth, frameHeight, 1);
@@ -222,11 +223,11 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
222223

223224
final byte[] buffer = new byte[rgbByteSize];
224225

225-
while (av_read_frame(pFormatCtx, pInputPacket) == 0) {
226+
while (av_read_frame(pInputFormatCtx, pInputPacket) == 0) {
226227
if (AVPacket.stream_index(pInputPacket) == videoStreamIndex) {
227228
if (avcodec_send_packet(pInputCodecCtx, pInputPacket) == 0) {
228-
while (avcodec_receive_frame(pInputCodecCtx, pInputYUVFrame) == 0) {
229-
sws_scale(pInputSwsContext, AVFrame.data(pInputYUVFrame), AVFrame.linesize(pInputYUVFrame), 0, frameHeight, AVFrame.data(pInputRGBFrame), AVFrame.linesize(pInputRGBFrame));
229+
while (avcodec_receive_frame(pInputCodecCtx, pInputTMPFrame) == 0) {
230+
sws_scale(pInputSwsContext, AVFrame.data(pInputTMPFrame), AVFrame.linesize(pInputTMPFrame), 0, frameHeight, AVFrame.data(pInputRGBFrame), AVFrame.linesize(pInputRGBFrame));
230231

231232
final var pInputData = AVFrame.data(pInputRGBFrame);
232233
MemorySegment.copy(pInputData.get(C_POINTER, 0), 0, MemorySegment.ofArray(buffer), 0, rgbByteSize);
@@ -238,16 +239,20 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
238239
}
239240

240241
if (avcodec_send_packet(pInputCodecCtx, NULL) == 0) {
241-
while (avcodec_receive_frame(pInputCodecCtx, pInputYUVFrame) == 0) {
242-
sws_scale(pInputSwsContext, AVFrame.data(pInputYUVFrame), AVFrame.linesize(pInputYUVFrame), 0, frameHeight, AVFrame.data(pInputRGBFrame), AVFrame.linesize(pInputRGBFrame));
242+
while (avcodec_receive_frame(pInputCodecCtx, pInputTMPFrame) == 0) {
243+
sws_scale(pInputSwsContext, AVFrame.data(pInputTMPFrame), AVFrame.linesize(pInputTMPFrame), 0, frameHeight, AVFrame.data(pInputRGBFrame), AVFrame.linesize(pInputRGBFrame));
243244

244245
final var pInputData = AVFrame.data(pInputRGBFrame);
245246
MemorySegment.copy(pInputData.get(C_POINTER, 0), 0, MemorySegment.ofArray(buffer), 0, rgbByteSize);
246247

247248
consumer.accept(++frameCount, buffer);
248249
}
249250
}
250-
} catch (Exception e) {
251+
} finally {
252+
if (!pInputPacket.equals(NULL)) {
253+
av_packet_unref(pInputPacket);
254+
}
255+
251256
if (!pInputCodecCtx.equals(NULL)) {
252257
avcodec_close(pInputCodecCtx);
253258
}
@@ -256,12 +261,8 @@ private static int loadVideo(String fileName, BiConsumer<Integer, byte[]> consum
256261
sws_freeContext(pInputSwsContext);
257262
}
258263

259-
if (!pInputPacket.equals(NULL)) {
260-
av_packet_unref(pInputPacket);
261-
}
262-
263-
if (!pInputYUVFrame.equals(NULL)) {
264-
av_free(pInputYUVFrame);
264+
if (!pInputTMPFrame.equals(NULL)) {
265+
av_free(pInputTMPFrame);
265266
}
266267

267268
if (!pInputRGBFrame.equals(NULL)) {
@@ -280,16 +281,14 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
280281
int frameCount = 0;
281282

282283
try (var arena = Arena.ofConfined()) {
283-
var ppOutputAVIOCtx = NULL;
284284
var pOutputFormatCtx = NULL;
285-
var pOutputFormat = NULL;
286285
var pOutputCodecCtx = NULL;
286+
var pOutputAVIOCtx = NULL;
287+
var pOutputSwsContext = NULL;
287288
var pOutputRGBFrame = NULL;
288289
var pOutputYUVFrame = NULL;
289-
var pOutputSwsContext = NULL;
290290
var pOutputRGBBuffer = NULL;
291291
var pOutputYUVBuffer = NULL;
292-
var pOutputProperties = NULL;
293292

294293
try {
295294
pOutputFormatCtx = avformat_alloc_context();
@@ -300,22 +299,24 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
300299

301300
final var pOutputFileName = arena.allocateFrom(fileName);
302301

303-
pOutputFormat = av_guess_format(NULL, pOutputFileName, NULL);
302+
final var pOutputFormat = av_guess_format(NULL, pOutputFileName, NULL);
304303

305304
if (pOutputFormat.equals(NULL)) {
306305
throw new RuntimeException(formatSaveVideoError(fileName, "Can't allocate output format"));
307306
}
308307

309-
if (AVOutputFormat.video_codec(pOutputFormat) == AV_CODEC_ID_NONE()) {
310-
throw new RuntimeException(formatSaveVideoError(fileName, "Can't find codec"));
308+
final int outputVideoCodec = AVOutputFormat.video_codec(pOutputFormat);
309+
310+
if (outputVideoCodec == AV_CODEC_ID_NONE()) {
311+
throw new RuntimeException(formatSaveVideoError(fileName, "Video codec not found"));
311312
}
312313

313314
AVFormatContext.oformat(pOutputFormatCtx, pOutputFormat);
314315

315-
final var pOutputCodec = avcodec_find_encoder(AVOutputFormat.video_codec(pOutputFormat));
316+
final var pOutputCodec = avcodec_find_encoder(outputVideoCodec);
316317

317318
if (pOutputCodec.equals(NULL)) {
318-
throw new RuntimeException(formatSaveVideoError(fileName, "Can't find codec"));
319+
throw new RuntimeException(formatSaveVideoError(fileName, "Can't find encoder"));
319320
}
320321

321322
pOutputCodecCtx = avcodec_alloc_context3(pOutputCodec);
@@ -328,7 +329,7 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
328329
AVRational.num(pTimeBase, 1);
329330
AVRational.den(pTimeBase, fps);
330331

331-
AVCodecContext.codec_id(pOutputCodecCtx, AVOutputFormat.video_codec(pOutputFormat));
332+
AVCodecContext.codec_id(pOutputCodecCtx, outputVideoCodec);
332333
AVCodecContext.codec_type(pOutputCodecCtx, AVMEDIA_TYPE_VIDEO());
333334
AVCodecContext.width(pOutputCodecCtx, frameWidth);
334335
AVCodecContext.height(pOutputCodecCtx, frameHeight);
@@ -348,7 +349,7 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
348349
throw new RuntimeException(formatSaveVideoError(fileName, "Unexpected number of streams"));
349350
}
350351

351-
final var pOutputCodecParameters = arena.allocate(AVCodecParameters.layout());
352+
final var pOutputCodecParameters = avcodec_parameters_alloc();
352353

353354
if (pOutputCodecParameters.equals(NULL)) {
354355
throw new RuntimeException(formatSaveVideoError(fileName, "Can't allocate codec parameters"));
@@ -358,27 +359,27 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
358359
throw new RuntimeException(formatLoadVideoError(fileName, "Can't copy codec parameters"));
359360
}
360361

361-
AVCodecParameters.codec_id(pOutputCodecParameters, AVOutputFormat.video_codec(pOutputFormat));
362+
AVCodecParameters.codec_id(pOutputCodecParameters, outputVideoCodec);
362363
AVCodecParameters.codec_type(pOutputCodecParameters, AVMEDIA_TYPE_VIDEO());
363364
AVCodecParameters.width(pOutputCodecParameters, frameWidth);
364365
AVCodecParameters.height(pOutputCodecParameters, frameHeight);
365366
AVStream.codecpar(pOutputStream, pOutputCodecParameters);
366367
AVStream.time_base(pOutputStream, pTimeBase);
367368

368-
pOutputProperties = av_stream_new_side_data(pOutputStream, AV_PKT_DATA_CPB_PROPERTIES(), AVCPBProperties.sizeof());
369+
final var pOutputProperties = av_stream_new_side_data(pOutputStream, AV_PKT_DATA_CPB_PROPERTIES(), AVCPBProperties.sizeof());
369370
AVCPBProperties.buffer_size(pOutputProperties, frameWidth * frameHeight * 3L * 2L);
370371

371372
if (avcodec_open2(pOutputCodecCtx, pOutputCodec, NULL) != 0) {
372-
throw new RuntimeException(formatSaveVideoError(fileName, "Can't open codec"));
373+
throw new RuntimeException(formatSaveVideoError(fileName, "Can't open encoder"));
373374
}
374375

375-
ppOutputAVIOCtx = arena.allocate(C_POINTER);
376+
final var ppOutputAVIOCtx = arena.allocate(C_POINTER);
376377

377378
if (avio_open2(ppOutputAVIOCtx, pOutputFileName, AVIO_FLAG_WRITE(), NULL, NULL) < 0) {
378379
throw new RuntimeException(formatSaveVideoError(fileName, "Can't open file"));
379380
}
380381

381-
final var pOutputAVIOCtx = ppOutputAVIOCtx.get(C_POINTER, 0);
382+
pOutputAVIOCtx = ppOutputAVIOCtx.get(C_POINTER, 0);
382383

383384
if (pOutputAVIOCtx.equals(NULL)) {
384385
throw new RuntimeException(formatLoadVideoError(fileName, "Can't allocate IO context"));
@@ -473,9 +474,9 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
473474
}
474475

475476
av_write_trailer(pOutputFormatCtx);
476-
} catch (Exception e) {
477-
if (!ppOutputAVIOCtx.equals(NULL)) {
478-
avio_close(ppOutputAVIOCtx);
477+
} finally {
478+
if (!pOutputAVIOCtx.equals(NULL)) {
479+
avio_close(pOutputAVIOCtx);
479480
}
480481

481482
if (!pOutputCodecCtx.equals(NULL)) {
@@ -486,10 +487,6 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
486487
sws_freeContext(pOutputSwsContext);
487488
}
488489

489-
if (!pOutputProperties.equals(NULL)) {
490-
av_free(pOutputProperties);
491-
}
492-
493490
if (!pOutputYUVFrame.equals(NULL)) {
494491
av_free(pOutputYUVFrame);
495492
}
@@ -498,10 +495,6 @@ private static int saveVideo(String fileName, int fps, int frames, int frameWidt
498495
av_free(pOutputRGBFrame);
499496
}
500497

501-
if (!pOutputFormat.equals(NULL)) {
502-
av_free(pOutputFormat);
503-
}
504-
505498
if (!pOutputFormatCtx.equals(NULL)) {
506499
avformat_free_context(pOutputFormatCtx);
507500
}

ffmpeg4java-macos-examples/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
<argument>-Djava.library.path=${project.build.directory}/lib</argument>
6666
<argument>com.nextbreakpoint.ffmpeg4java.macos.ConvertVideoMain</argument>
6767
<argument>sample.mpg</argument>
68-
<argument>output.mov</argument>
68+
<argument>output.mp4</argument>
6969
</arguments>
7070
</configuration>
7171
</execution>

0 commit comments

Comments
 (0)