diff mbox series

[FFmpeg-devel,v4,3/4] avformat/mov: Refactor DOVI box parsing to use ff_isom_parse_dvcc_dvvc

Message ID 20210927025728.285093-3-tcChlisop0@gmail.com
State New
Headers show
Series [FFmpeg-devel,v4,1/4] avformat/dovi_isom Implement Dolby Vision configuration parsing/writing | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

quietvoid Sept. 27, 2021, 2:57 a.m. UTC
Read at most 24 bytes, but in reality only 5 bytes are used for parsing.
The rest of the bytes are reserved in the specification.

Signed-off-by: quietvoid <tcChlisop0@gmail.com>
---
 libavformat/mov.c | 51 ++++++++++-------------------------------------
 1 file changed, 10 insertions(+), 41 deletions(-)

Comments

Andreas Rheinhardt Sept. 27, 2021, 3:32 a.m. UTC | #1
quietvoid:
> Read at most 24 bytes, but in reality only 5 bytes are used for parsing.
> The rest of the bytes are reserved in the specification.
> 
> Signed-off-by: quietvoid <tcChlisop0@gmail.com>
> ---
>  libavformat/mov.c | 51 ++++++++++-------------------------------------
>  1 file changed, 10 insertions(+), 41 deletions(-)
> 
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index d0b8b2595b..e052f7ad96 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -61,6 +61,8 @@
>  #include "mov_chan.h"
>  #include "replaygain.h"
>  
> +#include "libavformat/dovi_isom.h"
> +
>  #if CONFIG_ZLIB
>  #include <zlib.h>
>  #endif
> @@ -6799,58 +6801,25 @@ static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>  {
>      AVStream *st;
> -    uint32_t buf;
> -    AVDOVIDecoderConfigurationRecord *dovi;
> -    size_t dovi_size;
> +    uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
>      int ret;
> +    int64_t read_size = atom.size;
>  
>      if (c->fc->nb_streams < 1)
>          return 0;
>      st = c->fc->streams[c->fc->nb_streams-1];
>  
> -    if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
> -        return AVERROR_INVALIDDATA;
> -
> -    dovi = av_dovi_alloc(&dovi_size);
> -    if (!dovi)
> -        return AVERROR(ENOMEM);
> -
> -    dovi->dv_version_major = avio_r8(pb);
> -    dovi->dv_version_minor = avio_r8(pb);
> -
> -    buf = avio_rb16(pb);
> -    dovi->dv_profile        = (buf >> 9) & 0x7f;    // 7 bits
> -    dovi->dv_level          = (buf >> 3) & 0x3f;    // 6 bits
> -    dovi->rpu_present_flag  = (buf >> 2) & 0x01;    // 1 bit
> -    dovi->el_present_flag   = (buf >> 1) & 0x01;    // 1 bit
> -    dovi->bl_present_flag   =  buf       & 0x01;    // 1 bit
> -    if (atom.size >= 24) {  // 4 + 4 + 4 * 4
> -        buf = avio_r8(pb);
> -        dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
> -    } else {
> -        // 0 stands for None
> -        // Dolby Vision V1.2.93 profiles and levels
> -        dovi->dv_bl_signal_compatibility_id = 0;
> +    // At most 24 bytes
> +    if (read_size > ISOM_DVCC_DVVC_SIZE) {
> +        read_size = ISOM_DVCC_DVVC_SIZE;
>      }
>  
> -    ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
> -                                  (uint8_t *)dovi, dovi_size);
> -    if (ret < 0) {
> -        av_free(dovi);
> +    if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
>          return ret;
> -    }
>  
> -    av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
> -           "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
> -           dovi->dv_version_major, dovi->dv_version_minor,
> -           dovi->dv_profile, dovi->dv_level,
> -           dovi->rpu_present_flag,
> -           dovi->el_present_flag,
> -           dovi->bl_present_flag,
> -           dovi->dv_bl_signal_compatibility_id
> -        );
> +    read_size = ret;

ffio_read_size always returns an error if it could not read exactly the
amount of bytes desired by the caller. If you want to support truncated
data, you will have to use avio_read().

>  
> -    return 0;
> +    return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
>  }
>  
>  static const MOVParseTableEntry mov_default_parse_table[] = {
>
diff mbox series

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index d0b8b2595b..e052f7ad96 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -61,6 +61,8 @@ 
 #include "mov_chan.h"
 #include "replaygain.h"
 
+#include "libavformat/dovi_isom.h"
+
 #if CONFIG_ZLIB
 #include <zlib.h>
 #endif
@@ -6799,58 +6801,25 @@  static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
-    uint32_t buf;
-    AVDOVIDecoderConfigurationRecord *dovi;
-    size_t dovi_size;
+    uint8_t buf[ISOM_DVCC_DVVC_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
     int ret;
+    int64_t read_size = atom.size;
 
     if (c->fc->nb_streams < 1)
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
 
-    if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
-        return AVERROR_INVALIDDATA;
-
-    dovi = av_dovi_alloc(&dovi_size);
-    if (!dovi)
-        return AVERROR(ENOMEM);
-
-    dovi->dv_version_major = avio_r8(pb);
-    dovi->dv_version_minor = avio_r8(pb);
-
-    buf = avio_rb16(pb);
-    dovi->dv_profile        = (buf >> 9) & 0x7f;    // 7 bits
-    dovi->dv_level          = (buf >> 3) & 0x3f;    // 6 bits
-    dovi->rpu_present_flag  = (buf >> 2) & 0x01;    // 1 bit
-    dovi->el_present_flag   = (buf >> 1) & 0x01;    // 1 bit
-    dovi->bl_present_flag   =  buf       & 0x01;    // 1 bit
-    if (atom.size >= 24) {  // 4 + 4 + 4 * 4
-        buf = avio_r8(pb);
-        dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
-    } else {
-        // 0 stands for None
-        // Dolby Vision V1.2.93 profiles and levels
-        dovi->dv_bl_signal_compatibility_id = 0;
+    // At most 24 bytes
+    if (read_size > ISOM_DVCC_DVVC_SIZE) {
+        read_size = ISOM_DVCC_DVVC_SIZE;
     }
 
-    ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
-                                  (uint8_t *)dovi, dovi_size);
-    if (ret < 0) {
-        av_free(dovi);
+    if ((ret = ffio_read_size(pb, buf, read_size)) < 0)
         return ret;
-    }
 
-    av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
-           "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
-           dovi->dv_version_major, dovi->dv_version_minor,
-           dovi->dv_profile, dovi->dv_level,
-           dovi->rpu_present_flag,
-           dovi->el_present_flag,
-           dovi->bl_present_flag,
-           dovi->dv_bl_signal_compatibility_id
-        );
+    read_size = ret;
 
-    return 0;
+    return ff_isom_parse_dvcc_dvvc(c->fc, st, buf, read_size);
 }
 
 static const MOVParseTableEntry mov_default_parse_table[] = {