Mercurial > hg > nginx
comparison src/http/modules/ngx_http_mp4_module.c @ 4585:3f874d645f45
Mp4: sanity checks cleanup.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 12 Apr 2012 12:18:14 +0000 |
parents | 778ea2f7268c |
children | 2b6cb7528409 |
comparison
equal
deleted
inserted
replaced
4584:3d51fa5a110d | 4585:3f874d645f45 |
---|---|
154 } ngx_http_mp4_atom_handler_t; | 154 } ngx_http_mp4_atom_handler_t; |
155 | 155 |
156 | 156 |
157 #define ngx_mp4_atom_header(mp4) (mp4->buffer_pos - 8) | 157 #define ngx_mp4_atom_header(mp4) (mp4->buffer_pos - 8) |
158 #define ngx_mp4_atom_data(mp4) mp4->buffer_pos | 158 #define ngx_mp4_atom_data(mp4) mp4->buffer_pos |
159 #define ngx_mp4_atom_data_size(t) (uint64_t) (sizeof(t) - 8) | |
159 #define ngx_mp4_atom_next(mp4, n) mp4->buffer_pos += n; mp4->offset += n | 160 #define ngx_mp4_atom_next(mp4, n) mp4->buffer_pos += n; mp4->offset += n |
160 | 161 |
161 | 162 |
162 #define ngx_mp4_set_atom_name(p, n1, n2, n3, n4) \ | 163 #define ngx_mp4_set_atom_name(p, n1, n2, n3, n4) \ |
163 ((u_char *) (p))[4] = n1; \ | 164 ((u_char *) (p))[4] = n1; \ |
202 | 203 |
203 | 204 |
204 static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4); | 205 static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4); |
205 static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4, | 206 static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4, |
206 ngx_http_mp4_atom_handler_t *atom, uint64_t atom_data_size); | 207 ngx_http_mp4_atom_handler_t *atom, uint64_t atom_data_size); |
207 static ngx_int_t ngx_http_mp4_read(ngx_http_mp4_file_t *mp4); | 208 static ngx_int_t ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size); |
208 static ngx_int_t ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, | 209 static ngx_int_t ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, |
209 uint64_t atom_data_size); | 210 uint64_t atom_data_size); |
210 static ngx_int_t ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, | 211 static ngx_int_t ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, |
211 uint64_t atom_data_size); | 212 uint64_t atom_data_size); |
212 static ngx_int_t ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, | 213 static ngx_int_t ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, |
263 uint64_t atom_data_size); | 264 uint64_t atom_data_size); |
264 static ngx_int_t ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, | 265 static ngx_int_t ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, |
265 ngx_http_mp4_trak_t *trak); | 266 ngx_http_mp4_trak_t *trak); |
266 static ngx_int_t ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, | 267 static ngx_int_t ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, |
267 uint64_t atom_data_size); | 268 uint64_t atom_data_size); |
268 static void ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, | 269 static ngx_int_t ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, |
269 ngx_http_mp4_trak_t *trak); | 270 ngx_http_mp4_trak_t *trak); |
270 static ngx_int_t ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, | 271 static ngx_int_t ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, |
271 uint64_t atom_data_size); | 272 uint64_t atom_data_size); |
272 static ngx_int_t ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4, | 273 static ngx_int_t ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4, |
273 ngx_http_mp4_trak_t *trak); | 274 ngx_http_mp4_trak_t *trak); |
699 | 700 |
700 if (ngx_http_mp4_update_stsc_atom(mp4, &trak[i]) != NGX_OK) { | 701 if (ngx_http_mp4_update_stsc_atom(mp4, &trak[i]) != NGX_OK) { |
701 return NGX_ERROR; | 702 return NGX_ERROR; |
702 } | 703 } |
703 | 704 |
704 ngx_http_mp4_update_stsz_atom(mp4, &trak[i]); | 705 if (ngx_http_mp4_update_stsz_atom(mp4, &trak[i]) != NGX_OK) { |
706 return NGX_ERROR; | |
707 } | |
705 | 708 |
706 if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) { | 709 if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) { |
707 if (ngx_http_mp4_update_co64_atom(mp4, &trak[i]) != NGX_OK) { | 710 if (ngx_http_mp4_update_co64_atom(mp4, &trak[i]) != NGX_OK) { |
708 return NGX_ERROR; | 711 return NGX_ERROR; |
709 } | 712 } |
791 | 794 |
792 end = mp4->offset + atom_data_size; | 795 end = mp4->offset + atom_data_size; |
793 | 796 |
794 while (mp4->offset < end) { | 797 while (mp4->offset < end) { |
795 | 798 |
796 if (mp4->buffer_pos + sizeof(uint32_t) > mp4->buffer_end) { | 799 if (ngx_http_mp4_read(mp4, sizeof(uint32_t)) != NGX_OK) { |
797 if (ngx_http_mp4_read(mp4) != NGX_OK) { | 800 return NGX_ERROR; |
798 return NGX_ERROR; | |
799 } | |
800 } | 801 } |
801 | 802 |
802 atom_header = mp4->buffer_pos; | 803 atom_header = mp4->buffer_pos; |
803 atom_size = ngx_mp4_get_32value(atom_header); | 804 atom_size = ngx_mp4_get_32value(atom_header); |
804 atom_header_size = sizeof(ngx_mp4_atom_header_t); | 805 atom_header_size = sizeof(ngx_mp4_atom_header_t); |
811 | 812 |
812 if (atom_size < sizeof(ngx_mp4_atom_header_t)) { | 813 if (atom_size < sizeof(ngx_mp4_atom_header_t)) { |
813 | 814 |
814 if (atom_size == 1) { | 815 if (atom_size == 1) { |
815 | 816 |
816 if (mp4->buffer_pos + sizeof(ngx_mp4_atom_header64_t) | 817 if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header64_t)) |
817 > mp4->buffer_end) | 818 != NGX_OK) |
818 { | 819 { |
819 if (ngx_http_mp4_read(mp4) != NGX_OK) { | 820 return NGX_ERROR; |
820 return NGX_ERROR; | |
821 } | |
822 | |
823 atom_header = mp4->buffer_pos; | |
824 } | 821 } |
825 | 822 |
826 /* 64-bit atom size */ | 823 /* 64-bit atom size */ |
824 atom_header = mp4->buffer_pos; | |
827 atom_size = ngx_mp4_get_64value(atom_header + 8); | 825 atom_size = ngx_mp4_get_64value(atom_header + 8); |
828 atom_header_size = sizeof(ngx_mp4_atom_header64_t); | 826 atom_header_size = sizeof(ngx_mp4_atom_header64_t); |
829 | 827 |
830 } else { | 828 } else { |
831 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 829 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
833 mp4->file.name.data, atom_size); | 831 mp4->file.name.data, atom_size); |
834 return NGX_ERROR; | 832 return NGX_ERROR; |
835 } | 833 } |
836 } | 834 } |
837 | 835 |
838 if (mp4->buffer_pos + sizeof(ngx_mp4_atom_header_t) > mp4->buffer_end) { | 836 if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header_t)) != NGX_OK) { |
839 if (ngx_http_mp4_read(mp4) != NGX_OK) { | 837 return NGX_ERROR; |
840 return NGX_ERROR; | 838 } |
841 } | 839 |
842 | 840 atom_header = mp4->buffer_pos; |
843 atom_header = mp4->buffer_pos; | |
844 } | |
845 | |
846 atom_name = atom_header + sizeof(uint32_t); | 841 atom_name = atom_header + sizeof(uint32_t); |
847 | 842 |
848 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 843 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
849 "mp4 atom: %*s @%O:%uL", | 844 "mp4 atom: %*s @%O:%uL", |
850 4, atom_name, mp4->offset, atom_size); | 845 4, atom_name, mp4->offset, atom_size); |
846 | |
847 if (atom_size > (uint64_t) (NGX_MAX_OFF_T_VALUE - mp4->offset) | |
848 || mp4->offset + (off_t) atom_size > end) | |
849 { | |
850 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
851 "\"%s\" mp4 atom too large:%uL", | |
852 mp4->file.name.data, atom_size); | |
853 return NGX_ERROR; | |
854 } | |
851 | 855 |
852 for (n = 0; atom[n].name; n++) { | 856 for (n = 0; atom[n].name; n++) { |
853 | 857 |
854 if (ngx_strncmp(atom_name, atom[n].name, 4) == 0) { | 858 if (ngx_strncmp(atom_name, atom[n].name, 4) == 0) { |
855 | 859 |
873 return NGX_OK; | 877 return NGX_OK; |
874 } | 878 } |
875 | 879 |
876 | 880 |
877 static ngx_int_t | 881 static ngx_int_t |
878 ngx_http_mp4_read(ngx_http_mp4_file_t *mp4) | 882 ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size) |
879 { | 883 { |
880 ngx_int_t n; | 884 ssize_t n; |
885 | |
886 if (mp4->buffer_pos + size <= mp4->buffer_end) { | |
887 return NGX_OK; | |
888 } | |
881 | 889 |
882 if (mp4->offset + (off_t) mp4->buffer_size > mp4->end) { | 890 if (mp4->offset + (off_t) mp4->buffer_size > mp4->end) { |
883 mp4->buffer_size = (size_t) (mp4->end - mp4->offset); | 891 mp4->buffer_size = (size_t) (mp4->end - mp4->offset); |
892 } | |
893 | |
894 if (mp4->buffer_size < size) { | |
895 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
896 "\"%s\" mp4 file truncated", mp4->file.name.data); | |
897 return NGX_ERROR; | |
884 } | 898 } |
885 | 899 |
886 if (mp4->buffer == NULL) { | 900 if (mp4->buffer == NULL) { |
887 mp4->buffer = ngx_palloc(mp4->request->pool, mp4->buffer_size); | 901 mp4->buffer = ngx_palloc(mp4->request->pool, mp4->buffer_size); |
888 if (mp4->buffer == NULL) { | 902 if (mp4->buffer == NULL) { |
889 return NGX_ERROR; | 903 return NGX_ERROR; |
890 } | 904 } |
891 | 905 |
892 mp4->buffer_start = mp4->buffer; | 906 mp4->buffer_start = mp4->buffer; |
893 mp4->buffer_end = mp4->buffer + mp4->buffer_size; | |
894 } | 907 } |
895 | 908 |
896 n = ngx_read_file(&mp4->file, mp4->buffer_start, mp4->buffer_size, | 909 n = ngx_read_file(&mp4->file, mp4->buffer_start, mp4->buffer_size, |
897 mp4->offset); | 910 mp4->offset); |
898 | 911 |
899 if (n == NGX_ERROR) { | 912 if (n == NGX_ERROR) { |
900 return NGX_ERROR; | 913 return NGX_ERROR; |
901 } | 914 } |
902 | 915 |
903 if (n == 0) { | 916 if ((size_t) n != mp4->buffer_size) { |
904 return NGX_OK; | 917 ngx_log_error(NGX_LOG_CRIT, mp4->file.log, 0, |
918 ngx_read_file_n " read only %z of %z from \"%s\"", | |
919 n, mp4->buffer_size, mp4->file.name.data); | |
920 return NGX_ERROR; | |
905 } | 921 } |
906 | 922 |
907 mp4->buffer_pos = mp4->buffer_start; | 923 mp4->buffer_pos = mp4->buffer_start; |
924 mp4->buffer_end = mp4->buffer_start + mp4->buffer_size; | |
908 | 925 |
909 return NGX_OK; | 926 return NGX_OK; |
910 } | 927 } |
911 | 928 |
912 | 929 |
917 size_t atom_size; | 934 size_t atom_size; |
918 ngx_buf_t *atom; | 935 ngx_buf_t *atom; |
919 | 936 |
920 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ftyp atom"); | 937 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ftyp atom"); |
921 | 938 |
922 if (atom_data_size > 1024) { | 939 if (atom_data_size > 1024 |
940 || ngx_mp4_atom_data(mp4) + atom_data_size > mp4->buffer_end) | |
941 { | |
923 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 942 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
924 "\"%s\" mp4 ftyp atom is too large:%uL", | 943 "\"%s\" mp4 ftyp atom is too large:%uL", |
925 mp4->file.name.data, atom_data_size); | 944 mp4->file.name.data, atom_data_size); |
926 return NGX_ERROR; | 945 return NGX_ERROR; |
927 } | 946 } |
1166 atom_header = ngx_mp4_atom_header(mp4); | 1185 atom_header = ngx_mp4_atom_header(mp4); |
1167 mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header; | 1186 mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header; |
1168 mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header; | 1187 mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header; |
1169 ngx_mp4_set_atom_name(atom_header, 'm', 'v', 'h', 'd'); | 1188 ngx_mp4_set_atom_name(atom_header, 'm', 'v', 'h', 'd'); |
1170 | 1189 |
1190 if (ngx_mp4_atom_data_size(ngx_mp4_mvhd_atom_t) > atom_data_size) { | |
1191 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1192 "\"%s\" mp4 mvhd atom too small", mp4->file.name.data); | |
1193 return NGX_ERROR; | |
1194 } | |
1195 | |
1171 if (mvhd_atom->version[0] == 0) { | 1196 if (mvhd_atom->version[0] == 0) { |
1172 /* version 0: 32-bit duration */ | 1197 /* version 0: 32-bit duration */ |
1173 timescale = ngx_mp4_get_32value(mvhd_atom->timescale); | 1198 timescale = ngx_mp4_get_32value(mvhd_atom->timescale); |
1174 duration = ngx_mp4_get_32value(mvhd_atom->duration); | 1199 duration = ngx_mp4_get_32value(mvhd_atom->duration); |
1175 | 1200 |
1176 } else { | 1201 } else { |
1177 /* version 1: 64-bit duration */ | 1202 /* version 1: 64-bit duration */ |
1203 | |
1204 if (ngx_mp4_atom_data_size(ngx_mp4_mvhd64_atom_t) > atom_data_size) { | |
1205 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1206 "\"%s\" mp4 mvhd atom too small", | |
1207 mp4->file.name.data); | |
1208 return NGX_ERROR; | |
1209 } | |
1210 | |
1178 timescale = ngx_mp4_get_32value(mvhd64_atom->timescale); | 1211 timescale = ngx_mp4_get_32value(mvhd64_atom->timescale); |
1179 duration = ngx_mp4_get_64value(mvhd64_atom->duration); | 1212 duration = ngx_mp4_get_64value(mvhd64_atom->duration); |
1180 } | 1213 } |
1181 | 1214 |
1182 mp4->timescale = timescale; | 1215 mp4->timescale = timescale; |
1343 atom_header = ngx_mp4_atom_header(mp4); | 1376 atom_header = ngx_mp4_atom_header(mp4); |
1344 tkhd_atom = (ngx_mp4_tkhd_atom_t *) atom_header; | 1377 tkhd_atom = (ngx_mp4_tkhd_atom_t *) atom_header; |
1345 tkhd64_atom = (ngx_mp4_tkhd64_atom_t *) atom_header; | 1378 tkhd64_atom = (ngx_mp4_tkhd64_atom_t *) atom_header; |
1346 ngx_mp4_set_atom_name(tkhd_atom, 't', 'k', 'h', 'd'); | 1379 ngx_mp4_set_atom_name(tkhd_atom, 't', 'k', 'h', 'd'); |
1347 | 1380 |
1381 if (ngx_mp4_atom_data_size(ngx_mp4_tkhd_atom_t) > atom_data_size) { | |
1382 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1383 "\"%s\" mp4 tkhd atom too small", mp4->file.name.data); | |
1384 return NGX_ERROR; | |
1385 } | |
1386 | |
1348 if (tkhd_atom->version[0] == 0) { | 1387 if (tkhd_atom->version[0] == 0) { |
1349 /* version 0: 32-bit duration */ | 1388 /* version 0: 32-bit duration */ |
1350 duration = ngx_mp4_get_32value(tkhd_atom->duration); | 1389 duration = ngx_mp4_get_32value(tkhd_atom->duration); |
1351 | 1390 |
1352 } else { | 1391 } else { |
1353 /* version 1: 64-bit duration */ | 1392 /* version 1: 64-bit duration */ |
1393 | |
1394 if (ngx_mp4_atom_data_size(ngx_mp4_tkhd64_atom_t) > atom_data_size) { | |
1395 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1396 "\"%s\" mp4 tkhd atom too small", | |
1397 mp4->file.name.data); | |
1398 return NGX_ERROR; | |
1399 } | |
1400 | |
1354 duration = ngx_mp4_get_64value(tkhd64_atom->duration); | 1401 duration = ngx_mp4_get_64value(tkhd64_atom->duration); |
1355 } | 1402 } |
1356 | 1403 |
1357 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 1404 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1358 "tkhd duration:%uL, time:%.3fs", | 1405 "tkhd duration:%uL, time:%.3fs", |
1472 atom_header = ngx_mp4_atom_header(mp4); | 1519 atom_header = ngx_mp4_atom_header(mp4); |
1473 mdhd_atom = (ngx_mp4_mdhd_atom_t *) atom_header; | 1520 mdhd_atom = (ngx_mp4_mdhd_atom_t *) atom_header; |
1474 mdhd64_atom = (ngx_mp4_mdhd64_atom_t *) atom_header; | 1521 mdhd64_atom = (ngx_mp4_mdhd64_atom_t *) atom_header; |
1475 ngx_mp4_set_atom_name(mdhd_atom, 'm', 'd', 'h', 'd'); | 1522 ngx_mp4_set_atom_name(mdhd_atom, 'm', 'd', 'h', 'd'); |
1476 | 1523 |
1524 if (ngx_mp4_atom_data_size(ngx_mp4_mdhd_atom_t) > atom_data_size) { | |
1525 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1526 "\"%s\" mp4 mdhd atom too small", mp4->file.name.data); | |
1527 return NGX_ERROR; | |
1528 } | |
1529 | |
1477 if (mdhd_atom->version[0] == 0) { | 1530 if (mdhd_atom->version[0] == 0) { |
1478 /* version 0: everything is 32-bit */ | 1531 /* version 0: everything is 32-bit */ |
1479 timescale = ngx_mp4_get_32value(mdhd_atom->timescale); | 1532 timescale = ngx_mp4_get_32value(mdhd_atom->timescale); |
1480 duration = ngx_mp4_get_32value(mdhd_atom->duration); | 1533 duration = ngx_mp4_get_32value(mdhd_atom->duration); |
1481 | 1534 |
1482 } else { | 1535 } else { |
1483 /* version 1: 64-bit duration and 32-bit timescale */ | 1536 /* version 1: 64-bit duration and 32-bit timescale */ |
1537 | |
1538 if (ngx_mp4_atom_data_size(ngx_mp4_mdhd64_atom_t) > atom_data_size) { | |
1539 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1540 "\"%s\" mp4 mdhd atom too small", | |
1541 mp4->file.name.data); | |
1542 return NGX_ERROR; | |
1543 } | |
1544 | |
1484 timescale = ngx_mp4_get_32value(mdhd64_atom->timescale); | 1545 timescale = ngx_mp4_get_32value(mdhd64_atom->timescale); |
1485 duration = ngx_mp4_get_64value(mdhd64_atom->duration); | 1546 duration = ngx_mp4_get_64value(mdhd64_atom->duration); |
1486 } | 1547 } |
1487 | 1548 |
1488 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 1549 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1754 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | 1815 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; |
1755 atom_table = atom_header + atom_size; | 1816 atom_table = atom_header + atom_size; |
1756 ngx_mp4_set_32value(stsd_atom->size, atom_size); | 1817 ngx_mp4_set_32value(stsd_atom->size, atom_size); |
1757 ngx_mp4_set_atom_name(stsd_atom, 's', 't', 's', 'd'); | 1818 ngx_mp4_set_atom_name(stsd_atom, 's', 't', 's', 'd'); |
1758 | 1819 |
1759 if ((uint64_t) (sizeof(ngx_mp4_stsd_atom_t) - sizeof(ngx_mp4_atom_header_t)) | 1820 if (ngx_mp4_atom_data_size(ngx_mp4_stsd_atom_t) > atom_data_size) { |
1760 > atom_data_size) | |
1761 { | |
1762 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 1821 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
1763 "\"%s\" mp4 stsd atom too large", | 1822 "\"%s\" mp4 stsd atom too small", mp4->file.name.data); |
1764 mp4->file.name.data); | |
1765 return NGX_ERROR; | 1823 return NGX_ERROR; |
1766 } | 1824 } |
1767 | 1825 |
1768 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 1826 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1769 "stsd entries:%uD, media:%*s", | 1827 "stsd entries:%uD, media:%*s", |
1823 | 1881 |
1824 atom_header = ngx_mp4_atom_header(mp4); | 1882 atom_header = ngx_mp4_atom_header(mp4); |
1825 stts_atom = (ngx_mp4_stts_atom_t *) atom_header; | 1883 stts_atom = (ngx_mp4_stts_atom_t *) atom_header; |
1826 ngx_mp4_set_atom_name(stts_atom, 's', 't', 't', 's'); | 1884 ngx_mp4_set_atom_name(stts_atom, 's', 't', 't', 's'); |
1827 | 1885 |
1886 if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t) > atom_data_size) { | |
1887 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1888 "\"%s\" mp4 stts atom too small", mp4->file.name.data); | |
1889 return NGX_ERROR; | |
1890 } | |
1891 | |
1828 entries = ngx_mp4_get_32value(stts_atom->entries); | 1892 entries = ngx_mp4_get_32value(stts_atom->entries); |
1829 | 1893 |
1830 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 1894 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1831 "mp4 time-to-sample entries:%uD", entries); | 1895 "mp4 time-to-sample entries:%uD", entries); |
1832 | 1896 |
1897 if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t) | |
1898 + entries * sizeof(ngx_mp4_stts_entry_t) > atom_data_size) | |
1899 { | |
1900 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1901 "\"%s\" mp4 stts atom too small", mp4->file.name.data); | |
1902 return NGX_ERROR; | |
1903 } | |
1904 | |
1833 atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t); | 1905 atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t); |
1834 atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t); | 1906 atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t); |
1835 | |
1836 if ((uint64_t) (atom_end - stts_atom->version) > atom_data_size) { | |
1837 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1838 "\"%s\" mp4 stts atom too large", | |
1839 mp4->file.name.data); | |
1840 return NGX_ERROR; | |
1841 } | |
1842 | 1907 |
1843 trak = ngx_mp4_last_trak(mp4); | 1908 trak = ngx_mp4_last_trak(mp4); |
1844 trak->time_to_sample_entries = entries; | 1909 trak->time_to_sample_entries = entries; |
1845 | 1910 |
1846 atom = &trak->stts_atom_buf; | 1911 atom = &trak->stts_atom_buf; |
1971 | 2036 |
1972 atom_header = ngx_mp4_atom_header(mp4); | 2037 atom_header = ngx_mp4_atom_header(mp4); |
1973 stss_atom = (ngx_http_mp4_stss_atom_t *) atom_header; | 2038 stss_atom = (ngx_http_mp4_stss_atom_t *) atom_header; |
1974 ngx_mp4_set_atom_name(stss_atom, 's', 't', 's', 's'); | 2039 ngx_mp4_set_atom_name(stss_atom, 's', 't', 's', 's'); |
1975 | 2040 |
2041 if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t) > atom_data_size) { | |
2042 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2043 "\"%s\" mp4 stss atom too small", mp4->file.name.data); | |
2044 return NGX_ERROR; | |
2045 } | |
2046 | |
1976 entries = ngx_mp4_get_32value(stss_atom->entries); | 2047 entries = ngx_mp4_get_32value(stss_atom->entries); |
1977 | 2048 |
1978 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 2049 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1979 "sync sample entries:%uD", entries); | 2050 "sync sample entries:%uD", entries); |
1980 | 2051 |
1986 atom = &trak->stss_atom_buf; | 2057 atom = &trak->stss_atom_buf; |
1987 atom->temporary = 1; | 2058 atom->temporary = 1; |
1988 atom->pos = atom_header; | 2059 atom->pos = atom_header; |
1989 atom->last = atom_table; | 2060 atom->last = atom_table; |
1990 | 2061 |
2062 if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t) | |
2063 + entries * sizeof(uint32_t) > atom_data_size) | |
2064 { | |
2065 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2066 "\"%s\" mp4 stss atom too small", mp4->file.name.data); | |
2067 return NGX_ERROR; | |
2068 } | |
2069 | |
1991 atom_end = atom_table + entries * sizeof(uint32_t); | 2070 atom_end = atom_table + entries * sizeof(uint32_t); |
1992 | |
1993 if ((uint64_t) (atom_end - stss_atom->version) > atom_data_size) { | |
1994 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1995 "\"%s\" mp4 stss atom too large", mp4->file.name.data); | |
1996 return NGX_ERROR; | |
1997 } | |
1998 | 2071 |
1999 data = &trak->stss_data_buf; | 2072 data = &trak->stss_data_buf; |
2000 data->temporary = 1; | 2073 data->temporary = 1; |
2001 data->pos = atom_table; | 2074 data->pos = atom_table; |
2002 data->last = atom_end; | 2075 data->last = atom_end; |
2116 | 2189 |
2117 atom_header = ngx_mp4_atom_header(mp4); | 2190 atom_header = ngx_mp4_atom_header(mp4); |
2118 ctts_atom = (ngx_mp4_ctts_atom_t *) atom_header; | 2191 ctts_atom = (ngx_mp4_ctts_atom_t *) atom_header; |
2119 ngx_mp4_set_atom_name(ctts_atom, 'c', 't', 't', 's'); | 2192 ngx_mp4_set_atom_name(ctts_atom, 'c', 't', 't', 's'); |
2120 | 2193 |
2194 if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t) > atom_data_size) { | |
2195 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2196 "\"%s\" mp4 ctts atom too small", mp4->file.name.data); | |
2197 return NGX_ERROR; | |
2198 } | |
2199 | |
2121 entries = ngx_mp4_get_32value(ctts_atom->entries); | 2200 entries = ngx_mp4_get_32value(ctts_atom->entries); |
2122 | 2201 |
2123 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 2202 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
2124 "composition offset entries:%uD", entries); | 2203 "composition offset entries:%uD", entries); |
2125 | 2204 |
2131 atom = &trak->ctts_atom_buf; | 2210 atom = &trak->ctts_atom_buf; |
2132 atom->temporary = 1; | 2211 atom->temporary = 1; |
2133 atom->pos = atom_header; | 2212 atom->pos = atom_header; |
2134 atom->last = atom_table; | 2213 atom->last = atom_table; |
2135 | 2214 |
2215 if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t) | |
2216 + entries * sizeof(ngx_mp4_ctts_entry_t) > atom_data_size) | |
2217 { | |
2218 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2219 "\"%s\" mp4 ctts atom too small", mp4->file.name.data); | |
2220 return NGX_ERROR; | |
2221 } | |
2222 | |
2136 atom_end = atom_table + entries * sizeof(ngx_mp4_ctts_entry_t); | 2223 atom_end = atom_table + entries * sizeof(ngx_mp4_ctts_entry_t); |
2137 | |
2138 if ((uint64_t) (atom_end - ctts_atom->version) > atom_data_size) { | |
2139 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2140 "\"%s\" mp4 ctts atom too large", mp4->file.name.data); | |
2141 return NGX_ERROR; | |
2142 } | |
2143 | 2224 |
2144 data = &trak->ctts_data_buf; | 2225 data = &trak->ctts_data_buf; |
2145 data->temporary = 1; | 2226 data->temporary = 1; |
2146 data->pos = atom_table; | 2227 data->pos = atom_table; |
2147 data->last = atom_end; | 2228 data->last = atom_end; |
2249 | 2330 |
2250 atom_header = ngx_mp4_atom_header(mp4); | 2331 atom_header = ngx_mp4_atom_header(mp4); |
2251 stsc_atom = (ngx_mp4_stsc_atom_t *) atom_header; | 2332 stsc_atom = (ngx_mp4_stsc_atom_t *) atom_header; |
2252 ngx_mp4_set_atom_name(stsc_atom, 's', 't', 's', 'c'); | 2333 ngx_mp4_set_atom_name(stsc_atom, 's', 't', 's', 'c'); |
2253 | 2334 |
2335 if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t) > atom_data_size) { | |
2336 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2337 "\"%s\" mp4 stsc atom too small", mp4->file.name.data); | |
2338 return NGX_ERROR; | |
2339 } | |
2340 | |
2254 entries = ngx_mp4_get_32value(stsc_atom->entries); | 2341 entries = ngx_mp4_get_32value(stsc_atom->entries); |
2255 | 2342 |
2256 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 2343 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
2257 "sample-to-chunk entries:%uD", entries); | 2344 "sample-to-chunk entries:%uD", entries); |
2258 | 2345 |
2346 if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t) | |
2347 + entries * sizeof(ngx_mp4_stsc_entry_t) > atom_data_size) | |
2348 { | |
2349 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2350 "\"%s\" mp4 stsc atom too small", mp4->file.name.data); | |
2351 return NGX_ERROR; | |
2352 } | |
2353 | |
2259 atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t); | 2354 atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t); |
2260 atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t); | 2355 atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t); |
2261 | |
2262 if ((uint64_t) (atom_end - stsc_atom->version) > atom_data_size) { | |
2263 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2264 "\"%s\" mp4 stsc atom too large", | |
2265 mp4->file.name.data); | |
2266 return NGX_ERROR; | |
2267 } | |
2268 | 2356 |
2269 trak = ngx_mp4_last_trak(mp4); | 2357 trak = ngx_mp4_last_trak(mp4); |
2270 trak->sample_to_chunk_entries = entries; | 2358 trak->sample_to_chunk_entries = entries; |
2271 | 2359 |
2272 atom = &trak->stsc_atom_buf; | 2360 atom = &trak->stsc_atom_buf; |
2311 data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf; | 2399 data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf; |
2312 | 2400 |
2313 if (data == NULL) { | 2401 if (data == NULL) { |
2314 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 2402 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
2315 "no mp4 stsc atoms were found in \"%s\"", | 2403 "no mp4 stsc atoms were found in \"%s\"", |
2404 mp4->file.name.data); | |
2405 return NGX_ERROR; | |
2406 } | |
2407 | |
2408 if (trak->sample_to_chunk_entries == 0) { | |
2409 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2410 "zero number of entries in stsc atom in \"%s\"", | |
2316 mp4->file.name.data); | 2411 mp4->file.name.data); |
2317 return NGX_ERROR; | 2412 return NGX_ERROR; |
2318 } | 2413 } |
2319 | 2414 |
2320 start_sample = (uint32_t) trak->start_sample; | 2415 start_sample = (uint32_t) trak->start_sample; |
2456 | 2551 |
2457 atom_header = ngx_mp4_atom_header(mp4); | 2552 atom_header = ngx_mp4_atom_header(mp4); |
2458 stsz_atom = (ngx_mp4_stsz_atom_t *) atom_header; | 2553 stsz_atom = (ngx_mp4_stsz_atom_t *) atom_header; |
2459 ngx_mp4_set_atom_name(stsz_atom, 's', 't', 's', 'z'); | 2554 ngx_mp4_set_atom_name(stsz_atom, 's', 't', 's', 'z'); |
2460 | 2555 |
2556 if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t) > atom_data_size) { | |
2557 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2558 "\"%s\" mp4 stsz atom too small", mp4->file.name.data); | |
2559 return NGX_ERROR; | |
2560 } | |
2561 | |
2461 size = ngx_mp4_get_32value(stsz_atom->uniform_size); | 2562 size = ngx_mp4_get_32value(stsz_atom->uniform_size); |
2462 entries = ngx_mp4_get_32value(stsz_atom->entries); | 2563 entries = ngx_mp4_get_32value(stsz_atom->entries); |
2463 | 2564 |
2464 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 2565 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
2465 "sample uniform size:%uD, entries:%uD", size, entries); | 2566 "sample uniform size:%uD, entries:%uD", size, entries); |
2475 atom->last = atom_table; | 2576 atom->last = atom_table; |
2476 | 2577 |
2477 trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf = atom; | 2578 trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf = atom; |
2478 | 2579 |
2479 if (size == 0) { | 2580 if (size == 0) { |
2480 atom_end = atom_table + entries * sizeof(uint32_t); | 2581 if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t) |
2481 | 2582 + entries * sizeof(uint32_t) > atom_data_size) |
2482 if ((uint64_t) (atom_end - stsz_atom->version) > atom_data_size) { | 2583 { |
2483 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 2584 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
2484 "\"%s\" mp4 stsz atom too large", | 2585 "\"%s\" mp4 stsz atom too small", |
2485 mp4->file.name.data); | 2586 mp4->file.name.data); |
2486 return NGX_ERROR; | 2587 return NGX_ERROR; |
2487 } | 2588 } |
2589 | |
2590 atom_end = atom_table + entries * sizeof(uint32_t); | |
2488 | 2591 |
2489 data = &trak->stsz_data_buf; | 2592 data = &trak->stsz_data_buf; |
2490 data->temporary = 1; | 2593 data->temporary = 1; |
2491 data->pos = atom_table; | 2594 data->pos = atom_table; |
2492 data->last = atom_end; | 2595 data->last = atom_end; |
2505 | 2608 |
2506 return NGX_OK; | 2609 return NGX_OK; |
2507 } | 2610 } |
2508 | 2611 |
2509 | 2612 |
2510 static void | 2613 static ngx_int_t |
2511 ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, | 2614 ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, |
2512 ngx_http_mp4_trak_t *trak) | 2615 ngx_http_mp4_trak_t *trak) |
2513 { | 2616 { |
2514 size_t atom_size; | 2617 size_t atom_size; |
2515 uint32_t *pos, *end; | 2618 uint32_t *pos, *end; |
2526 "mp4 stsz atom update"); | 2629 "mp4 stsz atom update"); |
2527 | 2630 |
2528 data = trak->out[NGX_HTTP_MP4_STSZ_DATA].buf; | 2631 data = trak->out[NGX_HTTP_MP4_STSZ_DATA].buf; |
2529 | 2632 |
2530 if (data) { | 2633 if (data) { |
2634 if (trak->start_sample > trak->sample_sizes_entries) { | |
2635 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2636 "start time is out mp4 stsz samples in \"%s\"", | |
2637 mp4->file.name.data); | |
2638 return NGX_ERROR; | |
2639 } | |
2640 | |
2531 data->pos += trak->start_sample * sizeof(uint32_t); | 2641 data->pos += trak->start_sample * sizeof(uint32_t); |
2532 end = (uint32_t *) data->pos; | 2642 end = (uint32_t *) data->pos; |
2533 | 2643 |
2534 for (pos = end - trak->chunk_samples; pos < end; pos++) { | 2644 for (pos = end - trak->chunk_samples; pos < end; pos++) { |
2535 trak->chunk_samples_size += ngx_mp4_get_32value(pos); | 2645 trak->chunk_samples_size += ngx_mp4_get_32value(pos); |
2546 | 2656 |
2547 ngx_mp4_set_32value(stsz_atom->size, atom_size); | 2657 ngx_mp4_set_32value(stsz_atom->size, atom_size); |
2548 ngx_mp4_set_32value(stsz_atom->entries, | 2658 ngx_mp4_set_32value(stsz_atom->entries, |
2549 trak->sample_sizes_entries - trak->start_sample); | 2659 trak->sample_sizes_entries - trak->start_sample); |
2550 } | 2660 } |
2661 | |
2662 return NGX_OK; | |
2551 } | 2663 } |
2552 | 2664 |
2553 | 2665 |
2554 typedef struct { | 2666 typedef struct { |
2555 u_char size[4]; | 2667 u_char size[4]; |
2575 | 2687 |
2576 atom_header = ngx_mp4_atom_header(mp4); | 2688 atom_header = ngx_mp4_atom_header(mp4); |
2577 stco_atom = (ngx_mp4_stco_atom_t *) atom_header; | 2689 stco_atom = (ngx_mp4_stco_atom_t *) atom_header; |
2578 ngx_mp4_set_atom_name(stco_atom, 's', 't', 'c', 'o'); | 2690 ngx_mp4_set_atom_name(stco_atom, 's', 't', 'c', 'o'); |
2579 | 2691 |
2692 if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t) > atom_data_size) { | |
2693 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2694 "\"%s\" mp4 stco atom too small", mp4->file.name.data); | |
2695 return NGX_ERROR; | |
2696 } | |
2697 | |
2580 entries = ngx_mp4_get_32value(stco_atom->entries); | 2698 entries = ngx_mp4_get_32value(stco_atom->entries); |
2581 | 2699 |
2582 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); | 2700 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); |
2701 | |
2702 if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t) | |
2703 + entries * sizeof(uint32_t) > atom_data_size) | |
2704 { | |
2705 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2706 "\"%s\" mp4 stco atom too small", mp4->file.name.data); | |
2707 return NGX_ERROR; | |
2708 } | |
2583 | 2709 |
2584 atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t); | 2710 atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t); |
2585 atom_end = atom_table + entries * sizeof(uint32_t); | 2711 atom_end = atom_table + entries * sizeof(uint32_t); |
2586 | |
2587 if ((uint64_t) (atom_end - stco_atom->version) > atom_data_size) { | |
2588 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2589 "\"%s\" mp4 stco atom too large", mp4->file.name.data); | |
2590 return NGX_ERROR; | |
2591 } | |
2592 | 2712 |
2593 trak = ngx_mp4_last_trak(mp4); | 2713 trak = ngx_mp4_last_trak(mp4); |
2594 trak->chunks = entries; | 2714 trak->chunks = entries; |
2595 | 2715 |
2596 atom = &trak->stco_atom_buf; | 2716 atom = &trak->stco_atom_buf; |
2632 data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf; | 2752 data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf; |
2633 | 2753 |
2634 if (data == NULL) { | 2754 if (data == NULL) { |
2635 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 2755 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
2636 "no mp4 stco atoms were found in \"%s\"", | 2756 "no mp4 stco atoms were found in \"%s\"", |
2757 mp4->file.name.data); | |
2758 return NGX_ERROR; | |
2759 } | |
2760 | |
2761 if (trak->start_chunk > trak->chunks) { | |
2762 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2763 "start time is out mp4 stco chunks in \"%s\"", | |
2637 mp4->file.name.data); | 2764 mp4->file.name.data); |
2638 return NGX_ERROR; | 2765 return NGX_ERROR; |
2639 } | 2766 } |
2640 | 2767 |
2641 data->pos += trak->start_chunk * sizeof(uint32_t); | 2768 data->pos += trak->start_chunk * sizeof(uint32_t); |
2711 | 2838 |
2712 atom_header = ngx_mp4_atom_header(mp4); | 2839 atom_header = ngx_mp4_atom_header(mp4); |
2713 co64_atom = (ngx_mp4_co64_atom_t *) atom_header; | 2840 co64_atom = (ngx_mp4_co64_atom_t *) atom_header; |
2714 ngx_mp4_set_atom_name(co64_atom, 'c', 'o', '6', '4'); | 2841 ngx_mp4_set_atom_name(co64_atom, 'c', 'o', '6', '4'); |
2715 | 2842 |
2843 if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t) > atom_data_size) { | |
2844 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2845 "\"%s\" mp4 co64 atom too small", mp4->file.name.data); | |
2846 return NGX_ERROR; | |
2847 } | |
2848 | |
2716 entries = ngx_mp4_get_32value(co64_atom->entries); | 2849 entries = ngx_mp4_get_32value(co64_atom->entries); |
2717 | 2850 |
2718 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); | 2851 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); |
2852 | |
2853 if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t) | |
2854 + entries * sizeof(uint64_t) > atom_data_size) | |
2855 { | |
2856 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2857 "\"%s\" mp4 co64 atom too small", mp4->file.name.data); | |
2858 return NGX_ERROR; | |
2859 } | |
2719 | 2860 |
2720 atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t); | 2861 atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t); |
2721 atom_end = atom_table + entries * sizeof(uint64_t); | 2862 atom_end = atom_table + entries * sizeof(uint64_t); |
2722 | |
2723 if ((uint64_t) (atom_end - co64_atom->version) > atom_data_size) { | |
2724 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2725 "\"%s\" mp4 co64 atom too large", mp4->file.name.data); | |
2726 return NGX_ERROR; | |
2727 } | |
2728 | 2863 |
2729 trak = ngx_mp4_last_trak(mp4); | 2864 trak = ngx_mp4_last_trak(mp4); |
2730 trak->chunks = entries; | 2865 trak->chunks = entries; |
2731 | 2866 |
2732 atom = &trak->co64_atom_buf; | 2867 atom = &trak->co64_atom_buf; |
2772 "no mp4 co64 atoms were found in \"%s\"", | 2907 "no mp4 co64 atoms were found in \"%s\"", |
2773 mp4->file.name.data); | 2908 mp4->file.name.data); |
2774 return NGX_ERROR; | 2909 return NGX_ERROR; |
2775 } | 2910 } |
2776 | 2911 |
2912 if (trak->start_chunk > trak->chunks) { | |
2913 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2914 "start time is out mp4 co64 chunks in \"%s\"", | |
2915 mp4->file.name.data); | |
2916 return NGX_ERROR; | |
2917 } | |
2918 | |
2777 data->pos += trak->start_chunk * sizeof(uint64_t); | 2919 data->pos += trak->start_chunk * sizeof(uint64_t); |
2778 atom_size = sizeof(ngx_mp4_co64_atom_t) + (data->last - data->pos); | 2920 atom_size = sizeof(ngx_mp4_co64_atom_t) + (data->last - data->pos); |
2779 trak->size += atom_size; | 2921 trak->size += atom_size; |
2780 | 2922 |
2781 trak->start_offset = ngx_mp4_get_64value(data->pos); | 2923 trak->start_offset = ngx_mp4_get_64value(data->pos); |