comparison src/http/modules/ngx_http_mp4_module.c @ 4099:9ee6944590c0

Skipping traks with unsupported media formats.
author Igor Sysoev <igor@sysoev.ru>
date Wed, 14 Sep 2011 14:04:41 +0000
parents a3e07fab98a3
children b1e19ba949fa
comparison
equal deleted inserted replaced
4098:a3e07fab98a3 4099:9ee6944590c0
1176 1176
1177 1177
1178 static ngx_int_t 1178 static ngx_int_t
1179 ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 1179 ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
1180 { 1180 {
1181 u_char *atom_header; 1181 u_char *atom_header, *atom_end;
1182 off_t atom_file_end;
1183 ngx_int_t rc;
1182 ngx_buf_t *atom; 1184 ngx_buf_t *atom;
1183 ngx_http_mp4_trak_t *trak; 1185 ngx_http_mp4_trak_t *trak;
1184 1186
1185 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 trak atom"); 1187 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 trak atom");
1186 1188
1199 atom->pos = atom_header; 1201 atom->pos = atom_header;
1200 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); 1202 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
1201 1203
1202 trak->out[NGX_HTTP_MP4_TRAK_ATOM].buf = atom; 1204 trak->out[NGX_HTTP_MP4_TRAK_ATOM].buf = atom;
1203 1205
1204 return ngx_http_mp4_read_atom(mp4, ngx_http_mp4_trak_atoms, atom_data_size); 1206 atom_end = mp4->buffer_pos + atom_data_size;
1207 atom_file_end = mp4->offset + atom_data_size;
1208
1209 rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_trak_atoms, atom_data_size);
1210
1211 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1212 "mp4 trak atom: %i", rc);
1213
1214 if (rc == NGX_DECLINED) {
1215 /* skip this trak */
1216 ngx_memzero(trak, sizeof(ngx_http_mp4_trak_t));
1217 mp4->trak.nelts--;
1218 mp4->buffer_pos = atom_end;
1219 mp4->offset = atom_file_end;
1220 return NGX_OK;
1221 }
1222
1223 return rc;
1205 } 1224 }
1206 1225
1207 1226
1208 static void 1227 static void
1209 ngx_http_mp4_update_trak_atom(ngx_http_mp4_file_t *mp4, 1228 ngx_http_mp4_update_trak_atom(ngx_http_mp4_file_t *mp4,
1670 u_char size[4]; 1689 u_char size[4];
1671 u_char name[4]; 1690 u_char name[4];
1672 u_char version[1]; 1691 u_char version[1];
1673 u_char flags[3]; 1692 u_char flags[3];
1674 u_char entries[4]; 1693 u_char entries[4];
1694
1695 u_char media_size[4];
1696 u_char media_name[4];
1675 } ngx_mp4_stsd_atom_t; 1697 } ngx_mp4_stsd_atom_t;
1676 1698
1677 1699
1678 static ngx_int_t 1700 static ngx_int_t
1679 ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 1701 ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
1680 { 1702 {
1681 u_char *atom_header, *atom_table; 1703 u_char *atom_header, *atom_table;
1682 size_t atom_size; 1704 size_t atom_size;
1705 uint32_t entries;
1683 ngx_buf_t *atom; 1706 ngx_buf_t *atom;
1684 ngx_mp4_stsd_atom_t *stsd_atom; 1707 ngx_mp4_stsd_atom_t *stsd_atom;
1685 ngx_http_mp4_trak_t *trak; 1708 ngx_http_mp4_trak_t *trak;
1686 1709
1687 /* sample description atom */ 1710 /* sample description atom */
1693 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; 1716 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
1694 atom_table = atom_header + atom_size; 1717 atom_table = atom_header + atom_size;
1695 ngx_mp4_set_32value(stsd_atom->size, atom_size); 1718 ngx_mp4_set_32value(stsd_atom->size, atom_size);
1696 ngx_mp4_set_atom_name(stsd_atom, 's', 't', 's', 'd'); 1719 ngx_mp4_set_atom_name(stsd_atom, 's', 't', 's', 'd');
1697 1720
1698 #if (NGX_DEBUG) 1721 entries = ngx_mp4_get_32value(stsd_atom->entries);
1722
1723 if ((uint64_t) (sizeof(ngx_mp4_stsd_atom_t) - sizeof(ngx_mp4_atom_header_t))
1724 > atom_data_size) {
1725 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
1726 "\"%s\" mp4 stsd atom too large",
1727 mp4->file.name.data);
1728 return NGX_ERROR;
1729 }
1730
1731 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1732 "stsd entries:%uD, media:%*s",
1733 ngx_mp4_get_32value(stsd_atom->entries),
1734 4, stsd_atom->media_name);
1735
1736 /* supported media format: "avc1" (H.264) and "mp4a" (MPEG-4/AAC) */
1737
1738 if (ngx_strncmp(stsd_atom->media_name, "avc1", 4) != 0
1739 && ngx_strncmp(stsd_atom->media_name, "mp4a", 4) != 0)
1699 { 1740 {
1700 uint32_t entries; 1741 return NGX_DECLINED;
1701 1742 }
1702 entries = ngx_mp4_get_32value(stsd_atom->entries);
1703
1704 if (entries) {
1705 /* codecs of interest: avc1 (H.264), mp4a (MPEG-4 audio) */
1706
1707 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
1708 "stsd entries:%uD, codec:%*s",
1709 entries, 4,
1710 atom_header + sizeof(ngx_mp4_stsd_atom_t) + 4);
1711
1712 }
1713 }
1714 #endif
1715 1743
1716 trak = ngx_mp4_last_trak(mp4); 1744 trak = ngx_mp4_last_trak(mp4);
1717 1745
1718 atom = &trak->stsd_atom_buf; 1746 atom = &trak->stsd_atom_buf;
1719 atom->temporary = 1; 1747 atom->temporary = 1;