comparison src/http/modules/ngx_http_mp4_module.c @ 5543:5730c0193842

Mp4: skip tracks shorter than seek position (ticket #414). Mp4 module does not check movie and track durations when reading file. Instead it generates errors when track metadata is shorter than seek position. Now such tracks are skipped and movie duration check is performed at file read stage.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 29 Jan 2014 13:33:45 +0400
parents 847c308917af
children 2f586f1684fa
comparison
equal deleted inserted replaced
5542:847c308917af 5543:5730c0193842
1206 ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 1206 ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
1207 { 1207 {
1208 u_char *atom_header; 1208 u_char *atom_header;
1209 size_t atom_size; 1209 size_t atom_size;
1210 uint32_t timescale; 1210 uint32_t timescale;
1211 uint64_t duration; 1211 uint64_t duration, start_time;
1212 ngx_buf_t *atom; 1212 ngx_buf_t *atom;
1213 ngx_mp4_mvhd_atom_t *mvhd_atom; 1213 ngx_mp4_mvhd_atom_t *mvhd_atom;
1214 ngx_mp4_mvhd64_atom_t *mvhd64_atom; 1214 ngx_mp4_mvhd64_atom_t *mvhd64_atom;
1215 1215
1216 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom"); 1216 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom");
1249 1249
1250 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 1250 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1251 "mvhd timescale:%uD, duration:%uL, time:%.3fs", 1251 "mvhd timescale:%uD, duration:%uL, time:%.3fs",
1252 timescale, duration, (double) duration / timescale); 1252 timescale, duration, (double) duration / timescale);
1253 1253
1254 duration -= (uint64_t) mp4->start * timescale / 1000; 1254 start_time = (uint64_t) mp4->start * timescale / 1000;
1255
1256 if (duration < start_time) {
1257 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1258 "\"%s\" mp4 start time exceeds file duration",
1259 mp4->file.name.data);
1260 return NGX_ERROR;
1261 }
1262
1263 duration -= start_time;
1255 1264
1256 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 1265 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1257 "mvhd new duration:%uL, time:%.3fs", 1266 "mvhd new duration:%uL, time:%.3fs",
1258 duration, (double) duration / timescale); 1267 duration, (double) duration / timescale);
1259 1268
1396 static ngx_int_t 1405 static ngx_int_t
1397 ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 1406 ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
1398 { 1407 {
1399 u_char *atom_header; 1408 u_char *atom_header;
1400 size_t atom_size; 1409 size_t atom_size;
1401 uint64_t duration; 1410 uint64_t duration, start_time;
1402 ngx_buf_t *atom; 1411 ngx_buf_t *atom;
1403 ngx_http_mp4_trak_t *trak; 1412 ngx_http_mp4_trak_t *trak;
1404 ngx_mp4_tkhd_atom_t *tkhd_atom; 1413 ngx_mp4_tkhd_atom_t *tkhd_atom;
1405 ngx_mp4_tkhd64_atom_t *tkhd64_atom; 1414 ngx_mp4_tkhd64_atom_t *tkhd64_atom;
1406 1415
1436 1445
1437 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 1446 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1438 "tkhd duration:%uL, time:%.3fs", 1447 "tkhd duration:%uL, time:%.3fs",
1439 duration, (double) duration / mp4->timescale); 1448 duration, (double) duration / mp4->timescale);
1440 1449
1441 duration -= (uint64_t) mp4->start * mp4->timescale / 1000; 1450 start_time = (uint64_t) mp4->start * mp4->timescale / 1000;
1451
1452 if (duration < start_time) {
1453 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1454 "tkhd duration is less than start time");
1455 return NGX_DECLINED;
1456 }
1457
1458 duration -= start_time;
1442 1459
1443 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 1460 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1444 "tkhd new duration:%uL, time:%.3fs", 1461 "tkhd new duration:%uL, time:%.3fs",
1445 duration, (double) duration / mp4->timescale); 1462 duration, (double) duration / mp4->timescale);
1446 1463
1539 ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 1556 ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
1540 { 1557 {
1541 u_char *atom_header; 1558 u_char *atom_header;
1542 size_t atom_size; 1559 size_t atom_size;
1543 uint32_t timescale; 1560 uint32_t timescale;
1544 uint64_t duration; 1561 uint64_t duration, start_time;
1545 ngx_buf_t *atom; 1562 ngx_buf_t *atom;
1546 ngx_http_mp4_trak_t *trak; 1563 ngx_http_mp4_trak_t *trak;
1547 ngx_mp4_mdhd_atom_t *mdhd_atom; 1564 ngx_mp4_mdhd_atom_t *mdhd_atom;
1548 ngx_mp4_mdhd64_atom_t *mdhd64_atom; 1565 ngx_mp4_mdhd64_atom_t *mdhd64_atom;
1549 1566
1581 1598
1582 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 1599 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1583 "mdhd timescale:%uD, duration:%uL, time:%.3fs", 1600 "mdhd timescale:%uD, duration:%uL, time:%.3fs",
1584 timescale, duration, (double) duration / timescale); 1601 timescale, duration, (double) duration / timescale);
1585 1602
1586 duration -= (uint64_t) mp4->start * timescale / 1000; 1603 start_time = (uint64_t) mp4->start * timescale / 1000;
1604
1605 if (duration < start_time) {
1606 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1607 "mdhd duration is less than start time");
1608 return NGX_DECLINED;
1609 }
1610
1611 duration -= start_time;
1587 1612
1588 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, 1613 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1589 "mdhd new duration:%uL, time:%.3fs", 1614 "mdhd new duration:%uL, time:%.3fs",
1590 duration, (double) duration / timescale); 1615 duration, (double) duration / timescale);
1591 1616