diff --git a/build.gradle b/build.gradle index 91c10a1d97d..3e256d394ab 100644 --- a/build.gradle +++ b/build.gradle @@ -2855,6 +2855,7 @@ project(":media") { media name: "libav-12.1", ext: "tar.gz" media name: "ffmpeg-3.3.3", ext: "tar.gz" media name: "ffmpeg-4.0.2", ext: "tar.gz" + media name: "ffmpeg-5.1.2", ext: "tar.gz" } implementation project(":base") implementation project(":graphics") @@ -3003,10 +3004,12 @@ project(":media") { def copyLibAVStubs = {String fromDir, String toDir -> FileCollection config = files("config.h") FileCollection libavcodec = files("avcodec.h", "avfft.h", "dxva2.h", "vaapi.h", "vda.h", - "vdpau.h", "version.h", "xvmc.h", "old_codec_ids.h") + "vdpau.h", "version.h", "xvmc.h", "old_codec_ids.h", + "codec.h", "codec_desc.h", "codec_par.h", "codec_id.h", + "defs.h", "packet.h", "version_major.h") FileCollection libavdevice = files("avdevice.h", "version.h") FileCollection libavfilter = files("avfiltergraph.h", "avfilter.h", "buffersink.h", "buffersrc.h", "version.h"); - FileCollection libavformat = files("avformat.h", "avio.h", "version.h") + FileCollection libavformat = files("avformat.h", "avio.h", "version.h", "version_major.h") FileCollection libavresample = files("avresample.h", "version.h") FileCollection libavutil = files("adler32.h", "blowfish.h", "error.h", "log.h", "pixfmt.h", "aes.h", "bswap.h", "eval.h", "lzo.h", "random_seed.h", @@ -3019,7 +3022,7 @@ project(":media") { "dict.h", "lfg.h", "pixdesc.h", "intfloat_readwrite.h", "old_pix_fmts.h", "audioconvert.h", "cpu.h", "hwcontext.h") FileCollection libavutil_x86 = files("cpu.h") // Use cpu.h from x86 instead of libavutil root if exist - FileCollection libswscale = files("swscale.h", "version.h") + FileCollection libswscale = files("swscale.h", "version.h", "version_major.h") def copyLibAVFiles = {FileCollection files, String fDir, String tDir -> File dir = file(tDir) @@ -3199,8 +3202,8 @@ project(":media") { doLast { project.ext.libav = [:] project.ext.libav.basedir = "${buildDir}/native/linux/ffmpeg" - project.ext.libav.versions = [ "3.3.3", "4.0.2" ] - project.ext.libav.versionmap = [ "3.3.3" : "57", "4.0.2" : "58" ] + project.ext.libav.versions = [ "3.3.3", "4.0.2", "5.1.2" ] + project.ext.libav.versionmap = [ "3.3.3" : "57", "4.0.2" : "58", "5.1.2" : "59" ] libav.versions.each { version -> def libavDir = "${libav.basedir}/ffmpeg-${version}" @@ -3280,7 +3283,7 @@ project(":media") { project.ext.libav.libavffmpeg.versions = [ "56" ] project.ext.libav.ffmpeg = [:] project.ext.libav.ffmpeg.basedir = "${buildDir}/native/linux/ffmpeg/ffmpeg" - project.ext.libav.ffmpeg.versions = [ "57", "58" ] + project.ext.libav.ffmpeg.versions = [ "57", "58", "59" ] project.ext.libav.versions.each { version -> def libavDir = "${project.ext.libav.basedir}-${version}" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 72aa7211dea..c1edfd5352d 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -18,6 +18,11 @@ + + + + + diff --git a/modules/javafx.media/src/main/java/com/sun/media/jfxmediaimpl/NativeMediaManager.java b/modules/javafx.media/src/main/java/com/sun/media/jfxmediaimpl/NativeMediaManager.java index d2c9dfa2652..594b971c79e 100644 --- a/modules/javafx.media/src/main/java/com/sun/media/jfxmediaimpl/NativeMediaManager.java +++ b/modules/javafx.media/src/main/java/com/sun/media/jfxmediaimpl/NativeMediaManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,6 +125,7 @@ protected NativeMediaManager() { dependencies.add("avplugin-ffmpeg-56"); dependencies.add("avplugin-ffmpeg-57"); dependencies.add("avplugin-ffmpeg-58"); + dependencies.add("avplugin-ffmpeg-59"); } if (HostUtils.isMacOSX()) { dependencies.add("fxplugins"); diff --git a/modules/javafx.media/src/main/native/gstreamer/gstreamer-lite/gstreamer/gst/gstregistry.c b/modules/javafx.media/src/main/native/gstreamer/gstreamer-lite/gstreamer/gst/gstregistry.c index ac7068b4b48..9f67de9062d 100644 --- a/modules/javafx.media/src/main/native/gstreamer/gstreamer-lite/gstreamer/gst/gstregistry.c +++ b/modules/javafx.media/src/main/native/gstreamer/gstreamer-lite/gstreamer/gst/gstregistry.c @@ -146,7 +146,7 @@ static const int AVCODEC_LIBAV_EXPLICIT_VERSIONS[] = { 54, 56 }; // For ffmpeg (libavcodec-ffmpeg.so) static const int AVCODEC_FFMPEG_EXPLICIT_VERSIONS[] = { 56 }; // For libav or ffmpeg (libavcodec.so) -static const int AVCODEC_EXPLICIT_VERSIONS[] = { 57, 58 }; +static const int AVCODEC_EXPLICIT_VERSIONS[] = { 57, 58, 59 }; /* * Callback passed to dl_iterate_phdr(): finds the path of diff --git a/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.c b/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.c index a7f7626b6bf..cad2b8a5ec4 100644 --- a/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.c +++ b/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,7 +124,7 @@ static gboolean audiodecoder_init_state(AudioDecoder *decoder); static gboolean audiodecoder_open_init(AudioDecoder *decoder, GstCaps* caps); static gboolean audiodecoder_src_event(GstPad* pad, GstObject *parent, GstEvent* event); -#if DECODE_AUDIO4 +#if DECODE_AUDIO4 || USE_SEND_RECEIVE static gboolean audiodecoder_is_oformat_supported(int format); #endif @@ -190,7 +190,7 @@ static gboolean audiodecoder_init_state(AudioDecoder *decoder) decoder->codec_id = CODEC_ID_NONE; #endif -#if !DECODE_AUDIO4 +#if !DECODE_AUDIO4 && !USE_SEND_RECEIVE decoder->samples = av_mallocz(AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!decoder->samples) return FALSE; @@ -225,7 +225,7 @@ static void audiodecoder_state_reset(AudioDecoder *decoder) static void audiodecoder_close_decoder(AudioDecoder *decoder) { -#if !DECODE_AUDIO4 +#if !DECODE_AUDIO4 && !USE_SEND_RECEIVE if (decoder->samples) { av_free(decoder->samples); @@ -649,7 +649,7 @@ static GstFlowReturn audiodecoder_chain(GstPad *pad, GstObject *parent, GstBuffe GstMapInfo info2; gboolean unmap_buf = FALSE; -#if DECODE_AUDIO4 +#if DECODE_AUDIO4 || USE_SEND_RECEIVE gint got_frame = 0; int sample, ci; #else @@ -712,14 +712,24 @@ static GstFlowReturn audiodecoder_chain(GstPad *pad, GstObject *parent, GstBuffe decoder->packet.data = info.data; decoder->packet.size = info.size; -#if DECODE_AUDIO4 +#if USE_SEND_RECEIVE + num_dec = avcodec_send_packet(base->context, &decoder->packet); + if (num_dec == 0) + { + num_dec = avcodec_receive_frame(base->context, base->frame); + if (num_dec == 0) + { + got_frame = 1; + } + } +#elif DECODE_AUDIO4 num_dec = avcodec_decode_audio4(base->context, base->frame, &got_frame, &decoder->packet); #else num_dec = avcodec_decode_audio3(base->context, (int16_t*)decoder->samples, &outbuf_size, &decoder->packet); #endif -#if DECODE_AUDIO4 +#if DECODE_AUDIO4 || USE_SEND_RECEIVE if (num_dec < 0 || !got_frame) #else if (num_dec < 0 || outbuf_size == 0) @@ -732,7 +742,7 @@ static GstFlowReturn audiodecoder_chain(GstPad *pad, GstObject *parent, GstBuffe } GstBuffer *outbuf = NULL; -#if DECODE_AUDIO4 +#if DECODE_AUDIO4 || USE_SEND_RECEIVE if (!audiodecoder_is_oformat_supported(base->frame->format)) { gst_element_message_full(GST_ELEMENT(decoder), GST_MESSAGE_ERROR, GST_CORE_ERROR, GST_CORE_ERROR_NOT_IMPLEMENTED, @@ -767,7 +777,7 @@ static GstFlowReturn audiodecoder_chain(GstPad *pad, GstObject *parent, GstBuffe goto _exit; } -#if DECODE_AUDIO4 +#if DECODE_AUDIO4 || USE_SEND_RECEIVE if (base->frame->format == AV_SAMPLE_FMT_S16P || base->frame->format == AV_SAMPLE_FMT_FLTP) { // Make sure we received expected data @@ -876,7 +886,7 @@ static GstFlowReturn audiodecoder_chain(GstPad *pad, GstObject *parent, GstBuffe return ret; } -#if DECODE_AUDIO4 +#if DECODE_AUDIO4 || USE_SEND_RECEIVE static gboolean audiodecoder_is_oformat_supported(int format) { return (format == AV_SAMPLE_FMT_S16P || format == AV_SAMPLE_FMT_FLTP || diff --git a/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.h b/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.h index 2fca4b06da2..09867edbb74 100644 --- a/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.h +++ b/modules/javafx.media/src/main/native/gstreamer/plugins/av/audiodecoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ typedef struct _AudioDecoderClass AudioDecoderClass; struct _AudioDecoder { BaseDecoder parent; -#if !DECODE_AUDIO4 +#if !DECODE_AUDIO4 && !USE_SEND_RECEIVE guint8 *samples; // temporary output buffer #endif diff --git a/modules/javafx.media/src/main/native/gstreamer/plugins/av/avdefines.h b/modules/javafx.media/src/main/native/gstreamer/plugins/av/avdefines.h index a51ad0cf48c..60fa7b631cf 100644 --- a/modules/javafx.media/src/main/native/gstreamer/plugins/av/avdefines.h +++ b/modules/javafx.media/src/main/native/gstreamer/plugins/av/avdefines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ #define AVDEFINES_H // According to ffmpeg Git they introduced -// _decode_audio4 in version 53.25.0 -#define DECODE_AUDIO4 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,25,0)) +// _decode_audio4 in version 53.25.0 and removed in version 59 +#define DECODE_AUDIO4 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,25,0) && LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,0,0)) // New AVCodecID was introduced in 54.25.0 #define NEW_CODEC_ID (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0)) @@ -39,5 +39,19 @@ // HEVC/H.265 support should be available in 56 and up #define HEVC_SUPPORT (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56,0,0)) +// "codec" field was removed from AVStream in 59 and "codecpar" should be used +// instead. +#define CODEC_PAR (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(59,0,0)) + +// Use "av_packet_unref()" +#define PACKET_UNREF (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(59,0,0)) + +// Use "avcodec_send_packet()" and "avcodec_receive_frame()" +#define USE_SEND_RECEIVE (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(59,0,0)) + +// Do not call avcodec_register_all() and av_register_all() +// Not required since 58 and removed in 59 +#define NO_REGISTER_ALL (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(59,0,0)) + #endif /* AVDEFINES_H */ diff --git a/modules/javafx.media/src/main/native/gstreamer/plugins/av/decoder.c b/modules/javafx.media/src/main/native/gstreamer/plugins/av/decoder.c index c33fbe27dcc..954e5209506 100644 --- a/modules/javafx.media/src/main/native/gstreamer/plugins/av/decoder.c +++ b/modules/javafx.media/src/main/native/gstreamer/plugins/av/decoder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ * questions. */ +#include #include "decoder.h" #include @@ -76,7 +77,9 @@ static void basedecoder_init(BaseDecoder *self) static void basedecoder_class_init(BaseDecoderClass *g_class) { +#if !NO_REGISTER_ALL avcodec_register_all(); +#endif g_class->init_context = basedecoder_init_context_default; } @@ -104,8 +107,9 @@ gboolean basedecoder_open_decoder(BaseDecoder *decoder, CodecIDType id) #else decoder->frame = avcodec_alloc_frame(); #endif - if (!decoder->frame) + if (!decoder->frame) { return FALSE; // Can't create frame + } G_LOCK(avlib_lock); diff --git a/modules/javafx.media/src/main/native/gstreamer/plugins/av/mpegtsdemuxer.c b/modules/javafx.media/src/main/native/gstreamer/plugins/av/mpegtsdemuxer.c index 5a31308ff16..1fc959767d5 100644 --- a/modules/javafx.media/src/main/native/gstreamer/plugins/av/mpegtsdemuxer.c +++ b/modules/javafx.media/src/main/native/gstreamer/plugins/av/mpegtsdemuxer.c @@ -226,7 +226,9 @@ static void mpegts_demuxer_class_init(MpegTSDemuxerClass *g_class) G_OBJECT_CLASS (g_class)->finalize = GST_DEBUG_FUNCPTR(mpegts_demuxer_finalize); gstelement_class->change_state = mpegts_demuxer_change_state; +#if !NO_REGISTER_ALL av_register_all(); +#endif } static void mpegts_demuxer_init(MpegTSDemuxer *demuxer) @@ -515,7 +517,11 @@ static void mpegts_demuxer_add_pad(MpegTSDemuxer *demuxer, GstPad *pad, GstCaps gst_element_add_pad(GST_ELEMENT(demuxer), pad); } +#if CODEC_PAR +static GstBuffer* get_codec_extradata(AVCodecParameters *codec) +#else static GstBuffer* get_codec_extradata(AVCodecContext *codec) +#endif { GstBuffer *codec_data = NULL; if (codec->extradata) @@ -536,28 +542,42 @@ static void mpegts_demuxer_check_streams(MpegTSDemuxer *demuxer) int i; for (i = 0; i < demuxer->context->nb_streams; i++) { +#if CODEC_PAR + switch (demuxer->context->streams[i]->codecpar->codec_type) +#else switch (demuxer->context->streams[i]->codec->codec_type) +#endif { case AVMEDIA_TYPE_VIDEO: if (demuxer->video.stream_index < 0) { AVStream *stream = demuxer->context->streams[i]; -#if NEW_CODEC_ID +#if CODEC_PAR + if (stream->codecpar->codec_id == AV_CODEC_ID_H264) +#elif NEW_CODEC_ID if (stream->codec->codec_id == AV_CODEC_ID_H264) #else if (stream->codec->codec_id == CODEC_ID_H264) #endif { demuxer->video.stream_index = i; +#if CODEC_PAR + demuxer->video.codec_id = stream->codecpar->codec_id; +#else demuxer->video.codec_id = stream->codec->codec_id; +#endif #ifdef ENABLE_VIDEO gchar *name = g_strdup_printf ("video%02d", i); GstCaps *caps = gst_caps_new_simple ("video/x-h264", "hls", G_TYPE_BOOLEAN, TRUE, NULL); +#if CODEC_PAR + GstBuffer *codec_data = get_codec_extradata(stream->codecpar); +#else GstBuffer *codec_data = get_codec_extradata(stream->codec); +#endif if (codec_data) gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL); @@ -574,24 +594,38 @@ static void mpegts_demuxer_check_streams(MpegTSDemuxer *demuxer) if (demuxer->audio.stream_index < 0) { AVStream *stream = demuxer->context->streams[i]; -#if NEW_CODEC_ID +#if CODEC_PAR + if (stream->codecpar->codec_id == AV_CODEC_ID_AAC) +#elif NEW_CODEC_ID if (stream->codec->codec_id == AV_CODEC_ID_AAC) #else if (stream->codec->codec_id == CODEC_ID_AAC) #endif { demuxer->audio.stream_index = i; +#if CODEC_PAR + demuxer->audio.codec_id = stream->codecpar->codec_id; + gint channels = stream->codecpar->ch_layout.nb_channels; + gint sample_rate = stream->codecpar->sample_rate; + gint bit_rate = stream->codecpar->bit_rate; +#else demuxer->audio.codec_id = stream->codec->codec_id; - + gint channels = stream->codec->channels; + gint sample_rate = stream->codec->sample_rate; + gint bit_rate = stream->codec->bit_rate; +#endif gchar *name = g_strdup_printf ("audio%02d", i); GstCaps *caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4, - "channels", G_TYPE_INT, stream->codec->channels, - "rate", G_TYPE_INT, stream->codec->sample_rate, - "bitrate", G_TYPE_INT, stream->codec->bit_rate, + "channels", G_TYPE_INT, channels, + "rate", G_TYPE_INT, sample_rate, + "bitrate", G_TYPE_INT, bit_rate, "hls", G_TYPE_BOOLEAN, TRUE, NULL); - +#if CODEC_PAR + GstBuffer *codec_data = get_codec_extradata(stream->codecpar); +#else GstBuffer *codec_data = get_codec_extradata(stream->codec); +#endif if (codec_data) gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL); @@ -631,7 +665,11 @@ static inline GstBuffer* packet_to_buffer(AVPacket *packet) static inline gboolean same_stream(MpegTSDemuxer *demuxer, Stream *stream, AVPacket *packet) { +#if CODEC_PAR + return demuxer->context->streams[packet->stream_index]->codecpar->codec_id == stream->codec_id; +#else return demuxer->context->streams[packet->stream_index]->codec->codec_id == stream->codec_id; +#endif } static GstFlowReturn process_video_packet(MpegTSDemuxer *demuxer, AVPacket *packet) @@ -874,7 +912,11 @@ static ParseAction mpegts_demuxer_read_frame(MpegTSDemuxer *demuxer) break; } +#if PACKET_UNREF + av_packet_unref(&packet); +#else av_free_packet(&packet); +#endif return result; } diff --git a/modules/javafx.media/src/main/native/gstreamer/plugins/av/videodecoder.c b/modules/javafx.media/src/main/native/gstreamer/plugins/av/videodecoder.c index 2fe4f0e8ede..2a584d669bc 100644 --- a/modules/javafx.media/src/main/native/gstreamer/plugins/av/videodecoder.c +++ b/modules/javafx.media/src/main/native/gstreamer/plugins/av/videodecoder.c @@ -713,8 +713,25 @@ static GstFlowReturn videodecoder_chain(GstPad *pad, GstObject *parent, GstBuffe base->context->reordered_opaque = GST_BUFFER_TIMESTAMP(buf); else base->context->reordered_opaque = AV_NOPTS_VALUE; +#if USE_SEND_RECEIVE + num_dec = avcodec_send_packet(base->context, &decoder->packet); + if (num_dec == 0) + { + num_dec = avcodec_receive_frame(base->context, base->frame); + if (num_dec == 0) + decoder->frame_finished = 1; + else + decoder->frame_finished = 0; + } +#else num_dec = avcodec_decode_video2(base->context, base->frame, &decoder->frame_finished, &decoder->packet); +#endif + +#if PACKET_UNREF + av_packet_unref(&decoder->packet); +#else av_free_packet(&decoder->packet); +#endif } else { @@ -732,7 +749,19 @@ static GstFlowReturn videodecoder_chain(GstPad *pad, GstObject *parent, GstBuffe else base->context->reordered_opaque = AV_NOPTS_VALUE; +#if USE_SEND_RECEIVE + num_dec = avcodec_send_packet(base->context, &decoder->packet); + if (num_dec == 0) + { + num_dec = avcodec_receive_frame(base->context, base->frame); + if (num_dec == 0) + decoder->frame_finished = 1; + else + decoder->frame_finished = 0; + } +#else num_dec = avcodec_decode_video2(base->context, base->frame, &decoder->frame_finished, &decoder->packet); +#endif } if (num_dec < 0)