h264dec: support broken files with mp4 extradata/annex b data

Message ID 1475309571-31537-1-git-send-email-anton@khirnov.net
State Committed
Commit 5bf2454e7cb03609b3ec1a3cf4c22427fe5f8e36
Headers show

Commit Message

Anton Khirnov Oct. 1, 2016, 8:12 a.m.
Bug-Id: 966
---
 libavcodec/h264dec.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

Comments

Luca Barbato Oct. 1, 2016, 1:22 p.m. | #1
On 01/10/16 10:12, Anton Khirnov wrote:
> Bug-Id: 966
> ---
>  libavcodec/h264dec.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 

sounds ok.
Vittorio Giovara Oct. 1, 2016, 6:09 p.m. | #2
On Sat, Oct 1, 2016 at 4:12 AM, Anton Khirnov <anton@khirnov.net> wrote:
> Bug-Id: 966
> ---
>  libavcodec/h264dec.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
> index 2c5a7db..330a74d 100644
> --- a/libavcodec/h264dec.c
> +++ b/libavcodec/h264dec.c
> @@ -530,7 +530,24 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
>      if (ret < 0) {
>          av_log(avctx, AV_LOG_ERROR,
>                 "Error splitting the input into NAL units.\n");
> -        return ret;
> +
> +        /* There are samples in the wild with mp4-style extradata, but Annex B
> +         * data in the packets. If we fail parsing the packet as mp4, try it again
> +         * as Annex B. */
> +        if (h->is_avc && !(avctx->err_recognition & AV_EF_EXPLODE)) {
> +            int err = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, 0, 0,
> +                                            avctx->codec_id);
> +            if (err >= 0) {
> +                av_log(avctx, AV_LOG_WARNING,
> +                       "The stream seems to contain AVCC extradata with Annex B "
> +                       "formatted data, which is invalid.");
> +                h->is_avc = 0;
> +                ret       = 0;
> +            }
> +        }
> +
> +        if (ret < 0)
> +            return ret;
>      }
>
>      if (avctx->active_thread_type & FF_THREAD_FRAME)
> --

Would it be possible to add a fate test for this?

Patch

diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 2c5a7db..330a74d 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -530,7 +530,24 @@  static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR,
                "Error splitting the input into NAL units.\n");
-        return ret;
+
+        /* There are samples in the wild with mp4-style extradata, but Annex B
+         * data in the packets. If we fail parsing the packet as mp4, try it again
+         * as Annex B. */
+        if (h->is_avc && !(avctx->err_recognition & AV_EF_EXPLODE)) {
+            int err = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, 0, 0,
+                                            avctx->codec_id);
+            if (err >= 0) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "The stream seems to contain AVCC extradata with Annex B "
+                       "formatted data, which is invalid.");
+                h->is_avc = 0;
+                ret       = 0;
+            }
+        }
+
+        if (ret < 0)
+            return ret;
     }
 
     if (avctx->active_thread_type & FF_THREAD_FRAME)