Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8294400: Provide media support for libavcodec version 59 #119

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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