[FFmpeg-devel] Access to the dolby vision decoder info

Submitted by Dmitrij.Gresserman@loewe.de on Feb. 1, 2019, 4:05 p.m.

Details

Message ID AEB6F99C59AFC04FB890F68057924E510115AFF1@CQEX10.loewe.de
State New
Headers show

Commit Message

Dmitrij.Gresserman@loewe.de Feb. 1, 2019, 4:05 p.m.
Hello,

i need access to the dolby vision decoder info.
This includes the Dolby Vision Configuration Box and decoder configuration record (dvcC/dvvC).
Also includes the DOVI Video Stream Descriptor.
Here is my approach attached as a patch.

Best regards
[Ein einzigartiges Sounderlebnis mit Loewe und Mimi Defined™]<https://www.loewe.tv/mimi>
________________________________
Visit our website: https://www.loewe.tv/int

[Facebook]<https://www.facebook.com/LoeweDeutschland>  [Instagram] <https://www.instagram.com/loewe.international/>   [Pinterest] <https://www.pinterest.com/loewetv/>   [YouTube] <http://www.youtube.com/user/loewe>

Loewe Technologies GmbH, Industriestraße 11, 96317 Kronach
Tel. +49 9261 99-500 • Fax +49 9261 99-515
ccc@loewe.de<mailto:ccc@loewe.de> • www.loewe.tv<https://www.loewe.tv>

Executive Management: Dr. Ralf Vogt, Peter Nortmann • Registered Office: Kronach • Commercial Register: Amtsgericht Coburg HRB 5443

Comments

Carl Eugen Hoyos Feb. 1, 2019, 4:42 p.m.
2019-02-01 17:05 GMT+01:00, Gresserman Dmitrij <Dmitrij.Gresserman@loewe.de>:

> i need access to the dolby vision decoder info.
> This includes the Dolby Vision Configuration Box and
> decoder configuration record (dvcC/dvvC).
> Also includes the DOVI Video Stream Descriptor.
> Here is my approach attached as a patch.

Could you elaborate on why you are adding prefixes to the
actual data? Is this something only your decoder expects
or do all decoders (known to you) expect the extradata
with the prefix you add?
How would the differently prefixed data be written into
mov / mpegts on remuxing?

Thank you, Carl Eugen
Dmitrij.Gresserman@loewe.de Feb. 1, 2019, 6:15 p.m.
The prefixes i'm adding to the data are not needed by the decoder at this point. It's only my approach to provide information on the origin of the dolby vision decoder info.

Best Regards
[Ein einzigartiges Sounderlebnis mit Loewe und Mimi Defined™]<https://www.loewe.tv/mimi>
________________________________
Visit our website: https://www.loewe.tv/int

[Facebook]<https://www.facebook.com/LoeweDeutschland>  [Instagram] <https://www.instagram.com/loewe.international/>   [Pinterest] <https://www.pinterest.com/loewetv/>   [YouTube] <http://www.youtube.com/user/loewe>

Loewe Technologies GmbH, Industriestraße 11, 96317 Kronach
Tel. +49 9261 99-500 • Fax +49 9261 99-515
ccc@loewe.de<mailto:ccc@loewe.de> • www.loewe.tv<https://www.loewe.tv>

Executive Management: Dr. Ralf Vogt, Peter Nortmann • Registered Office: Kronach • Commercial Register: Amtsgericht Coburg HRB 5443
Carl Eugen Hoyos Feb. 1, 2019, 6:30 p.m.
2019-02-01 19:15 GMT+01:00, Gresserman Dmitrij <Dmitrij.Gresserman@loewe.de>:
> The prefixes i'm adding to the data are not needed by the
> decoder at this point.

How does the decoder distinguish between the different data
structures?

> It's only my approach to provide information on the origin
> of the dolby vision decoder info.

Is the origin information necessary?

Carl Eugen
Dmitrij.Gresserman@loewe.de Feb. 1, 2019, 7:42 p.m.
The main motivation of the patch is to provide the complete structure of the Dolby Vision Configuration Box and decoder configuration record (dvcC/dvvC) and the DOVI Video Stream Descriptor. This provided structure can be parsed now and used (for example in dump.c) to indicate if a dolby vision stream is part of the analyzed file. Furthermore the profile and type of the dolby vsion sub streams can be displayed now.

The information of the origin is needed to parse the provided structure. The Descriptor and the Boxes have at this point nearly equal structures, but the reserved size varies significantly. So it may become releveant to know the origin of the provided structure in the future, therefore i added the prefixes.

Best Regards
[Ein einzigartiges Sounderlebnis mit Loewe und Mimi Defined™]<https://www.loewe.tv/mimi>
________________________________
Visit our website: https://www.loewe.tv/int

[Facebook]<https://www.facebook.com/LoeweDeutschland>  [Instagram] <https://www.instagram.com/loewe.international/>   [Pinterest] <https://www.pinterest.com/loewetv/>   [YouTube] <http://www.youtube.com/user/loewe>

Loewe Technologies GmbH, Industriestraße 11, 96317 Kronach
Tel. +49 9261 99-500 • Fax +49 9261 99-515
ccc@loewe.de<mailto:ccc@loewe.de> • www.loewe.tv<https://www.loewe.tv>

Executive Management: Dr. Ralf Vogt, Peter Nortmann • Registered Office: Kronach • Commercial Register: Amtsgericht Coburg HRB 5443
Hendrik Leppkes Feb. 1, 2019, 7:56 p.m.
On Fri, Feb 1, 2019 at 8:42 PM Gresserman Dmitrij
<Dmitrij.Gresserman@loewe.de> wrote:
>
> The main motivation of the patch is to provide the complete structure of the Dolby Vision Configuration Box and decoder configuration record (dvcC/dvvC) and the DOVI Video Stream Descriptor. This provided structure can be parsed now and used (for example in dump.c) to indicate if a dolby vision stream is part of the analyzed file. Furthermore the profile and type of the dolby vsion sub streams can be displayed now.
>
> The information of the origin is needed to parse the provided structure. The Descriptor and the Boxes have at this point nearly equal structures, but the reserved size varies significantly. So it may become releveant to know the origin of the provided structure in the future, therefore i added the prefixes.
>

We try to define full structures for our side-data types, and not just
copy opaque info from the bitstream into it.
So I would suggest to actually create a struct for it (in avutil,
similar to other HDR metadata), and parsing both blocks into the
structurure. This would make using and understanding the structs from
API users much easier.

side data structures are also designed to be extensible in the future,
so if new fields are being added from the reserved space, we can
extend the structures and add them.

This would then automatically resolve any ambiguity between the
structs from different containers.

- Hendrik
Dmitrij.Gresserman@loewe.de Feb. 4, 2019, 4:04 p.m.
Hello Hendrik,

I fully agree with your approach and already thought about this. Parsing this directly to a structure would the correct approach for a final future patch. Unfortunately at this point in development, i need the most flexibility possible, with simultaneously minimal reaction time.

Best Regards
[Ein einzigartiges Sounderlebnis mit Loewe und Mimi Defined™]<https://www.loewe.tv/mimi>
________________________________
Visit our website: https://www.loewe.tv/int

[Facebook]<https://www.facebook.com/LoeweDeutschland>  [Instagram] <https://www.instagram.com/loewe.international/>   [Pinterest] <https://www.pinterest.com/loewetv/>   [YouTube] <http://www.youtube.com/user/loewe>

Loewe Technologies GmbH, Industriestraße 11, 96317 Kronach
Tel. +49 9261 99-500 • Fax +49 9261 99-515
ccc@loewe.de<mailto:ccc@loewe.de> • www.loewe.tv<https://www.loewe.tv>

Executive Management: Dr. Ralf Vogt, Peter Nortmann • Registered Office: Kronach • Commercial Register: Amtsgericht Coburg HRB 5443
Hendrik Leppkes Feb. 4, 2019, 4:06 p.m.
On Mon, Feb 4, 2019 at 5:04 PM Gresserman Dmitrij
<Dmitrij.Gresserman@loewe.de> wrote:
>
> I fully agree with your approach and already thought about this. Parsing this directly to a structure would the correct approach for a final future patch. Unfortunately at this point in development, i need the most flexibility possible, with simultaneously minimal reaction time.
>

Since adding new types like this is basically public API, with certain
stability guarantees once added, we prefer proper solutions, instead
of quick hacks, otherwise we'll be dragging it around for years to
come.

- Hendrik
Dmitrij.Gresserman@loewe.de Feb. 4, 2019, 4:39 p.m.
Once again you are right.
I just wanted to show my approach to this community, to let you know, maybe it could help someone else.
I don't insist on adding this approach to your repositories.

Best Regards
[Ein einzigartiges Sounderlebnis mit Loewe und Mimi Defined™]<https://www.loewe.tv/mimi>
________________________________
Visit our website: https://www.loewe.tv/int

[Facebook]<https://www.facebook.com/LoeweDeutschland>  [Instagram] <https://www.instagram.com/loewe.international/>   [Pinterest] <https://www.pinterest.com/loewetv/>   [YouTube] <http://www.youtube.com/user/loewe>

Loewe Technologies GmbH, Industriestraße 11, 96317 Kronach
Tel. +49 9261 99-500 • Fax +49 9261 99-515
ccc@loewe.de<mailto:ccc@loewe.de> • www.loewe.tv<https://www.loewe.tv>

Executive Management: Dr. Ralf Vogt, Peter Nortmann • Registered Office: Kronach • Commercial Register: Amtsgericht Coburg HRB 5443

Patch hide | download patch | download mbox

From 8193bc14390d7e36a768b0f19b99f8374e83b5f2 Mon Sep 17 00:00:00 2001
From: gressermdm <Dmitrij.Gresserman@loewe.de>
Date: Thu, 31 Jan 2019 20:28:25 +0100
Subject: [PATCH 2/2] Access to the dolby vision decoder info

---
 libavcodec/avcodec.h |  9 +++++++
 libavformat/dump.c   | 39 +++++++++++++++++++++++++++++
 libavformat/mov.c    | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/mpegts.c | 31 +++++++++++++++++++++++
 4 files changed, 148 insertions(+)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 81b30dc..f2f3d93 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1378,6 +1378,15 @@  enum AVPacketSideDataType {
     AV_PKT_DATA_REFERENCE_TRACK,
 
     /**
+     * This side data contains an unsigned integer byte stream of the
+     * DOVI Descriptor or Dolby Vision Configuration Box.
+     * In addition the type of the Descriptor/Box is also added as FourCC
+     * to the begin of the stream as 4 bytes.
+     * This information can be used to configure the decoder for Dolby Vision.
+     */
+    AV_PKT_DOLBY_VISION_DECODER_INFO,
+
+    /**
      * The number of side data types.
      * This is not part of the public API/ABI in the sense that it may
      * change when new side data types are added.
diff --git a/libavformat/dump.c b/libavformat/dump.c
index ef20070..974ccfb 100644
--- a/libavformat/dump.c
+++ b/libavformat/dump.c
@@ -398,6 +398,41 @@  static void dump_reference_track(void *ctx, AVPacketSideData *sd)
     av_log(ctx, AV_LOG_INFO, "%"PRIu32"", *track_id);
 }
 
+static void dump_dolby_vision_decoder_info(void *ctx, AVStream *st, AVPacketSideData *sd)
+{
+    uint8_t *dolby_data;
+
+    uint8_t dv_profile;
+    uint8_t dv_level;
+    uint8_t rpu_present_flag;
+    uint8_t el_presenet_flag;
+    uint8_t bl_present_flag;
+
+    if (sd->size < 8){
+        av_log(ctx, AV_LOG_INFO, "invalid data");
+        return;
+    }
+
+    dolby_data = sd->data;
+    if (!dolby_data) {
+        av_log(ctx, AV_LOG_INFO, "invalid data");
+        return;
+    }
+
+    av_log(ctx, AV_LOG_INFO, "(0x%"PRIx8"%"PRIx8"%"PRIx8"%"PRIx8") ",
+            dolby_data[0], dolby_data[1], dolby_data[2], dolby_data[3]);
+    dolby_data += 4;
+
+    dv_profile = dolby_data[2] >> 1;
+    dv_level = ( dolby_data[2] << 7 ) + ( dolby_data[3] >> 3 );
+    rpu_present_flag = dolby_data[3] & 4;
+    el_presenet_flag = dolby_data[3] & 2;
+    bl_present_flag = dolby_data[3] & 1;
+
+    av_log(ctx, AV_LOG_INFO, "profile:%"PRIx8" level:%"PRIx8"%s%s%s", dv_profile, dv_level,
+            rpu_present_flag ? " rpu" : "", el_presenet_flag ? " el" : "", bl_present_flag ? " bl" : "");
+}
+
 static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
 {
     int i;
@@ -461,6 +496,10 @@  static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
             av_log(ctx, AV_LOG_INFO, "reference track: ");
             dump_reference_track(ctx, &sd);
             break;
+        case AV_PKT_DOLBY_VISION_DECODER_INFO:
+            av_log(ctx, AV_LOG_INFO, "dolby vision: ");
+            dump_dolby_vision_decoder_info(ctx, st, &sd);
+            break;
         default:
             av_log(ctx, AV_LOG_INFO,
                    "unknown side data type %d (%d bytes)", sd.type, sd.size);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 922776e..057968f 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -6669,6 +6669,8 @@  static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         return AVERROR(ENOMEM);
     *track_id = (uint32_t)avio_rb32(pb);
 
+    if (c->fc->nb_streams < 1)
+        return AVERROR_INVALIDDATA;
     st = c->fc->streams[c->fc->nb_streams-1];
     ret = av_stream_add_side_data(st, AV_PKT_DATA_REFERENCE_TRACK,
                                   (uint8_t *)track_id, sizeof(uint32_t));
@@ -6680,6 +6682,71 @@  static int mov_read_vdep(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     return 0;
 }
 
+static uint8_t *mov_read_dv_config(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    uint8_t *dolby_data;
+    AVStream *st;
+    size_t size_total;
+    int ret;
+
+    if (c->fc->nb_streams < 1)
+        return NULL;
+    st = c->fc->streams[c->fc->nb_streams-1];
+
+    if (atom.size < 4)
+        return NULL;
+
+    size_total = atom.size + 4;
+
+    dolby_data = av_mallocz(size_total);
+    if (!dolby_data)
+        return NULL;
+    avio_read(pb, dolby_data+4, atom.size);
+
+    ret = av_stream_add_side_data(st, AV_PKT_DOLBY_VISION_DECODER_INFO,
+                                  (uint8_t *)dolby_data, size_total);
+    if (ret < 0) {
+        av_free(dolby_data);
+        return NULL;
+    }
+
+    return dolby_data;
+}
+
+static int mov_read_dvcC(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    uint8_t *dolby_data;
+    dolby_data = mov_read_dv_config(c, pb, atom);
+
+    if (dolby_data) {
+        dolby_data[0] = 'd';
+        dolby_data[1] = 'v';
+        dolby_data[2] = 'c';
+        dolby_data[3] = 'C';
+    } else {
+        return AVERROR_INVALIDDATA;
+    }
+
+    return 0;
+}
+
+static int mov_read_dvvC(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    uint8_t *dolby_data;
+    dolby_data = mov_read_dv_config(c, pb, atom);
+
+    if (dolby_data) {
+        dolby_data[0] = 'd';
+        dolby_data[1] = 'v';
+        dolby_data[2] = 'v';
+        dolby_data[3] = 'C';
+    } else {
+        return AVERROR_INVALIDDATA;
+    }
+
+    return 0;
+}
+
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_aclr },
 { MKTAG('A','P','R','G'), mov_read_avid },
@@ -6774,6 +6841,8 @@  static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('m','d','c','v'), mov_read_mdcv },
 { MKTAG('c','l','l','i'), mov_read_clli },
 { MKTAG('v','d','e','p'), mov_read_vdep },
+{ MKTAG('d','v','c','C'), mov_read_dvcC },
+{ MKTAG('d','v','v','C'), mov_read_dvvC },
 { 0, NULL }
 };
 
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index edf6b57..af6ae5e 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -2002,6 +2002,37 @@  int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
             }
         }
         break;
+    case 0xb0: /* dovi descriptor */
+        {
+            uint8_t *dolby_data;
+            size_t size_total;
+            int ret;
+
+            if (desc_len < 4)
+                return AVERROR_INVALIDDATA;
+            size_total = desc_len + 4;
+
+            dolby_data = av_mallocz(size_total);
+            if (!dolby_data)
+                return AVERROR(ENOMEM);
+
+            dolby_data[0] = 'D';
+            dolby_data[1] = 'O';
+            dolby_data[2] = 'V';
+            dolby_data[3] = 'I';
+
+            for ( int i = 4; i < size_total; i++ ) {
+                dolby_data[i] = get8(pp, desc_end);
+            }
+
+            ret = av_stream_add_side_data(st, AV_PKT_DOLBY_VISION_DECODER_INFO,
+                                          (uint8_t *)dolby_data, size_total);
+            if (ret < 0) {
+                av_free(dolby_data);
+                return ret;
+            }
+        }
+        break;
     default:
         break;
     }
-- 
2.7.4