winlin

for #738, decode mp4 video track boxes.

@@ -236,6 +236,7 @@ int proxy(srs_mp4_t mp4, srs_rtmp_t ortmp) @@ -236,6 +236,7 @@ int proxy(srs_mp4_t mp4, srs_rtmp_t ortmp)
236 int ret = 0; 236 int ret = 0;
237 237
238 if ((ret = srs_mp4_init_demuxer(mp4)) != 0) { 238 if ((ret = srs_mp4_init_demuxer(mp4)) != 0) {
  239 + srs_human_trace("init demuxer failed. ret=%d", ret);
239 return ret; 240 return ret;
240 } 241 }
241 if ((ret = connect_oc(ortmp)) != 0) { 242 if ((ret = connect_oc(ortmp)) != 0) {
@@ -247,6 +247,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -247,6 +247,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
247 #define ERROR_MP4_BOX_ILLEGAL_TYPE 3071 247 #define ERROR_MP4_BOX_ILLEGAL_TYPE 3071
248 #define ERROR_MP4_BOX_ILLEGAL_SCHEMA 3072 248 #define ERROR_MP4_BOX_ILLEGAL_SCHEMA 3072
249 #define ERROR_MP4_BOX_STRING 3073 249 #define ERROR_MP4_BOX_STRING 3073
  250 +#define ERROR_MP4_BOX_ILLEGAL_BRAND 3074
  251 +#define ERROR_MP4_NOT_NON_SEEKABLE 3075
250 252
251 /////////////////////////////////////////////////////// 253 ///////////////////////////////////////////////////////
252 // HTTP/StreamCaster/KAFKA protocol error. 254 // HTTP/StreamCaster/KAFKA protocol error.
@@ -64,6 +64,18 @@ using namespace std; @@ -64,6 +64,18 @@ using namespace std;
64 #define SRS_MP4_BOX_CO64 0x636f3634 // 'co64' 64 #define SRS_MP4_BOX_CO64 0x636f3634 // 'co64'
65 #define SRS_MP4_BOX_STSZ 0x7374737a // 'stsz' 65 #define SRS_MP4_BOX_STSZ 0x7374737a // 'stsz'
66 #define SRS_MP4_BOX_STZ2 0x73747a32 // 'stz2' 66 #define SRS_MP4_BOX_STZ2 0x73747a32 // 'stz2'
  67 +#define SRS_MP4_BOX_AVC1 0x61766331 // 'avc1'
  68 +#define SRS_MP4_BOX_AVCC 0x61766343 // 'avcC'
  69 +#define SRS_MP4_BOX_MP4A 0x6d703461 // 'mp4a'
  70 +#define SRS_MP4_BOX_ESDS 0x65736473 // 'esds'
  71 +
  72 +#define SRS_MP4_BRAND_ISOM 0x69736f6d // 'isom'
  73 +#define SRS_MP4_BRAND_ISO2 0x69736f32 // 'iso2'
  74 +#define SRS_MP4_BRAND_AVC1 0x61766331 // 'avc1'
  75 +#define SRS_MP4_BRAND_MP41 0x6d703431 // 'mp41'
  76 +
  77 +#define SRS_MP4_HANDLER_VIDE 0x76696465 // 'vide'
  78 +#define SRS_MP4_HANDLER_SOUN 0x736f756e // 'soun'
67 79
68 #define SRS_MP4_EOF_SIZE 0 80 #define SRS_MP4_EOF_SIZE 0
69 #define SRS_MP4_USE_LARGE_SIZE 1 81 #define SRS_MP4_USE_LARGE_SIZE 1
@@ -75,9 +87,12 @@ int srs_mp4_string_length(const string& v) @@ -75,9 +87,12 @@ int srs_mp4_string_length(const string& v)
75 87
76 void srs_mp4_string_write(SrsBuffer* buf, const string& v) 88 void srs_mp4_string_write(SrsBuffer* buf, const string& v)
77 { 89 {
78 - if (!v.empty()) {  
79 - buf->write_bytes((char*)v.data(), (int)v.length()); 90 + // Nothing for empty string.
  91 + if (v.empty()) {
  92 + return;
80 } 93 }
  94 +
  95 + buf->write_bytes((char*)v.data(), (int)v.length());
81 buf->write_1bytes(0x00); 96 buf->write_1bytes(0x00);
82 } 97 }
83 98
@@ -85,19 +100,22 @@ int srs_mp4_string_read(SrsBuffer* buf, string& v, int left) @@ -85,19 +100,22 @@ int srs_mp4_string_read(SrsBuffer* buf, string& v, int left)
85 { 100 {
86 int ret = ERROR_SUCCESS; 101 int ret = ERROR_SUCCESS;
87 102
88 - char* p = buf->data() + buf->pos(); 103 + if (left == 0) {
  104 + return ret;
  105 + }
89 106
90 - char* start = p;  
91 - while (p < start + left) {  
92 - if (*p == 0x00) {  
93 - v.append(start, p - start);  
94 - buf->skip((int)(p - start));  
95 - return ret;  
96 - } 107 + char* start = buf->data() + buf->pos();
  108 + size_t len = strnlen(start, left);
  109 +
  110 + if (len == left) {
  111 + ret = ERROR_MP4_BOX_STRING;
  112 + srs_error("MP4 string corrupt, left=%d. ret=%d", left, ret);
  113 + return ret;
97 } 114 }
98 115
99 - ret = ERROR_MP4_BOX_STRING;  
100 - srs_error("MP4 string corrupt, left=%d. ret=%d", left, ret); 116 + v.append(start, len);
  117 + buf->skip((int)len + 1);
  118 +
101 return ret; 119 return ret;
102 } 120 }
103 121
@@ -132,6 +150,21 @@ int SrsMp4Box::left_space(SrsBuffer* buf) @@ -132,6 +150,21 @@ int SrsMp4Box::left_space(SrsBuffer* buf)
132 return (int)sz() - (buf->pos() - start_pos); 150 return (int)sz() - (buf->pos() - start_pos);
133 } 151 }
134 152
  153 +bool SrsMp4Box::is_ftyp()
  154 +{
  155 + return type == SRS_MP4_BOX_FTYP;
  156 +}
  157 +
  158 +bool SrsMp4Box::is_moov()
  159 +{
  160 + return type == SRS_MP4_BOX_MOOV;
  161 +}
  162 +
  163 +bool SrsMp4Box::is_mdat()
  164 +{
  165 + return type == SRS_MP4_BOX_MDAT;
  166 +}
  167 +
135 int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) 168 int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
136 { 169 {
137 *ppbox = NULL; 170 *ppbox = NULL;
@@ -196,6 +229,9 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) @@ -196,6 +229,9 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
196 case SRS_MP4_BOX_STCO: box = new SrsMp4ChunkOffsetBox(); break; 229 case SRS_MP4_BOX_STCO: box = new SrsMp4ChunkOffsetBox(); break;
197 case SRS_MP4_BOX_CO64: box = new SrsMp4ChunkLargeOffsetBox(); break; 230 case SRS_MP4_BOX_CO64: box = new SrsMp4ChunkLargeOffsetBox(); break;
198 case SRS_MP4_BOX_STSZ: box = new SrsMp4SampleSizeBox(); break; 231 case SRS_MP4_BOX_STSZ: box = new SrsMp4SampleSizeBox(); break;
  232 + case SRS_MP4_BOX_AVC1: box = new SrsMp4VisualSampleEntry(); break;
  233 + case SRS_MP4_BOX_AVCC: box = new SrsMp4AvccBox(); break;
  234 + case SRS_MP4_BOX_MP4A: box = new SrsMp4AudioSampleEntry(); break;
199 default: 235 default:
200 ret = ERROR_MP4_BOX_ILLEGAL_TYPE; 236 ret = ERROR_MP4_BOX_ILLEGAL_TYPE;
201 srs_error("MP4 illegal box type=%d. ret=%d", type, ret); 237 srs_error("MP4 illegal box type=%d. ret=%d", type, ret);
@@ -722,7 +758,7 @@ int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf) @@ -722,7 +758,7 @@ int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf)
722 } 758 }
723 759
724 rate = buf->read_4bytes(); 760 rate = buf->read_4bytes();
725 - volume = buf->read_4bytes(); 761 + volume = buf->read_2bytes();
726 buf->skip(2); 762 buf->skip(2);
727 buf->skip(8); 763 buf->skip(8);
728 for (int i = 0; i < 9; i++) { 764 for (int i = 0; i < 9; i++) {
@@ -862,53 +898,6 @@ SrsMp4ElstEntry::SrsMp4ElstEntry() @@ -862,53 +898,6 @@ SrsMp4ElstEntry::SrsMp4ElstEntry()
862 media_rate_fraction = 0; 898 media_rate_fraction = 0;
863 } 899 }
864 900
865 -int SrsMp4ElstEntry::nb_header(uint32_t version)  
866 -{  
867 - int size = 0;  
868 -  
869 - if (version == 1) {  
870 - size += 8+8;  
871 - } else {  
872 - size += 4+4;  
873 - }  
874 -  
875 - size += 2+2;  
876 -  
877 - return size;  
878 -}  
879 -  
880 -int SrsMp4ElstEntry::encode_header(SrsBuffer* buf, uint32_t version)  
881 -{  
882 - if (version == 1) {  
883 - buf->write_8bytes(segment_duration);  
884 - buf->write_8bytes(media_time);  
885 - } else {  
886 - buf->write_4bytes((uint32_t)segment_duration);  
887 - buf->write_4bytes((int32_t)media_time);  
888 - }  
889 -  
890 - buf->write_2bytes(media_rate_integer);  
891 - buf->write_2bytes(media_rate_fraction);  
892 -  
893 - return ERROR_SUCCESS;  
894 -}  
895 -  
896 -int SrsMp4ElstEntry::decode_header(SrsBuffer* buf, uint32_t version)  
897 -{  
898 - if (version == 1) {  
899 - segment_duration = buf->read_8bytes();  
900 - media_time = buf->read_8bytes();  
901 - } else {  
902 - segment_duration = buf->read_4bytes();  
903 - media_time = buf->read_4bytes();  
904 - }  
905 -  
906 - media_rate_integer = buf->read_2bytes();  
907 - media_rate_fraction = buf->read_2bytes();  
908 -  
909 - return ERROR_SUCCESS;  
910 -}  
911 -  
912 SrsMp4EditListBox::SrsMp4EditListBox() 901 SrsMp4EditListBox::SrsMp4EditListBox()
913 { 902 {
914 type = SRS_MP4_BOX_ELST; 903 type = SRS_MP4_BOX_ELST;
@@ -924,11 +913,12 @@ SrsMp4EditListBox::~SrsMp4EditListBox() @@ -924,11 +913,12 @@ SrsMp4EditListBox::~SrsMp4EditListBox()
924 913
925 int SrsMp4EditListBox::nb_header() 914 int SrsMp4EditListBox::nb_header()
926 { 915 {
927 - int size = SrsMp4FullBox::nb_header(); 916 + int size = SrsMp4FullBox::nb_header() + 4;
928 917
929 - for (uint32_t i = 0; i < entry_count; i++) {  
930 - SrsMp4ElstEntry& entry = entries[i];  
931 - size += entry.nb_header(version); 918 + if (version == 1) {
  919 + size += entry_count * (2+2+8+8);
  920 + } else {
  921 + size += entry_count * (2+2+4+4);
932 } 922 }
933 923
934 return size; 924 return size;
@@ -942,11 +932,20 @@ int SrsMp4EditListBox::encode_header(SrsBuffer* buf) @@ -942,11 +932,20 @@ int SrsMp4EditListBox::encode_header(SrsBuffer* buf)
942 return ret; 932 return ret;
943 } 933 }
944 934
  935 + buf->write_4bytes(entry_count);
945 for (uint32_t i = 0; i < entry_count; i++) { 936 for (uint32_t i = 0; i < entry_count; i++) {
946 SrsMp4ElstEntry& entry = entries[i]; 937 SrsMp4ElstEntry& entry = entries[i];
947 - if ((ret = entry.encode_header(buf, version)) != ERROR_SUCCESS) {  
948 - return ret; 938 +
  939 + if (version == 1) {
  940 + buf->write_8bytes(entry.segment_duration);
  941 + buf->write_8bytes(entry.media_time);
  942 + } else {
  943 + buf->write_4bytes((uint32_t)entry.segment_duration);
  944 + buf->write_4bytes((int32_t)entry.media_time);
949 } 945 }
  946 +
  947 + buf->write_2bytes(entry.media_rate_integer);
  948 + buf->write_2bytes(entry.media_rate_fraction);
950 } 949 }
951 950
952 return ret; 951 return ret;
@@ -960,16 +959,23 @@ int SrsMp4EditListBox::decode_header(SrsBuffer* buf) @@ -960,16 +959,23 @@ int SrsMp4EditListBox::decode_header(SrsBuffer* buf)
960 return ret; 959 return ret;
961 } 960 }
962 961
963 - int left = left_space(buf);  
964 - entry_count = left / SrsMp4ElstEntry().nb_header(version); 962 + entry_count = buf->read_4bytes();
965 if (entry_count > 0) { 963 if (entry_count > 0) {
966 entries = new SrsMp4ElstEntry[entry_count]; 964 entries = new SrsMp4ElstEntry[entry_count];
967 } 965 }
968 for (int i = 0; i < entry_count; i++) { 966 for (int i = 0; i < entry_count; i++) {
969 SrsMp4ElstEntry& entry = entries[i]; 967 SrsMp4ElstEntry& entry = entries[i];
970 - if ((ret = entry.decode_header(buf, version)) != ERROR_SUCCESS) {  
971 - return ret; 968 +
  969 + if (version == 1) {
  970 + entry.segment_duration = buf->read_8bytes();
  971 + entry.media_time = buf->read_8bytes();
  972 + } else {
  973 + entry.segment_duration = buf->read_4bytes();
  974 + entry.media_time = buf->read_4bytes();
972 } 975 }
  976 +
  977 + entry.media_rate_integer = buf->read_2bytes();
  978 + entry.media_rate_fraction = buf->read_2bytes();
973 } 979 }
974 980
975 return ret; 981 return ret;
@@ -1104,6 +1110,16 @@ SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox() @@ -1104,6 +1110,16 @@ SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox()
1104 { 1110 {
1105 } 1111 }
1106 1112
  1113 +bool SrsMp4HandlerReferenceBox::is_video()
  1114 +{
  1115 + return handler_type == SRS_MP4_HANDLER_VIDE;
  1116 +}
  1117 +
  1118 +bool SrsMp4HandlerReferenceBox::is_audio()
  1119 +{
  1120 + return handler_type == SRS_MP4_HANDLER_SOUN;
  1121 +}
  1122 +
1107 int SrsMp4HandlerReferenceBox::nb_header() 1123 int SrsMp4HandlerReferenceBox::nb_header()
1108 { 1124 {
1109 return SrsMp4FullBox::nb_header()+4+4+12+srs_mp4_string_length(name); 1125 return SrsMp4FullBox::nb_header()+4+4+12+srs_mp4_string_length(name);
@@ -1268,12 +1284,26 @@ SrsMp4DataEntryBox::~SrsMp4DataEntryBox() @@ -1268,12 +1284,26 @@ SrsMp4DataEntryBox::~SrsMp4DataEntryBox()
1268 { 1284 {
1269 } 1285 }
1270 1286
1271 -int SrsMp4DataEntryBox::nb_header() 1287 +SrsMp4DataEntryUrlBox::SrsMp4DataEntryUrlBox()
1272 { 1288 {
  1289 + type = SRS_MP4_BOX_URL;
  1290 +}
  1291 +
  1292 +SrsMp4DataEntryUrlBox::~SrsMp4DataEntryUrlBox()
  1293 +{
  1294 +}
  1295 +
  1296 +int SrsMp4DataEntryUrlBox::nb_header()
  1297 +{
  1298 + // a 24-bit integer with flags; one flag is defined (x000001) which means that the media
  1299 + // data is in the same file as the Movie Box containing this data reference.
  1300 + if (flags == 1) {
  1301 + return SrsMp4FullBox::nb_header();
  1302 + }
1273 return SrsMp4FullBox::nb_header()+srs_mp4_string_length(location); 1303 return SrsMp4FullBox::nb_header()+srs_mp4_string_length(location);
1274 } 1304 }
1275 1305
1276 -int SrsMp4DataEntryBox::encode_header(SrsBuffer* buf) 1306 +int SrsMp4DataEntryUrlBox::encode_header(SrsBuffer* buf)
1277 { 1307 {
1278 int ret = ERROR_SUCCESS; 1308 int ret = ERROR_SUCCESS;
1279 1309
@@ -1281,12 +1311,19 @@ int SrsMp4DataEntryBox::encode_header(SrsBuffer* buf) @@ -1281,12 +1311,19 @@ int SrsMp4DataEntryBox::encode_header(SrsBuffer* buf)
1281 return ret; 1311 return ret;
1282 } 1312 }
1283 1313
  1314 + // a 24-bit integer with flags; one flag is defined (x000001) which means that the media
  1315 + // data is in the same file as the Movie Box containing this data reference.
  1316 + if (location.empty()) {
  1317 + flags = 0x01;
  1318 + return ret;
  1319 + }
  1320 +
1284 srs_mp4_string_write(buf, location); 1321 srs_mp4_string_write(buf, location);
1285 1322
1286 return ret; 1323 return ret;
1287 } 1324 }
1288 1325
1289 -int SrsMp4DataEntryBox::decode_header(SrsBuffer* buf) 1326 +int SrsMp4DataEntryUrlBox::decode_header(SrsBuffer* buf)
1290 { 1327 {
1291 int ret = ERROR_SUCCESS; 1328 int ret = ERROR_SUCCESS;
1292 1329
@@ -1294,23 +1331,20 @@ int SrsMp4DataEntryBox::decode_header(SrsBuffer* buf) @@ -1294,23 +1331,20 @@ int SrsMp4DataEntryBox::decode_header(SrsBuffer* buf)
1294 return ret; 1331 return ret;
1295 } 1332 }
1296 1333
  1334 + // a 24-bit integer with flags; one flag is defined (x000001) which means that the media
  1335 + // data is in the same file as the Movie Box containing this data reference.
  1336 + if (flags == 0x01) {
  1337 + return ret;
  1338 + }
  1339 +
1297 if ((ret = srs_mp4_string_read(buf, location, left_space(buf))) != ERROR_SUCCESS) { 1340 if ((ret = srs_mp4_string_read(buf, location, left_space(buf))) != ERROR_SUCCESS) {
1298 - srs_error("MP4 urx read string failed. ret=%d", ret); 1341 + srs_error("MP4 url read location failed. ret=%d", ret);
1299 return ret; 1342 return ret;
1300 } 1343 }
1301 1344
1302 return ret; 1345 return ret;
1303 } 1346 }
1304 1347
1305 -SrsMp4DataEntryUrlBox::SrsMp4DataEntryUrlBox()  
1306 -{  
1307 - type = SRS_MP4_BOX_URL;  
1308 -}  
1309 -  
1310 -SrsMp4DataEntryUrlBox::~SrsMp4DataEntryUrlBox()  
1311 -{  
1312 -}  
1313 -  
1314 SrsMp4DataEntryUrnBox::SrsMp4DataEntryUrnBox() 1348 SrsMp4DataEntryUrnBox::SrsMp4DataEntryUrnBox()
1315 { 1349 {
1316 type = SRS_MP4_BOX_URN; 1350 type = SRS_MP4_BOX_URN;
@@ -1322,7 +1356,7 @@ SrsMp4DataEntryUrnBox::~SrsMp4DataEntryUrnBox() @@ -1322,7 +1356,7 @@ SrsMp4DataEntryUrnBox::~SrsMp4DataEntryUrnBox()
1322 1356
1323 int SrsMp4DataEntryUrnBox::nb_header() 1357 int SrsMp4DataEntryUrnBox::nb_header()
1324 { 1358 {
1325 - return SrsMp4DataEntryBox::nb_header()+srs_mp4_string_length(name); 1359 + return SrsMp4FullBox::nb_header()+srs_mp4_string_length(location)+srs_mp4_string_length(name);
1326 } 1360 }
1327 1361
1328 int SrsMp4DataEntryUrnBox::encode_header(SrsBuffer* buf) 1362 int SrsMp4DataEntryUrnBox::encode_header(SrsBuffer* buf)
@@ -1333,6 +1367,7 @@ int SrsMp4DataEntryUrnBox::encode_header(SrsBuffer* buf) @@ -1333,6 +1367,7 @@ int SrsMp4DataEntryUrnBox::encode_header(SrsBuffer* buf)
1333 return ret; 1367 return ret;
1334 } 1368 }
1335 1369
  1370 + srs_mp4_string_write(buf, location);
1336 srs_mp4_string_write(buf, name); 1371 srs_mp4_string_write(buf, name);
1337 1372
1338 return ret; 1373 return ret;
@@ -1346,8 +1381,13 @@ int SrsMp4DataEntryUrnBox::decode_header(SrsBuffer* buf) @@ -1346,8 +1381,13 @@ int SrsMp4DataEntryUrnBox::decode_header(SrsBuffer* buf)
1346 return ret; 1381 return ret;
1347 } 1382 }
1348 1383
  1384 + if ((ret = srs_mp4_string_read(buf, location, left_space(buf))) != ERROR_SUCCESS) {
  1385 + srs_error("MP4 urn read location failed. ret=%d", ret);
  1386 + return ret;
  1387 + }
  1388 +
1349 if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) { 1389 if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) {
1350 - srs_error("MP4 urn read string failed. ret=%d", ret); 1390 + srs_error("MP4 urn read name failed. ret=%d", ret);
1351 return ret; 1391 return ret;
1352 } 1392 }
1353 1393
@@ -1578,6 +1618,55 @@ int SrsMp4VisualSampleEntry::decode_header(SrsBuffer* buf) @@ -1578,6 +1618,55 @@ int SrsMp4VisualSampleEntry::decode_header(SrsBuffer* buf)
1578 return ret; 1618 return ret;
1579 } 1619 }
1580 1620
  1621 +SrsMp4AvccBox::SrsMp4AvccBox()
  1622 +{
  1623 + type = SRS_MP4_BOX_AVCC;
  1624 + nb_config = 0;
  1625 + avc_config = NULL;
  1626 +}
  1627 +
  1628 +SrsMp4AvccBox::~SrsMp4AvccBox()
  1629 +{
  1630 + srs_freepa(avc_config);
  1631 +}
  1632 +
  1633 +int SrsMp4AvccBox::nb_header()
  1634 +{
  1635 + return SrsMp4Box::nb_header()+nb_config;
  1636 +}
  1637 +
  1638 +int SrsMp4AvccBox::encode_header(SrsBuffer* buf)
  1639 +{
  1640 + int ret = ERROR_SUCCESS;
  1641 +
  1642 + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) {
  1643 + return ret;
  1644 + }
  1645 +
  1646 + if (nb_config) {
  1647 + buf->write_bytes((char*)avc_config, nb_config);
  1648 + }
  1649 +
  1650 + return ret;
  1651 +}
  1652 +
  1653 +int SrsMp4AvccBox::decode_header(SrsBuffer* buf)
  1654 +{
  1655 + int ret = ERROR_SUCCESS;
  1656 +
  1657 + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) {
  1658 + return ret;
  1659 + }
  1660 +
  1661 + nb_config = left_space(buf);
  1662 + if (nb_config) {
  1663 + avc_config = new uint8_t[nb_config];
  1664 + buf->read_bytes((char*)avc_config, nb_config);
  1665 + }
  1666 +
  1667 + return ret;
  1668 +}
  1669 +
1581 SrsMp4AudioSampleEntry::SrsMp4AudioSampleEntry() 1670 SrsMp4AudioSampleEntry::SrsMp4AudioSampleEntry()
1582 { 1671 {
1583 reserved0 = 0; 1672 reserved0 = 0;
@@ -1905,8 +1994,7 @@ int SrsMp4SyncSampleBox::decode_header(SrsBuffer* buf) @@ -1905,8 +1994,7 @@ int SrsMp4SyncSampleBox::decode_header(SrsBuffer* buf)
1905 sample_numbers = new uint32_t[entry_count]; 1994 sample_numbers = new uint32_t[entry_count];
1906 } 1995 }
1907 for (uint32_t i = 0; i < entry_count; i++) { 1996 for (uint32_t i = 0; i < entry_count; i++) {
1908 - uint32_t sample_number = sample_numbers[i];  
1909 - buf->write_4bytes(sample_number); 1997 + sample_numbers[i] = buf->read_4bytes();
1910 } 1998 }
1911 1999
1912 return ret; 2000 return ret;
@@ -2143,16 +2231,18 @@ int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf) @@ -2143,16 +2231,18 @@ int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf)
2143 return ret; 2231 return ret;
2144 } 2232 }
2145 2233
  2234 +#define SRS_MP4_BUF_SIZE 4096
  2235 +
2146 SrsMp4Decoder::SrsMp4Decoder() 2236 SrsMp4Decoder::SrsMp4Decoder()
2147 { 2237 {
2148 reader = NULL; 2238 reader = NULL;
2149 - next = NULL; 2239 + buf = new char[SRS_MP4_BUF_SIZE];
2150 stream = new SrsSimpleStream(); 2240 stream = new SrsSimpleStream();
2151 } 2241 }
2152 2242
2153 SrsMp4Decoder::~SrsMp4Decoder() 2243 SrsMp4Decoder::~SrsMp4Decoder()
2154 { 2244 {
2155 - srs_freep(next); 2245 + srs_freepa(buf);
2156 srs_freep(stream); 2246 srs_freep(stream);
2157 } 2247 }
2158 2248
@@ -2163,36 +2253,90 @@ int SrsMp4Decoder::initialize(ISrsReader* r) @@ -2163,36 +2253,90 @@ int SrsMp4Decoder::initialize(ISrsReader* r)
2163 srs_assert(r); 2253 srs_assert(r);
2164 reader = r; 2254 reader = r;
2165 2255
2166 - if ((ret = load_next_box(&next)) != ERROR_SUCCESS) {  
2167 - return ret; 2256 + // File Type Box (ftyp)
  2257 + if (true) {
  2258 + SrsMp4Box* box = NULL;
  2259 + SrsAutoFree(SrsMp4Box, box);
  2260 +
  2261 + if ((ret = load_next_box(&box, SRS_MP4_BOX_FTYP)) != ERROR_SUCCESS) {
  2262 + return ret;
  2263 + }
  2264 + SrsMp4FileTypeBox* ftyp = dynamic_cast<SrsMp4FileTypeBox*>(box);
  2265 +
  2266 + bool legal_brand = false;
  2267 + static uint32_t legal_brands[] = {
  2268 + SRS_MP4_BRAND_ISOM, SRS_MP4_BRAND_ISO2, SRS_MP4_BRAND_AVC1, SRS_MP4_BRAND_MP41
  2269 + };
  2270 + for (int i = 0; i < sizeof(legal_brands)/sizeof(uint32_t); i++) {
  2271 + if (ftyp->major_brand == legal_brands[i]) {
  2272 + legal_brand = true;
  2273 + break;
  2274 + }
  2275 + }
  2276 + if (!legal_brand) {
  2277 + ret = ERROR_MP4_BOX_ILLEGAL_BRAND;
  2278 + srs_error("MP4 brand is illegal, brand=%d. ret=%d", ftyp->major_brand, ret);
  2279 + return ret;
  2280 + }
  2281 + }
  2282 +
  2283 + // Media Data Box (mdat) or Movie Box (moov)
  2284 + SrsMp4Box* box = NULL;
  2285 + SrsAutoFree(SrsMp4Box, box);
  2286 + while (true) {
  2287 + if ((ret = load_next_box(&box, 0)) != ERROR_SUCCESS) {
  2288 + return ret;
  2289 + }
  2290 +
  2291 + if (!box->is_mdat() && !box->is_moov()) {
  2292 + srs_freep(box);
  2293 + continue;
  2294 + }
  2295 + break;
2168 } 2296 }
2169 2297
2170 - if (next->type != SRS_MP4_BOX_FTYP) {  
2171 - ret = ERROR_MP4_BOX_ILLEGAL_SCHEMA;  
2172 - srs_error("MP4 first box must be FTYP, not %d. ret=%d", next->type, ret); 2298 + // Only support non-seek mp4, that is, mdat should never before moov.
  2299 + // @see https://github.com/ossrs/srs/issues/738#issuecomment-276343669
  2300 + if (box->is_mdat()) {
  2301 + ret = ERROR_MP4_NOT_NON_SEEKABLE;
  2302 + srs_error("MP4 is not non-seekable. ret=%d", ret);
2173 return ret; 2303 return ret;
2174 } 2304 }
2175 2305
2176 return ret; 2306 return ret;
2177 } 2307 }
2178 2308
2179 -int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox) 2309 +int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox, uint32_t required_box_type)
2180 { 2310 {
2181 int ret = ERROR_SUCCESS; 2311 int ret = ERROR_SUCCESS;
2182 2312
2183 - // Ignore for already loaded.  
2184 - if (next) {  
2185 - return ret; 2313 + while (true) {
  2314 + SrsMp4Box* box = NULL;
  2315 + if ((ret = do_load_next_box(&box, required_box_type)) != ERROR_SUCCESS) {
  2316 + srs_freep(box);
  2317 + return ret;
  2318 + }
  2319 +
  2320 + if (!required_box_type || box->type == required_box_type) {
  2321 + *ppbox = box;
  2322 + break;
  2323 + }
  2324 + srs_freep(box);
2186 } 2325 }
2187 2326
2188 - char* buf = new char[4096];  
2189 - SrsAutoFreeA(char, buf); 2327 + return ret;
  2328 +}
  2329 +
  2330 +int SrsMp4Decoder::do_load_next_box(SrsMp4Box** ppbox, uint32_t required_box_type)
  2331 +{
  2332 + int ret = ERROR_SUCCESS;
2190 2333
  2334 + SrsMp4Box* box = NULL;
2191 while (true) { 2335 while (true) {
2192 - uint64_t required = next? next->sz():4; 2336 + uint64_t required = box? box->sz():4;
2193 while (stream->length() < required) { 2337 while (stream->length() < required) {
2194 ssize_t nread; 2338 ssize_t nread;
2195 - if ((ret = reader->read(buf, 4096, &nread)) != ERROR_SUCCESS) { 2339 + if ((ret = reader->read(buf, SRS_MP4_BUF_SIZE, &nread)) != ERROR_SUCCESS) {
2196 srs_error("MP4 load failed, nread=%d, required=%d. ret=%d", nread, required, ret); 2340 srs_error("MP4 load failed, nread=%d, required=%d. ret=%d", nread, required, ret);
2197 return ret; 2341 return ret;
2198 } 2342 }
@@ -2205,7 +2349,7 @@ int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox) @@ -2205,7 +2349,7 @@ int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox)
2205 SrsAutoFree(SrsBuffer, buffer); 2349 SrsAutoFree(SrsBuffer, buffer);
2206 2350
2207 // Discovery the box with basic header. 2351 // Discovery the box with basic header.
2208 - if (!next && (ret = SrsMp4Box::discovery(buffer, ppbox)) != ERROR_SUCCESS) { 2352 + if (!box && (ret = SrsMp4Box::discovery(buffer, &box)) != ERROR_SUCCESS) {
2209 if (ret == ERROR_MP4_BOX_REQUIRE_SPACE) { 2353 if (ret == ERROR_MP4_BOX_REQUIRE_SPACE) {
2210 continue; 2354 continue;
2211 } 2355 }
@@ -2214,13 +2358,23 @@ int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox) @@ -2214,13 +2358,23 @@ int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox)
2214 } 2358 }
2215 2359
2216 // Decode util we can demux the whole box. 2360 // Decode util we can demux the whole box.
2217 - if (!buffer->require((int)next->sz())) { 2361 + if (!buffer->require((int)box->sz())) {
2218 continue; 2362 continue;
2219 } 2363 }
2220 - ret = next->decode(buffer); 2364 +
  2365 + if (!required_box_type || box->type == required_box_type) {
  2366 + ret = box->decode(buffer);
  2367 + }
2221 2368
2222 // Remove the consumed bytes. 2369 // Remove the consumed bytes.
2223 - stream->erase((int)next->sz()); 2370 + stream->erase((int)box->sz());
  2371 +
  2372 + if (ret != ERROR_SUCCESS) {
  2373 + srs_freep(box);
  2374 + } else {
  2375 + *ppbox = box;
  2376 + }
  2377 +
2224 break; 2378 break;
2225 } 2379 }
2226 2380
@@ -72,6 +72,10 @@ public: @@ -72,6 +72,10 @@ public:
72 virtual uint64_t sz(); 72 virtual uint64_t sz();
73 // Get the left space of box, for decoder. 73 // Get the left space of box, for decoder.
74 virtual int left_space(SrsBuffer* buf); 74 virtual int left_space(SrsBuffer* buf);
  75 + // Box type helper.
  76 + virtual bool is_ftyp();
  77 + virtual bool is_moov();
  78 + virtual bool is_mdat();
75 /** 79 /**
76 * Discovery the box from buffer. 80 * Discovery the box from buffer.
77 * @param ppbox Output the discoveried box, which user must free it. 81 * @param ppbox Output the discoveried box, which user must free it.
@@ -353,10 +357,6 @@ public: @@ -353,10 +357,6 @@ public:
353 int16_t media_rate_fraction; 357 int16_t media_rate_fraction;
354 public: 358 public:
355 SrsMp4ElstEntry(); 359 SrsMp4ElstEntry();
356 -public:  
357 - virtual int nb_header(uint32_t version);  
358 - virtual int encode_header(SrsBuffer* buf, uint32_t version);  
359 - virtual int decode_header(SrsBuffer* buf, uint32_t version);  
360 }; 360 };
361 361
362 /** 362 /**
@@ -463,6 +463,9 @@ public: @@ -463,6 +463,9 @@ public:
463 public: 463 public:
464 SrsMp4HandlerReferenceBox(); 464 SrsMp4HandlerReferenceBox();
465 virtual ~SrsMp4HandlerReferenceBox(); 465 virtual ~SrsMp4HandlerReferenceBox();
  466 +public:
  467 + virtual bool is_video();
  468 + virtual bool is_audio();
466 protected: 469 protected:
467 virtual int nb_header(); 470 virtual int nb_header();
468 virtual int encode_header(SrsBuffer* buf); 471 virtual int encode_header(SrsBuffer* buf);
@@ -542,6 +545,8 @@ public: @@ -542,6 +545,8 @@ public:
542 /** 545 /**
543 * 8.7.2 Data Reference Box 546 * 8.7.2 Data Reference Box
544 * ISO_IEC_14496-12-base-format-2012.pdf, page 56 547 * ISO_IEC_14496-12-base-format-2012.pdf, page 56
  548 + * a 24-bit integer with flags; one flag is defined (x000001) which means that the media
  549 + * data is in the same file as the Movie Box containing this data reference.
545 */ 550 */
546 class SrsMp4DataEntryBox : public SrsMp4FullBox 551 class SrsMp4DataEntryBox : public SrsMp4FullBox
547 { 552 {
@@ -550,10 +555,6 @@ public: @@ -550,10 +555,6 @@ public:
550 public: 555 public:
551 SrsMp4DataEntryBox(); 556 SrsMp4DataEntryBox();
552 virtual ~SrsMp4DataEntryBox(); 557 virtual ~SrsMp4DataEntryBox();
553 -protected:  
554 - virtual int nb_header();  
555 - virtual int encode_header(SrsBuffer* buf);  
556 - virtual int decode_header(SrsBuffer* buf);  
557 }; 558 };
558 559
559 /** 560 /**
@@ -565,6 +566,10 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox @@ -565,6 +566,10 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox
565 public: 566 public:
566 SrsMp4DataEntryUrlBox(); 567 SrsMp4DataEntryUrlBox();
567 virtual ~SrsMp4DataEntryUrlBox(); 568 virtual ~SrsMp4DataEntryUrlBox();
  569 +protected:
  570 + virtual int nb_header();
  571 + virtual int encode_header(SrsBuffer* buf);
  572 + virtual int decode_header(SrsBuffer* buf);
568 }; 573 };
569 574
570 /** 575 /**
@@ -680,6 +685,24 @@ protected: @@ -680,6 +685,24 @@ protected:
680 }; 685 };
681 686
682 /** 687 /**
  688 + * 5.3.4 AVC Video Stream Definition (avcC)
  689 + * ISO_IEC_14496-15-AVC-format-2012.pdf, page 19
  690 + */
  691 +class SrsMp4AvccBox : public SrsMp4Box
  692 +{
  693 +public:
  694 + int nb_config;
  695 + uint8_t* avc_config;
  696 +public:
  697 + SrsMp4AvccBox();
  698 + virtual ~SrsMp4AvccBox();
  699 +protected:
  700 + virtual int nb_header();
  701 + virtual int encode_header(SrsBuffer* buf);
  702 + virtual int decode_header(SrsBuffer* buf);
  703 +};
  704 +
  705 +/**
683 * 8.5.2 Sample Description Box (mp4a) 706 * 8.5.2 Sample Description Box (mp4a)
684 * ISO_IEC_14496-12-base-format-2012.pdf, page 45 707 * ISO_IEC_14496-12-base-format-2012.pdf, page 45
685 */ 708 */
@@ -957,8 +980,8 @@ private: @@ -957,8 +980,8 @@ private:
957 // The stream used to demux the boxes. 980 // The stream used to demux the boxes.
958 // TODO: FIXME: refine for performance issue. 981 // TODO: FIXME: refine for performance issue.
959 SrsSimpleStream* stream; 982 SrsSimpleStream* stream;
960 - // Always load next box.  
961 - SrsMp4Box* next; 983 + // The temporary buffer to read from buffer.
  984 + char* buf;
962 public: 985 public:
963 SrsMp4Decoder(); 986 SrsMp4Decoder();
964 virtual ~SrsMp4Decoder(); 987 virtual ~SrsMp4Decoder();
@@ -970,7 +993,10 @@ public: @@ -970,7 +993,10 @@ public:
970 */ 993 */
971 virtual int initialize(ISrsReader* r); 994 virtual int initialize(ISrsReader* r);
972 private: 995 private:
973 - virtual int load_next_box(SrsMp4Box** ppbox); 996 + // Load the next box from reader.
  997 + // @param required_box_type The box type required, 0 for any box.
  998 + virtual int load_next_box(SrsMp4Box** ppbox, uint32_t required_box_type);
  999 + virtual int do_load_next_box(SrsMp4Box** ppbox, uint32_t required_box_type);
974 }; 1000 };
975 1001
976 #endif 1002 #endif