qtdemux: Add support for the avc3 sample entry format of the AVC file format

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
This commit is contained in:
Alex Ashley 2013-06-18 13:27:20 +01:00 committed by Sebastian Dröge
parent b68f419b6f
commit a965185dee
7 changed files with 23 additions and 2 deletions

View file

@ -3320,7 +3320,8 @@ atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
ste = atom_trak_add_video_entry (trak, context, entry->fourcc); ste = atom_trak_add_video_entry (trak, context, entry->fourcc);
trak->is_video = TRUE; 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->version = entry->version;
ste->width = entry->width; ste->width = entry->width;

View file

@ -143,6 +143,7 @@ G_BEGIN_DECLS
#define FOURCC_qtim GST_MAKE_FOURCC('q','t','i','m') #define FOURCC_qtim GST_MAKE_FOURCC('q','t','i','m')
#define FOURCC_drms GST_MAKE_FOURCC('d','r','m','s') #define FOURCC_drms GST_MAKE_FOURCC('d','r','m','s')
#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1') #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_h263 GST_MAKE_FOURCC('h','2','6','3')
#define FOURCC_s263 GST_MAKE_FOURCC('s','2','6','3') #define FOURCC_s263 GST_MAKE_FOURCC('s','2','6','3')
#define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C') #define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C')

View file

@ -59,10 +59,10 @@ G_BEGIN_DECLS
#define FOURCC_3gr6 GST_MAKE_FOURCC('3','g','r','6') #define FOURCC_3gr6 GST_MAKE_FOURCC('3','g','r','6')
#define FOURCC_3gg7 GST_MAKE_FOURCC('3','g','g','7') #define FOURCC_3gg7 GST_MAKE_FOURCC('3','g','g','7')
#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1') #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_qt__ GST_MAKE_FOURCC('q','t',' ',' ')
#define FOURCC_isml GST_MAKE_FOURCC('i','s','m','l') #define FOURCC_isml GST_MAKE_FOURCC('i','s','m','l')
#define FOURCC_piff GST_MAKE_FOURCC('p','i','f','f') #define FOURCC_piff GST_MAKE_FOURCC('p','i','f','f')
G_END_DECLS G_END_DECLS
#endif /* __FTYP_CC_H__ */ #endif /* __FTYP_CC_H__ */

View file

@ -58,6 +58,7 @@
#define QT_UINT64(a) ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4)) #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_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_avcC GST_MAKE_FOURCC('a','v','c','C')
GST_DEBUG_CATEGORY_STATIC (rtpxqtdepay_debug); GST_DEBUG_CATEGORY_STATIC (rtpxqtdepay_debug);
@ -179,6 +180,7 @@ gst_rtp_quicktime_parse_sd (GstRtpXQTDepay * rtpxqtdepay, guint8 * data,
switch (fourcc) { switch (fourcc) {
case FOURCC_avc1: case FOURCC_avc1:
case FOURCC_avc3:
{ {
guint32 chlen; guint32 chlen;

View file

@ -5400,6 +5400,12 @@ qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, const guint8 * buffer,
qtdemux_parse_container (qtdemux, node, buffer + 0x56, end); qtdemux_parse_container (qtdemux, node, buffer + 0x56, end);
break; break;
} }
case FOURCC_avc3:
{
GST_MEMDUMP_OBJECT (qtdemux, "avc3", buffer, end - buffer);
qtdemux_parse_container (qtdemux, node, buffer + 0x56, end);
break;
}
case FOURCC_mjp2: case FOURCC_mjp2:
{ {
qtdemux_parse_container (qtdemux, node, buffer + 86, end); qtdemux_parse_container (qtdemux, node, buffer + 86, end);
@ -7315,6 +7321,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
switch (fourcc) { switch (fourcc) {
case FOURCC_H264: case FOURCC_H264:
case FOURCC_avc1: case FOURCC_avc1:
case FOURCC_avc3:
{ {
gint len = QT_UINT32 (stsd_data) - 0x66; gint len = QT_UINT32 (stsd_data) - 0x66;
const guint8 *avc_data = 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", "stream-format", G_TYPE_STRING, "avc",
"alignment", G_TYPE_STRING, "au", NULL); "alignment", G_TYPE_STRING, "au", NULL);
break; 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', ' '): case GST_MAKE_FOURCC ('r', 'l', 'e', ' '):
_codec ("Run-length encoding"); _codec ("Run-length encoding");
caps = gst_caps_new_simple ("video/x-rle", caps = gst_caps_new_simple ("video/x-rle",

View file

@ -142,6 +142,7 @@ G_BEGIN_DECLS
#define FOURCC_H264 GST_MAKE_FOURCC('H','2','6','4') #define FOURCC_H264 GST_MAKE_FOURCC('H','2','6','4')
#define FOURCC_strf GST_MAKE_FOURCC('s','t','r','f') #define FOURCC_strf GST_MAKE_FOURCC('s','t','r','f')
#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1') #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_avcC GST_MAKE_FOURCC('a','v','c','C')
#define FOURCC_btrt GST_MAKE_FOURCC('b','t','r','t') #define FOURCC_btrt GST_MAKE_FOURCC('b','t','r','t')
#define FOURCC_VP31 GST_MAKE_FOURCC('V','P','3','1') #define FOURCC_VP31 GST_MAKE_FOURCC('V','P','3','1')

View file

@ -171,6 +171,9 @@ static const QtNodeType qt_node_types[] = {
qtdemux_dump_mehd}, qtdemux_dump_mehd},
{FOURCC_ovc1, "ovc1", 0}, {FOURCC_ovc1, "ovc1", 0},
{FOURCC_owma, "owma", 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_tfdt, "Track fragment decode time", 0, qtdemux_dump_tfdt},
{FOURCC_chap, "Chapter Reference"}, {FOURCC_chap, "Chapter Reference"},
{0, "unknown", 0,}, {0, "unknown", 0,},