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