comparison src/http/modules/ngx_http_mp4_module.c @ 8089:4032c1bdfa14

Mp4: disabled duplicate atoms. Most atoms should not appear more than once in a container. Previously, this was not enforced by the module, which could result in worker process crash, memory corruption and disclosure.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 19 Oct 2022 10:53:17 +0300
parents 1afd19dc7161
children f5515e727656
comparison
equal deleted inserted replaced
8088:e32b48848add 8089:4032c1bdfa14
1119 "\"%s\" mp4 ftyp atom is too large:%uL", 1119 "\"%s\" mp4 ftyp atom is too large:%uL",
1120 mp4->file.name.data, atom_data_size); 1120 mp4->file.name.data, atom_data_size);
1121 return NGX_ERROR; 1121 return NGX_ERROR;
1122 } 1122 }
1123 1123
1124 if (mp4->ftyp_atom.buf) {
1125 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1126 "duplicate mp4 ftyp atom in \"%s\"", mp4->file.name.data);
1127 return NGX_ERROR;
1128 }
1129
1124 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; 1130 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
1125 1131
1126 ftyp_atom = ngx_palloc(mp4->request->pool, atom_size); 1132 ftyp_atom = ngx_palloc(mp4->request->pool, atom_size);
1127 if (ftyp_atom == NULL) { 1133 if (ftyp_atom == NULL) {
1128 return NGX_ERROR; 1134 return NGX_ERROR;
1177 * mdat atom and client requests integral file 1183 * mdat atom and client requests integral file
1178 */ 1184 */
1179 return NGX_DECLINED; 1185 return NGX_DECLINED;
1180 } 1186 }
1181 1187
1188 if (mp4->moov_atom.buf) {
1189 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1190 "duplicate mp4 moov atom in \"%s\"", mp4->file.name.data);
1191 return NGX_ERROR;
1192 }
1193
1182 conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module); 1194 conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module);
1183 1195
1184 if (atom_data_size > mp4->buffer_size) { 1196 if (atom_data_size > mp4->buffer_size) {
1185 1197
1186 if (atom_data_size > conf->max_buffer_size) { 1198 if (atom_data_size > conf->max_buffer_size) {
1243 ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 1255 ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
1244 { 1256 {
1245 ngx_buf_t *data; 1257 ngx_buf_t *data;
1246 1258
1247 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom"); 1259 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom");
1260
1261 if (mp4->mdat_atom.buf) {
1262 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1263 "duplicate mp4 mdat atom in \"%s\"", mp4->file.name.data);
1264 return NGX_ERROR;
1265 }
1248 1266
1249 data = &mp4->mdat_data_buf; 1267 data = &mp4->mdat_data_buf;
1250 data->file = &mp4->file; 1268 data->file = &mp4->file;
1251 data->in_file = 1; 1269 data->in_file = 1;
1252 data->last_buf = (mp4->request == mp4->request->main) ? 1 : 0; 1270 data->last_buf = (mp4->request == mp4->request->main) ? 1 : 0;
1370 ngx_mp4_mvhd_atom_t *mvhd_atom; 1388 ngx_mp4_mvhd_atom_t *mvhd_atom;
1371 ngx_mp4_mvhd64_atom_t *mvhd64_atom; 1389 ngx_mp4_mvhd64_atom_t *mvhd64_atom;
1372 1390
1373 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom"); 1391 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom");
1374 1392
1393 if (mp4->mvhd_atom.buf) {
1394 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1395 "duplicate mp4 mvhd atom in \"%s\"", mp4->file.name.data);
1396 return NGX_ERROR;
1397 }
1398
1375 atom_header = ngx_mp4_atom_header(mp4); 1399 atom_header = ngx_mp4_atom_header(mp4);
1376 mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header; 1400 mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header;
1377 mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header; 1401 mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header;
1378 ngx_mp4_set_atom_name(atom_header, 'm', 'v', 'h', 'd'); 1402 ngx_mp4_set_atom_name(atom_header, 'm', 'v', 'h', 'd');
1379 1403
1635 duration, (double) duration / mp4->timescale); 1659 duration, (double) duration / mp4->timescale);
1636 1660
1637 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; 1661 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
1638 1662
1639 trak = ngx_mp4_last_trak(mp4); 1663 trak = ngx_mp4_last_trak(mp4);
1664
1665 if (trak->out[NGX_HTTP_MP4_TKHD_ATOM].buf) {
1666 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1667 "duplicate mp4 tkhd atom in \"%s\"", mp4->file.name.data);
1668 return NGX_ERROR;
1669 }
1670
1640 trak->tkhd_size = atom_size; 1671 trak->tkhd_size = atom_size;
1641 trak->movie_duration = duration; 1672 trak->movie_duration = duration;
1642 1673
1643 ngx_mp4_set_32value(tkhd_atom->size, atom_size); 1674 ngx_mp4_set_32value(tkhd_atom->size, atom_size);
1644 1675
1673 1704
1674 atom_header = ngx_mp4_atom_header(mp4); 1705 atom_header = ngx_mp4_atom_header(mp4);
1675 ngx_mp4_set_atom_name(atom_header, 'm', 'd', 'i', 'a'); 1706 ngx_mp4_set_atom_name(atom_header, 'm', 'd', 'i', 'a');
1676 1707
1677 trak = ngx_mp4_last_trak(mp4); 1708 trak = ngx_mp4_last_trak(mp4);
1709
1710 if (trak->out[NGX_HTTP_MP4_MDIA_ATOM].buf) {
1711 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1712 "duplicate mp4 mdia atom in \"%s\"", mp4->file.name.data);
1713 return NGX_ERROR;
1714 }
1678 1715
1679 atom = &trak->mdia_atom_buf; 1716 atom = &trak->mdia_atom_buf;
1680 atom->temporary = 1; 1717 atom->temporary = 1;
1681 atom->pos = atom_header; 1718 atom->pos = atom_header;
1682 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); 1719 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
1797 duration, (double) duration / timescale); 1834 duration, (double) duration / timescale);
1798 1835
1799 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; 1836 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
1800 1837
1801 trak = ngx_mp4_last_trak(mp4); 1838 trak = ngx_mp4_last_trak(mp4);
1839
1840 if (trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf) {
1841 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1842 "duplicate mp4 mdhd atom in \"%s\"", mp4->file.name.data);
1843 return NGX_ERROR;
1844 }
1845
1802 trak->mdhd_size = atom_size; 1846 trak->mdhd_size = atom_size;
1803 trak->timescale = timescale; 1847 trak->timescale = timescale;
1804 trak->duration = duration; 1848 trak->duration = duration;
1805 1849
1806 ngx_mp4_set_32value(mdhd_atom->size, atom_size); 1850 ngx_mp4_set_32value(mdhd_atom->size, atom_size);
1860 ngx_mp4_set_32value(atom_header, atom_size); 1904 ngx_mp4_set_32value(atom_header, atom_size);
1861 ngx_mp4_set_atom_name(atom_header, 'h', 'd', 'l', 'r'); 1905 ngx_mp4_set_atom_name(atom_header, 'h', 'd', 'l', 'r');
1862 1906
1863 trak = ngx_mp4_last_trak(mp4); 1907 trak = ngx_mp4_last_trak(mp4);
1864 1908
1909 if (trak->out[NGX_HTTP_MP4_HDLR_ATOM].buf) {
1910 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1911 "duplicate mp4 hdlr atom in \"%s\"", mp4->file.name.data);
1912 return NGX_ERROR;
1913 }
1914
1865 atom = &trak->hdlr_atom_buf; 1915 atom = &trak->hdlr_atom_buf;
1866 atom->temporary = 1; 1916 atom->temporary = 1;
1867 atom->pos = atom_header; 1917 atom->pos = atom_header;
1868 atom->last = atom_header + atom_size; 1918 atom->last = atom_header + atom_size;
1869 1919
1887 1937
1888 atom_header = ngx_mp4_atom_header(mp4); 1938 atom_header = ngx_mp4_atom_header(mp4);
1889 ngx_mp4_set_atom_name(atom_header, 'm', 'i', 'n', 'f'); 1939 ngx_mp4_set_atom_name(atom_header, 'm', 'i', 'n', 'f');
1890 1940
1891 trak = ngx_mp4_last_trak(mp4); 1941 trak = ngx_mp4_last_trak(mp4);
1942
1943 if (trak->out[NGX_HTTP_MP4_MINF_ATOM].buf) {
1944 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1945 "duplicate mp4 minf atom in \"%s\"", mp4->file.name.data);
1946 return NGX_ERROR;
1947 }
1892 1948
1893 atom = &trak->minf_atom_buf; 1949 atom = &trak->minf_atom_buf;
1894 atom->temporary = 1; 1950 atom->temporary = 1;
1895 atom->pos = atom_header; 1951 atom->pos = atom_header;
1896 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); 1952 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
1931 ngx_mp4_set_32value(atom_header, atom_size); 1987 ngx_mp4_set_32value(atom_header, atom_size);
1932 ngx_mp4_set_atom_name(atom_header, 'v', 'm', 'h', 'd'); 1988 ngx_mp4_set_atom_name(atom_header, 'v', 'm', 'h', 'd');
1933 1989
1934 trak = ngx_mp4_last_trak(mp4); 1990 trak = ngx_mp4_last_trak(mp4);
1935 1991
1992 if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf
1993 || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf)
1994 {
1995 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1996 "duplicate mp4 vmhd/smhd atom in \"%s\"",
1997 mp4->file.name.data);
1998 return NGX_ERROR;
1999 }
2000
1936 atom = &trak->vmhd_atom_buf; 2001 atom = &trak->vmhd_atom_buf;
1937 atom->temporary = 1; 2002 atom->temporary = 1;
1938 atom->pos = atom_header; 2003 atom->pos = atom_header;
1939 atom->last = atom_header + atom_size; 2004 atom->last = atom_header + atom_size;
1940 2005
1962 ngx_mp4_set_32value(atom_header, atom_size); 2027 ngx_mp4_set_32value(atom_header, atom_size);
1963 ngx_mp4_set_atom_name(atom_header, 's', 'm', 'h', 'd'); 2028 ngx_mp4_set_atom_name(atom_header, 's', 'm', 'h', 'd');
1964 2029
1965 trak = ngx_mp4_last_trak(mp4); 2030 trak = ngx_mp4_last_trak(mp4);
1966 2031
2032 if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf
2033 || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf)
2034 {
2035 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
2036 "duplicate mp4 vmhd/smhd atom in \"%s\"",
2037 mp4->file.name.data);
2038 return NGX_ERROR;
2039 }
2040
1967 atom = &trak->smhd_atom_buf; 2041 atom = &trak->smhd_atom_buf;
1968 atom->temporary = 1; 2042 atom->temporary = 1;
1969 atom->pos = atom_header; 2043 atom->pos = atom_header;
1970 atom->last = atom_header + atom_size; 2044 atom->last = atom_header + atom_size;
1971 2045
1993 ngx_mp4_set_32value(atom_header, atom_size); 2067 ngx_mp4_set_32value(atom_header, atom_size);
1994 ngx_mp4_set_atom_name(atom_header, 'd', 'i', 'n', 'f'); 2068 ngx_mp4_set_atom_name(atom_header, 'd', 'i', 'n', 'f');
1995 2069
1996 trak = ngx_mp4_last_trak(mp4); 2070 trak = ngx_mp4_last_trak(mp4);
1997 2071
2072 if (trak->out[NGX_HTTP_MP4_DINF_ATOM].buf) {
2073 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
2074 "duplicate mp4 dinf atom in \"%s\"", mp4->file.name.data);
2075 return NGX_ERROR;
2076 }
2077
1998 atom = &trak->dinf_atom_buf; 2078 atom = &trak->dinf_atom_buf;
1999 atom->temporary = 1; 2079 atom->temporary = 1;
2000 atom->pos = atom_header; 2080 atom->pos = atom_header;
2001 atom->last = atom_header + atom_size; 2081 atom->last = atom_header + atom_size;
2002 2082
2020 2100
2021 atom_header = ngx_mp4_atom_header(mp4); 2101 atom_header = ngx_mp4_atom_header(mp4);
2022 ngx_mp4_set_atom_name(atom_header, 's', 't', 'b', 'l'); 2102 ngx_mp4_set_atom_name(atom_header, 's', 't', 'b', 'l');
2023 2103
2024 trak = ngx_mp4_last_trak(mp4); 2104 trak = ngx_mp4_last_trak(mp4);
2105
2106 if (trak->out[NGX_HTTP_MP4_STBL_ATOM].buf) {
2107 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
2108 "duplicate mp4 stbl atom in \"%s\"", mp4->file.name.data);
2109 return NGX_ERROR;
2110 }
2025 2111
2026 atom = &trak->stbl_atom_buf; 2112 atom = &trak->stbl_atom_buf;
2027 atom->temporary = 1; 2113 atom->temporary = 1;
2028 atom->pos = atom_header; 2114 atom->pos = atom_header;
2029 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); 2115 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
2141 "stsd entries:%uD, media:%*s", 2227 "stsd entries:%uD, media:%*s",
2142 ngx_mp4_get_32value(stsd_atom->entries), 2228 ngx_mp4_get_32value(stsd_atom->entries),
2143 (size_t) 4, stsd_atom->media_name); 2229 (size_t) 4, stsd_atom->media_name);
2144 2230
2145 trak = ngx_mp4_last_trak(mp4); 2231 trak = ngx_mp4_last_trak(mp4);
2232
2233 if (trak->out[NGX_HTTP_MP4_STSD_ATOM].buf) {
2234 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
2235 "duplicate mp4 stsd atom in \"%s\"", mp4->file.name.data);
2236 return NGX_ERROR;
2237 }
2146 2238
2147 atom = &trak->stsd_atom_buf; 2239 atom = &trak->stsd_atom_buf;
2148 atom->temporary = 1; 2240 atom->temporary = 1;
2149 atom->pos = atom_header; 2241 atom->pos = atom_header;
2150 atom->last = atom_table; 2242 atom->last = atom_table;
2210 2302
2211 atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t); 2303 atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t);
2212 atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t); 2304 atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t);
2213 2305
2214 trak = ngx_mp4_last_trak(mp4); 2306 trak = ngx_mp4_last_trak(mp4);
2307
2308 if (trak->out[NGX_HTTP_MP4_STTS_ATOM].buf) {
2309 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
2310 "duplicate mp4 stts atom in \"%s\"", mp4->file.name.data);
2311 return NGX_ERROR;
2312 }
2313
2215 trak->time_to_sample_entries = entries; 2314 trak->time_to_sample_entries = entries;
2216 2315
2217 atom = &trak->stts_atom_buf; 2316 atom = &trak->stts_atom_buf;
2218 atom->temporary = 1; 2317 atom->temporary = 1;
2219 atom->pos = atom_header; 2318 atom->pos = atom_header;
2478 2577
2479 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 2578 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
2480 "sync sample entries:%uD", entries); 2579 "sync sample entries:%uD", entries);
2481 2580
2482 trak = ngx_mp4_last_trak(mp4); 2581 trak = ngx_mp4_last_trak(mp4);
2582
2583 if (trak->out[NGX_HTTP_MP4_STSS_ATOM].buf) {
2584 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
2585 "duplicate mp4 stss atom in \"%s\"", mp4->file.name.data);
2586 return NGX_ERROR;
2587 }
2588
2483 trak->sync_samples_entries = entries; 2589 trak->sync_samples_entries = entries;
2484 2590
2485 atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t); 2591 atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t);
2486 2592
2487 atom = &trak->stss_atom_buf; 2593 atom = &trak->stss_atom_buf;
2676 2782
2677 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 2783 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
2678 "composition offset entries:%uD", entries); 2784 "composition offset entries:%uD", entries);
2679 2785
2680 trak = ngx_mp4_last_trak(mp4); 2786 trak = ngx_mp4_last_trak(mp4);
2787
2788 if (trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf) {
2789 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
2790 "duplicate mp4 ctts atom in \"%s\"", mp4->file.name.data);
2791 return NGX_ERROR;
2792 }
2793
2681 trak->composition_offset_entries = entries; 2794 trak->composition_offset_entries = entries;
2682 2795
2683 atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t); 2796 atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t);
2684 2797
2685 atom = &trak->ctts_atom_buf; 2798 atom = &trak->ctts_atom_buf;
2879 2992
2880 atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t); 2993 atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t);
2881 atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t); 2994 atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t);
2882 2995
2883 trak = ngx_mp4_last_trak(mp4); 2996 trak = ngx_mp4_last_trak(mp4);
2997
2998 if (trak->out[NGX_HTTP_MP4_STSC_ATOM].buf) {
2999 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
3000 "duplicate mp4 stsc atom in \"%s\"", mp4->file.name.data);
3001 return NGX_ERROR;
3002 }
3003
2884 trak->sample_to_chunk_entries = entries; 3004 trak->sample_to_chunk_entries = entries;
2885 3005
2886 atom = &trak->stsc_atom_buf; 3006 atom = &trak->stsc_atom_buf;
2887 atom->temporary = 1; 3007 atom->temporary = 1;
2888 atom->pos = atom_header; 3008 atom->pos = atom_header;
3211 3331
3212 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 3332 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
3213 "sample uniform size:%uD, entries:%uD", size, entries); 3333 "sample uniform size:%uD, entries:%uD", size, entries);
3214 3334
3215 trak = ngx_mp4_last_trak(mp4); 3335 trak = ngx_mp4_last_trak(mp4);
3336
3337 if (trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf) {
3338 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
3339 "duplicate mp4 stsz atom in \"%s\"", mp4->file.name.data);
3340 return NGX_ERROR;
3341 }
3342
3216 trak->sample_sizes_entries = entries; 3343 trak->sample_sizes_entries = entries;
3217 3344
3218 atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t); 3345 atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t);
3219 3346
3220 atom = &trak->stsz_atom_buf; 3347 atom = &trak->stsz_atom_buf;
3394 3521
3395 atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t); 3522 atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t);
3396 atom_end = atom_table + entries * sizeof(uint32_t); 3523 atom_end = atom_table + entries * sizeof(uint32_t);
3397 3524
3398 trak = ngx_mp4_last_trak(mp4); 3525 trak = ngx_mp4_last_trak(mp4);
3526
3527 if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf
3528 || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf)
3529 {
3530 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
3531 "duplicate mp4 stco/co64 atom in \"%s\"",
3532 mp4->file.name.data);
3533 return NGX_ERROR;
3534 }
3535
3399 trak->chunks = entries; 3536 trak->chunks = entries;
3400 3537
3401 atom = &trak->stco_atom_buf; 3538 atom = &trak->stco_atom_buf;
3402 atom->temporary = 1; 3539 atom->temporary = 1;
3403 atom->pos = atom_header; 3540 atom->pos = atom_header;
3600 3737
3601 atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t); 3738 atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t);
3602 atom_end = atom_table + entries * sizeof(uint64_t); 3739 atom_end = atom_table + entries * sizeof(uint64_t);
3603 3740
3604 trak = ngx_mp4_last_trak(mp4); 3741 trak = ngx_mp4_last_trak(mp4);
3742
3743 if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf
3744 || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf)
3745 {
3746 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
3747 "duplicate mp4 stco/co64 atom in \"%s\"",
3748 mp4->file.name.data);
3749 return NGX_ERROR;
3750 }
3751
3605 trak->chunks = entries; 3752 trak->chunks = entries;
3606 3753
3607 atom = &trak->co64_atom_buf; 3754 atom = &trak->co64_atom_buf;
3608 atom->temporary = 1; 3755 atom->temporary = 1;
3609 atom->pos = atom_header; 3756 atom->pos = atom_header;