Mercurial > hg > nginx
comparison src/http/modules/ngx_http_mp4_module.c @ 5619:517b5b599e3f
Mp4: moved atom cropping code out of update functions.
It can now be reused for implementing mp4 end.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 20 Mar 2014 16:05:18 +0400 |
parents | e280ece17020 |
children | 0a567878254b |
comparison
equal
deleted
inserted
replaced
5618:c15350f4071c | 5619:517b5b599e3f |
---|---|
256 uint64_t atom_data_size); | 256 uint64_t atom_data_size); |
257 static ngx_int_t ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, | 257 static ngx_int_t ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, |
258 uint64_t atom_data_size); | 258 uint64_t atom_data_size); |
259 static ngx_int_t ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4, | 259 static ngx_int_t ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4, |
260 ngx_http_mp4_trak_t *trak); | 260 ngx_http_mp4_trak_t *trak); |
261 static ngx_int_t ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4, | |
262 ngx_http_mp4_trak_t *trak); | |
261 static ngx_int_t ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, | 263 static ngx_int_t ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, |
262 uint64_t atom_data_size); | 264 uint64_t atom_data_size); |
263 static ngx_int_t ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4, | 265 static ngx_int_t ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4, |
266 ngx_http_mp4_trak_t *trak); | |
267 static void ngx_http_mp4_crop_stss_data(ngx_http_mp4_file_t *mp4, | |
264 ngx_http_mp4_trak_t *trak); | 268 ngx_http_mp4_trak_t *trak); |
265 static ngx_int_t ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, | 269 static ngx_int_t ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, |
266 uint64_t atom_data_size); | 270 uint64_t atom_data_size); |
267 static void ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4, | 271 static void ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4, |
268 ngx_http_mp4_trak_t *trak); | 272 ngx_http_mp4_trak_t *trak); |
273 static void ngx_http_mp4_crop_ctts_data(ngx_http_mp4_file_t *mp4, | |
274 ngx_http_mp4_trak_t *trak); | |
269 static ngx_int_t ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, | 275 static ngx_int_t ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, |
270 uint64_t atom_data_size); | 276 uint64_t atom_data_size); |
271 static ngx_int_t ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, | 277 static ngx_int_t ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, |
278 ngx_http_mp4_trak_t *trak); | |
279 static ngx_int_t ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, | |
272 ngx_http_mp4_trak_t *trak); | 280 ngx_http_mp4_trak_t *trak); |
273 static ngx_int_t ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, | 281 static ngx_int_t ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, |
274 uint64_t atom_data_size); | 282 uint64_t atom_data_size); |
275 static ngx_int_t ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, | 283 static ngx_int_t ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, |
276 ngx_http_mp4_trak_t *trak); | 284 ngx_http_mp4_trak_t *trak); |
1979 | 1987 |
1980 static ngx_int_t | 1988 static ngx_int_t |
1981 ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4, | 1989 ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4, |
1982 ngx_http_mp4_trak_t *trak) | 1990 ngx_http_mp4_trak_t *trak) |
1983 { | 1991 { |
1984 size_t atom_size; | 1992 size_t atom_size; |
1985 uint32_t entries, count, duration; | 1993 ngx_buf_t *atom, *data; |
1986 uint64_t start_time; | 1994 ngx_mp4_stts_atom_t *stts_atom; |
1987 ngx_buf_t *atom, *data; | |
1988 ngx_uint_t start_sample; | |
1989 ngx_mp4_stts_atom_t *stts_atom; | |
1990 ngx_mp4_stts_entry_t *entry, *end; | |
1991 | 1995 |
1992 /* | 1996 /* |
1993 * mdia.minf.stbl.stts updating requires trak->timescale | 1997 * mdia.minf.stbl.stts updating requires trak->timescale |
1994 * from mdia.mdhd atom which may reside after mdia.minf | 1998 * from mdia.mdhd atom which may reside after mdia.minf |
1995 */ | 1999 */ |
2004 "no mp4 stts atoms were found in \"%s\"", | 2008 "no mp4 stts atoms were found in \"%s\"", |
2005 mp4->file.name.data); | 2009 mp4->file.name.data); |
2006 return NGX_ERROR; | 2010 return NGX_ERROR; |
2007 } | 2011 } |
2008 | 2012 |
2009 entries = trak->time_to_sample_entries; | 2013 if (ngx_http_mp4_crop_stts_data(mp4, trak) != NGX_OK) { |
2014 return NGX_ERROR; | |
2015 } | |
2016 | |
2017 atom_size = sizeof(ngx_mp4_stts_atom_t) + (data->last - data->pos); | |
2018 trak->size += atom_size; | |
2019 | |
2020 atom = trak->out[NGX_HTTP_MP4_STTS_ATOM].buf; | |
2021 stts_atom = (ngx_mp4_stts_atom_t *) atom->pos; | |
2022 ngx_mp4_set_32value(stts_atom->size, atom_size); | |
2023 ngx_mp4_set_32value(stts_atom->entries, trak->time_to_sample_entries); | |
2024 | |
2025 return NGX_OK; | |
2026 } | |
2027 | |
2028 | |
2029 static ngx_int_t | |
2030 ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4, | |
2031 ngx_http_mp4_trak_t *trak) | |
2032 { | |
2033 uint32_t count, duration; | |
2034 uint64_t start_time; | |
2035 ngx_buf_t *data; | |
2036 ngx_uint_t start_sample, entries; | |
2037 ngx_mp4_stts_entry_t *entry, *end; | |
2038 | |
2039 data = trak->out[NGX_HTTP_MP4_STTS_DATA].buf; | |
2040 | |
2010 start_time = (uint64_t) mp4->start * trak->timescale / 1000; | 2041 start_time = (uint64_t) mp4->start * trak->timescale / 1000; |
2011 | 2042 |
2012 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 2043 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
2013 "time-to-sample start_time:%uL", start_time); | 2044 "time-to-sample start_time:%uL", start_time); |
2014 | 2045 |
2046 entries = trak->time_to_sample_entries; | |
2015 start_sample = 0; | 2047 start_sample = 0; |
2016 entry = (ngx_mp4_stts_entry_t *) data->pos; | 2048 entry = (ngx_mp4_stts_entry_t *) data->pos; |
2017 end = (ngx_mp4_stts_entry_t *) data->last; | 2049 end = (ngx_mp4_stts_entry_t *) data->last; |
2018 | 2050 |
2019 while (entry < end) { | 2051 while (entry < end) { |
2045 found: | 2077 found: |
2046 | 2078 |
2047 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 2079 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
2048 "start_sample:%ui, new count:%uD", start_sample, count); | 2080 "start_sample:%ui, new count:%uD", start_sample, count); |
2049 | 2081 |
2082 trak->time_to_sample_entries = entries; | |
2050 trak->start_sample = start_sample; | 2083 trak->start_sample = start_sample; |
2051 | |
2052 data->pos = (u_char *) entry; | 2084 data->pos = (u_char *) entry; |
2053 atom_size = sizeof(ngx_mp4_stts_atom_t) + (data->last - data->pos); | |
2054 trak->size += atom_size; | |
2055 | |
2056 atom = trak->out[NGX_HTTP_MP4_STTS_ATOM].buf; | |
2057 stts_atom = (ngx_mp4_stts_atom_t *) atom->pos; | |
2058 ngx_mp4_set_32value(stts_atom->size, atom_size); | |
2059 ngx_mp4_set_32value(stts_atom->entries, entries); | |
2060 | 2085 |
2061 return NGX_OK; | 2086 return NGX_OK; |
2062 } | 2087 } |
2063 | 2088 |
2064 | 2089 |
2136 static ngx_int_t | 2161 static ngx_int_t |
2137 ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4, | 2162 ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4, |
2138 ngx_http_mp4_trak_t *trak) | 2163 ngx_http_mp4_trak_t *trak) |
2139 { | 2164 { |
2140 size_t atom_size; | 2165 size_t atom_size; |
2141 uint32_t entries, sample, start_sample, *entry, *end; | 2166 uint32_t sample, start_sample, *entry, *end; |
2142 ngx_buf_t *atom, *data; | 2167 ngx_buf_t *atom, *data; |
2143 ngx_http_mp4_stss_atom_t *stss_atom; | 2168 ngx_http_mp4_stss_atom_t *stss_atom; |
2144 | 2169 |
2145 /* | 2170 /* |
2146 * mdia.minf.stbl.stss updating requires trak->start_sample | 2171 * mdia.minf.stbl.stss updating requires trak->start_sample |
2155 | 2180 |
2156 if (data == NULL) { | 2181 if (data == NULL) { |
2157 return NGX_OK; | 2182 return NGX_OK; |
2158 } | 2183 } |
2159 | 2184 |
2160 /* sync samples starts from 1 */ | 2185 ngx_http_mp4_crop_stss_data(mp4, trak); |
2161 start_sample = trak->start_sample + 1; | |
2162 entries = trak->sync_samples_entries; | |
2163 | 2186 |
2164 entry = (uint32_t *) data->pos; | 2187 entry = (uint32_t *) data->pos; |
2165 end = (uint32_t *) data->last; | 2188 end = (uint32_t *) data->last; |
2166 | |
2167 while (entry < end) { | |
2168 sample = ngx_mp4_get_32value(entry); | |
2169 | |
2170 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2171 "start:%uD, sync:%uD", start_sample, sample); | |
2172 | |
2173 if (sample >= start_sample) { | |
2174 goto found; | |
2175 } | |
2176 | |
2177 entries--; | |
2178 entry++; | |
2179 } | |
2180 | |
2181 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2182 "start sample is out of mp4 stss atom"); | |
2183 | |
2184 found: | |
2185 | |
2186 data->pos = (u_char *) entry; | |
2187 | 2189 |
2188 start_sample = trak->start_sample; | 2190 start_sample = trak->start_sample; |
2189 | 2191 |
2190 while (entry < end) { | 2192 while (entry < end) { |
2191 sample = ngx_mp4_get_32value(entry); | 2193 sample = ngx_mp4_get_32value(entry); |
2199 | 2201 |
2200 atom = trak->out[NGX_HTTP_MP4_STSS_ATOM].buf; | 2202 atom = trak->out[NGX_HTTP_MP4_STSS_ATOM].buf; |
2201 stss_atom = (ngx_http_mp4_stss_atom_t *) atom->pos; | 2203 stss_atom = (ngx_http_mp4_stss_atom_t *) atom->pos; |
2202 | 2204 |
2203 ngx_mp4_set_32value(stss_atom->size, atom_size); | 2205 ngx_mp4_set_32value(stss_atom->size, atom_size); |
2204 ngx_mp4_set_32value(stss_atom->entries, entries); | 2206 ngx_mp4_set_32value(stss_atom->entries, trak->sync_samples_entries); |
2205 | 2207 |
2206 return NGX_OK; | 2208 return NGX_OK; |
2209 } | |
2210 | |
2211 | |
2212 static void | |
2213 ngx_http_mp4_crop_stss_data(ngx_http_mp4_file_t *mp4, | |
2214 ngx_http_mp4_trak_t *trak) | |
2215 { | |
2216 uint32_t sample, start_sample, *entry, *end; | |
2217 ngx_buf_t *data; | |
2218 ngx_uint_t entries; | |
2219 | |
2220 data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf; | |
2221 | |
2222 /* sync samples starts from 1 */ | |
2223 start_sample = trak->start_sample + 1; | |
2224 entries = trak->sync_samples_entries; | |
2225 | |
2226 entry = (uint32_t *) data->pos; | |
2227 end = (uint32_t *) data->last; | |
2228 | |
2229 while (entry < end) { | |
2230 sample = ngx_mp4_get_32value(entry); | |
2231 | |
2232 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2233 "start:%uD, sync:%uD", start_sample, sample); | |
2234 | |
2235 if (sample >= start_sample) { | |
2236 goto found; | |
2237 } | |
2238 | |
2239 entries--; | |
2240 entry++; | |
2241 } | |
2242 | |
2243 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2244 "start sample is out of mp4 stss atom"); | |
2245 | |
2246 found: | |
2247 | |
2248 data->pos = (u_char *) entry; | |
2249 trak->sync_samples_entries = entries; | |
2207 } | 2250 } |
2208 | 2251 |
2209 | 2252 |
2210 typedef struct { | 2253 typedef struct { |
2211 u_char size[4]; | 2254 u_char size[4]; |
2285 | 2328 |
2286 static void | 2329 static void |
2287 ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4, | 2330 ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4, |
2288 ngx_http_mp4_trak_t *trak) | 2331 ngx_http_mp4_trak_t *trak) |
2289 { | 2332 { |
2290 size_t atom_size; | 2333 size_t atom_size; |
2291 uint32_t entries, count, start_sample; | 2334 ngx_buf_t *atom, *data; |
2292 ngx_buf_t *atom, *data; | 2335 ngx_mp4_ctts_atom_t *ctts_atom; |
2293 ngx_mp4_ctts_atom_t *ctts_atom; | |
2294 ngx_mp4_ctts_entry_t *entry, *end; | |
2295 | 2336 |
2296 /* | 2337 /* |
2297 * mdia.minf.stbl.ctts updating requires trak->start_sample | 2338 * mdia.minf.stbl.ctts updating requires trak->start_sample |
2298 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | 2339 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd |
2299 * atom which may reside after mdia.minf | 2340 * atom which may reside after mdia.minf |
2306 | 2347 |
2307 if (data == NULL) { | 2348 if (data == NULL) { |
2308 return; | 2349 return; |
2309 } | 2350 } |
2310 | 2351 |
2352 ngx_http_mp4_crop_ctts_data(mp4, trak); | |
2353 | |
2354 if (trak->composition_offset_entries == 0) { | |
2355 trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = NULL; | |
2356 trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = NULL; | |
2357 return; | |
2358 } | |
2359 | |
2360 atom_size = sizeof(ngx_mp4_ctts_atom_t) + (data->last - data->pos); | |
2361 trak->size += atom_size; | |
2362 | |
2363 atom = trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf; | |
2364 ctts_atom = (ngx_mp4_ctts_atom_t *) atom->pos; | |
2365 | |
2366 ngx_mp4_set_32value(ctts_atom->size, atom_size); | |
2367 ngx_mp4_set_32value(ctts_atom->entries, trak->composition_offset_entries); | |
2368 | |
2369 return; | |
2370 } | |
2371 | |
2372 | |
2373 static void | |
2374 ngx_http_mp4_crop_ctts_data(ngx_http_mp4_file_t *mp4, | |
2375 ngx_http_mp4_trak_t *trak) | |
2376 { | |
2377 uint32_t count, start_sample; | |
2378 ngx_buf_t *data; | |
2379 ngx_uint_t entries; | |
2380 ngx_mp4_ctts_entry_t *entry, *end; | |
2381 | |
2382 data = trak->out[NGX_HTTP_MP4_CTTS_DATA].buf; | |
2383 | |
2311 /* sync samples starts from 1 */ | 2384 /* sync samples starts from 1 */ |
2312 start_sample = trak->start_sample + 1; | 2385 start_sample = trak->start_sample + 1; |
2313 entries = trak->composition_offset_entries; | 2386 entries = trak->composition_offset_entries; |
2314 entry = (ngx_mp4_ctts_entry_t *) data->pos; | 2387 entry = (ngx_mp4_ctts_entry_t *) data->pos; |
2315 end = (ngx_mp4_ctts_entry_t *) data->last; | 2388 end = (ngx_mp4_ctts_entry_t *) data->last; |
2330 start_sample -= count; | 2403 start_sample -= count; |
2331 entries--; | 2404 entries--; |
2332 entry++; | 2405 entry++; |
2333 } | 2406 } |
2334 | 2407 |
2335 trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = NULL; | 2408 data->pos = (u_char *) end; |
2336 trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = NULL; | 2409 trak->composition_offset_entries = 0; |
2337 | 2410 |
2338 return; | 2411 return; |
2339 | 2412 |
2340 found: | 2413 found: |
2341 | 2414 |
2342 data->pos = (u_char *) entry; | 2415 data->pos = (u_char *) entry; |
2343 atom_size = sizeof(ngx_mp4_ctts_atom_t) + (data->last - data->pos); | 2416 trak->composition_offset_entries = entries; |
2344 trak->size += atom_size; | |
2345 | |
2346 atom = trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf; | |
2347 ctts_atom = (ngx_mp4_ctts_atom_t *) atom->pos; | |
2348 | |
2349 ngx_mp4_set_32value(ctts_atom->size, atom_size); | |
2350 ngx_mp4_set_32value(ctts_atom->entries, entries); | |
2351 | |
2352 return; | |
2353 } | 2417 } |
2354 | 2418 |
2355 | 2419 |
2356 typedef struct { | 2420 typedef struct { |
2357 u_char size[4]; | 2421 u_char size[4]; |
2426 static ngx_int_t | 2490 static ngx_int_t |
2427 ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, | 2491 ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, |
2428 ngx_http_mp4_trak_t *trak) | 2492 ngx_http_mp4_trak_t *trak) |
2429 { | 2493 { |
2430 size_t atom_size; | 2494 size_t atom_size; |
2431 uint32_t start_sample, entries, chunk, samples, id, | 2495 uint32_t chunk; |
2432 next_chunk, n; | 2496 ngx_buf_t *atom, *data; |
2433 ngx_buf_t *atom, *data, *buf; | |
2434 ngx_mp4_stsc_atom_t *stsc_atom; | 2497 ngx_mp4_stsc_atom_t *stsc_atom; |
2435 ngx_mp4_stsc_entry_t *entry, *first, *end; | 2498 ngx_mp4_stsc_entry_t *entry, *end; |
2436 | 2499 |
2437 /* | 2500 /* |
2438 * mdia.minf.stbl.stsc updating requires trak->start_sample | 2501 * mdia.minf.stbl.stsc updating requires trak->start_sample |
2439 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | 2502 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd |
2440 * atom which may reside after mdia.minf | 2503 * atom which may reside after mdia.minf |
2457 "zero number of entries in stsc atom in \"%s\"", | 2520 "zero number of entries in stsc atom in \"%s\"", |
2458 mp4->file.name.data); | 2521 mp4->file.name.data); |
2459 return NGX_ERROR; | 2522 return NGX_ERROR; |
2460 } | 2523 } |
2461 | 2524 |
2525 if (ngx_http_mp4_crop_stsc_data(mp4, trak) != NGX_OK) { | |
2526 return NGX_ERROR; | |
2527 } | |
2528 | |
2529 entry = (ngx_mp4_stsc_entry_t *) data->pos; | |
2530 end = (ngx_mp4_stsc_entry_t *) data->last; | |
2531 | |
2532 while (entry < end) { | |
2533 chunk = ngx_mp4_get_32value(entry->chunk); | |
2534 chunk -= trak->start_chunk; | |
2535 ngx_mp4_set_32value(entry->chunk, chunk); | |
2536 entry++; | |
2537 } | |
2538 | |
2539 atom_size = sizeof(ngx_mp4_stsc_atom_t) | |
2540 + trak->sample_to_chunk_entries * sizeof(ngx_mp4_stsc_entry_t); | |
2541 | |
2542 trak->size += atom_size; | |
2543 | |
2544 atom = trak->out[NGX_HTTP_MP4_STSC_ATOM].buf; | |
2545 stsc_atom = (ngx_mp4_stsc_atom_t *) atom->pos; | |
2546 | |
2547 ngx_mp4_set_32value(stsc_atom->size, atom_size); | |
2548 ngx_mp4_set_32value(stsc_atom->entries, trak->sample_to_chunk_entries); | |
2549 | |
2550 return NGX_OK; | |
2551 } | |
2552 | |
2553 | |
2554 static ngx_int_t | |
2555 ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, | |
2556 ngx_http_mp4_trak_t *trak) | |
2557 { | |
2558 uint32_t start_sample, chunk, samples, id, next_chunk, n; | |
2559 ngx_buf_t *data, *buf; | |
2560 ngx_uint_t entries, target_chunk, chunk_samples; | |
2561 ngx_mp4_stsc_entry_t *entry, *end, *first; | |
2562 | |
2563 data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf; | |
2564 | |
2462 start_sample = (uint32_t) trak->start_sample; | 2565 start_sample = (uint32_t) trak->start_sample; |
2463 entries = trak->sample_to_chunk_entries - 1; | 2566 entries = trak->sample_to_chunk_entries - 1; |
2464 | 2567 |
2465 entry = (ngx_mp4_stsc_entry_t *) data->pos; | 2568 entry = (ngx_mp4_stsc_entry_t *) data->pos; |
2466 end = (ngx_mp4_stsc_entry_t *) data->last; | 2569 end = (ngx_mp4_stsc_entry_t *) data->last; |
2519 "zero number of samples in \"%s\"", | 2622 "zero number of samples in \"%s\"", |
2520 mp4->file.name.data); | 2623 mp4->file.name.data); |
2521 return NGX_ERROR; | 2624 return NGX_ERROR; |
2522 } | 2625 } |
2523 | 2626 |
2524 trak->start_chunk = chunk - 1; | 2627 target_chunk = chunk - 1; |
2525 | 2628 target_chunk += start_sample / samples; |
2526 trak->start_chunk += start_sample / samples; | 2629 chunk_samples = start_sample % samples; |
2527 trak->chunk_samples = start_sample % samples; | |
2528 | 2630 |
2529 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 2631 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
2530 "start chunk:%ui, samples:%uD", | 2632 "start chunk:%ui, samples:%uD", |
2531 trak->start_chunk, trak->chunk_samples); | 2633 target_chunk, chunk_samples); |
2532 | 2634 |
2533 data->pos = (u_char *) entry; | 2635 data->pos = (u_char *) entry; |
2534 atom_size = sizeof(ngx_mp4_stsc_atom_t) + (data->last - data->pos); | 2636 |
2535 | 2637 trak->start_chunk = target_chunk; |
2536 ngx_mp4_set_32value(entry->chunk, 1); | 2638 trak->chunk_samples = chunk_samples; |
2537 | 2639 |
2538 if (trak->chunk_samples && next_chunk - trak->start_chunk == 2) { | 2640 ngx_mp4_set_32value(entry->chunk, trak->start_chunk + 1); |
2539 | 2641 |
2540 /* last chunk in the entry */ | 2642 samples -= chunk_samples; |
2541 | 2643 |
2542 ngx_mp4_set_32value(entry->samples, samples - trak->chunk_samples); | 2644 if (chunk_samples && next_chunk - target_chunk == 2) { |
2543 | 2645 |
2544 } else if (trak->chunk_samples) { | 2646 ngx_mp4_set_32value(entry->samples, samples); |
2647 | |
2648 } else if (chunk_samples) { | |
2545 | 2649 |
2546 first = &trak->stsc_chunk_entry; | 2650 first = &trak->stsc_chunk_entry; |
2547 ngx_mp4_set_32value(first->chunk, 1); | 2651 ngx_mp4_set_32value(first->chunk, 1); |
2548 ngx_mp4_set_32value(first->samples, samples - trak->chunk_samples); | 2652 ngx_mp4_set_32value(first->samples, samples); |
2549 ngx_mp4_set_32value(first->id, id); | 2653 ngx_mp4_set_32value(first->id, id); |
2550 | 2654 |
2551 buf = &trak->stsc_chunk_buf; | 2655 buf = &trak->stsc_chunk_buf; |
2552 buf->temporary = 1; | 2656 buf->temporary = 1; |
2553 buf->pos = (u_char *) first; | 2657 buf->pos = (u_char *) first; |
2554 buf->last = (u_char *) first + sizeof(ngx_mp4_stsc_entry_t); | 2658 buf->last = (u_char *) first + sizeof(ngx_mp4_stsc_entry_t); |
2555 | 2659 |
2556 trak->out[NGX_HTTP_MP4_STSC_CHUNK].buf = buf; | 2660 trak->out[NGX_HTTP_MP4_STSC_CHUNK].buf = buf; |
2557 | 2661 |
2558 ngx_mp4_set_32value(entry->chunk, 2); | 2662 ngx_mp4_set_32value(entry->chunk, trak->start_chunk + 2); |
2559 | 2663 |
2560 entries++; | 2664 entries++; |
2561 atom_size += sizeof(ngx_mp4_stsc_entry_t); | 2665 } |
2562 } | 2666 |
2563 | 2667 trak->sample_to_chunk_entries = entries; |
2564 while (++entry < end) { | |
2565 chunk = ngx_mp4_get_32value(entry->chunk); | |
2566 chunk -= trak->start_chunk; | |
2567 ngx_mp4_set_32value(entry->chunk, chunk); | |
2568 } | |
2569 | |
2570 trak->size += atom_size; | |
2571 | |
2572 atom = trak->out[NGX_HTTP_MP4_STSC_ATOM].buf; | |
2573 stsc_atom = (ngx_mp4_stsc_atom_t *) atom->pos; | |
2574 | |
2575 ngx_mp4_set_32value(stsc_atom->size, atom_size); | |
2576 ngx_mp4_set_32value(stsc_atom->entries, entries); | |
2577 | 2668 |
2578 return NGX_OK; | 2669 return NGX_OK; |
2579 } | 2670 } |
2580 | 2671 |
2581 | 2672 |