winlin

for #738, complete all mp4 boxes codec.

@@ -61,7 +61,9 @@ using namespace std; @@ -61,7 +61,9 @@ using namespace std;
61 #define SRS_MP4_BOX_STSS 0x73747373 // 'stss' 61 #define SRS_MP4_BOX_STSS 0x73747373 // 'stss'
62 #define SRS_MP4_BOX_STSC 0x73747363 // 'stsc' 62 #define SRS_MP4_BOX_STSC 0x73747363 // 'stsc'
63 #define SRS_MP4_BOX_STCO 0x7374636f // 'stco' 63 #define SRS_MP4_BOX_STCO 0x7374636f // 'stco'
  64 +#define SRS_MP4_BOX_CO64 0x636f3634 // 'co64'
64 #define SRS_MP4_BOX_STSZ 0x7374737a // 'stsz' 65 #define SRS_MP4_BOX_STSZ 0x7374737a // 'stsz'
  66 +#define SRS_MP4_BOX_STZ2 0x73747a32 // 'stz2'
65 67
66 #define SRS_MP4_EOF_SIZE 0 68 #define SRS_MP4_EOF_SIZE 0
67 #define SRS_MP4_USE_LARGE_SIZE 1 69 #define SRS_MP4_USE_LARGE_SIZE 1
@@ -192,6 +194,7 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) @@ -192,6 +194,7 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
192 case SRS_MP4_BOX_STSS: box = new SrsMp4SyncSampleBox(); break; 194 case SRS_MP4_BOX_STSS: box = new SrsMp4SyncSampleBox(); break;
193 case SRS_MP4_BOX_STSC: box = new SrsMp4Sample2ChunkBox(); break; 195 case SRS_MP4_BOX_STSC: box = new SrsMp4Sample2ChunkBox(); break;
194 case SRS_MP4_BOX_STCO: box = new SrsMp4ChunkOffsetBox(); break; 196 case SRS_MP4_BOX_STCO: box = new SrsMp4ChunkOffsetBox(); break;
  197 + case SRS_MP4_BOX_CO64: box = new SrsMp4ChunkLargeOffsetBox(); break;
195 case SRS_MP4_BOX_STSZ: box = new SrsMp4SampleSizeBox(); break; 198 case SRS_MP4_BOX_STSZ: box = new SrsMp4SampleSizeBox(); break;
196 default: 199 default:
197 ret = ERROR_MP4_BOX_ILLEGAL_TYPE; 200 ret = ERROR_MP4_BOX_ILLEGAL_TYPE;
@@ -1420,18 +1423,16 @@ int SrsMp4DataReferenceBox::decode_header(SrsBuffer* buf) @@ -1420,18 +1423,16 @@ int SrsMp4DataReferenceBox::decode_header(SrsBuffer* buf)
1420 return ret; 1423 return ret;
1421 } 1424 }
1422 1425
1423 - int left = left_space(buf);  
1424 - while (left > 0) { 1426 + uint32_t nb_entries = buf->read_4bytes();
  1427 + for (uint32_t i = 0; i < nb_entries; i++) {
1425 SrsMp4Box* box = NULL; 1428 SrsMp4Box* box = NULL;
1426 if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) { 1429 if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) {
1427 return ret; 1430 return ret;
1428 } 1431 }
1429 1432
1430 - int pos = buf->pos();  
1431 if ((ret = box->decode(buf)) != ERROR_SUCCESS) { 1433 if ((ret = box->decode(buf)) != ERROR_SUCCESS) {
1432 return ret; 1434 return ret;
1433 } 1435 }
1434 - left -= buf->pos() - pos;  
1435 1436
1436 SrsMp4FullBox* fbox = dynamic_cast<SrsMp4FullBox*>(box); 1437 SrsMp4FullBox* fbox = dynamic_cast<SrsMp4FullBox*>(box);
1437 if (fbox) { 1438 if (fbox) {
@@ -1660,6 +1661,8 @@ int SrsMp4SampleDescriptionBox::nb_header() @@ -1660,6 +1661,8 @@ int SrsMp4SampleDescriptionBox::nb_header()
1660 { 1661 {
1661 int size = SrsMp4FullBox::nb_header(); 1662 int size = SrsMp4FullBox::nb_header();
1662 1663
  1664 + size += 4;
  1665 +
1663 vector<SrsMp4SampleEntry*>::iterator it; 1666 vector<SrsMp4SampleEntry*>::iterator it;
1664 for (it = entries.begin(); it != entries.end(); ++it) { 1667 for (it = entries.begin(); it != entries.end(); ++it) {
1665 SrsMp4SampleEntry* entry = *it; 1668 SrsMp4SampleEntry* entry = *it;
@@ -1677,6 +1680,8 @@ int SrsMp4SampleDescriptionBox::encode_header(SrsBuffer* buf) @@ -1677,6 +1680,8 @@ int SrsMp4SampleDescriptionBox::encode_header(SrsBuffer* buf)
1677 return ret; 1680 return ret;
1678 } 1681 }
1679 1682
  1683 + buf->write_4bytes(entry_count());
  1684 +
1680 vector<SrsMp4SampleEntry*>::iterator it; 1685 vector<SrsMp4SampleEntry*>::iterator it;
1681 for (it = entries.begin(); it != entries.end(); ++it) { 1686 for (it = entries.begin(); it != entries.end(); ++it) {
1682 SrsMp4SampleEntry* entry = *it; 1687 SrsMp4SampleEntry* entry = *it;
@@ -1696,18 +1701,16 @@ int SrsMp4SampleDescriptionBox::decode_header(SrsBuffer* buf) @@ -1696,18 +1701,16 @@ int SrsMp4SampleDescriptionBox::decode_header(SrsBuffer* buf)
1696 return ret; 1701 return ret;
1697 } 1702 }
1698 1703
1699 - int left = left_space(buf);  
1700 - while (left > 0) { 1704 + uint32_t nb_entries = buf->read_4bytes();
  1705 + for (uint32_t i = 0; i < nb_entries; i++) {
1701 SrsMp4Box* box = NULL; 1706 SrsMp4Box* box = NULL;
1702 if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) { 1707 if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) {
1703 return ret; 1708 return ret;
1704 } 1709 }
1705 1710
1706 - int pos = buf->pos();  
1707 if ((ret = box->decode(buf)) != ERROR_SUCCESS) { 1711 if ((ret = box->decode(buf)) != ERROR_SUCCESS) {
1708 return ret; 1712 return ret;
1709 } 1713 }
1710 - left -= buf->pos() - pos;  
1711 1714
1712 SrsMp4SampleEntry* entry = dynamic_cast<SrsMp4SampleEntry*>(box); 1715 SrsMp4SampleEntry* entry = dynamic_cast<SrsMp4SampleEntry*>(box);
1713 if (entry) { 1716 if (entry) {
@@ -1741,7 +1744,7 @@ SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox() @@ -1741,7 +1744,7 @@ SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox()
1741 1744
1742 int SrsMp4DecodingTime2SampleBox::nb_header() 1745 int SrsMp4DecodingTime2SampleBox::nb_header()
1743 { 1746 {
1744 - return SrsMp4FullBox::nb_header(); 1747 + return SrsMp4FullBox::nb_header() + 4 + 8*entry_count;
1745 } 1748 }
1746 1749
1747 int SrsMp4DecodingTime2SampleBox::encode_header(SrsBuffer* buf) 1750 int SrsMp4DecodingTime2SampleBox::encode_header(SrsBuffer* buf)
@@ -1752,6 +1755,13 @@ int SrsMp4DecodingTime2SampleBox::encode_header(SrsBuffer* buf) @@ -1752,6 +1755,13 @@ int SrsMp4DecodingTime2SampleBox::encode_header(SrsBuffer* buf)
1752 return ret; 1755 return ret;
1753 } 1756 }
1754 1757
  1758 + buf->write_4bytes(entry_count);
  1759 + for (uint32_t i = 0; i < entry_count; i++) {
  1760 + SrsMp4SttsEntry& entry = entries[i];
  1761 + buf->write_4bytes(entry.sample_count);
  1762 + buf->write_4bytes(entry.sample_delta);
  1763 + }
  1764 +
1755 return ret; 1765 return ret;
1756 } 1766 }
1757 1767
@@ -1763,6 +1773,16 @@ int SrsMp4DecodingTime2SampleBox::decode_header(SrsBuffer* buf) @@ -1763,6 +1773,16 @@ int SrsMp4DecodingTime2SampleBox::decode_header(SrsBuffer* buf)
1763 return ret; 1773 return ret;
1764 } 1774 }
1765 1775
  1776 + entry_count = buf->read_4bytes();
  1777 + if (entry_count) {
  1778 + entries = new SrsMp4SttsEntry[entry_count];
  1779 + }
  1780 + for (uint32_t i = 0; i < entry_count; i++) {
  1781 + SrsMp4SttsEntry& entry = entries[i];
  1782 + entry.sample_count = buf->read_4bytes();
  1783 + entry.sample_delta = buf->read_4bytes();
  1784 + }
  1785 +
1766 return ret; 1786 return ret;
1767 } 1787 }
1768 1788
@@ -1787,7 +1807,7 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox() @@ -1787,7 +1807,7 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox()
1787 1807
1788 int SrsMp4CompositionTime2SampleBox::nb_header() 1808 int SrsMp4CompositionTime2SampleBox::nb_header()
1789 { 1809 {
1790 - return SrsMp4FullBox::nb_header(); 1810 + return SrsMp4FullBox::nb_header() + 4 + 8*entry_count;
1791 } 1811 }
1792 1812
1793 int SrsMp4CompositionTime2SampleBox::encode_header(SrsBuffer* buf) 1813 int SrsMp4CompositionTime2SampleBox::encode_header(SrsBuffer* buf)
@@ -1798,6 +1818,17 @@ int SrsMp4CompositionTime2SampleBox::encode_header(SrsBuffer* buf) @@ -1798,6 +1818,17 @@ int SrsMp4CompositionTime2SampleBox::encode_header(SrsBuffer* buf)
1798 return ret; 1818 return ret;
1799 } 1819 }
1800 1820
  1821 + buf->write_4bytes(entry_count);
  1822 + for (uint32_t i = 0; i < entry_count; i++) {
  1823 + SrsMp4CttsEntry& entry = entries[i];
  1824 + buf->write_4bytes(entry.sample_count);
  1825 + if (version == 0) {
  1826 + buf->write_4bytes((uint32_t)entry.sample_offset);
  1827 + } else if (version == 1) {
  1828 + buf->write_4bytes((int32_t)entry.sample_offset);
  1829 + }
  1830 + }
  1831 +
1801 return ret; 1832 return ret;
1802 } 1833 }
1803 1834
@@ -1809,6 +1840,20 @@ int SrsMp4CompositionTime2SampleBox::decode_header(SrsBuffer* buf) @@ -1809,6 +1840,20 @@ int SrsMp4CompositionTime2SampleBox::decode_header(SrsBuffer* buf)
1809 return ret; 1840 return ret;
1810 } 1841 }
1811 1842
  1843 + entry_count = buf->read_4bytes();
  1844 + if (entry_count) {
  1845 + entries = new SrsMp4CttsEntry[entry_count];
  1846 + }
  1847 + for (uint32_t i = 0; i < entry_count; i++) {
  1848 + SrsMp4CttsEntry& entry = entries[i];
  1849 + entry.sample_count = buf->read_4bytes();
  1850 + if (version == 0) {
  1851 + entry.sample_offset = (uint32_t)buf->read_4bytes();
  1852 + } else if (version == 1) {
  1853 + entry.sample_offset = (int32_t)buf->read_4bytes();
  1854 + }
  1855 + }
  1856 +
1812 return ret; 1857 return ret;
1813 } 1858 }
1814 1859
@@ -1827,7 +1872,7 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox() @@ -1827,7 +1872,7 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox()
1827 1872
1828 int SrsMp4SyncSampleBox::nb_header() 1873 int SrsMp4SyncSampleBox::nb_header()
1829 { 1874 {
1830 - return SrsMp4FullBox::nb_header(); 1875 + return SrsMp4FullBox::nb_header() +4 +4*entry_count;
1831 } 1876 }
1832 1877
1833 int SrsMp4SyncSampleBox::encode_header(SrsBuffer* buf) 1878 int SrsMp4SyncSampleBox::encode_header(SrsBuffer* buf)
@@ -1838,6 +1883,12 @@ int SrsMp4SyncSampleBox::encode_header(SrsBuffer* buf) @@ -1838,6 +1883,12 @@ int SrsMp4SyncSampleBox::encode_header(SrsBuffer* buf)
1838 return ret; 1883 return ret;
1839 } 1884 }
1840 1885
  1886 + buf->write_4bytes(entry_count);
  1887 + for (uint32_t i = 0; i < entry_count; i++) {
  1888 + uint32_t sample_number = sample_numbers[i];
  1889 + buf->write_4bytes(sample_number);
  1890 + }
  1891 +
1841 return ret; 1892 return ret;
1842 } 1893 }
1843 1894
@@ -1849,6 +1900,15 @@ int SrsMp4SyncSampleBox::decode_header(SrsBuffer* buf) @@ -1849,6 +1900,15 @@ int SrsMp4SyncSampleBox::decode_header(SrsBuffer* buf)
1849 return ret; 1900 return ret;
1850 } 1901 }
1851 1902
  1903 + entry_count = buf->read_4bytes();
  1904 + if (entry_count > 0) {
  1905 + sample_numbers = new uint32_t[entry_count];
  1906 + }
  1907 + for (uint32_t i = 0; i < entry_count; i++) {
  1908 + uint32_t sample_number = sample_numbers[i];
  1909 + buf->write_4bytes(sample_number);
  1910 + }
  1911 +
1852 return ret; 1912 return ret;
1853 } 1913 }
1854 1914
@@ -1874,7 +1934,7 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox() @@ -1874,7 +1934,7 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox()
1874 1934
1875 int SrsMp4Sample2ChunkBox::nb_header() 1935 int SrsMp4Sample2ChunkBox::nb_header()
1876 { 1936 {
1877 - return SrsMp4FullBox::nb_header(); 1937 + return SrsMp4FullBox::nb_header() +4 + 12*entry_count;
1878 } 1938 }
1879 1939
1880 int SrsMp4Sample2ChunkBox::encode_header(SrsBuffer* buf) 1940 int SrsMp4Sample2ChunkBox::encode_header(SrsBuffer* buf)
@@ -1885,6 +1945,14 @@ int SrsMp4Sample2ChunkBox::encode_header(SrsBuffer* buf) @@ -1885,6 +1945,14 @@ int SrsMp4Sample2ChunkBox::encode_header(SrsBuffer* buf)
1885 return ret; 1945 return ret;
1886 } 1946 }
1887 1947
  1948 + buf->write_4bytes(entry_count);
  1949 + for (uint32_t i = 0; i < entry_count; i++) {
  1950 + SrsMp4StscEntry& entry = entries[i];
  1951 + buf->write_4bytes(entry.first_chunk);
  1952 + buf->write_4bytes(entry.samples_per_chunk);
  1953 + buf->write_4bytes(entry.sample_description_index);
  1954 + }
  1955 +
1888 return ret; 1956 return ret;
1889 } 1957 }
1890 1958
@@ -1896,6 +1964,17 @@ int SrsMp4Sample2ChunkBox::decode_header(SrsBuffer* buf) @@ -1896,6 +1964,17 @@ int SrsMp4Sample2ChunkBox::decode_header(SrsBuffer* buf)
1896 return ret; 1964 return ret;
1897 } 1965 }
1898 1966
  1967 + entry_count = buf->read_4bytes();
  1968 + if (entry_count) {
  1969 + entries = new SrsMp4StscEntry[entry_count];
  1970 + }
  1971 + for (uint32_t i = 0; i < entry_count; i++) {
  1972 + SrsMp4StscEntry& entry = entries[i];
  1973 + entry.first_chunk = buf->read_4bytes();
  1974 + entry.samples_per_chunk = buf->read_4bytes();
  1975 + entry.sample_description_index = buf->read_4bytes();
  1976 + }
  1977 +
1899 return ret; 1978 return ret;
1900 } 1979 }
1901 1980
@@ -1914,7 +1993,7 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox() @@ -1914,7 +1993,7 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox()
1914 1993
1915 int SrsMp4ChunkOffsetBox::nb_header() 1994 int SrsMp4ChunkOffsetBox::nb_header()
1916 { 1995 {
1917 - return SrsMp4FullBox::nb_header(); 1996 + return SrsMp4FullBox::nb_header() +4 +4*entry_count;
1918 } 1997 }
1919 1998
1920 int SrsMp4ChunkOffsetBox::encode_header(SrsBuffer* buf) 1999 int SrsMp4ChunkOffsetBox::encode_header(SrsBuffer* buf)
@@ -1925,6 +2004,11 @@ int SrsMp4ChunkOffsetBox::encode_header(SrsBuffer* buf) @@ -1925,6 +2004,11 @@ int SrsMp4ChunkOffsetBox::encode_header(SrsBuffer* buf)
1925 return ret; 2004 return ret;
1926 } 2005 }
1927 2006
  2007 + buf->write_4bytes(entry_count);
  2008 + for (uint32_t i = 0; i < entry_count; i++) {
  2009 + buf->write_4bytes(entries[i]);
  2010 + }
  2011 +
1928 return ret; 2012 return ret;
1929 } 2013 }
1930 2014
@@ -1936,6 +2020,67 @@ int SrsMp4ChunkOffsetBox::decode_header(SrsBuffer* buf) @@ -1936,6 +2020,67 @@ int SrsMp4ChunkOffsetBox::decode_header(SrsBuffer* buf)
1936 return ret; 2020 return ret;
1937 } 2021 }
1938 2022
  2023 + entry_count = buf->read_4bytes();
  2024 + if (entry_count) {
  2025 + entries = new uint32_t[entry_count];
  2026 + }
  2027 + for (uint32_t i = 0; i < entry_count; i++) {
  2028 + entries[i] = buf->read_4bytes();
  2029 + }
  2030 +
  2031 + return ret;
  2032 +}
  2033 +
  2034 +SrsMp4ChunkLargeOffsetBox::SrsMp4ChunkLargeOffsetBox()
  2035 +{
  2036 + type = SRS_MP4_BOX_CO64;
  2037 +
  2038 + entry_count = 0;
  2039 + entries = NULL;
  2040 +}
  2041 +
  2042 +SrsMp4ChunkLargeOffsetBox::~SrsMp4ChunkLargeOffsetBox()
  2043 +{
  2044 + srs_freepa(entries);
  2045 +}
  2046 +
  2047 +int SrsMp4ChunkLargeOffsetBox::nb_header()
  2048 +{
  2049 + return SrsMp4FullBox::nb_header() +4 +8*entry_count;
  2050 +}
  2051 +
  2052 +int SrsMp4ChunkLargeOffsetBox::encode_header(SrsBuffer* buf)
  2053 +{
  2054 + int ret = ERROR_SUCCESS;
  2055 +
  2056 + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
  2057 + return ret;
  2058 + }
  2059 +
  2060 + buf->write_4bytes(entry_count);
  2061 + for (uint32_t i = 0; i < entry_count; i++) {
  2062 + buf->write_8bytes(entries[i]);
  2063 + }
  2064 +
  2065 + return ret;
  2066 +}
  2067 +
  2068 +int SrsMp4ChunkLargeOffsetBox::decode_header(SrsBuffer* buf)
  2069 +{
  2070 + int ret = ERROR_SUCCESS;
  2071 +
  2072 + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
  2073 + return ret;
  2074 + }
  2075 +
  2076 + entry_count = buf->read_4bytes();
  2077 + if (entry_count) {
  2078 + entries = new uint64_t[entry_count];
  2079 + }
  2080 + for (uint32_t i = 0; i < entry_count; i++) {
  2081 + entries[i] = buf->read_8bytes();
  2082 + }
  2083 +
1939 return ret; 2084 return ret;
1940 } 2085 }
1941 2086
@@ -1954,7 +2099,11 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox() @@ -1954,7 +2099,11 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox()
1954 2099
1955 int SrsMp4SampleSizeBox::nb_header() 2100 int SrsMp4SampleSizeBox::nb_header()
1956 { 2101 {
1957 - return SrsMp4FullBox::nb_header(); 2102 + int size = SrsMp4FullBox::nb_header() +4+4;
  2103 + if (sample_size == 0) {
  2104 + size += 4*sample_count;
  2105 + }
  2106 + return size;
1958 } 2107 }
1959 2108
1960 int SrsMp4SampleSizeBox::encode_header(SrsBuffer* buf) 2109 int SrsMp4SampleSizeBox::encode_header(SrsBuffer* buf)
@@ -1965,6 +2114,12 @@ int SrsMp4SampleSizeBox::encode_header(SrsBuffer* buf) @@ -1965,6 +2114,12 @@ int SrsMp4SampleSizeBox::encode_header(SrsBuffer* buf)
1965 return ret; 2114 return ret;
1966 } 2115 }
1967 2116
  2117 + buf->write_4bytes(sample_size);
  2118 + buf->write_4bytes(sample_count);
  2119 + for (uint32_t i = 0; i < sample_count && sample_size == 0; i++) {
  2120 + buf->write_4bytes(entry_sizes[i]);
  2121 + }
  2122 +
1968 return ret; 2123 return ret;
1969 } 2124 }
1970 2125
@@ -1976,6 +2131,15 @@ int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf) @@ -1976,6 +2131,15 @@ int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf)
1976 return ret; 2131 return ret;
1977 } 2132 }
1978 2133
  2134 + sample_size = buf->read_4bytes();
  2135 + sample_count = buf->read_4bytes();
  2136 + if (sample_size == 0) {
  2137 + entry_sizes = new uint32_t[sample_count];
  2138 + }
  2139 + for (uint32_t i = 0; i < sample_count && sample_size == 0; i++) {
  2140 + entry_sizes[i] = buf->read_4bytes();
  2141 + }
  2142 +
1979 return ret; 2143 return ret;
1980 } 2144 }
1981 2145
@@ -761,7 +761,6 @@ protected: @@ -761,7 +761,6 @@ protected:
761 virtual int decode_header(SrsBuffer* buf); 761 virtual int decode_header(SrsBuffer* buf);
762 }; 762 };
763 763
764 -  
765 /** 764 /**
766 * 8.6.1.3 Composition Time to Sample Box (ctts), for Video. 765 * 8.6.1.3 Composition Time to Sample Box (ctts), for Video.
767 * ISO_IEC_14496-12-base-format-2012.pdf, page 49 766 * ISO_IEC_14496-12-base-format-2012.pdf, page 49
@@ -872,7 +871,7 @@ protected: @@ -872,7 +871,7 @@ protected:
872 }; 871 };
873 872
874 /** 873 /**
875 - * 8.7.5 Chunk Offset Box (stco or co64), for Audio/Video. 874 + * 8.7.5 Chunk Offset Box (stco), for Audio/Video.
876 * ISO_IEC_14496-12-base-format-2012.pdf, page 59 875 * ISO_IEC_14496-12-base-format-2012.pdf, page 59
877 * The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting 876 * The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting
878 * the use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of 877 * the use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of
@@ -883,9 +882,9 @@ class SrsMp4ChunkOffsetBox : public SrsMp4FullBox @@ -883,9 +882,9 @@ class SrsMp4ChunkOffsetBox : public SrsMp4FullBox
883 public: 882 public:
884 // an integer that gives the number of entries in the following table 883 // an integer that gives the number of entries in the following table
885 uint32_t entry_count; 884 uint32_t entry_count;
886 - // a 32 or 64 bit integer that gives the offset of the start of a chunk into its containing 885 + // a 32 bit integer that gives the offset of the start of a chunk into its containing
887 // media file. 886 // media file.
888 - uint64_t* entries; 887 + uint32_t* entries;
889 public: 888 public:
890 SrsMp4ChunkOffsetBox(); 889 SrsMp4ChunkOffsetBox();
891 virtual ~SrsMp4ChunkOffsetBox(); 890 virtual ~SrsMp4ChunkOffsetBox();
@@ -896,8 +895,32 @@ protected: @@ -896,8 +895,32 @@ protected:
896 }; 895 };
897 896
898 /** 897 /**
899 - * 8.7.3 Sample Size Boxes (stsz or stz2), for Audio/Video.  
900 - * ISO_IEC_14496-12-base-format-2012.pdf, page 57 898 + * 8.7.5 Chunk Large Offset Box (co64), for Audio/Video.
  899 + * ISO_IEC_14496-12-base-format-2012.pdf, page 59
  900 + * The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting
  901 + * the use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of
  902 + * these variants will occur in any single instance of a sample table.
  903 + */
  904 +class SrsMp4ChunkLargeOffsetBox : public SrsMp4FullBox
  905 +{
  906 +public:
  907 + // an integer that gives the number of entries in the following table
  908 + uint32_t entry_count;
  909 + // a 64 bit integer that gives the offset of the start of a chunk into its containing
  910 + // media file.
  911 + uint64_t* entries;
  912 +public:
  913 + SrsMp4ChunkLargeOffsetBox();
  914 + virtual ~SrsMp4ChunkLargeOffsetBox();
  915 +protected:
  916 + virtual int nb_header();
  917 + virtual int encode_header(SrsBuffer* buf);
  918 + virtual int decode_header(SrsBuffer* buf);
  919 +};
  920 +
  921 +/**
  922 + * 8.7.3.2 Sample Size Box (stsz), for Audio/Video.
  923 + * ISO_IEC_14496-12-base-format-2012.pdf, page 58
901 * This box contains the sample count and a table giving the size in bytes of each sample. This allows the media data 924 * This box contains the sample count and a table giving the size in bytes of each sample. This allows the media data
902 * itself to be unframed. The total number of samples in the media is always indicated in the sample count. 925 * itself to be unframed. The total number of samples in the media is always indicated in the sample count.
903 */ 926 */