qtdemux: Add support for the avc3 sample entry format of the AVC file format
authorAlex Ashley <bugzilla@ashley-family.net>
Tue, 18 Jun 2013 12:27:20 +0000 (13:27 +0100)
committerSebastian Dröge <slomo@circular-chaos.org>
Wed, 4 Sep 2013 11:33:22 +0000 (13:33 +0200)
Amendment 2 of ISO/IEC 14496-15 (AVC file format) is defining a new
structure for fragmented MP4 called "avc3". The principal difference
between AVC1 and AVC3 is the location of the codec initialisation
data (e.g. SPS, PPS). In AVC1 this data is placed in the initial
MOOV box (moov.trak.mdia.minf.stbl.stsd.avc1) but in AVC3 this data
goes in the first sample of every fragment (i.e. the first sample in
each mdat box).  The principal reason for avc3 is to make it easier
for client implementations, because it removes the requirement to
insert the SPS+PPS in to the decoder pipeline every time there is a
representation change.

This commit adds support for the "avc3" atom, which is almost identical
to the "avc1" atom, except it does not contain any SPS or PPS data.

https://bugzilla.gnome.org/show_bug.cgi?id=702004

gst/isomp4/atoms.c
gst/isomp4/fourcc.h
gst/isomp4/ftypcc.h
gst/isomp4/gstrtpxqtdepay.c
gst/isomp4/qtdemux.c
gst/isomp4/qtdemux_fourcc.h
gst/isomp4/qtdemux_types.c

index 7b9af62..f6df24a 100644 (file)
@@ -3320,7 +3320,8 @@ atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
   ste = atom_trak_add_video_entry (trak, context, entry->fourcc);
 
   trak->is_video = TRUE;
-  trak->is_h264 = (entry->fourcc == FOURCC_avc1);
+  trak->is_h264 = (entry->fourcc == FOURCC_avc1
+      || entry->fourcc == FOURCC_avc3);
 
   ste->version = entry->version;
   ste->width = entry->width;
index bcb182e..1769c7b 100644 (file)
@@ -143,6 +143,7 @@ G_BEGIN_DECLS
 #define FOURCC_qtim     GST_MAKE_FOURCC('q','t','i','m')
 #define FOURCC_drms     GST_MAKE_FOURCC('d','r','m','s')
 #define FOURCC_avc1     GST_MAKE_FOURCC('a','v','c','1')
+#define FOURCC_avc3     GST_MAKE_FOURCC('a','v','c','3')
 #define FOURCC_h263     GST_MAKE_FOURCC('h','2','6','3')
 #define FOURCC_s263     GST_MAKE_FOURCC('s','2','6','3')
 #define FOURCC_avcC     GST_MAKE_FOURCC('a','v','c','C')
index b8b2c5e..6da9a09 100644 (file)
@@ -59,10 +59,10 @@ G_BEGIN_DECLS
 #define FOURCC_3gr6     GST_MAKE_FOURCC('3','g','r','6')
 #define FOURCC_3gg7     GST_MAKE_FOURCC('3','g','g','7')
 #define FOURCC_avc1     GST_MAKE_FOURCC('a','v','c','1')
+#define FOURCC_avc3     GST_MAKE_FOURCC('a','v','c','3')
 #define FOURCC_qt__     GST_MAKE_FOURCC('q','t',' ',' ')
 #define FOURCC_isml     GST_MAKE_FOURCC('i','s','m','l')
 #define FOURCC_piff     GST_MAKE_FOURCC('p','i','f','f')
 
 G_END_DECLS
-
 #endif /* __FTYP_CC_H__ */
index 54baf09..3bce461 100644 (file)
@@ -58,6 +58,7 @@
 #define QT_UINT64(a)  ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4))
 
 #define FOURCC_avc1     GST_MAKE_FOURCC('a','v','c','1')
+#define FOURCC_avc3     GST_MAKE_FOURCC('a','v','c','3')
 #define FOURCC_avcC     GST_MAKE_FOURCC('a','v','c','C')
 
 GST_DEBUG_CATEGORY_STATIC (rtpxqtdepay_debug);
@@ -179,6 +180,7 @@ gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data,
 
   switch (fourcc) {
     case FOURCC_avc1:
+    case FOURCC_avc3:
     {
       guint32 chlen;
 
index 36b6fbe..3ac4182 100644 (file)
@@ -5400,6 +5400,12 @@ qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, const guint8 * buffer,
         qtdemux_parse_container (qtdemux, node, buffer + 0x56, end);
         break;
       }
+      case FOURCC_avc3:
+      {
+        GST_MEMDUMP_OBJECT (qtdemux, "avc3", buffer, end - buffer);
+        qtdemux_parse_container (qtdemux, node, buffer + 0x56, end);
+        break;
+      }
       case FOURCC_mjp2:
       {
         qtdemux_parse_container (qtdemux, node, buffer + 86, end);
@@ -7315,6 +7321,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
       switch (fourcc) {
         case FOURCC_H264:
         case FOURCC_avc1:
+        case FOURCC_avc3:
         {
           gint len = QT_UINT32 (stsd_data) - 0x66;
           const guint8 *avc_data = stsd_data + 0x66;
@@ -10345,6 +10352,12 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
           "stream-format", G_TYPE_STRING, "avc",
           "alignment", G_TYPE_STRING, "au", NULL);
       break;
+    case GST_MAKE_FOURCC ('a', 'v', 'c', '3'):
+      _codec ("H.264 / AVC");
+      caps = gst_caps_new_simple ("video/x-h264",
+          "stream-format", G_TYPE_STRING, "avc3",
+          "alignment", G_TYPE_STRING, "au", NULL);
+      break;
     case GST_MAKE_FOURCC ('r', 'l', 'e', ' '):
       _codec ("Run-length encoding");
       caps = gst_caps_new_simple ("video/x-rle",
index d3a972b..6b8bd06 100644 (file)
@@ -142,6 +142,7 @@ G_BEGIN_DECLS
 #define FOURCC_H264     GST_MAKE_FOURCC('H','2','6','4')
 #define FOURCC_strf     GST_MAKE_FOURCC('s','t','r','f')
 #define FOURCC_avc1     GST_MAKE_FOURCC('a','v','c','1')
+#define FOURCC_avc3     GST_MAKE_FOURCC('a','v','c','3')
 #define FOURCC_avcC     GST_MAKE_FOURCC('a','v','c','C')
 #define FOURCC_btrt     GST_MAKE_FOURCC('b','t','r','t')
 #define FOURCC_VP31     GST_MAKE_FOURCC('V','P','3','1')
index 92e1814..e9f32cc 100644 (file)
@@ -171,6 +171,9 @@ static const QtNodeType qt_node_types[] = {
       qtdemux_dump_mehd},
   {FOURCC_ovc1, "ovc1", 0},
   {FOURCC_owma, "owma", 0},
+  {FOURCC_avcC, "AV codec configuration container", 0},
+  {FOURCC_avc1, "AV codec configuration v1", 0},
+  {FOURCC_avc3, "AV codec configuration v3", 0},
   {FOURCC_tfdt, "Track fragment decode time", 0, qtdemux_dump_tfdt},
   {FOURCC_chap, "Chapter Reference"},
   {0, "unknown", 0,},