Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8294400: Provide media support for libavcodec version 59
Reviewed-by: arapte
Backport-of: ac8382bd378c7b51ccd625af46bdf10d24176692
  • Loading branch information
kevinrushforth committed Nov 23, 2022
1 parent fb072e5 commit ea6091a
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 32 deletions.
15 changes: 9 additions & 6 deletions build.gradle
Expand Up @@ -3340,6 +3340,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")
Expand Down Expand Up @@ -3488,10 +3489,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",
Expand All @@ -3504,7 +3507,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)
Expand Down Expand Up @@ -3684,8 +3687,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}"
Expand Down Expand Up @@ -3765,7 +3768,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}"
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2018, 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
Expand Down Expand Up @@ -124,6 +124,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");
Expand Down
Expand Up @@ -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
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2018, 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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -652,7 +652,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
Expand Down Expand Up @@ -715,14 +715,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)
Expand All @@ -735,7 +745,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,
Expand Down Expand Up @@ -770,7 +780,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
Expand Down Expand Up @@ -879,7 +889,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 ||
Expand Down
@@ -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
Expand Down Expand Up @@ -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

Expand Down
@@ -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
Expand Down Expand Up @@ -27,14 +27,28 @@
#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))

// New Frame alloc functions were introduced in 55.28.0
#define NEW_ALLOC_FRAME (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,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 */

@@ -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
Expand All @@ -23,6 +23,7 @@
* questions.
*/

#include <stdio.h>
#include "decoder.h"
#include <libavutil/mem.h>

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down
Expand Up @@ -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)
Expand Down Expand Up @@ -517,7 +519,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)
Expand All @@ -538,28 +544,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);

Expand All @@ -576,24 +596,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);

Expand Down Expand Up @@ -633,7 +667,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)
Expand Down Expand Up @@ -876,7 +914,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;
}

Expand Down

1 comment on commit ea6091a

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.