[FFmpeg-cvslog] matroskadec: Add support for parsing Matroska ContentEncKeyID

Frank Galligan git at videolan.org
Wed Mar 20 21:40:44 CET 2013


ffmpeg | branch: master | Frank Galligan <fgalligan at chromium.org> | Thu Mar  7 08:11:38 2013 -0800| [b853103fe0e59edc8970462abc6c181610ad9216] | committer: Michael Niedermayer

matroskadec: Add support for parsing Matroska ContentEncKeyID

This patch adds the enums for the ContentEncryption elements.
This patch also adds support for parsing the ContentEncKeyID. The
ContentEncKeyID is then base64 encoded and stored in the stream's
metadata.

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b853103fe0e59edc8970462abc6c181610ad9216
---

 libavformat/matroska.h    |    9 ++++++++
 libavformat/matroskadec.c |   53 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index 8e6f8cc..8a7e10b 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -137,6 +137,15 @@
 #define MATROSKA_ID_ENCODINGCOMPALGO 0x4254
 #define MATROSKA_ID_ENCODINGCOMPSETTINGS 0x4255
 
+#define MATROSKA_ID_ENCODINGENCRYPTION 0x5035
+#define MATROSKA_ID_ENCODINGENCAESSETTINGS 0x47E7
+#define MATROSKA_ID_ENCODINGENCALGO 0x47E1
+#define MATROSKA_ID_ENCODINGENCKEYID 0x47E2
+#define MATROSKA_ID_ENCODINGSIGALGO 0x47E5
+#define MATROSKA_ID_ENCODINGSIGHASHALGO 0x47E6
+#define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4
+#define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3
+
 /* ID in the cues master */
 #define MATROSKA_ID_POINTENTRY 0xBB
 
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 115c926..eea29da 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -39,6 +39,7 @@
 #include "matroska.h"
 #include "libavcodec/bytestream.h"
 #include "libavcodec/mpeg4audio.h"
+#include "libavutil/base64.h"
 #include "libavutil/intfloat.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/avstring.h"
@@ -102,9 +103,15 @@ typedef struct {
 } MatroskaTrackCompression;
 
 typedef struct {
+    uint64_t algo;
+    EbmlBin  key_id;
+} MatroskaTrackEncryption;
+
+typedef struct {
     uint64_t scope;
     uint64_t type;
     MatroskaTrackCompression compression;
+    MatroskaTrackEncryption encryption;
 } MatroskaTrackEncoding;
 
 typedef struct {
@@ -345,10 +352,21 @@ static EbmlSyntax matroska_track_encoding_compression[] = {
     { 0 }
 };
 
+static EbmlSyntax matroska_track_encoding_encryption[] = {
+    { MATROSKA_ID_ENCODINGENCALGO,        EBML_UINT, 0, offsetof(MatroskaTrackEncryption,algo), {.u=0} },
+    { MATROSKA_ID_ENCODINGENCKEYID,       EBML_BIN, 0, offsetof(MatroskaTrackEncryption,key_id) },
+    { MATROSKA_ID_ENCODINGENCAESSETTINGS, EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGALGO,        EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGHASHALGO,    EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGKEYID,       EBML_NONE },
+    { MATROSKA_ID_ENCODINGSIGNATURE,      EBML_NONE },
+    { 0 }
+};
 static EbmlSyntax matroska_track_encoding[] = {
     { MATROSKA_ID_ENCODINGSCOPE,      EBML_UINT, 0, offsetof(MatroskaTrackEncoding,scope), {.u=1} },
     { MATROSKA_ID_ENCODINGTYPE,       EBML_UINT, 0, offsetof(MatroskaTrackEncoding,type), {.u=0} },
     { MATROSKA_ID_ENCODINGCOMPRESSION,EBML_NEST, 0, offsetof(MatroskaTrackEncoding,compression), {.n=matroska_track_encoding_compression} },
+    { MATROSKA_ID_ENCODINGENCRYPTION, EBML_NEST, 0, offsetof(MatroskaTrackEncoding,encryption), {.n=matroska_track_encoding_encryption} },
     { MATROSKA_ID_ENCODINGORDER,      EBML_NONE },
     { 0 }
 };
@@ -1541,6 +1559,7 @@ static int matroska_read_header(AVFormatContext *s)
         int extradata_offset = 0;
         uint32_t fourcc = 0;
         AVIOContext b;
+        char* key_id_base64 = NULL;
 
         /* Apply some sanity checks. */
         if (track->type != MATROSKA_TRACK_TYPE_VIDEO &&
@@ -1571,8 +1590,24 @@ static int matroska_read_header(AVFormatContext *s)
             av_log(matroska->ctx, AV_LOG_ERROR,
                    "Multiple combined encodings not supported");
         } else if (encodings_list->nb_elem == 1) {
-            if (encodings[0].type ||
-                (
+            if (encodings[0].type) {
+                if (encodings[0].encryption.key_id.size > 0) {
+                    /* Save the encryption key id to be stored later as a
+                       metadata tag. */
+                    const int b64_size = AV_BASE64_SIZE(encodings[0].encryption.key_id.size);
+                    key_id_base64 = av_malloc(b64_size);
+                    if (key_id_base64 == NULL)
+                        return AVERROR(ENOMEM);
+
+                    av_base64_encode(key_id_base64, b64_size,
+                                     encodings[0].encryption.key_id.data,
+                                     encodings[0].encryption.key_id.size);
+                } else {
+                    encodings[0].scope = 0;
+                    av_log(matroska->ctx, AV_LOG_ERROR,
+                           "Unsupported encoding type");
+                }
+            } else if (
 #if CONFIG_ZLIB
                  encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB &&
 #endif
@@ -1582,7 +1617,7 @@ static int matroska_read_header(AVFormatContext *s)
 #if CONFIG_LZO
                  encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO &&
 #endif
-                 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP)) {
+                 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) {
                 encodings[0].scope = 0;
                 av_log(matroska->ctx, AV_LOG_ERROR,
                        "Unsupported encoding type");
@@ -1612,8 +1647,16 @@ static int matroska_read_header(AVFormatContext *s)
         }
 
         st = track->stream = avformat_new_stream(s, NULL);
-        if (st == NULL)
+        if (st == NULL) {
+            av_free(key_id_base64);
             return AVERROR(ENOMEM);
+        }
+
+        if (key_id_base64) {
+            /* export encryption key id as base64 metadata tag */
+            av_dict_set(&st->metadata, "enc_key_id", key_id_base64, 0);
+            av_freep(&key_id_base64);
+        }
 
         if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC")
             && track->codec_priv.size >= 40
@@ -2105,7 +2148,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
     int offset = 0, res;
     AVPacket *pkt;
 
-    if (encodings && encodings->scope & 1) {
+    if (encodings && !encodings->type && encodings->scope & 1) {
         res = matroska_decode_buffer(&pkt_data, &pkt_size, track);
         if (res < 0)
             return res;



More information about the ffmpeg-cvslog mailing list