diff mbox

[FFmpeg-devel,10/21] libavformat/movenc: add the urim sample descriptor

Message ID 1471943019-14136-11-git-send-email-erkki.seppala.ext@nokia.com
State Superseded
Headers show

Commit Message

erkki.seppala.ext@nokia.com Aug. 23, 2016, 9:03 a.m. UTC
From: Erkki Seppälä <erkki.seppala.ext@nokia.com>

This also adds libavformat/movmeta that contains the meta data
information. Later commits will add public interfaces for accessing
the data.

Signed-off-by: Erkki Seppälä <erkki.seppala.ext@nokia.com>
Signed-off-by: OZOPlayer <OZOPL@nokia.com>
---
 libavcodec/avcodec.h  | 18 ++++++++++-
 libavformat/isom.c    |  1 +
 libavformat/movenc.c  | 83 ++++++++++++++++++++++++++++++++++++++++++++++++---
 libavformat/movenc.h  |  1 +
 libavformat/movmeta.h | 46 ++++++++++++++++++++++++++++
 5 files changed, 144 insertions(+), 5 deletions(-)
 create mode 100644 libavformat/movmeta.h
diff mbox

Patch

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 893b89b..36c85e9 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1349,6 +1349,16 @@  typedef struct AVCPBProperties {
  * @{
  */
 
+typedef struct AVTimedMetadata {
+    char        meta_tag[4];    /** 4cc describing this metadata box type */
+    int         meta_length;    /** length of data for the metadata type information */
+
+    char        conf_tag[4];    /** configurationg box type 4cc, ie. 'conf' */
+    int         conf_length;    /** length of the data for the configuration box */
+
+    /** followed by meta_length bytes of meta data followed by conf_length bytes of conf data */
+} AVTimedMetadata;
+
 typedef struct AVTrackReferences {
     char        tag[4];         /** 4cc used for describing this  */
     int         nb_tracks;      /** number of tracks */
@@ -1540,7 +1550,13 @@  enum AVPacketSideDataType {
      * (including the track list that follows it), for as long as
      * indicated by the key's length.
      */
-    AV_PKT_DATA_TRACK_REFERENCES
+    AV_PKT_DATA_TRACK_REFERENCES,
+
+    /**
+     * Configured the timed metadata parameters, such as the uri and
+     * meta data configuration. The key is of type AVTimedMetadata.
+     */
+    AV_PKT_DATA_TIMED_METADATA_INFO
 };
 
 #define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED
diff --git a/libavformat/isom.c b/libavformat/isom.c
index 1a90d00..473700f 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -357,6 +357,7 @@  const AVCodecTag ff_codec_movsubtitle_tags[] = {
 
 const AVCodecTag ff_codec_metadata_tags[] = {
     { AV_CODEC_ID_META, MKTAG('m', 'e', 't', 'a') },
+    { AV_CODEC_ID_META, MKTAG('u', 'r', 'i', 'm') },
     { AV_CODEC_ID_NONE, 0 },
 };
 
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 072e660..141f1a5 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1552,6 +1552,69 @@  static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
     return 10;
 }
 
+static int mov_write_urim_uri_box(AVIOContext *pb, const char *uri, int length)
+{
+    int64_t pos = avio_tell(pb);
+    avio_wb32(pb, 0);           /* size */
+    ffio_wfourcc(pb, "uri ");
+    avio_w8(pb, 0);             /* version */
+    avio_wb24(pb, 0);           /* flags */
+
+    avio_write(pb, uri, length); /* uri */
+    avio_w8(pb, 0);          /* null-terminated */
+
+    return update_size(pb, pos);
+}
+
+static int mov_write_conf_box(AVIOContext *pb, const uint8_t *data, int length, char* tag)
+{
+    int64_t pos = avio_tell(pb);
+    avio_wb32(pb, 0);           /* size */
+    ffio_wfourcc(pb, tag);
+
+    avio_w8(pb, 0);             /* version */
+    avio_wb24(pb, 0);           /* flags */
+
+    avio_write(pb, data, length); /* data */
+
+    return update_size(pb, pos);
+}
+
+static int mov_write_meta_codec(AVIOContext *pb, MOVTrack *track)
+{
+    int64_t pos = avio_tell(pb);
+
+    char *data;
+    char *tag;
+
+    AVTimedMetadata *meta =
+        (void*) av_stream_get_side_data(track->st, AV_PKT_DATA_TIMED_METADATA_INFO,
+                                        NULL);
+
+    av_assert0(meta);
+
+    avio_wb32(pb, 0);    /* size */
+    ffio_wfourcc(pb, meta->meta_tag);
+
+    avio_wb32(pb, 0);    /* Reserved */
+    avio_wb16(pb, 0);    /* Reserved */
+    avio_wb16(pb, 1);    /* Data-reference index */
+
+    data = (char*) (meta + 1);
+    tag = meta->meta_tag;
+    if (tag[0] == 'u' && tag[1] == 'r' && tag[2] == 'i' && tag[3] == 'm') {
+        mov_write_urim_uri_box(pb, data, meta->meta_length);
+        data += meta->meta_length;
+    }
+
+    if (meta->conf_length) {
+        mov_write_conf_box(pb, data, meta->conf_length, meta->conf_tag);
+        data += meta->conf_length;
+    }
+
+    return update_size(pb, pos);
+}
+
 static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -1951,6 +2014,18 @@  static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
     return update_size(pb, pos);
 }
 
+static int mov_write_data_tag(AVIOContext *pb, MOVTrack *track)
+{
+    if (track->par->codec_id == AV_CODEC_ID_META)
+        return mov_write_meta_codec(pb, track);
+    else if (track->par->codec_tag == MKTAG('t','m','c','d'))
+        return mov_write_tmcd_tag(pb, track);
+    else if (track->par->codec_tag == MKTAG('r','t','p',' '))
+        return mov_write_rtp_tag(pb, track);
+    else
+        return 0;
+}
+
 static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -1962,12 +2037,10 @@  static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
         mov_write_video_tag(pb, mov, track);
     else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
         mov_write_audio_tag(s, pb, mov, track);
+    else if (track->par->codec_type == AVMEDIA_TYPE_DATA)
+        mov_write_data_tag(pb, track);
     else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
         mov_write_subtitle_tag(pb, track);
-    else if (track->par->codec_tag == MKTAG('r','t','p',' '))
-        mov_write_rtp_tag(pb, track);
-    else if (track->par->codec_tag == MKTAG('t','m','c','d'))
-        mov_write_tmcd_tag(pb, track);
     return update_size(pb, pos);
 }
 
@@ -2309,6 +2382,8 @@  static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
         mov_write_vmhd_tag(pb);
     else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
         mov_write_smhd_tag(pb);
+    else if (track->par->codec_type == AVMEDIA_TYPE_DATA)
+        mov_write_nmhd_tag(pb);
     else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
         if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
             mov_write_gmhd_tag(pb, track);
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index 5bf9469..15aa4b3 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -26,6 +26,7 @@ 
 
 #include "avformat.h"
 #include "movenccenc.h"
+#include "movmeta.h"
 
 #define MOV_FRAG_INFO_ALLOC_INCREMENT 64
 #define MOV_INDEX_CLUSTER_SIZE 1024
diff --git a/libavformat/movmeta.h b/libavformat/movmeta.h
new file mode 100644
index 0000000..e57b381
--- /dev/null
+++ b/libavformat/movmeta.h
@@ -0,0 +1,46 @@ 
+/*
+ * MOV, 3GP, MP4 muxer
+ * Copyright (c) 2015 Erkki Seppälä <erkki.seppala.ext@nokia.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_MOVMETA_H
+#define AVFORMAT_MOVMETA_H
+
+#include "avformat.h"
+
+typedef enum MOVMetaType {
+    MOV_META_NONE,
+    MOV_META_URIM
+} MOVMetaType;
+
+typedef struct MOVConfMeta {
+    uint32_t    tag;
+    int         length;
+    void        *data;
+} MOVConfMeta;
+
+typedef struct MOVMeta {
+    uint32_t    tag;
+    int         length;
+    void        *data;
+
+    MOVConfMeta conf;
+} MOVMeta;
+
+#endif /* AVFORMAT_MOVMETA_H */