Commit 1b615375 authored by Adrien Béraud's avatar Adrien Béraud Committed by Adrien Béraud

ffmpeg: use Android MediaCodec accelerated decoding

* update ffmpeg to latest stable 3.3.1,
  update patches and remove deprecated patches and flags,
* enable ffmpeg ASM optimizations for all platforms but Android x86
  (see https://trac.ffmpeg.org/ticket/4928 )
* enable Android hardware accelerated decoding (MediaCodec),
  for now only with VP8, MPEG4

Change-Id: Ifac82ec7b9b71bd92a65a3575ac63e7ed80b510b
parent afa12b06
......@@ -15,7 +15,7 @@ diff --git a/configure b/configure
index 7154142..48c7049 100755
--- a/configure
+++ b/configure
@@ -2968,6 +2968,8 @@ alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp"
@@ -2988,6 +2988,8 @@ alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp"
alsa_outdev_deps="alsa_asoundlib_h"
avfoundation_indev_extralibs="-framework CoreVideo -framework Foundation -framework AVFoundation -framework CoreMedia"
avfoundation_indev_select="avfoundation"
......@@ -24,13 +24,13 @@ index 7154142..48c7049 100755
bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h"
caca_outdev_deps="libcaca"
decklink_indev_deps="decklink pthreads"
@@ -5719,6 +5721,9 @@ done
@@ -5756,6 +5758,9 @@ # these are off by default, so fail if requested and not available
enabled avfoundation_indev && { check_header_objcc AVFoundation/AVFoundation.h || disable avfoundation_indev; }
enabled avfoundation_indev && { check_lib2 CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
check_lib2 ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
enabled avfoundation_indev && { check_lib CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
check_lib ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
+enabled avfcapture_indev && { check_header_objcc AVFoundation/AVFoundation.h || disable avfcapture_indev; }
+enabled avfcapture_indev && { check_lib2 CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
+ check_lib2 ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
+enabled avfcapture_indev && { check_lib CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
+ check_lib ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
enabled cuda && check_header cuda.h # this is not a dependency
enabled cuvid && { enabled cuda ||
die "ERROR: CUVID requires CUDA"; }
......
From 60873bf992eab1d3bad8dd0fd11336363d44854d Mon Sep 17 00:00:00 2001
From: Anssi Hannula <anssi.hannula@iki.fi>
Date: Tue, 26 Jul 2016 13:23:43 +0300
Subject: [PATCH 1572/1572] avformat/utils: Fix find_stream_info not
considering the extradata it found
Commit 9200514ad8717c6 ("lavf: replace AVStream.codec with
AVStream.codecpar") merged in commit 6f69f7a8bf6a0d01 changed
avformat_find_stream_info() to put the extradata it got from
st->parser->parser->split() to st->internal->avctx instead of st->codec
(extradata in st->internal->avctx will be later copied to st->codecpar).
However, in the same function, the "is stream ready?" check was changed
to check for extradata in st->codecpar instead of st->codec, even
though st->codecpar is not yet updated at that point.
Extradata retrieved from split() is therefore not considered anymore,
and avformat_find_stream_info() will therefore needlessly continue
probing in some cases.
Fix that by checking for the extradata at st->internal->avctx where it
is actually put.
---
libavformat/utils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/utils.c b/libavformat/utils.c
index e5a99ff..5a902ea 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3432,7 +3432,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
break;
}
if (st->parser && st->parser->parser->split &&
- !st->codecpar->extradata)
+ !st->internal->avctx->extradata)
break;
if (st->first_dts == AV_NOPTS_VALUE &&
!(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
--
2.7.4
......@@ -18,7 +18,7 @@ diff --git a/configure b/configure
index 48c7049..d1ae770 100755
--- a/configure
+++ b/configure
@@ -2970,6 +2970,8 @@ avfoundation_indev_extralibs="-framework CoreVideo -framework Foundation -framew
@@ -2990,6 +2990,8 @@ avfoundation_indev_extralibs="-framework CoreVideo -framework Foundation -framew
avfoundation_indev_select="avfoundation"
avfcapture_indev_extralibs="-fobjc-arc -framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia"
avfcapture_indev_select="avfcapture"
......@@ -27,13 +27,13 @@ index 48c7049..d1ae770 100755
bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h"
caca_outdev_deps="libcaca"
decklink_indev_deps="decklink pthreads"
@@ -5724,6 +5726,9 @@ enabled avfoundation_indev && { check_lib2 CoreGraphics/CoreGraphics.h CGGetActi
@@ -5761,6 +5763,9 @@ enabled avfoundation_indev && { check_lib CoreGraphics/CoreGraphics.h CGGetActi
enabled avfcapture_indev && { check_header_objcc AVFoundation/AVFoundation.h || disable avfcapture_indev; }
enabled avfcapture_indev && { check_lib2 CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
check_lib2 ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
enabled avfcapture_indev && { check_lib CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
check_lib ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
+enabled avfgrab_indev && { check_header_objcc AVFoundation/AVFoundation.h || disable avfgrab_indev; }
+enabled avfgrab_indev && { check_lib2 CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
+ check_lib2 ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
+enabled avfgrab_indev && { check_lib CoreGraphics/CoreGraphics.h CGGetActiveDisplayList -framework CoreGraphics ||
+ check_lib ApplicationServices/ApplicationServices.h CGGetActiveDisplayList -framework ApplicationServices; }
enabled cuda && check_header cuda.h # this is not a dependency
enabled cuvid && { enabled cuda ||
die "ERROR: CUVID requires CUDA"; }
......
--- a/configure 2017-05-17 11:54:39.000000000 -0500
+++ b/configure 2017-05-17 11:55:14.000000000 -0500
@@ -5549,7 +5549,7 @@
check_func access
check_func_headers stdlib.h arc4random
-check_func_headers time.h clock_gettime || { check_func_headers time.h clock_gettime -lrt && add_extralibs -lrt && LIBRT="-lrt"; }
+#check_func_headers time.h clock_gettime || { check_func_headers time.h clock_gettime -lrt && add_extralibs -lrt && LIBRT="-lrt"; }
check_func fcntl
check_func fork
check_func gethrtime
FFMPEG_HASH := f7e9275f83ec116fc859367d61998eae8af438fc
FFMPEG_HASH := n3.3.1
FFMPEG_URL := https://git.ffmpeg.org/gitweb/ffmpeg.git/snapshot/$(FFMPEG_HASH).tar.gz
ifdef HAVE_WIN32
......@@ -13,83 +13,84 @@ ifdef HAVE_LINUX
PKGS += ffmpeg
endif
ifeq ($(call need_pkg,"libavcodec >= 57.48.101 libavformat >= 57.41.100 libswscale >= 4.1.100 libavdevice >= 57.0.101 libavutil >= 55.28.100"),)
PKGS_FOUND += ffmpeg
endif
DEPS_ffmpeg = iconv zlib x264 vpx opus speex $(DEPS_vpx)
FFMPEGCONF = \
--cc="$(CC)" \
--pkg-config="$(PKG_CONFIG)"
--cc="$(CC)" \
--pkg-config="$(PKG_CONFIG)"
#disable everything
FFMPEGCONF += \
--disable-everything \
--enable-zlib \
--enable-gpl \
--enable-swscale \
--enable-protocols \
--disable-programs \
--disable-sdl
--disable-everything \
--enable-zlib \
--enable-gpl \
--enable-swscale \
--enable-protocols \
--disable-programs \
--disable-sdl
#enable muxers/demuxers
FFMPEGCONF += \
--enable-demuxers \
--enable-muxers
--enable-demuxers \
--enable-muxers
#enable parsers
FFMPEGCONF += \
--enable-parser=h263 \
--enable-parser=h264 \
--enable-parser=mpeg4video \
--enable-parser=vp8
#librairies
ifndef HAVE_ANDROID
FFMPEGCONF += --enable-libx264
endif
--enable-parser=h263 \
--enable-parser=h264 \
--enable-parser=mpeg4video \
--enable-parser=vp8
#encoders/decoders
FFMPEGCONF += \
--enable-encoder=adpcm_g722 \
--enable-decoder=adpcm_g722 \
--enable-encoder=rawvideo \
--enable-decoder=rawvideo \
--enable-encoder=libx264 \
--enable-decoder=h264 \
--enable-encoder=pcm_alaw \
--enable-decoder=pcm_alaw \
--enable-encoder=pcm_mulaw \
--enable-decoder=pcm_mulaw \
--enable-encoder=mpeg4 \
--enable-decoder=mpeg4 \
--enable-encoder=libvpx_vp8 \
--enable-decoder=vp8 \
--enable-encoder=h263 \
--enable-encoder=h263p \
--enable-decoder=h263 \
--enable-encoder=mjpeg \
--enable-decoder=mjpeg \
--enable-decoder=mjpegb \
--enable-libspeex \
--enable-libopus \
--enable-libvpx \
--enable-encoder=libspeex \
--enable-decoder=libspeex \
--enable-encoder=libopus \
--enable-decoder=libopus
--enable-encoder=adpcm_g722 \
--enable-decoder=adpcm_g722 \
--enable-encoder=rawvideo \
--enable-decoder=rawvideo \
--enable-encoder=libx264 \
--enable-decoder=h264 \
--enable-encoder=pcm_alaw \
--enable-decoder=pcm_alaw \
--enable-encoder=pcm_mulaw \
--enable-decoder=pcm_mulaw \
--enable-encoder=mpeg4 \
--enable-decoder=mpeg4 \
--enable-encoder=libvpx_vp8 \
--enable-decoder=vp8 \
--enable-encoder=h263 \
--enable-encoder=h263p \
--enable-decoder=h263 \
--enable-encoder=mjpeg \
--enable-decoder=mjpeg \
--enable-decoder=mjpegb \
--enable-libspeex \
--enable-libopus \
--enable-libvpx \
--enable-encoder=libspeex \
--enable-decoder=libspeex \
--enable-encoder=libopus \
--enable-decoder=libopus
#encoders/decoders for images
FFMPEGCONF += \
--enable-encoder=gif \
--enable-decoder=gif \
--enable-encoder=jpegls \
--enable-decoder=jpegls \
--enable-encoder=ljpeg \
--enable-decoder=jpeg2000 \
--enable-encoder=png \
--enable-decoder=png \
--enable-encoder=bmp \
--enable-decoder=bmp \
--enable-encoder=tiff \
--enable-decoder=tiff
DEPS_ffmpeg = iconv zlib x264 vpx opus speex $(DEPS_vpx)
--enable-encoder=gif \
--enable-decoder=gif \
--enable-encoder=jpegls \
--enable-decoder=jpegls \
--enable-encoder=ljpeg \
--enable-decoder=jpeg2000 \
--enable-encoder=png \
--enable-decoder=png \
--enable-encoder=bmp \
--enable-decoder=bmp \
--enable-encoder=tiff \
--enable-decoder=tiff
#platform specific options
ifdef HAVE_WIN32
FFMPEGCONF += \
......@@ -99,8 +100,31 @@ FFMPEGCONF += \
endif
ifdef HAVE_LINUX
ifndef HAVE_ANDROID
FFMPEGCONF += --enable-pic
FFMPEGCONF += --extra-cxxflags=-fPIC --extra-cflags=-fPIC
ifdef HAVE_ANDROID
# Android Linux
FFMPEGCONF += \
--target-os=android \
--enable-jni \
--enable-mediacodec \
--enable-hwaccel=vp8_mediacodec \
--enable-hwaccel=mpeg4_mediacodec \
--enable-decoder=vp8_mediacodec \
--enable-decoder=mpeg4_mediacodec
# ASM not working on Android x86 https://trac.ffmpeg.org/ticket/4928
ifeq ($(ARCH),i386)
FFMPEGCONF += --disable-asm
endif
ifeq ($(ARCH),x86_64)
FFMPEGCONF += --disable-asm
endif
else
# Desktop Linux
FFMPEGCONF += \
--target-os=linux \
--enable-indev=v4l2 \
--enable-indev=xcbgrab \
--enable-vdpau \
--enable-hwaccel=h264_vdpau \
--enable-hwaccel=mpeg4_vdpau \
......@@ -111,6 +135,10 @@ FFMPEGCONF += \
endif
endif
ifndef HAVE_ANDROID
FFMPEGCONF += --enable-libx264
endif
ifdef HAVE_MACOSX
FFMPEGCONF += \
--enable-indev=avfcapture \
......@@ -123,21 +151,7 @@ FFMPEGCONF += \
--enable-cross-compile \
--arch=$(ARCH) \
--enable-pic \
--enable-indev=avfoundation
endif
DEPS_ffmpeg = iconv zlib x264 vpx opus speex $(DEPS_vpx)
# Linux
ifdef HAVE_LINUX
FFMPEGCONF += --target-os=linux --enable-pic
ifndef HAVE_ANDROID
FFMPEGCONF += --enable-indev=v4l2 --enable-indev=x11grab_xcb --enable-indev=x11grab --enable-x11grab
else
# used to avoid Text Relocations
FFMPEGCONF += --extra-cxxflags=-fPIC --extra-cflags=-fPIC
FFMPEGCONF += --disable-asm
endif
--enable-indev=avfoundation
endif
ifndef HAVE_IOS
......@@ -179,31 +193,23 @@ endif
# Windows
ifdef HAVE_WIN32
FFMPEGCONF += --target-os=mingw32 --enable-memalign-hack
FFMPEGCONF += --target-os=mingw32
FFMPEGCONF += --enable-w32threads --disable-decoder=dca
endif
ifeq ($(call need_pkg,"libavcodec >= 57.89.100 libavformat >= 57.71.100 libswscale >= 4.6.100 libavdevice >= 57.6.100 libavutil >= 55.58.100"),)
PKGS_FOUND += ffmpeg
endif
$(TARBALLS)/ffmpeg-$(FFMPEG_HASH).tar.xz:
$(TARBALLS)/ffmpeg-$(FFMPEG_HASH).tar.gz:
$(call download,$(FFMPEG_URL))
.sum-ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.xz
.sum-ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.gz
$(warning $@ is not implemented.)
touch $@
ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.xz .sum-ffmpeg
ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.gz .sum-ffmpeg
rm -Rf $@ $@-$(FFMPEG_HASH)
mkdir -p $@-$(FFMPEG_HASH)
(cd $@-$(FFMPEG_HASH) && tar x $(if ${BATCH_MODE},,-v) --strip-components=1 -f ../$<)
$(UPDATE_AUTOCONFIG)
ifdef HAVE_IOS
$(APPLY) $(SRC)/ffmpeg/clock_gettime.patch
endif
ifdef HAVE_MACOSX
$(APPLY) $(SRC)/ffmpeg/clock_gettime.patch
$(APPLY) $(SRC)/ffmpeg/0004-add-avfcapture-device.patch
$(APPLY) $(SRC)/ffmpeg/0005-add-avfgrab-device.patch
endif
......@@ -213,6 +219,6 @@ endif
cd $< && $(HOSTVARS) ./configure \
--extra-cflags="$(CFLAGS)" \
--extra-ldflags="$(LDFLAGS)" $(FFMPEGCONF) \
--prefix="$(PREFIX)" --enable-static --disable-shared
--prefix="$(PREFIX)" --enable-static --disable-shared
cd $< && $(MAKE) install-libs install-headers
touch $@
......@@ -26,6 +26,7 @@
#include "audio/audiobuffer.h"
#include "audio/ringbuffer.h"
#include "audio/resampler.h"
#include "video/decoder_finder.h"
#include "manager.h"
#ifdef RING_ACCEL
......@@ -41,8 +42,6 @@
namespace ring {
using std::string;
MediaDecoder::MediaDecoder() :
inputCtx_(avformat_alloc_context()),
startTime_(AV_NOPTS_VALUE)
......@@ -283,7 +282,7 @@ int MediaDecoder::setupFromVideoData()
// Get a pointer to the codec context for the video stream
avStream_ = inputCtx_->streams[streamIndex_];
#if LIBAVFORMAT_VERSION_CHECK(57, 7, 2, 40, 101) && !defined(_WIN32)
inputDecoder_ = avcodec_find_decoder(avStream_->codecpar->codec_id);
inputDecoder_ = video::findDecoder(avStream_->codecpar->codec_id);
if (!inputDecoder_) {
RING_ERR("Unsupported codec");
return -1;
......@@ -305,6 +304,7 @@ int MediaDecoder::setupFromVideoData()
return -1;
}
#endif
RING_DBG("Decoding video using %s (%s)", inputDecoder_->long_name, inputDecoder_->name);
decoderCtx_->thread_count = std::thread::hardware_concurrency();
......
......@@ -33,7 +33,8 @@ libvideo_la_SOURCES = \
video_receive_thread.cpp video_receive_thread.h \
video_sender.cpp video_sender.h \
video_rtp_session.cpp video_rtp_session.h \
sinkclient.cpp sinkclient.h
sinkclient.cpp sinkclient.h \
decoder_finder.h
if RING_ACCEL
libvideo_la_SOURCES += accel.cpp accel.h
......
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
extern "C" {
#include <libavcodec/avcodec.h>
}
namespace ring { namespace video {
/**
* Attempt to find standalone accelerated AVCodec decoder using AVCodecID,
* or fallback to the default decoder.
*/
AVCodec*
findDecoder(const enum AVCodecID codec_id)
{
const char* codec_name;
switch (codec_id) {
#ifdef __ANDROID__
case AV_CODEC_ID_MPEG4:
codec_name = "mpeg4_mediacodec"; break;
case AV_CODEC_ID_H264:
codec_name = "h264_mediacodec"; break;
case AV_CODEC_ID_HEVC:
codec_name = "hevc_mediacodec"; break;
case AV_CODEC_ID_VP8:
codec_name = "vp8_mediacodec"; break;
case AV_CODEC_ID_VP9:
codec_name = "vp9_mediacodec"; break;
#endif
default:
codec_name = nullptr;
}
AVCodec* codec = nullptr;
if (codec_name)
codec = avcodec_find_decoder_by_name(codec_name);
if (not codec)
codec = avcodec_find_decoder(codec_id);
return codec;
}
}} // namespace ring::video
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment