diff mbox

[FFmpeg-devel,v2,4/4] avcodec/mediacodecdec: add workaround for buggy amlogic mpeg2 decoder

Message ID 20180503022500.76182-4-ffmpeg@tmm1.net
State Accepted
Commit 9b563f6584b5ba2292975f0917268ac7b37497eb
Headers show

Commit Message

Aman Gupta May 3, 2018, 2:25 a.m. UTC
From: Aman Gupta <aman@tmm1.net>

---
 libavcodec/mediacodecdec.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

Comments

Matthieu Bouron May 3, 2018, 7:37 a.m. UTC | #1
On Wed, May 02, 2018 at 07:25:00PM -0700, Aman Gupta wrote:
> From: Aman Gupta <aman@tmm1.net>
> 
> ---
>  libavcodec/mediacodecdec.c | 22 +++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
> index 2ac22dd1f6..3a4240aa95 100644
> --- a/libavcodec/mediacodecdec.c
> +++ b/libavcodec/mediacodecdec.c
> @@ -48,6 +48,7 @@ typedef struct MediaCodecH264DecContext {
>      AVPacket buffered_pkt;
>  
>      int delay_flush;
> +    int amlogic_mpeg2_api23_workaround;
>  
>  } MediaCodecH264DecContext;
>  
> @@ -287,6 +288,7 @@ static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
>  static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
>  {
>      int ret;
> +    int sdk_int;
>  
>      const char *codec_mime = NULL;
>  
> @@ -377,7 +379,17 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
>          goto done;
>      }
>  
> -    av_log(avctx, AV_LOG_INFO, "MediaCodec started successfully, ret = %d\n", ret);
> +    av_log(avctx, AV_LOG_INFO,
> +           "MediaCodec started successfully: codec = %s, ret = %d\n",
> +           s->ctx->codec_name, ret);
> +
> +    sdk_int = ff_Build_SDK_INT(avctx);
> +    if (sdk_int <= 23 &&
> +        strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome") == 0) {
> +        av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on API=%d\n",
> +               s->ctx->codec_name, sdk_int);
> +        s->amlogic_mpeg2_api23_workaround = 1;
> +    }
>  
>  done:
>      if (format) {
> @@ -434,8 +446,12 @@ static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
>                  return ret;
>              }
>  
> -            /* poll for space again */
> -            continue;
> +            if (s->amlogic_mpeg2_api23_workaround && s->buffered_pkt.size <= 0) {
> +                /* fallthrough to fetch next packet regardless of input buffer space */
> +            } else {
> +                /* poll for space again */
> +                continue;
> +            }
>          }
>  
>          /* fetch new packet or eof */
> -- 
> 2.14.2
> 

Can you describe in the commit message what the issue is with this device
?

Thanks,
Aman Gupta May 3, 2018, 5:27 p.m. UTC | #2
On Thu, May 3, 2018 at 12:37 AM, Matthieu Bouron <matthieu.bouron@gmail.com>
wrote:

> On Wed, May 02, 2018 at 07:25:00PM -0700, Aman Gupta wrote:
> > From: Aman Gupta <aman@tmm1.net>
> >
> > ---
> >  libavcodec/mediacodecdec.c | 22 +++++++++++++++++++---
> >  1 file changed, 19 insertions(+), 3 deletions(-)
> >
> > diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
> > index 2ac22dd1f6..3a4240aa95 100644
> > --- a/libavcodec/mediacodecdec.c
> > +++ b/libavcodec/mediacodecdec.c
> > @@ -48,6 +48,7 @@ typedef struct MediaCodecH264DecContext {
> >      AVPacket buffered_pkt;
> >
> >      int delay_flush;
> > +    int amlogic_mpeg2_api23_workaround;
> >
> >  } MediaCodecH264DecContext;
> >
> > @@ -287,6 +288,7 @@ static int common_set_extradata(AVCodecContext
> *avctx, FFAMediaFormat *format)
> >  static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
> >  {
> >      int ret;
> > +    int sdk_int;
> >
> >      const char *codec_mime = NULL;
> >
> > @@ -377,7 +379,17 @@ static av_cold int mediacodec_decode_init(AVCodecContext
> *avctx)
> >          goto done;
> >      }
> >
> > -    av_log(avctx, AV_LOG_INFO, "MediaCodec started successfully, ret =
> %d\n", ret);
> > +    av_log(avctx, AV_LOG_INFO,
> > +           "MediaCodec started successfully: codec = %s, ret = %d\n",
> > +           s->ctx->codec_name, ret);
> > +
> > +    sdk_int = ff_Build_SDK_INT(avctx);
> > +    if (sdk_int <= 23 &&
> > +        strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome")
> == 0) {
> > +        av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on
> API=%d\n",
> > +               s->ctx->codec_name, sdk_int);
> > +        s->amlogic_mpeg2_api23_workaround = 1;
> > +    }
> >
> >  done:
> >      if (format) {
> > @@ -434,8 +446,12 @@ static int mediacodec_receive_frame(AVCodecContext
> *avctx, AVFrame *frame)
> >                  return ret;
> >              }
> >
> > -            /* poll for space again */
> > -            continue;
> > +            if (s->amlogic_mpeg2_api23_workaround &&
> s->buffered_pkt.size <= 0) {
> > +                /* fallthrough to fetch next packet regardless of input
> buffer space */
> > +            } else {
> > +                /* poll for space again */
> > +                continue;
> > +            }
> >          }
> >
> >          /* fetch new packet or eof */
> > --
> > 2.14.2
> >
>
> Can you describe in the commit message what the issue is with this device
> ?
>

Sure I can try. TBH I don't fully understand. I tested 7 devices, and this
was the only one that had issues. Without this change,
the picture would stall repeatedly during playback. After this change it
worked fine, though I can't explain why.

What's even more interesting is that two of the other devices I tried have
the same amlogic decoder but are running a newer
android OS, and work just fine without any changes.

Aman


>
> Thanks,
>
> --
> Matthieu B.
>
diff mbox

Patch

diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
index 2ac22dd1f6..3a4240aa95 100644
--- a/libavcodec/mediacodecdec.c
+++ b/libavcodec/mediacodecdec.c
@@ -48,6 +48,7 @@  typedef struct MediaCodecH264DecContext {
     AVPacket buffered_pkt;
 
     int delay_flush;
+    int amlogic_mpeg2_api23_workaround;
 
 } MediaCodecH264DecContext;
 
@@ -287,6 +288,7 @@  static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
 static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
 {
     int ret;
+    int sdk_int;
 
     const char *codec_mime = NULL;
 
@@ -377,7 +379,17 @@  static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
         goto done;
     }
 
-    av_log(avctx, AV_LOG_INFO, "MediaCodec started successfully, ret = %d\n", ret);
+    av_log(avctx, AV_LOG_INFO,
+           "MediaCodec started successfully: codec = %s, ret = %d\n",
+           s->ctx->codec_name, ret);
+
+    sdk_int = ff_Build_SDK_INT(avctx);
+    if (sdk_int <= 23 &&
+        strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome") == 0) {
+        av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on API=%d\n",
+               s->ctx->codec_name, sdk_int);
+        s->amlogic_mpeg2_api23_workaround = 1;
+    }
 
 done:
     if (format) {
@@ -434,8 +446,12 @@  static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
                 return ret;
             }
 
-            /* poll for space again */
-            continue;
+            if (s->amlogic_mpeg2_api23_workaround && s->buffered_pkt.size <= 0) {
+                /* fallthrough to fetch next packet regardless of input buffer space */
+            } else {
+                /* poll for space again */
+                continue;
+            }
         }
 
         /* fetch new packet or eof */