diff mbox

[FFmpeg-devel] flvdec: set need_context_update when changing codec id

Message ID 407bf1b7-2b73-4998-d8a7-660f01f8a30e@googlemail.com
State Superseded
Headers show

Commit Message

Andreas Cadhalpun Nov. 4, 2016, 9:28 p.m. UTC
Otherwise the codec context and codecpar might disagree on the codec id,
triggering asserts in av_parser_parse2.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
---
 libavformat/flvdec.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

Comments

Andreas Cadhalpun Nov. 22, 2016, 10:18 p.m. UTC | #1
On 04.11.2016 22:28, Andreas Cadhalpun wrote:
> Otherwise the codec context and codecpar might disagree on the codec id,
> triggering asserts in av_parser_parse2.
> 
> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
> ---
>  libavformat/flvdec.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> index e53c345..4ba7fc8 100644
> --- a/libavformat/flvdec.c
> +++ b/libavformat/flvdec.c
> @@ -289,7 +289,9 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
>  static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
>                                 int flv_codecid, int read)
>  {
> +    int ret = 0;
>      AVCodecParameters *par = vstream->codecpar;
> +    enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
>      switch (flv_codecid) {
>      case FLV_CODECID_H263:
>          par->codec_id = AV_CODEC_ID_FLV1;
> @@ -317,20 +319,26 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
>              else
>                  avio_skip(s->pb, 1);
>          }
> -        return 1;     // 1 byte body size adjustment for flv_read_packet()
> +        ret = 1;     // 1 byte body size adjustment for flv_read_packet()
> +        break;
>      case FLV_CODECID_H264:
>          par->codec_id = AV_CODEC_ID_H264;
>          vstream->need_parsing = AVSTREAM_PARSE_HEADERS;
> -        return 3;     // not 4, reading packet type will consume one byte
> +        ret = 3;     // not 4, reading packet type will consume one byte
> +        break;
>      case FLV_CODECID_MPEG4:
>          par->codec_id = AV_CODEC_ID_MPEG4;
> -        return 3;
> +        ret = 3;
> +        break;
>      default:
>          avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
>          par->codec_tag = flv_codecid;
>      }
>  
> -    return 0;
> +    if (par->codec_id != old_codec_id)
> +        vstream->internal->need_context_update = 1;
> +
> +    return ret;
>  }
>  
>  static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize)
> 

Ping. I intend to apply this in a few days.

Best regards,
Andreas
Michael Niedermayer Nov. 23, 2016, 2:26 a.m. UTC | #2
On Fri, Nov 04, 2016 at 10:28:20PM +0100, Andreas Cadhalpun wrote:
> Otherwise the codec context and codecpar might disagree on the codec id,
> triggering asserts in av_parser_parse2.
> 
> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
> ---
>  libavformat/flvdec.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> index e53c345..4ba7fc8 100644
> --- a/libavformat/flvdec.c
> +++ b/libavformat/flvdec.c
> @@ -289,7 +289,9 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
>  static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
>                                 int flv_codecid, int read)
>  {
> +    int ret = 0;
>      AVCodecParameters *par = vstream->codecpar;
> +    enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
>      switch (flv_codecid) {
>      case FLV_CODECID_H263:
>          par->codec_id = AV_CODEC_ID_FLV1;
> @@ -317,20 +319,26 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
>              else
>                  avio_skip(s->pb, 1);
>          }
> -        return 1;     // 1 byte body size adjustment for flv_read_packet()
> +        ret = 1;     // 1 byte body size adjustment for flv_read_packet()
> +        break;
>      case FLV_CODECID_H264:
>          par->codec_id = AV_CODEC_ID_H264;
>          vstream->need_parsing = AVSTREAM_PARSE_HEADERS;
> -        return 3;     // not 4, reading packet type will consume one byte
> +        ret = 3;     // not 4, reading packet type will consume one byte
> +        break;
>      case FLV_CODECID_MPEG4:
>          par->codec_id = AV_CODEC_ID_MPEG4;
> -        return 3;
> +        ret = 3;
> +        break;
>      default:
>          avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
>          par->codec_tag = flv_codecid;
>      }
>  
> -    return 0;
> +    if (par->codec_id != old_codec_id)
> +        vstream->internal->need_context_update = 1;

If this occurs only for fuzzed samples then rejecting the change
with a request for a sample seems better

changing teh codec_id midstream like this could, seems problematic
changing at at header time might be ok if that works better than not
changing it for some real sample

but maybe iam missing something

[...]
diff mbox

Patch

diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index e53c345..4ba7fc8 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -289,7 +289,9 @@  static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
                                int flv_codecid, int read)
 {
+    int ret = 0;
     AVCodecParameters *par = vstream->codecpar;
+    enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
     switch (flv_codecid) {
     case FLV_CODECID_H263:
         par->codec_id = AV_CODEC_ID_FLV1;
@@ -317,20 +319,26 @@  static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
             else
                 avio_skip(s->pb, 1);
         }
-        return 1;     // 1 byte body size adjustment for flv_read_packet()
+        ret = 1;     // 1 byte body size adjustment for flv_read_packet()
+        break;
     case FLV_CODECID_H264:
         par->codec_id = AV_CODEC_ID_H264;
         vstream->need_parsing = AVSTREAM_PARSE_HEADERS;
-        return 3;     // not 4, reading packet type will consume one byte
+        ret = 3;     // not 4, reading packet type will consume one byte
+        break;
     case FLV_CODECID_MPEG4:
         par->codec_id = AV_CODEC_ID_MPEG4;
-        return 3;
+        ret = 3;
+        break;
     default:
         avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
         par->codec_tag = flv_codecid;
     }
 
-    return 0;
+    if (par->codec_id != old_codec_id)
+        vstream->internal->need_context_update = 1;
+
+    return ret;
 }
 
 static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize)