diff mbox

[FFmpeg-devel,v3] lavc: add mpeg2 decoder/hwaccel to mediacodec

Message ID 20170605202258.95918-1-ffmpeg@tmm1.net
State Accepted
Commit a32a6b4201dca46c54247194bd5249dfb7c64874
Headers show

Commit Message

Aman Gupta June 5, 2017, 8:22 p.m. UTC
From: Aman Gupta <aman@tmm1.net>

Android TV and FireOS hardware supports mpeg2 hardware decoding via MediaCodec.
---
 configure                         |  2 ++
 libavcodec/Makefile               |  1 +
 libavcodec/allcodecs.c            |  2 ++
 libavcodec/mediacodecdec.c        | 40 ++++++++++++++++++++++++++++++++++++++-
 libavcodec/mediacodecdec_common.c |  7 +++++++
 5 files changed, 51 insertions(+), 1 deletion(-)

Comments

Aman Gupta June 6, 2017, 4:39 p.m. UTC | #1
On Mon, Jun 5, 2017 at 1:22 PM, Aman Gupta <ffmpeg@tmm1.net> wrote:

> From: Aman Gupta <aman@tmm1.net>
>
> Android TV and FireOS hardware supports mpeg2 hardware decoding via
> MediaCodec.
>

I tested this patch on an NVIDIA SHIELD, FireTV gen1 and FireTV Stick gen2
and they all worked as expected.

Let me know if you want me to make any other changes before it can be
merged.

Thanks.


> ---
>  configure                         |  2 ++
>  libavcodec/Makefile               |  1 +
>  libavcodec/allcodecs.c            |  2 ++
>  libavcodec/mediacodecdec.c        | 40 ++++++++++++++++++++++++++++++
> ++++++++-
>  libavcodec/mediacodecdec_common.c |  7 +++++++
>  5 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/configure b/configure
> index 72060ef0e9..5816de2398 100755
> --- a/configure
> +++ b/configure
> @@ -2656,6 +2656,7 @@ mpeg2_d3d11va_hwaccel_deps="d3d11va"
>  mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
>  mpeg2_dxva2_hwaccel_deps="dxva2"
>  mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
> +mpeg2_mediacodec_hwaccel_deps="mediacodec"
>  mpeg2_mmal_hwaccel_deps="mmal"
>  mpeg2_qsv_hwaccel_deps="libmfx"
>  mpeg2_qsv_hwaccel_select="qsvdec_mpeg2"
> @@ -2762,6 +2763,7 @@ mpeg1_vdpau_decoder_select="mpeg1video_decoder"
>  mpeg2_crystalhd_decoder_select="crystalhd"
>  mpeg2_cuvid_decoder_deps="cuda cuvid"
>  mpeg2_mmal_decoder_deps="mmal"
> +mpeg2_mediacodec_decoder_deps="mediacodec"
>  mpeg2_qsv_decoder_deps="libmfx"
>  mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel"
>  mpeg2_qsv_encoder_deps="libmfx"
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 0818950ad9..a752f87ef5 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -423,6 +423,7 @@ OBJS-$(CONFIG_MPEG2_QSV_DECODER)       +=
> qsvdec_other.o
>  OBJS-$(CONFIG_MPEG2_QSV_ENCODER)       += qsvenc_mpeg2.o
>  OBJS-$(CONFIG_MPEG2VIDEO_DECODER)      += mpeg12dec.o mpeg12.o
> mpeg12data.o
>  OBJS-$(CONFIG_MPEG2VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o
> +OBJS-$(CONFIG_MPEG2_MEDIACODEC_DECODER) += mediacodecdec.o
>  OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER)     += vaapi_encode_mpeg2.o
>  OBJS-$(CONFIG_MPEG4_DECODER)           += xvididct.o
>  OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 89fadcd2fa..4373ebd975 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -96,6 +96,7 @@ static void register_all(void)
>      REGISTER_HWACCEL(MPEG2_VAAPI,       mpeg2_vaapi);
>      REGISTER_HWACCEL(MPEG2_VDPAU,       mpeg2_vdpau);
>      REGISTER_HWACCEL(MPEG2_VIDEOTOOLBOX, mpeg2_videotoolbox);
> +    REGISTER_HWACCEL(MPEG2_MEDIACODEC,  mpeg2_mediacodec);
>      REGISTER_HWACCEL(MPEG4_CUVID,       mpeg4_cuvid);
>      REGISTER_HWACCEL(MPEG4_MEDIACODEC,  mpeg4_mediacodec);
>      REGISTER_HWACCEL(MPEG4_MMAL,        mpeg4_mmal);
> @@ -257,6 +258,7 @@ static void register_all(void)
>      REGISTER_DECODER(MPEG2_MMAL,        mpeg2_mmal);
>      REGISTER_DECODER(MPEG2_CRYSTALHD,   mpeg2_crystalhd);
>      REGISTER_DECODER(MPEG2_QSV,         mpeg2_qsv);
> +    REGISTER_DECODER(MPEG2_MEDIACODEC,  mpeg2_mediacodec);
>      REGISTER_DECODER(MSA1,              msa1);
>      REGISTER_DECODER(MSCC,              mscc);
>      REGISTER_DECODER(MSMPEG4V1,         msmpeg4v1);
> diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
> index ccfcb4b9ce..5bdeb6c1d7 100644
> --- a/libavcodec/mediacodecdec.c
> +++ b/libavcodec/mediacodecdec.c
> @@ -1,5 +1,5 @@
>  /*
> - * Android MediaCodec H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders
> + * Android MediaCodec MPEG-2 / H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders
>   *
>   * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com
> >
>   *
> @@ -267,6 +267,19 @@ done:
>  }
>  #endif
>
> +#if CONFIG_MPEG2_MEDIACODEC_DECODER
> +static int mpeg2_set_extradata(AVCodecContext *avctx, FFAMediaFormat
> *format)
> +{
> +    int ret = 0;
> +
> +    if (avctx->extradata) {
> +        ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata,
> avctx->extradata_size);
> +    }
> +
> +    return ret;
> +}
> +#endif
> +
>  #if CONFIG_MPEG4_MEDIACODEC_DECODER
>  static int mpeg4_set_extradata(AVCodecContext *avctx, FFAMediaFormat
> *format)
>  {
> @@ -333,6 +346,15 @@ static av_cold int mediacodec_decode_init(AVCodecContext
> *avctx)
>              goto done;
>          break;
>  #endif
> +#if CONFIG_MPEG2_MEDIACODEC_DECODER
> +    case AV_CODEC_ID_MPEG2VIDEO:
> +        codec_mime = "video/mpeg2";
> +
> +        ret = mpeg2_set_extradata(avctx, format);
> +        if (ret < 0)
> +            goto done;
> +        break;
> +#endif
>  #if CONFIG_MPEG4_MEDIACODEC_DECODER
>      case AV_CODEC_ID_MPEG4:
>          codec_mime = "video/mp4v-es",
> @@ -575,6 +597,22 @@ AVCodec ff_hevc_mediacodec_decoder = {
>  };
>  #endif
>
> +#if CONFIG_MPEG2_MEDIACODEC_DECODER
> +AVCodec ff_mpeg2_mediacodec_decoder = {
> +    .name           = "mpeg2_mediacodec",
> +    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 Android MediaCodec
> decoder"),
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_MPEG2VIDEO,
> +    .priv_data_size = sizeof(MediaCodecH264DecContext),
> +    .init           = mediacodec_decode_init,
> +    .decode         = mediacodec_decode_frame,
> +    .flush          = mediacodec_decode_flush,
> +    .close          = mediacodec_decode_close,
> +    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
> +    .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
> +};
> +#endif
> +
>  #if CONFIG_MPEG4_MEDIACODEC_DECODER
>  AVCodec ff_mpeg4_mediacodec_decoder = {
>      .name           = "mpeg4_mediacodec",
> diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_
> common.c
> index 2ec25c581d..1263188d34 100644
> --- a/libavcodec/mediacodecdec_common.c
> +++ b/libavcodec/mediacodecdec_common.c
> @@ -766,6 +766,13 @@ AVHWAccel ff_hevc_mediacodec_hwaccel = {
>      .pix_fmt = AV_PIX_FMT_MEDIACODEC,
>  };
>
> +AVHWAccel ff_mpeg2_mediacodec_hwaccel = {
> +    .name    = "mediacodec",
> +    .type    = AVMEDIA_TYPE_VIDEO,
> +    .id      = AV_CODEC_ID_MPEG2VIDEO,
> +    .pix_fmt = AV_PIX_FMT_MEDIACODEC,
> +};
> +
>  AVHWAccel ff_mpeg4_mediacodec_hwaccel = {
>      .name    = "mediacodec",
>      .type    = AVMEDIA_TYPE_VIDEO,
> --
> 2.11.0 (Apple Git-81)
>
>
Matthieu Bouron June 7, 2017, 8:56 p.m. UTC | #2
On Tue, Jun 06, 2017 at 09:39:25AM -0700, Aman Gupta wrote:
> On Mon, Jun 5, 2017 at 1:22 PM, Aman Gupta <ffmpeg@tmm1.net> wrote:
> 
> > From: Aman Gupta <aman@tmm1.net>
> >
> > Android TV and FireOS hardware supports mpeg2 hardware decoding via
> > MediaCodec.
> >
> 
> I tested this patch on an NVIDIA SHIELD, FireTV gen1 and FireTV Stick gen2
> and they all worked as expected.
> 
> Let me know if you want me to make any other changes before it can be
> merged.

The patch looks good to me and I will push it in a few hours (10h~ or so).

I was not able to find a single device supporting mpeg2 decoding though
MediaCodec, so I wasn't able to test the decoding part on my side.

[...]
Matthieu Bouron June 8, 2017, 6:32 p.m. UTC | #3
On Wed, Jun 07, 2017 at 10:56:29PM +0200, Matthieu Bouron wrote:
> On Tue, Jun 06, 2017 at 09:39:25AM -0700, Aman Gupta wrote:
> > On Mon, Jun 5, 2017 at 1:22 PM, Aman Gupta <ffmpeg@tmm1.net> wrote:
> > 
> > > From: Aman Gupta <aman@tmm1.net>
> > >
> > > Android TV and FireOS hardware supports mpeg2 hardware decoding via
> > > MediaCodec.
> > >
> > 
> > I tested this patch on an NVIDIA SHIELD, FireTV gen1 and FireTV Stick gen2
> > and they all worked as expected.
> > 
> > Let me know if you want me to make any other changes before it can be
> > merged.
> 
> The patch looks good to me and I will push it in a few hours (10h~ or so).
> 
> I was not able to find a single device supporting mpeg2 decoding though
> MediaCodec, so I wasn't able to test the decoding part on my side.

Patch applied.

[...]
diff mbox

Patch

diff --git a/configure b/configure
index 72060ef0e9..5816de2398 100755
--- a/configure
+++ b/configure
@@ -2656,6 +2656,7 @@  mpeg2_d3d11va_hwaccel_deps="d3d11va"
 mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
 mpeg2_dxva2_hwaccel_deps="dxva2"
 mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
+mpeg2_mediacodec_hwaccel_deps="mediacodec"
 mpeg2_mmal_hwaccel_deps="mmal"
 mpeg2_qsv_hwaccel_deps="libmfx"
 mpeg2_qsv_hwaccel_select="qsvdec_mpeg2"
@@ -2762,6 +2763,7 @@  mpeg1_vdpau_decoder_select="mpeg1video_decoder"
 mpeg2_crystalhd_decoder_select="crystalhd"
 mpeg2_cuvid_decoder_deps="cuda cuvid"
 mpeg2_mmal_decoder_deps="mmal"
+mpeg2_mediacodec_decoder_deps="mediacodec"
 mpeg2_qsv_decoder_deps="libmfx"
 mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel"
 mpeg2_qsv_encoder_deps="libmfx"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 0818950ad9..a752f87ef5 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -423,6 +423,7 @@  OBJS-$(CONFIG_MPEG2_QSV_DECODER)       += qsvdec_other.o
 OBJS-$(CONFIG_MPEG2_QSV_ENCODER)       += qsvenc_mpeg2.o
 OBJS-$(CONFIG_MPEG2VIDEO_DECODER)      += mpeg12dec.o mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_MPEG2VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o
+OBJS-$(CONFIG_MPEG2_MEDIACODEC_DECODER) += mediacodecdec.o
 OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER)     += vaapi_encode_mpeg2.o
 OBJS-$(CONFIG_MPEG4_DECODER)           += xvididct.o
 OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 89fadcd2fa..4373ebd975 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -96,6 +96,7 @@  static void register_all(void)
     REGISTER_HWACCEL(MPEG2_VAAPI,       mpeg2_vaapi);
     REGISTER_HWACCEL(MPEG2_VDPAU,       mpeg2_vdpau);
     REGISTER_HWACCEL(MPEG2_VIDEOTOOLBOX, mpeg2_videotoolbox);
+    REGISTER_HWACCEL(MPEG2_MEDIACODEC,  mpeg2_mediacodec);
     REGISTER_HWACCEL(MPEG4_CUVID,       mpeg4_cuvid);
     REGISTER_HWACCEL(MPEG4_MEDIACODEC,  mpeg4_mediacodec);
     REGISTER_HWACCEL(MPEG4_MMAL,        mpeg4_mmal);
@@ -257,6 +258,7 @@  static void register_all(void)
     REGISTER_DECODER(MPEG2_MMAL,        mpeg2_mmal);
     REGISTER_DECODER(MPEG2_CRYSTALHD,   mpeg2_crystalhd);
     REGISTER_DECODER(MPEG2_QSV,         mpeg2_qsv);
+    REGISTER_DECODER(MPEG2_MEDIACODEC,  mpeg2_mediacodec);
     REGISTER_DECODER(MSA1,              msa1);
     REGISTER_DECODER(MSCC,              mscc);
     REGISTER_DECODER(MSMPEG4V1,         msmpeg4v1);
diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
index ccfcb4b9ce..5bdeb6c1d7 100644
--- a/libavcodec/mediacodecdec.c
+++ b/libavcodec/mediacodecdec.c
@@ -1,5 +1,5 @@ 
 /*
- * Android MediaCodec H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders
+ * Android MediaCodec MPEG-2 / H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders
  *
  * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
  *
@@ -267,6 +267,19 @@  done:
 }
 #endif
 
+#if CONFIG_MPEG2_MEDIACODEC_DECODER
+static int mpeg2_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
+{
+    int ret = 0;
+
+    if (avctx->extradata) {
+        ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size);
+    }
+
+    return ret;
+}
+#endif
+
 #if CONFIG_MPEG4_MEDIACODEC_DECODER
 static int mpeg4_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
 {
@@ -333,6 +346,15 @@  static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
             goto done;
         break;
 #endif
+#if CONFIG_MPEG2_MEDIACODEC_DECODER
+    case AV_CODEC_ID_MPEG2VIDEO:
+        codec_mime = "video/mpeg2";
+
+        ret = mpeg2_set_extradata(avctx, format);
+        if (ret < 0)
+            goto done;
+        break;
+#endif
 #if CONFIG_MPEG4_MEDIACODEC_DECODER
     case AV_CODEC_ID_MPEG4:
         codec_mime = "video/mp4v-es",
@@ -575,6 +597,22 @@  AVCodec ff_hevc_mediacodec_decoder = {
 };
 #endif
 
+#if CONFIG_MPEG2_MEDIACODEC_DECODER
+AVCodec ff_mpeg2_mediacodec_decoder = {
+    .name           = "mpeg2_mediacodec",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 Android MediaCodec decoder"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
+    .priv_data_size = sizeof(MediaCodecH264DecContext),
+    .init           = mediacodec_decode_init,
+    .decode         = mediacodec_decode_frame,
+    .flush          = mediacodec_decode_flush,
+    .close          = mediacodec_decode_close,
+    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING,
+    .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS,
+};
+#endif
+
 #if CONFIG_MPEG4_MEDIACODEC_DECODER
 AVCodec ff_mpeg4_mediacodec_decoder = {
     .name           = "mpeg4_mediacodec",
diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c
index 2ec25c581d..1263188d34 100644
--- a/libavcodec/mediacodecdec_common.c
+++ b/libavcodec/mediacodecdec_common.c
@@ -766,6 +766,13 @@  AVHWAccel ff_hevc_mediacodec_hwaccel = {
     .pix_fmt = AV_PIX_FMT_MEDIACODEC,
 };
 
+AVHWAccel ff_mpeg2_mediacodec_hwaccel = {
+    .name    = "mediacodec",
+    .type    = AVMEDIA_TYPE_VIDEO,
+    .id      = AV_CODEC_ID_MPEG2VIDEO,
+    .pix_fmt = AV_PIX_FMT_MEDIACODEC,
+};
+
 AVHWAccel ff_mpeg4_mediacodec_hwaccel = {
     .name    = "mediacodec",
     .type    = AVMEDIA_TYPE_VIDEO,