[FFmpeg-devel] [PATCH 1/4] lavc: add mpeg4 mediacodec decoder

Matthieu Bouron matthieu.bouron at gmail.com
Thu Jul 28 16:58:29 EEST 2016


On Wed, Jul 27, 2016 at 06:39:27PM +0200, Matthieu Bouron wrote:
> On Tue, Jul 26, 2016 at 05:54:58PM +0200, Thomas Volkert wrote:
> > On 26.07.2016 11:15, Matthieu Bouron wrote:
> > > On Tue, Jul 26, 2016 at 11:00:46AM +0200, Matthieu Bouron wrote:
> > >> On Sun, Jul 24, 2016 at 03:06:14PM +0200, Thomas Volkert wrote:
> > >>> From: Thomas Volkert <thomas at netzeal.de>
> > >>>
> > >>> ---
> > >>>  Changelog                        |   1 +
> > >>>  configure                        |   1 +
> > >>>  libavcodec/Makefile              |   1 +
> > >>>  libavcodec/allcodecs.c           |   1 +
> > >>>  libavcodec/mediacodecdec_mpeg4.c | 239 +++++++++++++++++++++++++++++++++++++++
> > >>>  libavcodec/version.h             |   2 +-
> > >>>  6 files changed, 244 insertions(+), 1 deletion(-)
> > >>>  create mode 100644 libavcodec/mediacodecdec_mpeg4.c
> > >>>
> > >>> diff --git a/Changelog b/Changelog
> > >>> index 2bd18ec..b8bbdb9 100644
> > >>> --- a/Changelog
> > >>> +++ b/Changelog
> > >>> @@ -7,6 +7,7 @@ version <next>:
> > >>>  - Changed metadata print option to accept general urls
> > >>>  - Alias muxer for Ogg Video (.ogv)
> > >>>  - VP8 in Ogg muxing
> > >>> +- MediaCodec MPEG-4 decoding
> > >>>  
> > >>>  
> > >>>  version 3.1:
> > >>> diff --git a/configure b/configure
> > >>> index 1b41303..9004b06 100755
> > >>> --- a/configure
> > >>> +++ b/configure
> > >>> @@ -2621,6 +2621,7 @@ mpeg2_videotoolbox_hwaccel_select="mpeg2video_decoder"
> > >>>  mpeg2_xvmc_hwaccel_deps="xvmc"
> > >>>  mpeg2_xvmc_hwaccel_select="mpeg2video_decoder"
> > >>>  mpeg4_crystalhd_decoder_select="crystalhd"
> > >>> +mpeg4_mediacodec_decoder_deps="mediacodec"
> > >>>  mpeg4_mmal_decoder_deps="mmal"
> > >>>  mpeg4_mmal_decoder_select="mmal"
> > >>>  mpeg4_mmal_hwaccel_deps="mmal"
> > >>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> > >>> index abef19e..642cf2a 100644
> > >>> --- a/libavcodec/Makefile
> > >>> +++ b/libavcodec/Makefile
> > >>> @@ -317,6 +317,7 @@ OBJS-$(CONFIG_H264_DECODER)            += h264.o h264_cabac.o h264_cavlc.o \
> > >>>                                            h2645_parse.o
> > >>>  OBJS-$(CONFIG_H264_CUVID_DECODER)      += cuvid.o
> > >>>  OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec_h264.o
> > >>> +OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec_mpeg4.o
> > >>>  OBJS-$(CONFIG_H264_MMAL_DECODER)       += mmaldec.o
> > >>>  OBJS-$(CONFIG_H264_NVENC_ENCODER)      += nvenc_h264.o
> > >>>  OBJS-$(CONFIG_NVENC_ENCODER)           += nvenc_h264.o
> > >>> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> > >>> index 951e199..2d98694 100644
> > >>> --- a/libavcodec/allcodecs.c
> > >>> +++ b/libavcodec/allcodecs.c
> > >>> @@ -239,6 +239,7 @@ void avcodec_register_all(void)
> > >>>      REGISTER_ENCDEC (MPEG2VIDEO,        mpeg2video);
> > >>>      REGISTER_ENCDEC (MPEG4,             mpeg4);
> > >>>      REGISTER_DECODER(MPEG4_CRYSTALHD,   mpeg4_crystalhd);
> > >>> +    REGISTER_DECODER(MPEG4_MEDIACODEC,  mpeg4_mediacodec);
> > >>>      REGISTER_DECODER(MPEG4_MMAL,        mpeg4_mmal);
> > >> You should also add the relevant hwaccel entry in this file:
> > >>
> > >> +    REGISTER_HWACCEL(MPEG4_MEDIACODEC,  mpeg4_mediacodec);
> > >>
> > >> and declare the hwaccel at the bottom of libavcodec/mediacodecdec.c, like the h264 one.
> > >>
> > >>>  #if FF_API_VDPAU
> > >>>      REGISTER_DECODER(MPEG4_VDPAU,       mpeg4_vdpau);
> > >>> diff --git a/libavcodec/mediacodecdec_mpeg4.c b/libavcodec/mediacodecdec_mpeg4.c
> > >>> new file mode 100644
> > >>> index 0000000..7c4559b
> > >>> --- /dev/null
> > >>> +++ b/libavcodec/mediacodecdec_mpeg4.c
> > >>> @@ -0,0 +1,239 @@
> > >>> +/*
> > >>> + * Android MediaCodec MPEG 4 decoder
> > >>> + *
> > >>> + * Copyright (c) 2016 Thomas Volkert <thomas at netzeal.de>
> > >>> + *
> > >>> + * This file is part of FFmpeg.
> > >>> + *
> > >>> + * FFmpeg is free software; you can redistribute it and/or
> > >>> + * modify it under the terms of the GNU Lesser General Public
> > >>> + * License as published by the Free Software Foundation; either
> > >>> + * version 2.1 of the License, or (at your option) any later version.
> > >>> + *
> > >>> + * FFmpeg 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
> > >>> + * Lesser General Public License for more details.
> > >>> + *
> > >>> + * You should have received a copy of the GNU Lesser General Public
> > >>> + * License along with FFmpeg; if not, write to the Free Software
> > >>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> > >>> + */
> > >>> +
> > >>> +#include "libavutil/avassert.h"
> > >>> +#include "libavutil/common.h"
> > >>> +#include "libavutil/fifo.h"
> > >>> +
> > >>> +#include "avcodec.h"
> > >>> +#include "internal.h"
> > >>> +#include "mediacodecdec.h"
> > >>> +#include "mediacodec_wrapper.h"
> > >>> +
> > >>> +#define CODEC_MIME "video/mp4v-es"
> > >>> +
> > >>> +typedef struct MediaCodecMPEG4DecContext {
> > >>> +
> > >>> +    MediaCodecDecContext *ctx;
> > >>> +
> > >>> +    AVBSFContext *bsf;
> > >>> +
> > >>> +    AVFifoBuffer *fifo;
> > >>> +
> > >>> +    AVPacket filtered_pkt;
> > >>> +
> > >>> +} MediaCodecMPEG4DecContext;
> > >>> +
> > >>> +static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
> > >>> +{
> > >>> +    MediaCodecMPEG4DecContext *s = avctx->priv_data;
> > >>> +
> > >>> +    ff_mediacodec_dec_close(avctx, s->ctx);
> > >>> +    s->ctx = NULL;
> > >>> +
> > >>> +    av_fifo_free(s->fifo);
> > >>> +
> > >>> +    av_bsf_free(&s->bsf);
> > >>> +    av_packet_unref(&s->filtered_pkt);
> > >>> +
> > >>> +    return 0;
> > >>> +}
> > >>> +
> > >>> +static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
> > >>> +{
> > >>> +    int ret;
> > >>> +
> > >>> +    FFAMediaFormat *format = NULL;
> > >>> +    MediaCodecMPEG4DecContext *s = avctx->priv_data;
> > >>> +
> > >>> +    format = ff_AMediaFormat_new();
> > >>> +    if (!format) {
> > >>> +        av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n");
> > >>> +        ret = AVERROR_EXTERNAL;
> > >>> +        goto done;
> > >>> +    }
> > >>> +
> > >>> +    ff_AMediaFormat_setString(format, "mime", CODEC_MIME);
> > >>> +    ff_AMediaFormat_setInt32(format, "width", avctx->width);
> > >>> +    ff_AMediaFormat_setInt32(format, "height", avctx->height);
> > >> The relevant MPEG4 extradata (ESDS) in the csd-0 buffer are missing.
> > Yes, I've tested even more today and were able to reproduce problems
> > with some files.
> > The documentation from Google gives a hint about the reason.
> > 
> > >>
> > >> I've tested the decoder on a nexus 5 and one plus 3 either configured to
> > >> output to a surface or to output to cpu buffers and it does not work (I
> > >> guess it's because the codec extradata are missing).
> > > Forgot to mention the files I've tested the decoder against:
> > > http://samples.0x5c.me/MPEG4/
> > Did you face the same problems with the other files from the web page
> > I've send to you?
> 
> Sorry for the late reply, I only tested with the mpeg4 video sample. I'll
> test the other decoders tomorrow.

I've done the following test on a nexus 5 and a one plus 3.

VP8 decoder:
  * the decoder fails to configure with the sample you provided and this
  one http://samples.0x5c.me/VP8/bbb.webm

H263 decoder:
  * the decoder works with the h263 sample but not with the h263+ one

Matthieu
[...]


More information about the ffmpeg-devel mailing list