Mercurial > hg > nginx
annotate src/http/modules/ngx_http_mp4_module.c @ 7629:f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
In "co64" atom chunk start offset is a 64-bit unsigned integer. When trimming
the "mdat" atom, chunk offsets are casted to off_t values which are typically
64-bit signed integers. A specially crafted mp4 file with huge chunk offsets
may lead to off_t overflow and result in negative trim boundaries.
The consequences of the overflow are:
- Incorrect Content-Length header value in the response.
- Negative left boundary of the response file buffer holding the trimmed "mdat".
This leads to pread()/sendfile() errors followed by closing the client
connection.
On rare systems where off_t is a 32-bit integer, this scenario is also feasible
with the "stco" atom.
The fix is to add checks which make sure data chunks referenced by each track
are within the mp4 file boundaries. Additionally a few more checks are added to
ensure mp4 file consistency and log errors.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 26 Feb 2020 15:10:46 +0300 |
parents | be5cb9c67c05 |
children | 7a55311b0dc3 |
rev | line source |
---|---|
4085 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
4085 | 5 */ |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
12 #define NGX_HTTP_MP4_TRAK_ATOM 0 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
13 #define NGX_HTTP_MP4_TKHD_ATOM 1 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
14 #define NGX_HTTP_MP4_MDIA_ATOM 2 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
15 #define NGX_HTTP_MP4_MDHD_ATOM 3 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
16 #define NGX_HTTP_MP4_HDLR_ATOM 4 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
17 #define NGX_HTTP_MP4_MINF_ATOM 5 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
18 #define NGX_HTTP_MP4_VMHD_ATOM 6 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
19 #define NGX_HTTP_MP4_SMHD_ATOM 7 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
20 #define NGX_HTTP_MP4_DINF_ATOM 8 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
21 #define NGX_HTTP_MP4_STBL_ATOM 9 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
22 #define NGX_HTTP_MP4_STSD_ATOM 10 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
23 #define NGX_HTTP_MP4_STTS_ATOM 11 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
24 #define NGX_HTTP_MP4_STTS_DATA 12 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
25 #define NGX_HTTP_MP4_STSS_ATOM 13 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
26 #define NGX_HTTP_MP4_STSS_DATA 14 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
27 #define NGX_HTTP_MP4_CTTS_ATOM 15 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
28 #define NGX_HTTP_MP4_CTTS_DATA 16 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
29 #define NGX_HTTP_MP4_STSC_ATOM 17 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
30 #define NGX_HTTP_MP4_STSC_START 18 |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
31 #define NGX_HTTP_MP4_STSC_DATA 19 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
32 #define NGX_HTTP_MP4_STSC_END 20 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
33 #define NGX_HTTP_MP4_STSZ_ATOM 21 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
34 #define NGX_HTTP_MP4_STSZ_DATA 22 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
35 #define NGX_HTTP_MP4_STCO_ATOM 23 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
36 #define NGX_HTTP_MP4_STCO_DATA 24 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
37 #define NGX_HTTP_MP4_CO64_ATOM 25 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
38 #define NGX_HTTP_MP4_CO64_DATA 26 |
4112 | 39 |
40 #define NGX_HTTP_MP4_LAST_ATOM NGX_HTTP_MP4_CO64_DATA | |
4085 | 41 |
42 | |
43 typedef struct { | |
44 size_t buffer_size; | |
4089
e27670e1ab70
mp4_max_moov_size directive has been renamed to mp4_max_buffer_size.
Igor Sysoev <igor@sysoev.ru>
parents:
4088
diff
changeset
|
45 size_t max_buffer_size; |
4085 | 46 } ngx_http_mp4_conf_t; |
47 | |
48 | |
49 typedef struct { | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
50 u_char chunk[4]; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
51 u_char samples[4]; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
52 u_char id[4]; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
53 } ngx_mp4_stsc_entry_t; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
54 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
55 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
56 typedef struct { |
4085 | 57 uint32_t timescale; |
58 uint32_t time_to_sample_entries; | |
59 uint32_t sample_to_chunk_entries; | |
60 uint32_t sync_samples_entries; | |
61 uint32_t composition_offset_entries; | |
62 uint32_t sample_sizes_entries; | |
63 uint32_t chunks; | |
64 | |
65 ngx_uint_t start_sample; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
66 ngx_uint_t end_sample; |
4085 | 67 ngx_uint_t start_chunk; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
68 ngx_uint_t end_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
69 ngx_uint_t start_chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
70 ngx_uint_t end_chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
71 uint64_t start_chunk_samples_size; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
72 uint64_t end_chunk_samples_size; |
4085 | 73 off_t start_offset; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
74 off_t end_offset; |
4085 | 75 |
76 size_t tkhd_size; | |
77 size_t mdhd_size; | |
78 size_t hdlr_size; | |
79 size_t vmhd_size; | |
80 size_t smhd_size; | |
81 size_t dinf_size; | |
82 size_t size; | |
83 | |
84 ngx_chain_t out[NGX_HTTP_MP4_LAST_ATOM + 1]; | |
85 | |
86 ngx_buf_t trak_atom_buf; | |
87 ngx_buf_t tkhd_atom_buf; | |
88 ngx_buf_t mdia_atom_buf; | |
89 ngx_buf_t mdhd_atom_buf; | |
90 ngx_buf_t hdlr_atom_buf; | |
91 ngx_buf_t minf_atom_buf; | |
92 ngx_buf_t vmhd_atom_buf; | |
93 ngx_buf_t smhd_atom_buf; | |
94 ngx_buf_t dinf_atom_buf; | |
95 ngx_buf_t stbl_atom_buf; | |
96 ngx_buf_t stsd_atom_buf; | |
97 ngx_buf_t stts_atom_buf; | |
98 ngx_buf_t stts_data_buf; | |
99 ngx_buf_t stss_atom_buf; | |
100 ngx_buf_t stss_data_buf; | |
101 ngx_buf_t ctts_atom_buf; | |
102 ngx_buf_t ctts_data_buf; | |
103 ngx_buf_t stsc_atom_buf; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
104 ngx_buf_t stsc_start_chunk_buf; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
105 ngx_buf_t stsc_end_chunk_buf; |
4085 | 106 ngx_buf_t stsc_data_buf; |
107 ngx_buf_t stsz_atom_buf; | |
108 ngx_buf_t stsz_data_buf; | |
4107 | 109 ngx_buf_t stco_atom_buf; |
110 ngx_buf_t stco_data_buf; | |
4112 | 111 ngx_buf_t co64_atom_buf; |
112 ngx_buf_t co64_data_buf; | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
113 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
114 ngx_mp4_stsc_entry_t stsc_start_chunk_entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
115 ngx_mp4_stsc_entry_t stsc_end_chunk_entry; |
4085 | 116 } ngx_http_mp4_trak_t; |
117 | |
118 | |
119 typedef struct { | |
120 ngx_file_t file; | |
121 | |
122 u_char *buffer; | |
123 u_char *buffer_start; | |
124 u_char *buffer_pos; | |
125 u_char *buffer_end; | |
126 size_t buffer_size; | |
127 | |
128 off_t offset; | |
129 off_t end; | |
130 off_t content_length; | |
131 ngx_uint_t start; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
132 ngx_uint_t length; |
4085 | 133 uint32_t timescale; |
134 ngx_http_request_t *request; | |
135 ngx_array_t trak; | |
136 ngx_http_mp4_trak_t traks[2]; | |
137 | |
138 size_t ftyp_size; | |
139 size_t moov_size; | |
140 | |
141 ngx_chain_t *out; | |
142 ngx_chain_t ftyp_atom; | |
143 ngx_chain_t moov_atom; | |
144 ngx_chain_t mvhd_atom; | |
145 ngx_chain_t mdat_atom; | |
146 ngx_chain_t mdat_data; | |
147 | |
148 ngx_buf_t ftyp_atom_buf; | |
149 ngx_buf_t moov_atom_buf; | |
150 ngx_buf_t mvhd_atom_buf; | |
151 ngx_buf_t mdat_atom_buf; | |
152 ngx_buf_t mdat_data_buf; | |
153 | |
154 u_char moov_atom_header[8]; | |
155 u_char mdat_atom_header[16]; | |
156 } ngx_http_mp4_file_t; | |
157 | |
158 | |
159 typedef struct { | |
160 char *name; | |
161 ngx_int_t (*handler)(ngx_http_mp4_file_t *mp4, | |
162 uint64_t atom_data_size); | |
163 } ngx_http_mp4_atom_handler_t; | |
164 | |
165 | |
166 #define ngx_mp4_atom_header(mp4) (mp4->buffer_pos - 8) | |
167 #define ngx_mp4_atom_data(mp4) mp4->buffer_pos | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
168 #define ngx_mp4_atom_data_size(t) (uint64_t) (sizeof(t) - 8) |
5359
2fda9065d0f4
Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5358
diff
changeset
|
169 |
2fda9065d0f4
Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5358
diff
changeset
|
170 |
2fda9065d0f4
Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5358
diff
changeset
|
171 #define ngx_mp4_atom_next(mp4, n) \ |
7400
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
172 \ |
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
173 if (n > (size_t) (mp4->buffer_end - mp4->buffer_pos)) { \ |
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
174 mp4->buffer_pos = mp4->buffer_end; \ |
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
175 \ |
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
176 } else { \ |
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
177 mp4->buffer_pos += (size_t) n; \ |
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
178 } \ |
be5cb9c67c05
Mp4: fixed possible pointer overflow on 32-bit platforms.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7376
diff
changeset
|
179 \ |
5359
2fda9065d0f4
Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5358
diff
changeset
|
180 mp4->offset += n |
4085 | 181 |
182 | |
183 #define ngx_mp4_set_atom_name(p, n1, n2, n3, n4) \ | |
184 ((u_char *) (p))[4] = n1; \ | |
185 ((u_char *) (p))[5] = n2; \ | |
186 ((u_char *) (p))[6] = n3; \ | |
187 ((u_char *) (p))[7] = n4 | |
188 | |
189 #define ngx_mp4_get_32value(p) \ | |
4402
b20019ecfdcc
Fixed handling of mp4 above 2G and 32bit offsets (ticket #84).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4382
diff
changeset
|
190 ( ((uint32_t) ((u_char *) (p))[0] << 24) \ |
b20019ecfdcc
Fixed handling of mp4 above 2G and 32bit offsets (ticket #84).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4382
diff
changeset
|
191 + ( ((u_char *) (p))[1] << 16) \ |
b20019ecfdcc
Fixed handling of mp4 above 2G and 32bit offsets (ticket #84).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4382
diff
changeset
|
192 + ( ((u_char *) (p))[2] << 8) \ |
b20019ecfdcc
Fixed handling of mp4 above 2G and 32bit offsets (ticket #84).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4382
diff
changeset
|
193 + ( ((u_char *) (p))[3]) ) |
4085 | 194 |
195 #define ngx_mp4_set_32value(p, n) \ | |
196 ((u_char *) (p))[0] = (u_char) ((n) >> 24); \ | |
197 ((u_char *) (p))[1] = (u_char) ((n) >> 16); \ | |
198 ((u_char *) (p))[2] = (u_char) ((n) >> 8); \ | |
199 ((u_char *) (p))[3] = (u_char) (n) | |
200 | |
201 #define ngx_mp4_get_64value(p) \ | |
202 ( ((uint64_t) ((u_char *) (p))[0] << 56) \ | |
203 + ((uint64_t) ((u_char *) (p))[1] << 48) \ | |
204 + ((uint64_t) ((u_char *) (p))[2] << 40) \ | |
205 + ((uint64_t) ((u_char *) (p))[3] << 32) \ | |
206 + ((uint64_t) ((u_char *) (p))[4] << 24) \ | |
207 + ( ((u_char *) (p))[5] << 16) \ | |
208 + ( ((u_char *) (p))[6] << 8) \ | |
209 + ( ((u_char *) (p))[7]) ) | |
210 | |
211 #define ngx_mp4_set_64value(p, n) \ | |
4155
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
212 ((u_char *) (p))[0] = (u_char) ((uint64_t) (n) >> 56); \ |
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
213 ((u_char *) (p))[1] = (u_char) ((uint64_t) (n) >> 48); \ |
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
214 ((u_char *) (p))[2] = (u_char) ((uint64_t) (n) >> 40); \ |
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
215 ((u_char *) (p))[3] = (u_char) ((uint64_t) (n) >> 32); \ |
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
216 ((u_char *) (p))[4] = (u_char) ( (n) >> 24); \ |
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
217 ((u_char *) (p))[5] = (u_char) ( (n) >> 16); \ |
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
218 ((u_char *) (p))[6] = (u_char) ( (n) >> 8); \ |
d9636bf3f159
Fix of building on platforms with 32-bit off_t. (closed #23)
Igor Sysoev <igor@sysoev.ru>
parents:
4112
diff
changeset
|
219 ((u_char *) (p))[7] = (u_char) (n) |
4085 | 220 |
221 #define ngx_mp4_last_trak(mp4) \ | |
222 &((ngx_http_mp4_trak_t *) mp4->trak.elts)[mp4->trak.nelts - 1] | |
223 | |
224 | |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
225 static ngx_int_t ngx_http_mp4_handler(ngx_http_request_t *r); |
6782
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
226 static ngx_int_t ngx_http_mp4_atofp(u_char *line, size_t n, size_t point); |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
227 |
4085 | 228 static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4); |
229 static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4, | |
230 ngx_http_mp4_atom_handler_t *atom, uint64_t atom_data_size); | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
231 static ngx_int_t ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size); |
4085 | 232 static ngx_int_t ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, |
233 uint64_t atom_data_size); | |
234 static ngx_int_t ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, | |
235 uint64_t atom_data_size); | |
236 static ngx_int_t ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, | |
237 uint64_t atom_data_size); | |
238 static size_t ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4, | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
239 off_t start_offset, off_t end_offset); |
4085 | 240 static ngx_int_t ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, |
241 uint64_t atom_data_size); | |
242 static ngx_int_t ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4, | |
243 uint64_t atom_data_size); | |
244 static void ngx_http_mp4_update_trak_atom(ngx_http_mp4_file_t *mp4, | |
245 ngx_http_mp4_trak_t *trak); | |
246 static ngx_int_t ngx_http_mp4_read_cmov_atom(ngx_http_mp4_file_t *mp4, | |
247 uint64_t atom_data_size); | |
248 static ngx_int_t ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, | |
249 uint64_t atom_data_size); | |
250 static ngx_int_t ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4, | |
251 uint64_t atom_data_size); | |
252 static void ngx_http_mp4_update_mdia_atom(ngx_http_mp4_file_t *mp4, | |
253 ngx_http_mp4_trak_t *trak); | |
254 static ngx_int_t ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, | |
255 uint64_t atom_data_size); | |
256 static ngx_int_t ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, | |
257 uint64_t atom_data_size); | |
258 static ngx_int_t ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4, | |
259 uint64_t atom_data_size); | |
260 static void ngx_http_mp4_update_minf_atom(ngx_http_mp4_file_t *mp4, | |
261 ngx_http_mp4_trak_t *trak); | |
262 static ngx_int_t ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4, | |
263 uint64_t atom_data_size); | |
264 static ngx_int_t ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4, | |
265 uint64_t atom_data_size); | |
266 static ngx_int_t ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, | |
267 uint64_t atom_data_size); | |
268 static ngx_int_t ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, | |
269 uint64_t atom_data_size); | |
270 static void ngx_http_mp4_update_stbl_atom(ngx_http_mp4_file_t *mp4, | |
271 ngx_http_mp4_trak_t *trak); | |
272 static ngx_int_t ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, | |
273 uint64_t atom_data_size); | |
274 static ngx_int_t ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, | |
275 uint64_t atom_data_size); | |
276 static ngx_int_t ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4, | |
277 ngx_http_mp4_trak_t *trak); | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
278 static ngx_int_t ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
279 ngx_http_mp4_trak_t *trak, ngx_uint_t start); |
4085 | 280 static ngx_int_t ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, |
281 uint64_t atom_data_size); | |
282 static ngx_int_t ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4, | |
283 ngx_http_mp4_trak_t *trak); | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
284 static void ngx_http_mp4_crop_stss_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
285 ngx_http_mp4_trak_t *trak, ngx_uint_t start); |
4085 | 286 static ngx_int_t ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, |
287 uint64_t atom_data_size); | |
288 static void ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4, | |
289 ngx_http_mp4_trak_t *trak); | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
290 static void ngx_http_mp4_crop_ctts_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
291 ngx_http_mp4_trak_t *trak, ngx_uint_t start); |
4085 | 292 static ngx_int_t ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, |
293 uint64_t atom_data_size); | |
294 static ngx_int_t ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, | |
295 ngx_http_mp4_trak_t *trak); | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
296 static ngx_int_t ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
297 ngx_http_mp4_trak_t *trak, ngx_uint_t start); |
4085 | 298 static ngx_int_t ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, |
299 uint64_t atom_data_size); | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
300 static ngx_int_t ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, |
4085 | 301 ngx_http_mp4_trak_t *trak); |
302 static ngx_int_t ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, | |
303 uint64_t atom_data_size); | |
304 static ngx_int_t ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4, | |
305 ngx_http_mp4_trak_t *trak); | |
306 static void ngx_http_mp4_adjust_stco_atom(ngx_http_mp4_file_t *mp4, | |
307 ngx_http_mp4_trak_t *trak, int32_t adjustment); | |
4112 | 308 static ngx_int_t ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, |
309 uint64_t atom_data_size); | |
310 static ngx_int_t ngx_http_mp4_update_co64_atom(ngx_http_mp4_file_t *mp4, | |
311 ngx_http_mp4_trak_t *trak); | |
312 static void ngx_http_mp4_adjust_co64_atom(ngx_http_mp4_file_t *mp4, | |
313 ngx_http_mp4_trak_t *trak, off_t adjustment); | |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
314 |
4085 | 315 static char *ngx_http_mp4(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
316 static void *ngx_http_mp4_create_conf(ngx_conf_t *cf); | |
317 static char *ngx_http_mp4_merge_conf(ngx_conf_t *cf, void *parent, void *child); | |
318 | |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
319 |
4085 | 320 static ngx_command_t ngx_http_mp4_commands[] = { |
321 | |
322 { ngx_string("mp4"), | |
323 NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, | |
324 ngx_http_mp4, | |
325 0, | |
326 0, | |
327 NULL }, | |
328 | |
329 { ngx_string("mp4_buffer_size"), | |
330 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
331 ngx_conf_set_size_slot, | |
332 NGX_HTTP_LOC_CONF_OFFSET, | |
333 offsetof(ngx_http_mp4_conf_t, buffer_size), | |
334 NULL }, | |
335 | |
4089
e27670e1ab70
mp4_max_moov_size directive has been renamed to mp4_max_buffer_size.
Igor Sysoev <igor@sysoev.ru>
parents:
4088
diff
changeset
|
336 { ngx_string("mp4_max_buffer_size"), |
4085 | 337 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
338 ngx_conf_set_size_slot, | |
339 NGX_HTTP_LOC_CONF_OFFSET, | |
4089
e27670e1ab70
mp4_max_moov_size directive has been renamed to mp4_max_buffer_size.
Igor Sysoev <igor@sysoev.ru>
parents:
4088
diff
changeset
|
340 offsetof(ngx_http_mp4_conf_t, max_buffer_size), |
4085 | 341 NULL }, |
342 | |
343 ngx_null_command | |
344 }; | |
345 | |
346 | |
347 static ngx_http_module_t ngx_http_mp4_module_ctx = { | |
348 NULL, /* preconfiguration */ | |
349 NULL, /* postconfiguration */ | |
350 | |
351 NULL, /* create main configuration */ | |
352 NULL, /* init main configuration */ | |
353 | |
354 NULL, /* create server configuration */ | |
355 NULL, /* merge server configuration */ | |
356 | |
357 ngx_http_mp4_create_conf, /* create location configuration */ | |
358 ngx_http_mp4_merge_conf /* merge location configuration */ | |
359 }; | |
360 | |
361 | |
362 ngx_module_t ngx_http_mp4_module = { | |
363 NGX_MODULE_V1, | |
364 &ngx_http_mp4_module_ctx, /* module context */ | |
365 ngx_http_mp4_commands, /* module directives */ | |
366 NGX_HTTP_MODULE, /* module type */ | |
367 NULL, /* init master */ | |
368 NULL, /* init module */ | |
369 NULL, /* init process */ | |
370 NULL, /* init thread */ | |
371 NULL, /* exit thread */ | |
372 NULL, /* exit process */ | |
373 NULL, /* exit master */ | |
374 NGX_MODULE_V1_PADDING | |
375 }; | |
376 | |
377 | |
378 static ngx_http_mp4_atom_handler_t ngx_http_mp4_atoms[] = { | |
379 { "ftyp", ngx_http_mp4_read_ftyp_atom }, | |
380 { "moov", ngx_http_mp4_read_moov_atom }, | |
381 { "mdat", ngx_http_mp4_read_mdat_atom }, | |
382 { NULL, NULL } | |
383 }; | |
384 | |
385 static ngx_http_mp4_atom_handler_t ngx_http_mp4_moov_atoms[] = { | |
386 { "mvhd", ngx_http_mp4_read_mvhd_atom }, | |
387 { "trak", ngx_http_mp4_read_trak_atom }, | |
388 { "cmov", ngx_http_mp4_read_cmov_atom }, | |
389 { NULL, NULL } | |
390 }; | |
391 | |
392 static ngx_http_mp4_atom_handler_t ngx_http_mp4_trak_atoms[] = { | |
393 { "tkhd", ngx_http_mp4_read_tkhd_atom }, | |
394 { "mdia", ngx_http_mp4_read_mdia_atom }, | |
395 { NULL, NULL } | |
396 }; | |
397 | |
398 static ngx_http_mp4_atom_handler_t ngx_http_mp4_mdia_atoms[] = { | |
399 { "mdhd", ngx_http_mp4_read_mdhd_atom }, | |
400 { "hdlr", ngx_http_mp4_read_hdlr_atom }, | |
401 { "minf", ngx_http_mp4_read_minf_atom }, | |
402 { NULL, NULL } | |
403 }; | |
404 | |
405 static ngx_http_mp4_atom_handler_t ngx_http_mp4_minf_atoms[] = { | |
406 { "vmhd", ngx_http_mp4_read_vmhd_atom }, | |
407 { "smhd", ngx_http_mp4_read_smhd_atom }, | |
408 { "dinf", ngx_http_mp4_read_dinf_atom }, | |
409 { "stbl", ngx_http_mp4_read_stbl_atom }, | |
410 { NULL, NULL } | |
411 }; | |
412 | |
413 static ngx_http_mp4_atom_handler_t ngx_http_mp4_stbl_atoms[] = { | |
414 { "stsd", ngx_http_mp4_read_stsd_atom }, | |
415 { "stts", ngx_http_mp4_read_stts_atom }, | |
416 { "stss", ngx_http_mp4_read_stss_atom }, | |
417 { "ctts", ngx_http_mp4_read_ctts_atom }, | |
418 { "stsc", ngx_http_mp4_read_stsc_atom }, | |
419 { "stsz", ngx_http_mp4_read_stsz_atom }, | |
420 { "stco", ngx_http_mp4_read_stco_atom }, | |
4112 | 421 { "co64", ngx_http_mp4_read_co64_atom }, |
4085 | 422 { NULL, NULL } |
423 }; | |
424 | |
425 | |
426 static ngx_int_t | |
427 ngx_http_mp4_handler(ngx_http_request_t *r) | |
428 { | |
429 u_char *last; | |
430 size_t root; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
431 ngx_int_t rc, start, end; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
432 ngx_uint_t level, length; |
4085 | 433 ngx_str_t path, value; |
434 ngx_log_t *log; | |
435 ngx_buf_t *b; | |
436 ngx_chain_t out; | |
437 ngx_http_mp4_file_t *mp4; | |
438 ngx_open_file_info_t of; | |
439 ngx_http_core_loc_conf_t *clcf; | |
440 | |
441 if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { | |
442 return NGX_HTTP_NOT_ALLOWED; | |
443 } | |
444 | |
445 if (r->uri.data[r->uri.len - 1] == '/') { | |
446 return NGX_DECLINED; | |
447 } | |
448 | |
449 rc = ngx_http_discard_request_body(r); | |
450 | |
451 if (rc != NGX_OK) { | |
452 return rc; | |
453 } | |
454 | |
455 last = ngx_http_map_uri_to_path(r, &path, &root, 0); | |
456 if (last == NULL) { | |
457 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
458 } | |
459 | |
460 log = r->connection->log; | |
461 | |
462 path.len = last - path.data; | |
463 | |
464 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | |
465 "http mp4 filename: \"%V\"", &path); | |
466 | |
467 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
468 | |
469 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); | |
470 | |
471 of.read_ahead = clcf->read_ahead; | |
4087
3aa3b7bb9f0d
Bugfix of r4086: directio was always enabled if mp4 file was sent as is.
Igor Sysoev <igor@sysoev.ru>
parents:
4085
diff
changeset
|
472 of.directio = NGX_MAX_OFF_T_VALUE; |
4085 | 473 of.valid = clcf->open_file_cache_valid; |
474 of.min_uses = clcf->open_file_cache_min_uses; | |
475 of.errors = clcf->open_file_cache_errors; | |
476 of.events = clcf->open_file_cache_events; | |
4494
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
477 |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
478 if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
479 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
480 } |
4085 | 481 |
482 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) | |
483 != NGX_OK) | |
484 { | |
485 switch (of.err) { | |
486 | |
487 case 0: | |
488 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
489 | |
490 case NGX_ENOENT: | |
491 case NGX_ENOTDIR: | |
492 case NGX_ENAMETOOLONG: | |
493 | |
494 level = NGX_LOG_ERR; | |
495 rc = NGX_HTTP_NOT_FOUND; | |
496 break; | |
497 | |
498 case NGX_EACCES: | |
4478
08713bac87fc
Support for disable_symlinks in various modules.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
499 #if (NGX_HAVE_OPENAT) |
08713bac87fc
Support for disable_symlinks in various modules.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
500 case NGX_EMLINK: |
08713bac87fc
Support for disable_symlinks in various modules.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
501 case NGX_ELOOP: |
08713bac87fc
Support for disable_symlinks in various modules.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
502 #endif |
4085 | 503 |
504 level = NGX_LOG_ERR; | |
505 rc = NGX_HTTP_FORBIDDEN; | |
506 break; | |
507 | |
508 default: | |
509 | |
510 level = NGX_LOG_CRIT; | |
511 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
512 break; | |
513 } | |
514 | |
515 if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) { | |
516 ngx_log_error(level, log, of.err, | |
517 "%s \"%s\" failed", of.failed, path.data); | |
518 } | |
519 | |
520 return rc; | |
521 } | |
522 | |
523 if (!of.is_file) { | |
524 | |
525 if (ngx_close_file(of.fd) == NGX_FILE_ERROR) { | |
526 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
527 ngx_close_file_n " \"%s\" failed", path.data); | |
528 } | |
529 | |
530 return NGX_DECLINED; | |
531 } | |
532 | |
533 r->root_tested = !r->error_page; | |
534 r->allow_ranges = 1; | |
535 | |
536 start = -1; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
537 length = 0; |
4085 | 538 r->headers_out.content_length_n = of.size; |
539 mp4 = NULL; | |
540 b = NULL; | |
541 | |
542 if (r->args.len) { | |
543 | |
544 if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) { | |
545 | |
4156
67a4654ba7d9
Using strtod() instead of atofp() to support a lot of digits after dot in
Igor Sysoev <igor@sysoev.ru>
parents:
4155
diff
changeset
|
546 /* |
67a4654ba7d9
Using strtod() instead of atofp() to support a lot of digits after dot in
Igor Sysoev <igor@sysoev.ru>
parents:
4155
diff
changeset
|
547 * A Flash player may send start value with a lot of digits |
6782
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
548 * after dot so a custom function is used instead of ngx_atofp(). |
4156
67a4654ba7d9
Using strtod() instead of atofp() to support a lot of digits after dot in
Igor Sysoev <igor@sysoev.ru>
parents:
4155
diff
changeset
|
549 */ |
67a4654ba7d9
Using strtod() instead of atofp() to support a lot of digits after dot in
Igor Sysoev <igor@sysoev.ru>
parents:
4155
diff
changeset
|
550 |
6782
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
551 start = ngx_http_mp4_atofp(value.data, value.len, 3); |
4085 | 552 } |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
553 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
554 if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
555 |
6782
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
556 end = ngx_http_mp4_atofp(value.data, value.len, 3); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
557 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
558 if (end > 0) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
559 if (start < 0) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
560 start = 0; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
561 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
562 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
563 if (end > start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
564 length = end - start; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
565 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
566 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
567 } |
4085 | 568 } |
569 | |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
570 if (start >= 0) { |
5621
345e4fd4bb64
Range filter: single_range flag in request.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5620
diff
changeset
|
571 r->single_range = 1; |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
572 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
573 mp4 = ngx_pcalloc(r->pool, sizeof(ngx_http_mp4_file_t)); |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
574 if (mp4 == NULL) { |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
575 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
576 } |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
577 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
578 mp4->file.fd = of.fd; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
579 mp4->file.name = path; |
5496
9d056f10fb99
Style: removed surplus semicolons.
Valentin Bartenev <vbart@nginx.com>
parents:
5359
diff
changeset
|
580 mp4->file.log = r->connection->log; |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
581 mp4->end = of.size; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
582 mp4->start = (ngx_uint_t) start; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
583 mp4->length = length; |
5202
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
584 mp4->request = r; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
585 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
586 switch (ngx_http_mp4_process(mp4)) { |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
587 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
588 case NGX_DECLINED: |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
589 if (mp4->buffer) { |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
590 ngx_pfree(r->pool, mp4->buffer); |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
591 } |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
592 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
593 ngx_pfree(r->pool, mp4); |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
594 mp4 = NULL; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
595 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
596 break; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
597 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
598 case NGX_OK: |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
599 r->headers_out.content_length_n = mp4->content_length; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
600 break; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
601 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
602 default: /* NGX_ERROR */ |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
603 if (mp4->buffer) { |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
604 ngx_pfree(r->pool, mp4->buffer); |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
605 } |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
606 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
607 ngx_pfree(r->pool, mp4); |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
608 |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
609 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
610 } |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
611 } |
322434f13bd8
Mp4: indentation and style, no functional changes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5097
diff
changeset
|
612 |
4085 | 613 log->action = "sending mp4 to client"; |
614 | |
615 if (clcf->directio <= of.size) { | |
616 | |
617 /* | |
618 * DIRECTIO is set on transfer only | |
619 * to allow kernel to cache "moov" atom | |
620 */ | |
621 | |
622 if (ngx_directio_on(of.fd) == NGX_FILE_ERROR) { | |
623 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
624 ngx_directio_on_n " \"%s\" failed", path.data); | |
625 } | |
626 | |
4087
3aa3b7bb9f0d
Bugfix of r4086: directio was always enabled if mp4 file was sent as is.
Igor Sysoev <igor@sysoev.ru>
parents:
4085
diff
changeset
|
627 of.is_directio = 1; |
3aa3b7bb9f0d
Bugfix of r4086: directio was always enabled if mp4 file was sent as is.
Igor Sysoev <igor@sysoev.ru>
parents:
4085
diff
changeset
|
628 |
4085 | 629 if (mp4) { |
630 mp4->file.directio = 1; | |
631 } | |
632 } | |
633 | |
634 r->headers_out.status = NGX_HTTP_OK; | |
635 r->headers_out.last_modified_time = of.mtime; | |
636 | |
4748
192f54280a7a
Entity tags: set for static respones.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4705
diff
changeset
|
637 if (ngx_http_set_etag(r) != NGX_OK) { |
192f54280a7a
Entity tags: set for static respones.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4705
diff
changeset
|
638 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
192f54280a7a
Entity tags: set for static respones.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4705
diff
changeset
|
639 } |
192f54280a7a
Entity tags: set for static respones.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4705
diff
changeset
|
640 |
4085 | 641 if (ngx_http_set_content_type(r) != NGX_OK) { |
642 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
643 } | |
644 | |
645 if (mp4 == NULL) { | |
6973
99934aade555
Use ngx_calloc_buf() where appropriate.
Ruslan Ermilov <ru@nginx.com>
parents:
6818
diff
changeset
|
646 b = ngx_calloc_buf(r->pool); |
4085 | 647 if (b == NULL) { |
648 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
649 } | |
650 | |
651 b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); | |
652 if (b->file == NULL) { | |
653 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
654 } | |
655 } | |
656 | |
657 rc = ngx_http_send_header(r); | |
658 | |
659 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | |
660 return rc; | |
661 } | |
662 | |
663 if (mp4) { | |
664 return ngx_http_output_filter(r, mp4->out); | |
665 } | |
666 | |
667 b->file_pos = 0; | |
668 b->file_last = of.size; | |
669 | |
670 b->in_file = b->file_last ? 1 : 0; | |
4611
2b6cb7528409
Allows particular modules to handle subrequests properly.
Andrey Belov <defan@nginx.com>
parents:
4585
diff
changeset
|
671 b->last_buf = (r == r->main) ? 1 : 0; |
4085 | 672 b->last_in_chain = 1; |
673 | |
674 b->file->fd = of.fd; | |
675 b->file->name = path; | |
676 b->file->log = log; | |
677 b->file->directio = of.is_directio; | |
678 | |
679 out.buf = b; | |
680 out.next = NULL; | |
681 | |
682 return ngx_http_output_filter(r, &out); | |
683 } | |
684 | |
685 | |
686 static ngx_int_t | |
6782
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
687 ngx_http_mp4_atofp(u_char *line, size_t n, size_t point) |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
688 { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
689 ngx_int_t value, cutoff, cutlim; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
690 ngx_uint_t dot; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
691 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
692 /* same as ngx_atofp(), but allows additional digits */ |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
693 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
694 if (n == 0) { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
695 return NGX_ERROR; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
696 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
697 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
698 cutoff = NGX_MAX_INT_T_VALUE / 10; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
699 cutlim = NGX_MAX_INT_T_VALUE % 10; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
700 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
701 dot = 0; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
702 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
703 for (value = 0; n--; line++) { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
704 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
705 if (*line == '.') { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
706 if (dot) { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
707 return NGX_ERROR; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
708 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
709 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
710 dot = 1; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
711 continue; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
712 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
713 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
714 if (*line < '0' || *line > '9') { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
715 return NGX_ERROR; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
716 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
717 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
718 if (point == 0) { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
719 continue; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
720 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
721 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
722 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
723 return NGX_ERROR; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
724 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
725 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
726 value = value * 10 + (*line - '0'); |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
727 point -= dot; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
728 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
729 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
730 while (point--) { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
731 if (value > cutoff) { |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
732 return NGX_ERROR; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
733 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
734 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
735 value = value * 10; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
736 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
737 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
738 return value; |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
739 } |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
740 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
741 |
b123eae3fd4e
Mp4: introduced custom version of ngx_atofp().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6722
diff
changeset
|
742 static ngx_int_t |
4085 | 743 ngx_http_mp4_process(ngx_http_mp4_file_t *mp4) |
744 { | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
745 off_t start_offset, end_offset, adjustment; |
4085 | 746 ngx_int_t rc; |
747 ngx_uint_t i, j; | |
748 ngx_chain_t **prev; | |
749 ngx_http_mp4_trak_t *trak; | |
750 ngx_http_mp4_conf_t *conf; | |
751 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
752 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
753 "mp4 start:%ui, length:%ui", mp4->start, mp4->length); |
4085 | 754 |
755 conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module); | |
756 | |
757 mp4->buffer_size = conf->buffer_size; | |
758 | |
759 rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_atoms, mp4->end); | |
760 if (rc != NGX_OK) { | |
761 return rc; | |
762 } | |
763 | |
764 if (mp4->trak.nelts == 0) { | |
765 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
766 "no mp4 trak atoms were found in \"%s\"", | |
767 mp4->file.name.data); | |
768 return NGX_ERROR; | |
769 } | |
770 | |
771 if (mp4->mdat_atom.buf == NULL) { | |
772 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
773 "no mp4 mdat atom was found in \"%s\"", | |
774 mp4->file.name.data); | |
775 return NGX_ERROR; | |
776 } | |
777 | |
778 prev = &mp4->out; | |
779 | |
780 if (mp4->ftyp_atom.buf) { | |
781 *prev = &mp4->ftyp_atom; | |
782 prev = &mp4->ftyp_atom.next; | |
783 } | |
784 | |
785 *prev = &mp4->moov_atom; | |
786 prev = &mp4->moov_atom.next; | |
787 | |
788 if (mp4->mvhd_atom.buf) { | |
789 mp4->moov_size += mp4->mvhd_atom_buf.last - mp4->mvhd_atom_buf.pos; | |
790 *prev = &mp4->mvhd_atom; | |
791 prev = &mp4->mvhd_atom.next; | |
792 } | |
793 | |
794 start_offset = mp4->end; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
795 end_offset = 0; |
4085 | 796 trak = mp4->trak.elts; |
797 | |
798 for (i = 0; i < mp4->trak.nelts; i++) { | |
799 | |
800 if (ngx_http_mp4_update_stts_atom(mp4, &trak[i]) != NGX_OK) { | |
801 return NGX_ERROR; | |
802 } | |
803 | |
804 if (ngx_http_mp4_update_stss_atom(mp4, &trak[i]) != NGX_OK) { | |
805 return NGX_ERROR; | |
806 } | |
807 | |
808 ngx_http_mp4_update_ctts_atom(mp4, &trak[i]); | |
809 | |
810 if (ngx_http_mp4_update_stsc_atom(mp4, &trak[i]) != NGX_OK) { | |
811 return NGX_ERROR; | |
812 } | |
813 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
814 if (ngx_http_mp4_update_stsz_atom(mp4, &trak[i]) != NGX_OK) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
815 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
816 } |
4085 | 817 |
4112 | 818 if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) { |
819 if (ngx_http_mp4_update_co64_atom(mp4, &trak[i]) != NGX_OK) { | |
820 return NGX_ERROR; | |
821 } | |
822 | |
823 } else { | |
824 if (ngx_http_mp4_update_stco_atom(mp4, &trak[i]) != NGX_OK) { | |
825 return NGX_ERROR; | |
826 } | |
4085 | 827 } |
828 | |
829 ngx_http_mp4_update_stbl_atom(mp4, &trak[i]); | |
830 ngx_http_mp4_update_minf_atom(mp4, &trak[i]); | |
831 trak[i].size += trak[i].mdhd_size; | |
832 trak[i].size += trak[i].hdlr_size; | |
833 ngx_http_mp4_update_mdia_atom(mp4, &trak[i]); | |
834 trak[i].size += trak[i].tkhd_size; | |
835 ngx_http_mp4_update_trak_atom(mp4, &trak[i]); | |
836 | |
837 mp4->moov_size += trak[i].size; | |
838 | |
839 if (start_offset > trak[i].start_offset) { | |
840 start_offset = trak[i].start_offset; | |
841 } | |
842 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
843 if (end_offset < trak[i].end_offset) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
844 end_offset = trak[i].end_offset; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
845 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
846 |
4085 | 847 *prev = &trak[i].out[NGX_HTTP_MP4_TRAK_ATOM]; |
848 prev = &trak[i].out[NGX_HTTP_MP4_TRAK_ATOM].next; | |
849 | |
850 for (j = 0; j < NGX_HTTP_MP4_LAST_ATOM + 1; j++) { | |
851 if (trak[i].out[j].buf) { | |
852 *prev = &trak[i].out[j]; | |
853 prev = &trak[i].out[j].next; | |
854 } | |
855 } | |
856 } | |
857 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
858 if (end_offset < start_offset) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
859 end_offset = start_offset; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
860 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
861 |
4085 | 862 mp4->moov_size += 8; |
863 | |
864 ngx_mp4_set_32value(mp4->moov_atom_header, mp4->moov_size); | |
865 ngx_mp4_set_atom_name(mp4->moov_atom_header, 'm', 'o', 'o', 'v'); | |
866 mp4->content_length += mp4->moov_size; | |
867 | |
868 *prev = &mp4->mdat_atom; | |
869 | |
5097
37671d0042b7
Mp4: fixed handling of too small mdat atoms (ticket #266).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4820
diff
changeset
|
870 if (start_offset > mp4->mdat_data.buf->file_last) { |
37671d0042b7
Mp4: fixed handling of too small mdat atoms (ticket #266).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4820
diff
changeset
|
871 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
37671d0042b7
Mp4: fixed handling of too small mdat atoms (ticket #266).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4820
diff
changeset
|
872 "start time is out mp4 mdat atom in \"%s\"", |
37671d0042b7
Mp4: fixed handling of too small mdat atoms (ticket #266).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4820
diff
changeset
|
873 mp4->file.name.data); |
37671d0042b7
Mp4: fixed handling of too small mdat atoms (ticket #266).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4820
diff
changeset
|
874 return NGX_ERROR; |
37671d0042b7
Mp4: fixed handling of too small mdat atoms (ticket #266).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4820
diff
changeset
|
875 } |
37671d0042b7
Mp4: fixed handling of too small mdat atoms (ticket #266).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4820
diff
changeset
|
876 |
4085 | 877 adjustment = mp4->ftyp_size + mp4->moov_size |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
878 + ngx_http_mp4_update_mdat_atom(mp4, start_offset, end_offset) |
4085 | 879 - start_offset; |
880 | |
4088
8fe1da7b8386
bugfix of r4086: nginx could not be built without debug log.
Igor Sysoev <igor@sysoev.ru>
parents:
4087
diff
changeset
|
881 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
4579 | 882 "mp4 adjustment:%O", adjustment); |
4085 | 883 |
884 for (i = 0; i < mp4->trak.nelts; i++) { | |
4112 | 885 if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) { |
886 ngx_http_mp4_adjust_co64_atom(mp4, &trak[i], adjustment); | |
887 } else { | |
888 ngx_http_mp4_adjust_stco_atom(mp4, &trak[i], (int32_t) adjustment); | |
889 } | |
4085 | 890 } |
891 | |
892 return NGX_OK; | |
893 } | |
894 | |
895 | |
896 typedef struct { | |
897 u_char size[4]; | |
898 u_char name[4]; | |
899 } ngx_mp4_atom_header_t; | |
900 | |
901 typedef struct { | |
902 u_char size[4]; | |
903 u_char name[4]; | |
904 u_char size64[8]; | |
905 } ngx_mp4_atom_header64_t; | |
906 | |
907 | |
908 static ngx_int_t | |
909 ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4, | |
910 ngx_http_mp4_atom_handler_t *atom, uint64_t atom_data_size) | |
911 { | |
912 off_t end; | |
913 size_t atom_header_size; | |
914 u_char *atom_header, *atom_name; | |
915 uint64_t atom_size; | |
916 ngx_int_t rc; | |
917 ngx_uint_t n; | |
918 | |
919 end = mp4->offset + atom_data_size; | |
920 | |
921 while (mp4->offset < end) { | |
922 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
923 if (ngx_http_mp4_read(mp4, sizeof(uint32_t)) != NGX_OK) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
924 return NGX_ERROR; |
4085 | 925 } |
926 | |
927 atom_header = mp4->buffer_pos; | |
928 atom_size = ngx_mp4_get_32value(atom_header); | |
929 atom_header_size = sizeof(ngx_mp4_atom_header_t); | |
930 | |
931 if (atom_size == 0) { | |
932 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
933 "mp4 atom end"); | |
934 return NGX_OK; | |
935 } | |
936 | |
937 if (atom_size < sizeof(ngx_mp4_atom_header_t)) { | |
938 | |
939 if (atom_size == 1) { | |
940 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
941 if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header64_t)) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
942 != NGX_OK) |
4085 | 943 { |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
944 return NGX_ERROR; |
4085 | 945 } |
946 | |
947 /* 64-bit atom size */ | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
948 atom_header = mp4->buffer_pos; |
4085 | 949 atom_size = ngx_mp4_get_64value(atom_header + 8); |
950 atom_header_size = sizeof(ngx_mp4_atom_header64_t); | |
951 | |
7376
e5069816039b
Mp4: fixed reading 64-bit atoms.
Roman Arutyunyan <arut@nginx.com>
parents:
6973
diff
changeset
|
952 if (atom_size < sizeof(ngx_mp4_atom_header64_t)) { |
e5069816039b
Mp4: fixed reading 64-bit atoms.
Roman Arutyunyan <arut@nginx.com>
parents:
6973
diff
changeset
|
953 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
e5069816039b
Mp4: fixed reading 64-bit atoms.
Roman Arutyunyan <arut@nginx.com>
parents:
6973
diff
changeset
|
954 "\"%s\" mp4 atom is too small:%uL", |
e5069816039b
Mp4: fixed reading 64-bit atoms.
Roman Arutyunyan <arut@nginx.com>
parents:
6973
diff
changeset
|
955 mp4->file.name.data, atom_size); |
e5069816039b
Mp4: fixed reading 64-bit atoms.
Roman Arutyunyan <arut@nginx.com>
parents:
6973
diff
changeset
|
956 return NGX_ERROR; |
e5069816039b
Mp4: fixed reading 64-bit atoms.
Roman Arutyunyan <arut@nginx.com>
parents:
6973
diff
changeset
|
957 } |
e5069816039b
Mp4: fixed reading 64-bit atoms.
Roman Arutyunyan <arut@nginx.com>
parents:
6973
diff
changeset
|
958 |
4085 | 959 } else { |
960 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
961 "\"%s\" mp4 atom is too small:%uL", | |
962 mp4->file.name.data, atom_size); | |
963 return NGX_ERROR; | |
964 } | |
965 } | |
966 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
967 if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header_t)) != NGX_OK) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
968 return NGX_ERROR; |
4085 | 969 } |
970 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
971 atom_header = mp4->buffer_pos; |
4085 | 972 atom_name = atom_header + sizeof(uint32_t); |
973 | |
4088
8fe1da7b8386
bugfix of r4086: nginx could not be built without debug log.
Igor Sysoev <igor@sysoev.ru>
parents:
4087
diff
changeset
|
974 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
4085 | 975 "mp4 atom: %*s @%O:%uL", |
6478
3ef7bb882ad4
Fixed logging with variable field width.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6474
diff
changeset
|
976 (size_t) 4, atom_name, mp4->offset, atom_size); |
4085 | 977 |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
978 if (atom_size > (uint64_t) (NGX_MAX_OFF_T_VALUE - mp4->offset) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
979 || mp4->offset + (off_t) atom_size > end) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
980 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
981 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
982 "\"%s\" mp4 atom too large:%uL", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
983 mp4->file.name.data, atom_size); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
984 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
985 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
986 |
4085 | 987 for (n = 0; atom[n].name; n++) { |
988 | |
989 if (ngx_strncmp(atom_name, atom[n].name, 4) == 0) { | |
990 | |
991 ngx_mp4_atom_next(mp4, atom_header_size); | |
992 | |
993 rc = atom[n].handler(mp4, atom_size - atom_header_size); | |
994 if (rc != NGX_OK) { | |
995 return rc; | |
996 } | |
997 | |
998 goto next; | |
999 } | |
1000 } | |
1001 | |
1002 ngx_mp4_atom_next(mp4, atom_size); | |
1003 | |
1004 next: | |
1005 continue; | |
1006 } | |
1007 | |
1008 return NGX_OK; | |
1009 } | |
1010 | |
1011 | |
1012 static ngx_int_t | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1013 ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size) |
4085 | 1014 { |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1015 ssize_t n; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1016 |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1017 if (mp4->buffer_pos + size <= mp4->buffer_end) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1018 return NGX_OK; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1019 } |
4085 | 1020 |
1021 if (mp4->offset + (off_t) mp4->buffer_size > mp4->end) { | |
1022 mp4->buffer_size = (size_t) (mp4->end - mp4->offset); | |
1023 } | |
1024 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1025 if (mp4->buffer_size < size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1026 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1027 "\"%s\" mp4 file truncated", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1028 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1029 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1030 |
4085 | 1031 if (mp4->buffer == NULL) { |
1032 mp4->buffer = ngx_palloc(mp4->request->pool, mp4->buffer_size); | |
1033 if (mp4->buffer == NULL) { | |
1034 return NGX_ERROR; | |
1035 } | |
1036 | |
1037 mp4->buffer_start = mp4->buffer; | |
1038 } | |
1039 | |
1040 n = ngx_read_file(&mp4->file, mp4->buffer_start, mp4->buffer_size, | |
1041 mp4->offset); | |
1042 | |
1043 if (n == NGX_ERROR) { | |
1044 return NGX_ERROR; | |
1045 } | |
1046 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1047 if ((size_t) n != mp4->buffer_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1048 ngx_log_error(NGX_LOG_CRIT, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1049 ngx_read_file_n " read only %z of %z from \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1050 n, mp4->buffer_size, mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1051 return NGX_ERROR; |
4085 | 1052 } |
1053 | |
1054 mp4->buffer_pos = mp4->buffer_start; | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1055 mp4->buffer_end = mp4->buffer_start + mp4->buffer_size; |
4085 | 1056 |
1057 return NGX_OK; | |
1058 } | |
1059 | |
1060 | |
1061 static ngx_int_t | |
1062 ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1063 { | |
1064 u_char *ftyp_atom; | |
1065 size_t atom_size; | |
1066 ngx_buf_t *atom; | |
1067 | |
1068 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ftyp atom"); | |
1069 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1070 if (atom_data_size > 1024 |
5359
2fda9065d0f4
Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5358
diff
changeset
|
1071 || ngx_mp4_atom_data(mp4) + (size_t) atom_data_size > mp4->buffer_end) |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1072 { |
4085 | 1073 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
1074 "\"%s\" mp4 ftyp atom is too large:%uL", | |
1075 mp4->file.name.data, atom_data_size); | |
1076 return NGX_ERROR; | |
1077 } | |
1078 | |
1079 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1080 | |
1081 ftyp_atom = ngx_palloc(mp4->request->pool, atom_size); | |
1082 if (ftyp_atom == NULL) { | |
1083 return NGX_ERROR; | |
1084 } | |
1085 | |
1086 ngx_mp4_set_32value(ftyp_atom, atom_size); | |
1087 ngx_mp4_set_atom_name(ftyp_atom, 'f', 't', 'y', 'p'); | |
1088 | |
1089 /* | |
1090 * only moov atom content is guaranteed to be in mp4->buffer | |
1091 * during sending response, so ftyp atom content should be copied | |
1092 */ | |
1093 ngx_memcpy(ftyp_atom + sizeof(ngx_mp4_atom_header_t), | |
1094 ngx_mp4_atom_data(mp4), (size_t) atom_data_size); | |
1095 | |
1096 atom = &mp4->ftyp_atom_buf; | |
1097 atom->temporary = 1; | |
1098 atom->pos = ftyp_atom; | |
1099 atom->last = ftyp_atom + atom_size; | |
1100 | |
1101 mp4->ftyp_atom.buf = atom; | |
1102 mp4->ftyp_size = atom_size; | |
1103 mp4->content_length = atom_size; | |
1104 | |
1105 ngx_mp4_atom_next(mp4, atom_data_size); | |
1106 | |
1107 return NGX_OK; | |
1108 } | |
1109 | |
1110 | |
1111 /* | |
1112 * Small excess buffer to process atoms after moov atom, mp4->buffer_start | |
1113 * will be set to this buffer part after moov atom processing. | |
1114 */ | |
1115 #define NGX_HTTP_MP4_MOOV_BUFFER_EXCESS (4 * 1024) | |
1116 | |
1117 static ngx_int_t | |
1118 ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1119 { | |
1120 ngx_int_t rc; | |
1121 ngx_uint_t no_mdat; | |
1122 ngx_buf_t *atom; | |
1123 ngx_http_mp4_conf_t *conf; | |
1124 | |
1125 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 moov atom"); | |
1126 | |
1127 no_mdat = (mp4->mdat_atom.buf == NULL); | |
1128 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1129 if (no_mdat && mp4->start == 0 && mp4->length == 0) { |
4085 | 1130 /* |
1131 * send original file if moov atom resides before | |
1132 * mdat atom and client requests integral file | |
1133 */ | |
1134 return NGX_DECLINED; | |
1135 } | |
1136 | |
1137 conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module); | |
1138 | |
1139 if (atom_data_size > mp4->buffer_size) { | |
1140 | |
4089
e27670e1ab70
mp4_max_moov_size directive has been renamed to mp4_max_buffer_size.
Igor Sysoev <igor@sysoev.ru>
parents:
4088
diff
changeset
|
1141 if (atom_data_size > conf->max_buffer_size) { |
4085 | 1142 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
1143 "\"%s\" mp4 moov atom is too large:%uL, " | |
4089
e27670e1ab70
mp4_max_moov_size directive has been renamed to mp4_max_buffer_size.
Igor Sysoev <igor@sysoev.ru>
parents:
4088
diff
changeset
|
1144 "you may want to increase mp4_max_buffer_size", |
4085 | 1145 mp4->file.name.data, atom_data_size); |
1146 return NGX_ERROR; | |
1147 } | |
1148 | |
1149 ngx_pfree(mp4->request->pool, mp4->buffer); | |
1150 mp4->buffer = NULL; | |
1151 mp4->buffer_pos = NULL; | |
1152 mp4->buffer_end = NULL; | |
1153 | |
1154 mp4->buffer_size = (size_t) atom_data_size | |
1155 + NGX_HTTP_MP4_MOOV_BUFFER_EXCESS * no_mdat; | |
1156 } | |
1157 | |
4705
9a43b145a8ba
Mp4: fixed build on win32 after r4689.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4688
diff
changeset
|
1158 if (ngx_http_mp4_read(mp4, (size_t) atom_data_size) != NGX_OK) { |
4688
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1159 return NGX_ERROR; |
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1160 } |
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1161 |
4085 | 1162 mp4->trak.elts = &mp4->traks; |
1163 mp4->trak.size = sizeof(ngx_http_mp4_trak_t); | |
1164 mp4->trak.nalloc = 2; | |
1165 mp4->trak.pool = mp4->request->pool; | |
1166 | |
1167 atom = &mp4->moov_atom_buf; | |
1168 atom->temporary = 1; | |
1169 atom->pos = mp4->moov_atom_header; | |
1170 atom->last = mp4->moov_atom_header + 8; | |
1171 | |
1172 mp4->moov_atom.buf = &mp4->moov_atom_buf; | |
1173 | |
1174 rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_moov_atoms, atom_data_size); | |
1175 | |
1176 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 moov atom done"); | |
1177 | |
1178 if (no_mdat) { | |
1179 mp4->buffer_start = mp4->buffer_pos; | |
1180 mp4->buffer_size = NGX_HTTP_MP4_MOOV_BUFFER_EXCESS; | |
1181 | |
4688
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1182 if (mp4->buffer_start + mp4->buffer_size > mp4->buffer_end) { |
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1183 mp4->buffer = NULL; |
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1184 mp4->buffer_pos = NULL; |
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1185 mp4->buffer_end = NULL; |
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1186 } |
5fedb27c3e36
Mp4: fixed streaming if moov atom is at buffer edge.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4687
diff
changeset
|
1187 |
4085 | 1188 } else { |
1189 /* skip atoms after moov atom */ | |
1190 mp4->offset = mp4->end; | |
1191 } | |
1192 | |
1193 return rc; | |
1194 } | |
1195 | |
1196 | |
1197 static ngx_int_t | |
1198 ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1199 { | |
1200 ngx_buf_t *data; | |
1201 | |
1202 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom"); | |
1203 | |
1204 data = &mp4->mdat_data_buf; | |
1205 data->file = &mp4->file; | |
1206 data->in_file = 1; | |
6722
6136a51f9c21
Do not set last_buf flag in subrequests.
Roman Arutyunyan <arut@nginx.com>
parents:
6504
diff
changeset
|
1207 data->last_buf = (mp4->request == mp4->request->main) ? 1 : 0; |
4085 | 1208 data->last_in_chain = 1; |
1209 data->file_last = mp4->offset + atom_data_size; | |
1210 | |
1211 mp4->mdat_atom.buf = &mp4->mdat_atom_buf; | |
1212 mp4->mdat_atom.next = &mp4->mdat_data; | |
1213 mp4->mdat_data.buf = data; | |
1214 | |
1215 if (mp4->trak.nelts) { | |
1216 /* skip atoms after mdat atom */ | |
1217 mp4->offset = mp4->end; | |
1218 | |
1219 } else { | |
1220 ngx_mp4_atom_next(mp4, atom_data_size); | |
1221 } | |
1222 | |
1223 return NGX_OK; | |
1224 } | |
1225 | |
1226 | |
1227 static size_t | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1228 ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4, off_t start_offset, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1229 off_t end_offset) |
4085 | 1230 { |
1231 off_t atom_data_size; | |
1232 u_char *atom_header; | |
1233 uint32_t atom_header_size; | |
1234 uint64_t atom_size; | |
1235 ngx_buf_t *atom; | |
1236 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1237 atom_data_size = end_offset - start_offset; |
4085 | 1238 mp4->mdat_data.buf->file_pos = start_offset; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1239 mp4->mdat_data.buf->file_last = end_offset; |
4085 | 1240 |
4088
8fe1da7b8386
bugfix of r4086: nginx could not be built without debug log.
Igor Sysoev <igor@sysoev.ru>
parents:
4087
diff
changeset
|
1241 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
4085 | 1242 "mdat new offset @%O:%O", start_offset, atom_data_size); |
1243 | |
1244 atom_header = mp4->mdat_atom_header; | |
1245 | |
6818
2b2239a1e0d4
Mp4: fixed setting wrong mdat atom size in very rare cases.
hucongcong <hucong.c@foxmail.com>
parents:
6782
diff
changeset
|
1246 if ((uint64_t) atom_data_size |
2b2239a1e0d4
Mp4: fixed setting wrong mdat atom size in very rare cases.
hucongcong <hucong.c@foxmail.com>
parents:
6782
diff
changeset
|
1247 > (uint64_t) 0xffffffff - sizeof(ngx_mp4_atom_header_t)) |
2b2239a1e0d4
Mp4: fixed setting wrong mdat atom size in very rare cases.
hucongcong <hucong.c@foxmail.com>
parents:
6782
diff
changeset
|
1248 { |
4085 | 1249 atom_size = 1; |
1250 atom_header_size = sizeof(ngx_mp4_atom_header64_t); | |
1251 ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t), | |
1252 sizeof(ngx_mp4_atom_header64_t) + atom_data_size); | |
1253 } else { | |
1254 atom_size = sizeof(ngx_mp4_atom_header_t) + atom_data_size; | |
1255 atom_header_size = sizeof(ngx_mp4_atom_header_t); | |
1256 } | |
1257 | |
4282
71cdac0b9ea6
Fix of "Content-Length" header of MP4 response if start argument was used.
Igor Sysoev <igor@sysoev.ru>
parents:
4189
diff
changeset
|
1258 mp4->content_length += atom_header_size + atom_data_size; |
71cdac0b9ea6
Fix of "Content-Length" header of MP4 response if start argument was used.
Igor Sysoev <igor@sysoev.ru>
parents:
4189
diff
changeset
|
1259 |
4085 | 1260 ngx_mp4_set_32value(atom_header, atom_size); |
1261 ngx_mp4_set_atom_name(atom_header, 'm', 'd', 'a', 't'); | |
1262 | |
1263 atom = &mp4->mdat_atom_buf; | |
1264 atom->temporary = 1; | |
1265 atom->pos = atom_header; | |
1266 atom->last = atom_header + atom_header_size; | |
1267 | |
1268 return atom_header_size; | |
1269 } | |
1270 | |
1271 | |
1272 typedef struct { | |
1273 u_char size[4]; | |
1274 u_char name[4]; | |
1275 u_char version[1]; | |
1276 u_char flags[3]; | |
1277 u_char creation_time[4]; | |
1278 u_char modification_time[4]; | |
1279 u_char timescale[4]; | |
1280 u_char duration[4]; | |
1281 u_char rate[4]; | |
1282 u_char volume[2]; | |
1283 u_char reserved[10]; | |
1284 u_char matrix[36]; | |
1285 u_char preview_time[4]; | |
1286 u_char preview_duration[4]; | |
1287 u_char poster_time[4]; | |
1288 u_char selection_time[4]; | |
1289 u_char selection_duration[4]; | |
1290 u_char current_time[4]; | |
1291 u_char next_track_id[4]; | |
1292 } ngx_mp4_mvhd_atom_t; | |
1293 | |
1294 typedef struct { | |
1295 u_char size[4]; | |
1296 u_char name[4]; | |
1297 u_char version[1]; | |
1298 u_char flags[3]; | |
1299 u_char creation_time[8]; | |
1300 u_char modification_time[8]; | |
1301 u_char timescale[4]; | |
1302 u_char duration[8]; | |
1303 u_char rate[4]; | |
1304 u_char volume[2]; | |
1305 u_char reserved[10]; | |
1306 u_char matrix[36]; | |
1307 u_char preview_time[4]; | |
1308 u_char preview_duration[4]; | |
1309 u_char poster_time[4]; | |
1310 u_char selection_time[4]; | |
1311 u_char selection_duration[4]; | |
1312 u_char current_time[4]; | |
1313 u_char next_track_id[4]; | |
1314 } ngx_mp4_mvhd64_atom_t; | |
1315 | |
1316 | |
1317 static ngx_int_t | |
1318 ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1319 { | |
1320 u_char *atom_header; | |
1321 size_t atom_size; | |
1322 uint32_t timescale; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1323 uint64_t duration, start_time, length_time; |
4085 | 1324 ngx_buf_t *atom; |
1325 ngx_mp4_mvhd_atom_t *mvhd_atom; | |
1326 ngx_mp4_mvhd64_atom_t *mvhd64_atom; | |
1327 | |
1328 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom"); | |
1329 | |
1330 atom_header = ngx_mp4_atom_header(mp4); | |
1331 mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header; | |
1332 mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header; | |
1333 ngx_mp4_set_atom_name(atom_header, 'm', 'v', 'h', 'd'); | |
1334 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1335 if (ngx_mp4_atom_data_size(ngx_mp4_mvhd_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1336 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1337 "\"%s\" mp4 mvhd atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1338 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1339 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1340 |
4085 | 1341 if (mvhd_atom->version[0] == 0) { |
1342 /* version 0: 32-bit duration */ | |
1343 timescale = ngx_mp4_get_32value(mvhd_atom->timescale); | |
1344 duration = ngx_mp4_get_32value(mvhd_atom->duration); | |
1345 | |
1346 } else { | |
1347 /* version 1: 64-bit duration */ | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1348 |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1349 if (ngx_mp4_atom_data_size(ngx_mp4_mvhd64_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1350 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1351 "\"%s\" mp4 mvhd atom too small", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1352 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1353 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1354 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1355 |
4085 | 1356 timescale = ngx_mp4_get_32value(mvhd64_atom->timescale); |
1357 duration = ngx_mp4_get_64value(mvhd64_atom->duration); | |
1358 } | |
1359 | |
1360 mp4->timescale = timescale; | |
1361 | |
1362 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
1363 "mvhd timescale:%uD, duration:%uL, time:%.3fs", | |
1364 timescale, duration, (double) duration / timescale); | |
1365 | |
5543
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1366 start_time = (uint64_t) mp4->start * timescale / 1000; |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1367 |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1368 if (duration < start_time) { |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1369 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1370 "\"%s\" mp4 start time exceeds file duration", |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1371 mp4->file.name.data); |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1372 return NGX_ERROR; |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1373 } |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1374 |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1375 duration -= start_time; |
4085 | 1376 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1377 if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1378 length_time = (uint64_t) mp4->length * timescale / 1000; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1379 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1380 if (duration > length_time) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1381 duration = length_time; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1382 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1383 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1384 |
4085 | 1385 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1386 "mvhd new duration:%uL, time:%.3fs", | |
1387 duration, (double) duration / timescale); | |
1388 | |
1389 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1390 ngx_mp4_set_32value(mvhd_atom->size, atom_size); | |
1391 | |
1392 if (mvhd_atom->version[0] == 0) { | |
1393 ngx_mp4_set_32value(mvhd_atom->duration, duration); | |
1394 | |
1395 } else { | |
1396 ngx_mp4_set_64value(mvhd64_atom->duration, duration); | |
1397 } | |
1398 | |
1399 atom = &mp4->mvhd_atom_buf; | |
1400 atom->temporary = 1; | |
1401 atom->pos = atom_header; | |
1402 atom->last = atom_header + atom_size; | |
1403 | |
1404 mp4->mvhd_atom.buf = atom; | |
1405 | |
1406 ngx_mp4_atom_next(mp4, atom_data_size); | |
1407 | |
1408 return NGX_OK; | |
1409 } | |
1410 | |
1411 | |
1412 static ngx_int_t | |
1413 ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1414 { | |
4099
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1415 u_char *atom_header, *atom_end; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1416 off_t atom_file_end; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1417 ngx_int_t rc; |
4085 | 1418 ngx_buf_t *atom; |
1419 ngx_http_mp4_trak_t *trak; | |
1420 | |
1421 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 trak atom"); | |
1422 | |
1423 trak = ngx_array_push(&mp4->trak); | |
1424 if (trak == NULL) { | |
1425 return NGX_ERROR; | |
1426 } | |
1427 | |
1428 ngx_memzero(trak, sizeof(ngx_http_mp4_trak_t)); | |
1429 | |
1430 atom_header = ngx_mp4_atom_header(mp4); | |
1431 ngx_mp4_set_atom_name(atom_header, 't', 'r', 'a', 'k'); | |
1432 | |
1433 atom = &trak->trak_atom_buf; | |
1434 atom->temporary = 1; | |
1435 atom->pos = atom_header; | |
1436 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); | |
1437 | |
1438 trak->out[NGX_HTTP_MP4_TRAK_ATOM].buf = atom; | |
1439 | |
5359
2fda9065d0f4
Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5358
diff
changeset
|
1440 atom_end = mp4->buffer_pos + (size_t) atom_data_size; |
4099
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1441 atom_file_end = mp4->offset + atom_data_size; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1442 |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1443 rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_trak_atoms, atom_data_size); |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1444 |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1445 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1446 "mp4 trak atom: %i", rc); |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1447 |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1448 if (rc == NGX_DECLINED) { |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1449 /* skip this trak */ |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1450 ngx_memzero(trak, sizeof(ngx_http_mp4_trak_t)); |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1451 mp4->trak.nelts--; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1452 mp4->buffer_pos = atom_end; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1453 mp4->offset = atom_file_end; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1454 return NGX_OK; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1455 } |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1456 |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1457 return rc; |
4085 | 1458 } |
1459 | |
1460 | |
1461 static void | |
1462 ngx_http_mp4_update_trak_atom(ngx_http_mp4_file_t *mp4, | |
1463 ngx_http_mp4_trak_t *trak) | |
1464 { | |
1465 ngx_buf_t *atom; | |
1466 | |
1467 trak->size += sizeof(ngx_mp4_atom_header_t); | |
1468 atom = &trak->trak_atom_buf; | |
1469 ngx_mp4_set_32value(atom->pos, trak->size); | |
1470 } | |
1471 | |
1472 | |
1473 static ngx_int_t | |
1474 ngx_http_mp4_read_cmov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1475 { | |
1476 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
1477 "\"%s\" mp4 compressed moov atom (cmov) is not supported", | |
1478 mp4->file.name.data); | |
1479 | |
1480 return NGX_ERROR; | |
1481 } | |
1482 | |
1483 | |
1484 typedef struct { | |
1485 u_char size[4]; | |
1486 u_char name[4]; | |
1487 u_char version[1]; | |
1488 u_char flags[3]; | |
1489 u_char creation_time[4]; | |
1490 u_char modification_time[4]; | |
1491 u_char track_id[4]; | |
1492 u_char reserved1[4]; | |
1493 u_char duration[4]; | |
1494 u_char reserved2[8]; | |
1495 u_char layer[2]; | |
1496 u_char group[2]; | |
1497 u_char volume[2]; | |
6504 | 1498 u_char reserved3[2]; |
4085 | 1499 u_char matrix[36]; |
1500 u_char width[4]; | |
6504 | 1501 u_char height[4]; |
4085 | 1502 } ngx_mp4_tkhd_atom_t; |
1503 | |
1504 typedef struct { | |
1505 u_char size[4]; | |
1506 u_char name[4]; | |
1507 u_char version[1]; | |
1508 u_char flags[3]; | |
1509 u_char creation_time[8]; | |
1510 u_char modification_time[8]; | |
1511 u_char track_id[4]; | |
1512 u_char reserved1[4]; | |
1513 u_char duration[8]; | |
1514 u_char reserved2[8]; | |
1515 u_char layer[2]; | |
1516 u_char group[2]; | |
1517 u_char volume[2]; | |
6504 | 1518 u_char reserved3[2]; |
4085 | 1519 u_char matrix[36]; |
1520 u_char width[4]; | |
6504 | 1521 u_char height[4]; |
4085 | 1522 } ngx_mp4_tkhd64_atom_t; |
1523 | |
1524 | |
1525 static ngx_int_t | |
1526 ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1527 { | |
1528 u_char *atom_header; | |
1529 size_t atom_size; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1530 uint64_t duration, start_time, length_time; |
4085 | 1531 ngx_buf_t *atom; |
1532 ngx_http_mp4_trak_t *trak; | |
1533 ngx_mp4_tkhd_atom_t *tkhd_atom; | |
1534 ngx_mp4_tkhd64_atom_t *tkhd64_atom; | |
1535 | |
1536 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 tkhd atom"); | |
1537 | |
1538 atom_header = ngx_mp4_atom_header(mp4); | |
1539 tkhd_atom = (ngx_mp4_tkhd_atom_t *) atom_header; | |
1540 tkhd64_atom = (ngx_mp4_tkhd64_atom_t *) atom_header; | |
1541 ngx_mp4_set_atom_name(tkhd_atom, 't', 'k', 'h', 'd'); | |
1542 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1543 if (ngx_mp4_atom_data_size(ngx_mp4_tkhd_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1544 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1545 "\"%s\" mp4 tkhd atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1546 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1547 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1548 |
4085 | 1549 if (tkhd_atom->version[0] == 0) { |
1550 /* version 0: 32-bit duration */ | |
1551 duration = ngx_mp4_get_32value(tkhd_atom->duration); | |
1552 | |
1553 } else { | |
1554 /* version 1: 64-bit duration */ | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1555 |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1556 if (ngx_mp4_atom_data_size(ngx_mp4_tkhd64_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1557 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1558 "\"%s\" mp4 tkhd atom too small", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1559 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1560 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1561 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1562 |
4085 | 1563 duration = ngx_mp4_get_64value(tkhd64_atom->duration); |
1564 } | |
1565 | |
1566 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
1567 "tkhd duration:%uL, time:%.3fs", | |
1568 duration, (double) duration / mp4->timescale); | |
1569 | |
5543
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1570 start_time = (uint64_t) mp4->start * mp4->timescale / 1000; |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1571 |
5629
c7bbc5fcf27c
Mp4: fixed seeking to a track end.
Roman Arutyunyan <arut@nginx.com>
parents:
5622
diff
changeset
|
1572 if (duration <= start_time) { |
5543
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1573 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1574 "tkhd duration is less than start time"); |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1575 return NGX_DECLINED; |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1576 } |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1577 |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1578 duration -= start_time; |
4085 | 1579 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1580 if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1581 length_time = (uint64_t) mp4->length * mp4->timescale / 1000; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1582 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1583 if (duration > length_time) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1584 duration = length_time; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1585 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1586 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1587 |
4085 | 1588 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1589 "tkhd new duration:%uL, time:%.3fs", | |
1590 duration, (double) duration / mp4->timescale); | |
1591 | |
1592 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1593 | |
1594 trak = ngx_mp4_last_trak(mp4); | |
1595 trak->tkhd_size = atom_size; | |
1596 | |
1597 ngx_mp4_set_32value(tkhd_atom->size, atom_size); | |
1598 | |
1599 if (tkhd_atom->version[0] == 0) { | |
1600 ngx_mp4_set_32value(tkhd_atom->duration, duration); | |
1601 | |
1602 } else { | |
1603 ngx_mp4_set_64value(tkhd64_atom->duration, duration); | |
1604 } | |
1605 | |
1606 atom = &trak->tkhd_atom_buf; | |
1607 atom->temporary = 1; | |
1608 atom->pos = atom_header; | |
1609 atom->last = atom_header + atom_size; | |
1610 | |
1611 trak->out[NGX_HTTP_MP4_TKHD_ATOM].buf = atom; | |
1612 | |
1613 ngx_mp4_atom_next(mp4, atom_data_size); | |
1614 | |
1615 return NGX_OK; | |
1616 } | |
1617 | |
1618 | |
1619 static ngx_int_t | |
1620 ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1621 { | |
1622 u_char *atom_header; | |
1623 ngx_buf_t *atom; | |
1624 ngx_http_mp4_trak_t *trak; | |
1625 | |
1626 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "process mdia atom"); | |
1627 | |
1628 atom_header = ngx_mp4_atom_header(mp4); | |
1629 ngx_mp4_set_atom_name(atom_header, 'm', 'd', 'i', 'a'); | |
1630 | |
1631 trak = ngx_mp4_last_trak(mp4); | |
1632 | |
1633 atom = &trak->mdia_atom_buf; | |
1634 atom->temporary = 1; | |
1635 atom->pos = atom_header; | |
1636 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); | |
1637 | |
1638 trak->out[NGX_HTTP_MP4_MDIA_ATOM].buf = atom; | |
1639 | |
1640 return ngx_http_mp4_read_atom(mp4, ngx_http_mp4_mdia_atoms, atom_data_size); | |
1641 } | |
1642 | |
1643 | |
1644 static void | |
1645 ngx_http_mp4_update_mdia_atom(ngx_http_mp4_file_t *mp4, | |
1646 ngx_http_mp4_trak_t *trak) | |
1647 { | |
1648 ngx_buf_t *atom; | |
1649 | |
1650 trak->size += sizeof(ngx_mp4_atom_header_t); | |
1651 atom = &trak->mdia_atom_buf; | |
1652 ngx_mp4_set_32value(atom->pos, trak->size); | |
1653 } | |
1654 | |
1655 | |
1656 typedef struct { | |
1657 u_char size[4]; | |
1658 u_char name[4]; | |
1659 u_char version[1]; | |
1660 u_char flags[3]; | |
1661 u_char creation_time[4]; | |
1662 u_char modification_time[4]; | |
1663 u_char timescale[4]; | |
1664 u_char duration[4]; | |
1665 u_char language[2]; | |
1666 u_char quality[2]; | |
1667 } ngx_mp4_mdhd_atom_t; | |
1668 | |
1669 typedef struct { | |
1670 u_char size[4]; | |
1671 u_char name[4]; | |
1672 u_char version[1]; | |
1673 u_char flags[3]; | |
1674 u_char creation_time[8]; | |
1675 u_char modification_time[8]; | |
1676 u_char timescale[4]; | |
1677 u_char duration[8]; | |
1678 u_char language[2]; | |
1679 u_char quality[2]; | |
1680 } ngx_mp4_mdhd64_atom_t; | |
1681 | |
1682 | |
1683 static ngx_int_t | |
1684 ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1685 { | |
1686 u_char *atom_header; | |
1687 size_t atom_size; | |
1688 uint32_t timescale; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1689 uint64_t duration, start_time, length_time; |
4085 | 1690 ngx_buf_t *atom; |
1691 ngx_http_mp4_trak_t *trak; | |
1692 ngx_mp4_mdhd_atom_t *mdhd_atom; | |
1693 ngx_mp4_mdhd64_atom_t *mdhd64_atom; | |
1694 | |
1695 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdhd atom"); | |
1696 | |
1697 atom_header = ngx_mp4_atom_header(mp4); | |
1698 mdhd_atom = (ngx_mp4_mdhd_atom_t *) atom_header; | |
1699 mdhd64_atom = (ngx_mp4_mdhd64_atom_t *) atom_header; | |
1700 ngx_mp4_set_atom_name(mdhd_atom, 'm', 'd', 'h', 'd'); | |
1701 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1702 if (ngx_mp4_atom_data_size(ngx_mp4_mdhd_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1703 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1704 "\"%s\" mp4 mdhd atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1705 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1706 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1707 |
4085 | 1708 if (mdhd_atom->version[0] == 0) { |
1709 /* version 0: everything is 32-bit */ | |
1710 timescale = ngx_mp4_get_32value(mdhd_atom->timescale); | |
1711 duration = ngx_mp4_get_32value(mdhd_atom->duration); | |
1712 | |
1713 } else { | |
1714 /* version 1: 64-bit duration and 32-bit timescale */ | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1715 |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1716 if (ngx_mp4_atom_data_size(ngx_mp4_mdhd64_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1717 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1718 "\"%s\" mp4 mdhd atom too small", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1719 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1720 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1721 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
1722 |
4085 | 1723 timescale = ngx_mp4_get_32value(mdhd64_atom->timescale); |
1724 duration = ngx_mp4_get_64value(mdhd64_atom->duration); | |
1725 } | |
1726 | |
1727 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
1728 "mdhd timescale:%uD, duration:%uL, time:%.3fs", | |
1729 timescale, duration, (double) duration / timescale); | |
1730 | |
5543
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1731 start_time = (uint64_t) mp4->start * timescale / 1000; |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1732 |
5629
c7bbc5fcf27c
Mp4: fixed seeking to a track end.
Roman Arutyunyan <arut@nginx.com>
parents:
5622
diff
changeset
|
1733 if (duration <= start_time) { |
5543
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1734 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1735 "mdhd duration is less than start time"); |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1736 return NGX_DECLINED; |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1737 } |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1738 |
5730c0193842
Mp4: skip tracks shorter than seek position (ticket #414).
Roman Arutyunyan <arut@nginx.com>
parents:
5542
diff
changeset
|
1739 duration -= start_time; |
4085 | 1740 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1741 if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1742 length_time = (uint64_t) mp4->length * timescale / 1000; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1743 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1744 if (duration > length_time) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1745 duration = length_time; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1746 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1747 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
1748 |
4085 | 1749 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
1750 "mdhd new duration:%uL, time:%.3fs", | |
1751 duration, (double) duration / timescale); | |
1752 | |
1753 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1754 | |
1755 trak = ngx_mp4_last_trak(mp4); | |
1756 trak->mdhd_size = atom_size; | |
1757 trak->timescale = timescale; | |
1758 | |
1759 ngx_mp4_set_32value(mdhd_atom->size, atom_size); | |
1760 | |
1761 if (mdhd_atom->version[0] == 0) { | |
1762 ngx_mp4_set_32value(mdhd_atom->duration, duration); | |
1763 | |
1764 } else { | |
1765 ngx_mp4_set_64value(mdhd64_atom->duration, duration); | |
1766 } | |
1767 | |
1768 atom = &trak->mdhd_atom_buf; | |
1769 atom->temporary = 1; | |
1770 atom->pos = atom_header; | |
1771 atom->last = atom_header + atom_size; | |
1772 | |
1773 trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf = atom; | |
1774 | |
1775 ngx_mp4_atom_next(mp4, atom_data_size); | |
1776 | |
1777 return NGX_OK; | |
1778 } | |
1779 | |
1780 | |
1781 static ngx_int_t | |
1782 ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1783 { | |
1784 u_char *atom_header; | |
1785 size_t atom_size; | |
1786 ngx_buf_t *atom; | |
1787 ngx_http_mp4_trak_t *trak; | |
1788 | |
1789 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 hdlr atom"); | |
1790 | |
1791 atom_header = ngx_mp4_atom_header(mp4); | |
1792 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1793 ngx_mp4_set_32value(atom_header, atom_size); | |
1794 ngx_mp4_set_atom_name(atom_header, 'h', 'd', 'l', 'r'); | |
1795 | |
1796 trak = ngx_mp4_last_trak(mp4); | |
1797 | |
1798 atom = &trak->hdlr_atom_buf; | |
1799 atom->temporary = 1; | |
1800 atom->pos = atom_header; | |
1801 atom->last = atom_header + atom_size; | |
1802 | |
1803 trak->hdlr_size = atom_size; | |
1804 trak->out[NGX_HTTP_MP4_HDLR_ATOM].buf = atom; | |
1805 | |
1806 ngx_mp4_atom_next(mp4, atom_data_size); | |
1807 | |
1808 return NGX_OK; | |
1809 } | |
1810 | |
1811 | |
1812 static ngx_int_t | |
1813 ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1814 { | |
1815 u_char *atom_header; | |
1816 ngx_buf_t *atom; | |
1817 ngx_http_mp4_trak_t *trak; | |
1818 | |
1819 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "process minf atom"); | |
1820 | |
1821 atom_header = ngx_mp4_atom_header(mp4); | |
1822 ngx_mp4_set_atom_name(atom_header, 'm', 'i', 'n', 'f'); | |
1823 | |
1824 trak = ngx_mp4_last_trak(mp4); | |
1825 | |
1826 atom = &trak->minf_atom_buf; | |
1827 atom->temporary = 1; | |
1828 atom->pos = atom_header; | |
1829 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); | |
1830 | |
1831 trak->out[NGX_HTTP_MP4_MINF_ATOM].buf = atom; | |
1832 | |
1833 return ngx_http_mp4_read_atom(mp4, ngx_http_mp4_minf_atoms, atom_data_size); | |
1834 } | |
1835 | |
1836 | |
1837 static void | |
1838 ngx_http_mp4_update_minf_atom(ngx_http_mp4_file_t *mp4, | |
1839 ngx_http_mp4_trak_t *trak) | |
1840 { | |
1841 ngx_buf_t *atom; | |
1842 | |
1843 trak->size += sizeof(ngx_mp4_atom_header_t) | |
1844 + trak->vmhd_size | |
1845 + trak->smhd_size | |
1846 + trak->dinf_size; | |
1847 atom = &trak->minf_atom_buf; | |
1848 ngx_mp4_set_32value(atom->pos, trak->size); | |
1849 } | |
1850 | |
1851 | |
1852 static ngx_int_t | |
1853 ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1854 { | |
1855 u_char *atom_header; | |
1856 size_t atom_size; | |
1857 ngx_buf_t *atom; | |
1858 ngx_http_mp4_trak_t *trak; | |
1859 | |
1860 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 vmhd atom"); | |
1861 | |
1862 atom_header = ngx_mp4_atom_header(mp4); | |
1863 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1864 ngx_mp4_set_32value(atom_header, atom_size); | |
1865 ngx_mp4_set_atom_name(atom_header, 'v', 'm', 'h', 'd'); | |
1866 | |
1867 trak = ngx_mp4_last_trak(mp4); | |
1868 | |
1869 atom = &trak->vmhd_atom_buf; | |
1870 atom->temporary = 1; | |
1871 atom->pos = atom_header; | |
1872 atom->last = atom_header + atom_size; | |
1873 | |
1874 trak->vmhd_size += atom_size; | |
1875 trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf = atom; | |
1876 | |
1877 ngx_mp4_atom_next(mp4, atom_data_size); | |
1878 | |
1879 return NGX_OK; | |
1880 } | |
1881 | |
1882 | |
1883 static ngx_int_t | |
1884 ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1885 { | |
1886 u_char *atom_header; | |
1887 size_t atom_size; | |
1888 ngx_buf_t *atom; | |
1889 ngx_http_mp4_trak_t *trak; | |
1890 | |
1891 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 smhd atom"); | |
1892 | |
1893 atom_header = ngx_mp4_atom_header(mp4); | |
1894 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1895 ngx_mp4_set_32value(atom_header, atom_size); | |
1896 ngx_mp4_set_atom_name(atom_header, 's', 'm', 'h', 'd'); | |
1897 | |
1898 trak = ngx_mp4_last_trak(mp4); | |
1899 | |
1900 atom = &trak->smhd_atom_buf; | |
1901 atom->temporary = 1; | |
1902 atom->pos = atom_header; | |
1903 atom->last = atom_header + atom_size; | |
1904 | |
5807
6d468b45f40e
Mp4: use trak->smhd_size in ngx_http_mp4_read_smhd_atom().
Roman Arutyunyan <arut@nginx.com>
parents:
5638
diff
changeset
|
1905 trak->smhd_size += atom_size; |
4085 | 1906 trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf = atom; |
1907 | |
1908 ngx_mp4_atom_next(mp4, atom_data_size); | |
1909 | |
1910 return NGX_OK; | |
1911 } | |
1912 | |
1913 | |
1914 static ngx_int_t | |
1915 ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1916 { | |
1917 u_char *atom_header; | |
1918 size_t atom_size; | |
1919 ngx_buf_t *atom; | |
1920 ngx_http_mp4_trak_t *trak; | |
1921 | |
1922 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 dinf atom"); | |
1923 | |
1924 atom_header = ngx_mp4_atom_header(mp4); | |
1925 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
1926 ngx_mp4_set_32value(atom_header, atom_size); | |
1927 ngx_mp4_set_atom_name(atom_header, 'd', 'i', 'n', 'f'); | |
1928 | |
1929 trak = ngx_mp4_last_trak(mp4); | |
1930 | |
1931 atom = &trak->dinf_atom_buf; | |
1932 atom->temporary = 1; | |
1933 atom->pos = atom_header; | |
1934 atom->last = atom_header + atom_size; | |
1935 | |
1936 trak->dinf_size += atom_size; | |
1937 trak->out[NGX_HTTP_MP4_DINF_ATOM].buf = atom; | |
1938 | |
1939 ngx_mp4_atom_next(mp4, atom_data_size); | |
1940 | |
1941 return NGX_OK; | |
1942 } | |
1943 | |
1944 | |
1945 static ngx_int_t | |
1946 ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1947 { | |
1948 u_char *atom_header; | |
1949 ngx_buf_t *atom; | |
1950 ngx_http_mp4_trak_t *trak; | |
1951 | |
1952 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "process stbl atom"); | |
1953 | |
1954 atom_header = ngx_mp4_atom_header(mp4); | |
1955 ngx_mp4_set_atom_name(atom_header, 's', 't', 'b', 'l'); | |
1956 | |
1957 trak = ngx_mp4_last_trak(mp4); | |
1958 | |
1959 atom = &trak->stbl_atom_buf; | |
1960 atom->temporary = 1; | |
1961 atom->pos = atom_header; | |
1962 atom->last = atom_header + sizeof(ngx_mp4_atom_header_t); | |
1963 | |
1964 trak->out[NGX_HTTP_MP4_STBL_ATOM].buf = atom; | |
1965 | |
1966 return ngx_http_mp4_read_atom(mp4, ngx_http_mp4_stbl_atoms, atom_data_size); | |
1967 } | |
1968 | |
1969 | |
1970 static void | |
1971 ngx_http_mp4_update_stbl_atom(ngx_http_mp4_file_t *mp4, | |
1972 ngx_http_mp4_trak_t *trak) | |
1973 { | |
1974 ngx_buf_t *atom; | |
1975 | |
1976 trak->size += sizeof(ngx_mp4_atom_header_t); | |
1977 atom = &trak->stbl_atom_buf; | |
1978 ngx_mp4_set_32value(atom->pos, trak->size); | |
1979 } | |
1980 | |
1981 | |
1982 typedef struct { | |
1983 u_char size[4]; | |
1984 u_char name[4]; | |
1985 u_char version[1]; | |
1986 u_char flags[3]; | |
1987 u_char entries[4]; | |
4099
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1988 |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1989 u_char media_size[4]; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
1990 u_char media_name[4]; |
4085 | 1991 } ngx_mp4_stsd_atom_t; |
1992 | |
1993 | |
1994 static ngx_int_t | |
1995 ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
1996 { | |
1997 u_char *atom_header, *atom_table; | |
1998 size_t atom_size; | |
1999 ngx_buf_t *atom; | |
2000 ngx_mp4_stsd_atom_t *stsd_atom; | |
2001 ngx_http_mp4_trak_t *trak; | |
2002 | |
2003 /* sample description atom */ | |
2004 | |
2005 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsd atom"); | |
2006 | |
2007 atom_header = ngx_mp4_atom_header(mp4); | |
2008 stsd_atom = (ngx_mp4_stsd_atom_t *) atom_header; | |
2009 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; | |
2010 atom_table = atom_header + atom_size; | |
2011 ngx_mp4_set_32value(stsd_atom->size, atom_size); | |
2012 ngx_mp4_set_atom_name(stsd_atom, 's', 't', 's', 'd'); | |
2013 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2014 if (ngx_mp4_atom_data_size(ngx_mp4_stsd_atom_t) > atom_data_size) { |
4099
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2015 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2016 "\"%s\" mp4 stsd atom too small", mp4->file.name.data); |
4099
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2017 return NGX_ERROR; |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2018 } |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2019 |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2020 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2021 "stsd entries:%uD, media:%*s", |
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2022 ngx_mp4_get_32value(stsd_atom->entries), |
6478
3ef7bb882ad4
Fixed logging with variable field width.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6474
diff
changeset
|
2023 (size_t) 4, stsd_atom->media_name); |
4099
9ee6944590c0
Skipping traks with unsupported media formats.
Igor Sysoev <igor@sysoev.ru>
parents:
4098
diff
changeset
|
2024 |
4085 | 2025 trak = ngx_mp4_last_trak(mp4); |
2026 | |
2027 atom = &trak->stsd_atom_buf; | |
2028 atom->temporary = 1; | |
2029 atom->pos = atom_header; | |
2030 atom->last = atom_table; | |
2031 | |
2032 trak->out[NGX_HTTP_MP4_STSD_ATOM].buf = atom; | |
2033 trak->size += atom_size; | |
2034 | |
2035 ngx_mp4_atom_next(mp4, atom_data_size); | |
2036 | |
2037 return NGX_OK; | |
2038 } | |
2039 | |
2040 | |
2041 typedef struct { | |
2042 u_char size[4]; | |
2043 u_char name[4]; | |
2044 u_char version[1]; | |
2045 u_char flags[3]; | |
2046 u_char entries[4]; | |
2047 } ngx_mp4_stts_atom_t; | |
2048 | |
2049 typedef struct { | |
2050 u_char count[4]; | |
2051 u_char duration[4]; | |
2052 } ngx_mp4_stts_entry_t; | |
2053 | |
2054 | |
2055 static ngx_int_t | |
2056 ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2057 { | |
2058 u_char *atom_header, *atom_table, *atom_end; | |
2059 uint32_t entries; | |
2060 ngx_buf_t *atom, *data; | |
2061 ngx_mp4_stts_atom_t *stts_atom; | |
2062 ngx_http_mp4_trak_t *trak; | |
2063 | |
2064 /* time-to-sample atom */ | |
2065 | |
2066 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stts atom"); | |
2067 | |
2068 atom_header = ngx_mp4_atom_header(mp4); | |
2069 stts_atom = (ngx_mp4_stts_atom_t *) atom_header; | |
2070 ngx_mp4_set_atom_name(stts_atom, 's', 't', 't', 's'); | |
2071 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2072 if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2073 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2074 "\"%s\" mp4 stts atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2075 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2076 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2077 |
4085 | 2078 entries = ngx_mp4_get_32value(stts_atom->entries); |
2079 | |
2080 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
4096 | 2081 "mp4 time-to-sample entries:%uD", entries); |
4085 | 2082 |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2083 if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2084 + entries * sizeof(ngx_mp4_stts_entry_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2085 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2086 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2087 "\"%s\" mp4 stts atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2088 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2089 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2090 |
4085 | 2091 atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t); |
2092 atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t); | |
2093 | |
2094 trak = ngx_mp4_last_trak(mp4); | |
2095 trak->time_to_sample_entries = entries; | |
2096 | |
2097 atom = &trak->stts_atom_buf; | |
2098 atom->temporary = 1; | |
2099 atom->pos = atom_header; | |
2100 atom->last = atom_table; | |
2101 | |
2102 data = &trak->stts_data_buf; | |
2103 data->temporary = 1; | |
2104 data->pos = atom_table; | |
2105 data->last = atom_end; | |
2106 | |
2107 trak->out[NGX_HTTP_MP4_STTS_ATOM].buf = atom; | |
2108 trak->out[NGX_HTTP_MP4_STTS_DATA].buf = data; | |
2109 | |
2110 ngx_mp4_atom_next(mp4, atom_data_size); | |
2111 | |
2112 return NGX_OK; | |
2113 } | |
2114 | |
2115 | |
2116 static ngx_int_t | |
2117 ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4, | |
2118 ngx_http_mp4_trak_t *trak) | |
2119 { | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2120 size_t atom_size; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2121 ngx_buf_t *atom, *data; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2122 ngx_mp4_stts_atom_t *stts_atom; |
4085 | 2123 |
2124 /* | |
2125 * mdia.minf.stbl.stts updating requires trak->timescale | |
2126 * from mdia.mdhd atom which may reside after mdia.minf | |
2127 */ | |
2128 | |
2129 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2130 "mp4 stts atom update"); | |
2131 | |
2132 data = trak->out[NGX_HTTP_MP4_STTS_DATA].buf; | |
2133 | |
2134 if (data == NULL) { | |
2135 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2136 "no mp4 stts atoms were found in \"%s\"", | |
2137 mp4->file.name.data); | |
2138 return NGX_ERROR; | |
2139 } | |
2140 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2141 if (ngx_http_mp4_crop_stts_data(mp4, trak, 1) != NGX_OK) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2142 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2143 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2144 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2145 if (ngx_http_mp4_crop_stts_data(mp4, trak, 0) != NGX_OK) { |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2146 return NGX_ERROR; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2147 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2148 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2149 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2150 "time-to-sample entries:%uD", trak->time_to_sample_entries); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2151 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2152 atom_size = sizeof(ngx_mp4_stts_atom_t) + (data->last - data->pos); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2153 trak->size += atom_size; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2154 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2155 atom = trak->out[NGX_HTTP_MP4_STTS_ATOM].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2156 stts_atom = (ngx_mp4_stts_atom_t *) atom->pos; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2157 ngx_mp4_set_32value(stts_atom->size, atom_size); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2158 ngx_mp4_set_32value(stts_atom->entries, trak->time_to_sample_entries); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2159 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2160 return NGX_OK; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2161 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2162 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2163 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2164 static ngx_int_t |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2165 ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2166 ngx_http_mp4_trak_t *trak, ngx_uint_t start) |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2167 { |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2168 uint32_t count, duration, rest; |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2169 uint64_t start_time; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2170 ngx_buf_t *data; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2171 ngx_uint_t start_sample, entries, start_sec; |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2172 ngx_mp4_stts_entry_t *entry, *end; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2173 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2174 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2175 start_sec = mp4->start; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2176 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2177 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2178 "mp4 stts crop start_time:%ui", start_sec); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2179 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2180 } else if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2181 start_sec = mp4->length; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2182 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2183 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2184 "mp4 stts crop end_time:%ui", start_sec); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2185 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2186 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2187 return NGX_OK; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2188 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2189 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2190 data = trak->out[NGX_HTTP_MP4_STTS_DATA].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2191 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2192 start_time = (uint64_t) start_sec * trak->timescale / 1000; |
4085 | 2193 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2194 entries = trak->time_to_sample_entries; |
4085 | 2195 start_sample = 0; |
2196 entry = (ngx_mp4_stts_entry_t *) data->pos; | |
2197 end = (ngx_mp4_stts_entry_t *) data->last; | |
2198 | |
2199 while (entry < end) { | |
2200 count = ngx_mp4_get_32value(entry->count); | |
2201 duration = ngx_mp4_get_32value(entry->duration); | |
2202 | |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2203 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2204 "time:%uL, count:%uD, duration:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2205 start_time, count, duration); |
4085 | 2206 |
4306 | 2207 if (start_time < (uint64_t) count * duration) { |
4085 | 2208 start_sample += (ngx_uint_t) (start_time / duration); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2209 rest = (uint32_t) (start_time / duration); |
4085 | 2210 goto found; |
2211 } | |
2212 | |
2213 start_sample += count; | |
2214 start_time -= count * duration; | |
2215 entries--; | |
2216 entry++; | |
2217 } | |
2218 | |
5638
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2219 if (start) { |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2220 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2221 "start time is out mp4 stts samples in \"%s\"", |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2222 mp4->file.name.data); |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2223 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2224 return NGX_ERROR; |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2225 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2226 } else { |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2227 trak->end_sample = trak->start_sample + start_sample; |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2228 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2229 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2230 "end_sample:%ui", trak->end_sample); |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2231 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2232 return NGX_OK; |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2233 } |
4085 | 2234 |
2235 found: | |
2236 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2237 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2238 ngx_mp4_set_32value(entry->count, count - rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2239 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2240 trak->time_to_sample_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2241 trak->start_sample = start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2242 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2243 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2244 "start_sample:%ui, new count:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2245 trak->start_sample, count - rest); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2246 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2247 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2248 ngx_mp4_set_32value(entry->count, rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2249 data->last = (u_char *) (entry + 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2250 trak->time_to_sample_entries -= entries - 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2251 trak->end_sample = trak->start_sample + start_sample; |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2252 |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2253 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2254 "end_sample:%ui, new count:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2255 trak->end_sample, rest); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2256 } |
4085 | 2257 |
2258 return NGX_OK; | |
2259 } | |
2260 | |
2261 | |
2262 typedef struct { | |
2263 u_char size[4]; | |
2264 u_char name[4]; | |
2265 u_char version[1]; | |
2266 u_char flags[3]; | |
2267 u_char entries[4]; | |
2268 } ngx_http_mp4_stss_atom_t; | |
2269 | |
2270 | |
2271 static ngx_int_t | |
2272 ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2273 { | |
2274 u_char *atom_header, *atom_table, *atom_end; | |
2275 uint32_t entries; | |
2276 ngx_buf_t *atom, *data; | |
2277 ngx_http_mp4_trak_t *trak; | |
2278 ngx_http_mp4_stss_atom_t *stss_atom; | |
2279 | |
2280 /* sync samples atom */ | |
2281 | |
2282 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stss atom"); | |
2283 | |
2284 atom_header = ngx_mp4_atom_header(mp4); | |
2285 stss_atom = (ngx_http_mp4_stss_atom_t *) atom_header; | |
2286 ngx_mp4_set_atom_name(stss_atom, 's', 't', 's', 's'); | |
2287 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2288 if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2289 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2290 "\"%s\" mp4 stss atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2291 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2292 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2293 |
4085 | 2294 entries = ngx_mp4_get_32value(stss_atom->entries); |
2295 | |
2296 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
4096 | 2297 "sync sample entries:%uD", entries); |
4085 | 2298 |
2299 trak = ngx_mp4_last_trak(mp4); | |
2300 trak->sync_samples_entries = entries; | |
2301 | |
2302 atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t); | |
2303 | |
2304 atom = &trak->stss_atom_buf; | |
2305 atom->temporary = 1; | |
2306 atom->pos = atom_header; | |
2307 atom->last = atom_table; | |
2308 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2309 if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2310 + entries * sizeof(uint32_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2311 { |
4085 | 2312 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2313 "\"%s\" mp4 stss atom too small", mp4->file.name.data); |
4085 | 2314 return NGX_ERROR; |
2315 } | |
2316 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2317 atom_end = atom_table + entries * sizeof(uint32_t); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2318 |
4085 | 2319 data = &trak->stss_data_buf; |
2320 data->temporary = 1; | |
2321 data->pos = atom_table; | |
2322 data->last = atom_end; | |
2323 | |
2324 trak->out[NGX_HTTP_MP4_STSS_ATOM].buf = atom; | |
2325 trak->out[NGX_HTTP_MP4_STSS_DATA].buf = data; | |
2326 | |
2327 ngx_mp4_atom_next(mp4, atom_data_size); | |
2328 | |
2329 return NGX_OK; | |
2330 } | |
2331 | |
2332 | |
2333 static ngx_int_t | |
2334 ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4, | |
2335 ngx_http_mp4_trak_t *trak) | |
2336 { | |
2337 size_t atom_size; | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2338 uint32_t sample, start_sample, *entry, *end; |
4085 | 2339 ngx_buf_t *atom, *data; |
2340 ngx_http_mp4_stss_atom_t *stss_atom; | |
2341 | |
2342 /* | |
2343 * mdia.minf.stbl.stss updating requires trak->start_sample | |
2344 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
2345 * atom which may reside after mdia.minf | |
2346 */ | |
2347 | |
2348 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2349 "mp4 stss atom update"); | |
2350 | |
2351 data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf; | |
2352 | |
2353 if (data == NULL) { | |
2354 return NGX_OK; | |
2355 } | |
2356 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2357 ngx_http_mp4_crop_stss_data(mp4, trak, 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2358 ngx_http_mp4_crop_stss_data(mp4, trak, 0); |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2359 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2360 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2361 "sync sample entries:%uD", trak->sync_samples_entries); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2362 |
5622
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2363 if (trak->sync_samples_entries) { |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2364 entry = (uint32_t *) data->pos; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2365 end = (uint32_t *) data->last; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2366 |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2367 start_sample = trak->start_sample; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2368 |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2369 while (entry < end) { |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2370 sample = ngx_mp4_get_32value(entry); |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2371 sample -= start_sample; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2372 ngx_mp4_set_32value(entry, sample); |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2373 entry++; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2374 } |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2375 |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2376 } else { |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2377 trak->out[NGX_HTTP_MP4_STSS_DATA].buf = NULL; |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2378 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2379 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2380 atom_size = sizeof(ngx_http_mp4_stss_atom_t) + (data->last - data->pos); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2381 trak->size += atom_size; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2382 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2383 atom = trak->out[NGX_HTTP_MP4_STSS_ATOM].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2384 stss_atom = (ngx_http_mp4_stss_atom_t *) atom->pos; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2385 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2386 ngx_mp4_set_32value(stss_atom->size, atom_size); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2387 ngx_mp4_set_32value(stss_atom->entries, trak->sync_samples_entries); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2388 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2389 return NGX_OK; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2390 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2391 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2392 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2393 static void |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2394 ngx_http_mp4_crop_stss_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2395 ngx_http_mp4_trak_t *trak, ngx_uint_t start) |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2396 { |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2397 uint32_t sample, start_sample, *entry, *end; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2398 ngx_buf_t *data; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2399 ngx_uint_t entries; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2400 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2401 /* sync samples starts from 1 */ |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2402 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2403 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2404 start_sample = trak->start_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2405 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2406 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2407 "mp4 stss crop start_sample:%uD", start_sample); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2408 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2409 } else if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2410 start_sample = trak->end_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2411 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2412 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2413 "mp4 stss crop end_sample:%uD", start_sample); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2414 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2415 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2416 return; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2417 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2418 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2419 data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2420 |
4085 | 2421 entries = trak->sync_samples_entries; |
2422 entry = (uint32_t *) data->pos; | |
2423 end = (uint32_t *) data->last; | |
2424 | |
2425 while (entry < end) { | |
2426 sample = ngx_mp4_get_32value(entry); | |
2427 | |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2428 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2429 "sync:%uD", sample); |
4085 | 2430 |
2431 if (sample >= start_sample) { | |
2432 goto found; | |
2433 } | |
2434 | |
2435 entries--; | |
2436 entry++; | |
2437 } | |
2438 | |
5542
847c308917af
Mp4: fix seeks after the last key frame.
Roman Arutyunyan <arut@nginx.com>
parents:
5496
diff
changeset
|
2439 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2440 "sample is out of mp4 stss atom"); |
4085 | 2441 |
2442 found: | |
2443 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2444 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2445 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2446 trak->sync_samples_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2447 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2448 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2449 data->last = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2450 trak->sync_samples_entries -= entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2451 } |
4085 | 2452 } |
2453 | |
2454 | |
2455 typedef struct { | |
2456 u_char size[4]; | |
2457 u_char name[4]; | |
2458 u_char version[1]; | |
2459 u_char flags[3]; | |
2460 u_char entries[4]; | |
2461 } ngx_mp4_ctts_atom_t; | |
2462 | |
2463 typedef struct { | |
2464 u_char count[4]; | |
2465 u_char offset[4]; | |
2466 } ngx_mp4_ctts_entry_t; | |
2467 | |
2468 | |
2469 static ngx_int_t | |
2470 ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2471 { | |
2472 u_char *atom_header, *atom_table, *atom_end; | |
2473 uint32_t entries; | |
2474 ngx_buf_t *atom, *data; | |
2475 ngx_mp4_ctts_atom_t *ctts_atom; | |
2476 ngx_http_mp4_trak_t *trak; | |
2477 | |
2478 /* composition offsets atom */ | |
2479 | |
2480 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ctts atom"); | |
2481 | |
2482 atom_header = ngx_mp4_atom_header(mp4); | |
2483 ctts_atom = (ngx_mp4_ctts_atom_t *) atom_header; | |
2484 ngx_mp4_set_atom_name(ctts_atom, 'c', 't', 't', 's'); | |
2485 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2486 if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2487 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2488 "\"%s\" mp4 ctts atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2489 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2490 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2491 |
4085 | 2492 entries = ngx_mp4_get_32value(ctts_atom->entries); |
2493 | |
2494 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
4096 | 2495 "composition offset entries:%uD", entries); |
4085 | 2496 |
2497 trak = ngx_mp4_last_trak(mp4); | |
2498 trak->composition_offset_entries = entries; | |
2499 | |
2500 atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t); | |
2501 | |
2502 atom = &trak->ctts_atom_buf; | |
2503 atom->temporary = 1; | |
2504 atom->pos = atom_header; | |
2505 atom->last = atom_table; | |
2506 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2507 if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2508 + entries * sizeof(ngx_mp4_ctts_entry_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2509 { |
4085 | 2510 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2511 "\"%s\" mp4 ctts atom too small", mp4->file.name.data); |
4085 | 2512 return NGX_ERROR; |
2513 } | |
2514 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2515 atom_end = atom_table + entries * sizeof(ngx_mp4_ctts_entry_t); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2516 |
4085 | 2517 data = &trak->ctts_data_buf; |
2518 data->temporary = 1; | |
2519 data->pos = atom_table; | |
2520 data->last = atom_end; | |
2521 | |
2522 trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = atom; | |
2523 trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = data; | |
2524 | |
2525 ngx_mp4_atom_next(mp4, atom_data_size); | |
2526 | |
2527 return NGX_OK; | |
2528 } | |
2529 | |
2530 | |
2531 static void | |
2532 ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4, | |
2533 ngx_http_mp4_trak_t *trak) | |
2534 { | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2535 size_t atom_size; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2536 ngx_buf_t *atom, *data; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2537 ngx_mp4_ctts_atom_t *ctts_atom; |
4085 | 2538 |
2539 /* | |
2540 * mdia.minf.stbl.ctts updating requires trak->start_sample | |
2541 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
2542 * atom which may reside after mdia.minf | |
2543 */ | |
2544 | |
2545 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2546 "mp4 ctts atom update"); | |
2547 | |
2548 data = trak->out[NGX_HTTP_MP4_CTTS_DATA].buf; | |
2549 | |
2550 if (data == NULL) { | |
2551 return; | |
2552 } | |
2553 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2554 ngx_http_mp4_crop_ctts_data(mp4, trak, 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2555 ngx_http_mp4_crop_ctts_data(mp4, trak, 0); |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2556 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2557 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2558 "composition offset entries:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2559 trak->composition_offset_entries); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2560 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2561 if (trak->composition_offset_entries == 0) { |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2562 trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = NULL; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2563 trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = NULL; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2564 return; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2565 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2566 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2567 atom_size = sizeof(ngx_mp4_ctts_atom_t) + (data->last - data->pos); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2568 trak->size += atom_size; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2569 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2570 atom = trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2571 ctts_atom = (ngx_mp4_ctts_atom_t *) atom->pos; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2572 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2573 ngx_mp4_set_32value(ctts_atom->size, atom_size); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2574 ngx_mp4_set_32value(ctts_atom->entries, trak->composition_offset_entries); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2575 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2576 return; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2577 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2578 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2579 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2580 static void |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2581 ngx_http_mp4_crop_ctts_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2582 ngx_http_mp4_trak_t *trak, ngx_uint_t start) |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2583 { |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2584 uint32_t count, start_sample, rest; |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2585 ngx_buf_t *data; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2586 ngx_uint_t entries; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2587 ngx_mp4_ctts_entry_t *entry, *end; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2588 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2589 /* sync samples starts from 1 */ |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2590 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2591 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2592 start_sample = trak->start_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2593 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2594 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2595 "mp4 ctts crop start_sample:%uD", start_sample); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2596 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2597 } else if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2598 start_sample = trak->end_sample - trak->start_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2599 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2600 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2601 "mp4 ctts crop end_sample:%uD", start_sample); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2602 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2603 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2604 return; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2605 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2606 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2607 data = trak->out[NGX_HTTP_MP4_CTTS_DATA].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2608 |
4085 | 2609 entries = trak->composition_offset_entries; |
2610 entry = (ngx_mp4_ctts_entry_t *) data->pos; | |
2611 end = (ngx_mp4_ctts_entry_t *) data->last; | |
2612 | |
2613 while (entry < end) { | |
2614 count = ngx_mp4_get_32value(entry->count); | |
2615 | |
4088
8fe1da7b8386
bugfix of r4086: nginx could not be built without debug log.
Igor Sysoev <igor@sysoev.ru>
parents:
4087
diff
changeset
|
2616 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2617 "sample:%uD, count:%uD, offset:%uD", |
4085 | 2618 start_sample, count, ngx_mp4_get_32value(entry->offset)); |
2619 | |
6474 | 2620 if (start_sample <= count) { |
2621 rest = start_sample - 1; | |
2622 goto found; | |
2623 } | |
2624 | |
2625 start_sample -= count; | |
2626 entries--; | |
2627 entry++; | |
4085 | 2628 } |
2629 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2630 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2631 data->pos = (u_char *) end; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2632 trak->composition_offset_entries = 0; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2633 } |
4085 | 2634 |
2635 return; | |
2636 | |
2637 found: | |
2638 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2639 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2640 ngx_mp4_set_32value(entry->count, count - rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2641 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2642 trak->composition_offset_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2643 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2644 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2645 ngx_mp4_set_32value(entry->count, rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2646 data->last = (u_char *) (entry + 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2647 trak->composition_offset_entries -= entries - 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2648 } |
4085 | 2649 } |
2650 | |
2651 | |
2652 typedef struct { | |
2653 u_char size[4]; | |
2654 u_char name[4]; | |
2655 u_char version[1]; | |
2656 u_char flags[3]; | |
2657 u_char entries[4]; | |
2658 } ngx_mp4_stsc_atom_t; | |
2659 | |
2660 | |
2661 static ngx_int_t | |
2662 ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2663 { | |
2664 u_char *atom_header, *atom_table, *atom_end; | |
2665 uint32_t entries; | |
2666 ngx_buf_t *atom, *data; | |
2667 ngx_mp4_stsc_atom_t *stsc_atom; | |
2668 ngx_http_mp4_trak_t *trak; | |
2669 | |
2670 /* sample-to-chunk atom */ | |
2671 | |
2672 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsc atom"); | |
2673 | |
2674 atom_header = ngx_mp4_atom_header(mp4); | |
2675 stsc_atom = (ngx_mp4_stsc_atom_t *) atom_header; | |
2676 ngx_mp4_set_atom_name(stsc_atom, 's', 't', 's', 'c'); | |
2677 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2678 if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2679 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2680 "\"%s\" mp4 stsc atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2681 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2682 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2683 |
4085 | 2684 entries = ngx_mp4_get_32value(stsc_atom->entries); |
2685 | |
2686 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
4096 | 2687 "sample-to-chunk entries:%uD", entries); |
4085 | 2688 |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2689 if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2690 + entries * sizeof(ngx_mp4_stsc_entry_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2691 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2692 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2693 "\"%s\" mp4 stsc atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2694 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2695 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2696 |
4085 | 2697 atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t); |
2698 atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t); | |
2699 | |
2700 trak = ngx_mp4_last_trak(mp4); | |
2701 trak->sample_to_chunk_entries = entries; | |
2702 | |
2703 atom = &trak->stsc_atom_buf; | |
2704 atom->temporary = 1; | |
2705 atom->pos = atom_header; | |
2706 atom->last = atom_table; | |
2707 | |
2708 data = &trak->stsc_data_buf; | |
2709 data->temporary = 1; | |
2710 data->pos = atom_table; | |
2711 data->last = atom_end; | |
2712 | |
2713 trak->out[NGX_HTTP_MP4_STSC_ATOM].buf = atom; | |
2714 trak->out[NGX_HTTP_MP4_STSC_DATA].buf = data; | |
2715 | |
2716 ngx_mp4_atom_next(mp4, atom_data_size); | |
2717 | |
2718 return NGX_OK; | |
2719 } | |
2720 | |
2721 | |
2722 static ngx_int_t | |
2723 ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, | |
2724 ngx_http_mp4_trak_t *trak) | |
2725 { | |
2726 size_t atom_size; | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2727 uint32_t chunk; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2728 ngx_buf_t *atom, *data; |
4085 | 2729 ngx_mp4_stsc_atom_t *stsc_atom; |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2730 ngx_mp4_stsc_entry_t *entry, *end; |
4085 | 2731 |
2732 /* | |
2733 * mdia.minf.stbl.stsc updating requires trak->start_sample | |
2734 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
2735 * atom which may reside after mdia.minf | |
2736 */ | |
2737 | |
2738 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2739 "mp4 stsc atom update"); | |
2740 | |
2741 data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf; | |
2742 | |
2743 if (data == NULL) { | |
2744 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2745 "no mp4 stsc atoms were found in \"%s\"", | |
2746 mp4->file.name.data); | |
2747 return NGX_ERROR; | |
2748 } | |
2749 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2750 if (trak->sample_to_chunk_entries == 0) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2751 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2752 "zero number of entries in stsc atom in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2753 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2754 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2755 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2756 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2757 if (ngx_http_mp4_crop_stsc_data(mp4, trak, 1) != NGX_OK) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2758 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2759 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2760 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2761 if (ngx_http_mp4_crop_stsc_data(mp4, trak, 0) != NGX_OK) { |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2762 return NGX_ERROR; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2763 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2764 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2765 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2766 "sample-to-chunk entries:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2767 trak->sample_to_chunk_entries); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2768 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2769 entry = (ngx_mp4_stsc_entry_t *) data->pos; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2770 end = (ngx_mp4_stsc_entry_t *) data->last; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2771 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2772 while (entry < end) { |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2773 chunk = ngx_mp4_get_32value(entry->chunk); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2774 chunk -= trak->start_chunk; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2775 ngx_mp4_set_32value(entry->chunk, chunk); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2776 entry++; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2777 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2778 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2779 atom_size = sizeof(ngx_mp4_stsc_atom_t) |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2780 + trak->sample_to_chunk_entries * sizeof(ngx_mp4_stsc_entry_t); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2781 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2782 trak->size += atom_size; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2783 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2784 atom = trak->out[NGX_HTTP_MP4_STSC_ATOM].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2785 stsc_atom = (ngx_mp4_stsc_atom_t *) atom->pos; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2786 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2787 ngx_mp4_set_32value(stsc_atom->size, atom_size); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2788 ngx_mp4_set_32value(stsc_atom->entries, trak->sample_to_chunk_entries); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2789 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2790 return NGX_OK; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2791 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2792 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2793 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2794 static ngx_int_t |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2795 ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2796 ngx_http_mp4_trak_t *trak, ngx_uint_t start) |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2797 { |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2798 uint32_t start_sample, chunk, samples, id, next_chunk, n, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2799 prev_samples; |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2800 ngx_buf_t *data, *buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2801 ngx_uint_t entries, target_chunk, chunk_samples; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2802 ngx_mp4_stsc_entry_t *entry, *end, *first; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2803 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2804 entries = trak->sample_to_chunk_entries - 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2805 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2806 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2807 start_sample = (uint32_t) trak->start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2808 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2809 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2810 "mp4 stsc crop start_sample:%uD", start_sample); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2811 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2812 } else if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2813 start_sample = (uint32_t) (trak->end_sample - trak->start_sample); |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2814 samples = 0; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2815 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2816 data = trak->out[NGX_HTTP_MP4_STSC_START].buf; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2817 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2818 if (data) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2819 entry = (ngx_mp4_stsc_entry_t *) data->pos; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2820 samples = ngx_mp4_get_32value(entry->samples); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2821 entries--; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2822 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2823 if (samples > start_sample) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2824 samples = start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2825 ngx_mp4_set_32value(entry->samples, samples); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2826 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2827 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2828 start_sample -= samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2829 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2830 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2831 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2832 "mp4 stsc crop end_sample:%uD, ext_samples:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2833 start_sample, samples); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2834 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2835 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2836 return NGX_OK; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2837 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2838 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2839 data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2840 |
4085 | 2841 entry = (ngx_mp4_stsc_entry_t *) data->pos; |
2842 end = (ngx_mp4_stsc_entry_t *) data->last; | |
2843 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2844 chunk = ngx_mp4_get_32value(entry->chunk); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2845 samples = ngx_mp4_get_32value(entry->samples); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2846 id = ngx_mp4_get_32value(entry->id); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2847 prev_samples = 0; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2848 entry++; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2849 |
4085 | 2850 while (entry < end) { |
2851 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2852 next_chunk = ngx_mp4_get_32value(entry->chunk); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2853 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2854 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2855 "sample:%uD, chunk:%uD, chunks:%uD, " |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2856 "samples:%uD, id:%uD", |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2857 start_sample, chunk, next_chunk - chunk, samples, id); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2858 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2859 n = (next_chunk - chunk) * samples; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2860 |
5578
e280ece17020
Mp4: remove useless leading stsc entry in result mp4.
Roman Arutyunyan <arut@nginx.com>
parents:
5544
diff
changeset
|
2861 if (start_sample < n) { |
4085 | 2862 goto found; |
2863 } | |
2864 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2865 start_sample -= n; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2866 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2867 prev_samples = samples; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2868 chunk = next_chunk; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2869 samples = ngx_mp4_get_32value(entry->samples); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2870 id = ngx_mp4_get_32value(entry->id); |
4085 | 2871 entries--; |
2872 entry++; | |
2873 } | |
2874 | |
5544
2f586f1684fa
Mp4: fix seeks to standalone last chunk.
Roman Arutyunyan <arut@nginx.com>
parents:
5543
diff
changeset
|
2875 next_chunk = trak->chunks + 1; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2876 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2877 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2878 "sample:%uD, chunk:%uD, chunks:%uD, samples:%uD", |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2879 start_sample, chunk, next_chunk - chunk, samples); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2880 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2881 n = (next_chunk - chunk) * samples; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2882 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2883 if (start_sample > n) { |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2884 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2885 "%s time is out mp4 stsc chunks in \"%s\"", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2886 start ? "start" : "end", mp4->file.name.data); |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2887 return NGX_ERROR; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2888 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2889 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2890 found: |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2891 |
4085 | 2892 entries++; |
2893 entry--; | |
2894 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2895 if (samples == 0) { |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2896 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2897 "zero number of samples in \"%s\"", |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2898 mp4->file.name.data); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2899 return NGX_ERROR; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2900 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2901 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2902 target_chunk = chunk - 1; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2903 target_chunk += start_sample / samples; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2904 chunk_samples = start_sample % samples; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2905 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2906 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2907 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2908 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2909 trak->sample_to_chunk_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2910 trak->start_chunk = target_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2911 trak->start_chunk_samples = chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2912 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2913 ngx_mp4_set_32value(entry->chunk, trak->start_chunk + 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2914 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2915 samples -= chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2916 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2917 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2918 "start_chunk:%ui, start_chunk_samples:%ui", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2919 trak->start_chunk, trak->start_chunk_samples); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2920 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2921 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2922 if (start_sample) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2923 data->last = (u_char *) (entry + 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2924 trak->sample_to_chunk_entries -= entries - 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2925 trak->end_chunk_samples = samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2926 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2927 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2928 data->last = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2929 trak->sample_to_chunk_entries -= entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2930 trak->end_chunk_samples = prev_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2931 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2932 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2933 if (chunk_samples) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2934 trak->end_chunk = target_chunk + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2935 trak->end_chunk_samples = chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2936 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2937 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2938 trak->end_chunk = target_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2939 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2940 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2941 samples = chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2942 next_chunk = chunk + 1; |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2943 |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2944 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2945 "end_chunk:%ui, end_chunk_samples:%ui", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2946 trak->end_chunk, trak->end_chunk_samples); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2947 } |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2948 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2949 if (chunk_samples && next_chunk - target_chunk == 2) { |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2950 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2951 ngx_mp4_set_32value(entry->samples, samples); |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2952 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2953 } else if (chunk_samples && start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2954 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2955 first = &trak->stsc_start_chunk_entry; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2956 ngx_mp4_set_32value(first->chunk, 1); |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2957 ngx_mp4_set_32value(first->samples, samples); |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2958 ngx_mp4_set_32value(first->id, id); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2959 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2960 buf = &trak->stsc_start_chunk_buf; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2961 buf->temporary = 1; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2962 buf->pos = (u_char *) first; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2963 buf->last = (u_char *) first + sizeof(ngx_mp4_stsc_entry_t); |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2964 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2965 trak->out[NGX_HTTP_MP4_STSC_START].buf = buf; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2966 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2967 ngx_mp4_set_32value(entry->chunk, trak->start_chunk + 2); |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2968 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2969 trak->sample_to_chunk_entries++; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2970 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2971 } else if (chunk_samples) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2972 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2973 first = &trak->stsc_end_chunk_entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2974 ngx_mp4_set_32value(first->chunk, trak->end_chunk - trak->start_chunk); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2975 ngx_mp4_set_32value(first->samples, samples); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2976 ngx_mp4_set_32value(first->id, id); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2977 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2978 buf = &trak->stsc_end_chunk_buf; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2979 buf->temporary = 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2980 buf->pos = (u_char *) first; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2981 buf->last = (u_char *) first + sizeof(ngx_mp4_stsc_entry_t); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2982 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2983 trak->out[NGX_HTTP_MP4_STSC_END].buf = buf; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2984 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2985 trak->sample_to_chunk_entries++; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2986 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2987 |
4085 | 2988 return NGX_OK; |
2989 } | |
2990 | |
2991 | |
2992 typedef struct { | |
2993 u_char size[4]; | |
2994 u_char name[4]; | |
2995 u_char version[1]; | |
2996 u_char flags[3]; | |
2997 u_char uniform_size[4]; | |
2998 u_char entries[4]; | |
2999 } ngx_mp4_stsz_atom_t; | |
3000 | |
3001 | |
3002 static ngx_int_t | |
3003 ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
3004 { | |
3005 u_char *atom_header, *atom_table, *atom_end; | |
3006 size_t atom_size; | |
3007 uint32_t entries, size; | |
3008 ngx_buf_t *atom, *data; | |
3009 ngx_mp4_stsz_atom_t *stsz_atom; | |
3010 ngx_http_mp4_trak_t *trak; | |
3011 | |
3012 /* sample sizes atom */ | |
3013 | |
3014 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsz atom"); | |
3015 | |
3016 atom_header = ngx_mp4_atom_header(mp4); | |
3017 stsz_atom = (ngx_mp4_stsz_atom_t *) atom_header; | |
3018 ngx_mp4_set_atom_name(stsz_atom, 's', 't', 's', 'z'); | |
3019 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3020 if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3021 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3022 "\"%s\" mp4 stsz atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3023 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3024 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3025 |
4085 | 3026 size = ngx_mp4_get_32value(stsz_atom->uniform_size); |
3027 entries = ngx_mp4_get_32value(stsz_atom->entries); | |
3028 | |
3029 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3030 "sample uniform size:%uD, entries:%uD", size, entries); | |
3031 | |
3032 trak = ngx_mp4_last_trak(mp4); | |
3033 trak->sample_sizes_entries = entries; | |
3034 | |
3035 atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t); | |
3036 | |
3037 atom = &trak->stsz_atom_buf; | |
3038 atom->temporary = 1; | |
3039 atom->pos = atom_header; | |
3040 atom->last = atom_table; | |
3041 | |
3042 trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf = atom; | |
3043 | |
3044 if (size == 0) { | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3045 if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3046 + entries * sizeof(uint32_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3047 { |
4085 | 3048 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3049 "\"%s\" mp4 stsz atom too small", |
4085 | 3050 mp4->file.name.data); |
3051 return NGX_ERROR; | |
3052 } | |
3053 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3054 atom_end = atom_table + entries * sizeof(uint32_t); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3055 |
4085 | 3056 data = &trak->stsz_data_buf; |
3057 data->temporary = 1; | |
3058 data->pos = atom_table; | |
3059 data->last = atom_end; | |
3060 | |
3061 trak->out[NGX_HTTP_MP4_STSZ_DATA].buf = data; | |
3062 | |
3063 } else { | |
3064 /* if size != 0 then all samples are the same size */ | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3065 /* TODO : chunk samples */ |
4085 | 3066 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; |
3067 ngx_mp4_set_32value(atom_header, atom_size); | |
3068 trak->size += atom_size; | |
3069 } | |
3070 | |
3071 ngx_mp4_atom_next(mp4, atom_data_size); | |
3072 | |
3073 return NGX_OK; | |
3074 } | |
3075 | |
3076 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3077 static ngx_int_t |
4085 | 3078 ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, |
3079 ngx_http_mp4_trak_t *trak) | |
3080 { | |
3081 size_t atom_size; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3082 uint32_t *pos, *end, entries; |
4085 | 3083 ngx_buf_t *atom, *data; |
3084 ngx_mp4_stsz_atom_t *stsz_atom; | |
3085 | |
3086 /* | |
3087 * mdia.minf.stbl.stsz updating requires trak->start_sample | |
3088 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
3089 * atom which may reside after mdia.minf | |
3090 */ | |
3091 | |
3092 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3093 "mp4 stsz atom update"); | |
3094 | |
3095 data = trak->out[NGX_HTTP_MP4_STSZ_DATA].buf; | |
3096 | |
3097 if (data) { | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3098 entries = trak->sample_sizes_entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3099 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3100 if (trak->start_sample > entries) { |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3101 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3102 "start time is out mp4 stsz samples in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3103 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3104 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3105 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3106 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3107 entries -= trak->start_sample; |
4085 | 3108 data->pos += trak->start_sample * sizeof(uint32_t); |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3109 end = (uint32_t *) data->pos; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3110 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3111 for (pos = end - trak->start_chunk_samples; pos < end; pos++) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3112 trak->start_chunk_samples_size += ngx_mp4_get_32value(pos); |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3113 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3114 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3115 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3116 "chunk samples sizes:%uL", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3117 trak->start_chunk_samples_size); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3118 |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3119 if (trak->start_chunk_samples_size > (uint64_t) mp4->end) { |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3120 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3121 "too large mp4 start samples size in \"%s\"", |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3122 mp4->file.name.data); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3123 return NGX_ERROR; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3124 } |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3125 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3126 if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3127 if (trak->end_sample - trak->start_sample > entries) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3128 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3129 "end time is out mp4 stsz samples in \"%s\"", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3130 mp4->file.name.data); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3131 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3132 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3133 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3134 entries = trak->end_sample - trak->start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3135 data->last = data->pos + entries * sizeof(uint32_t); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3136 end = (uint32_t *) data->last; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3137 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3138 for (pos = end - trak->end_chunk_samples; pos < end; pos++) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3139 trak->end_chunk_samples_size += ngx_mp4_get_32value(pos); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3140 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3141 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3142 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3143 "mp4 stsz end_chunk_samples_size:%uL", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3144 trak->end_chunk_samples_size); |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3145 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3146 if (trak->end_chunk_samples_size > (uint64_t) mp4->end) { |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3147 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3148 "too large mp4 end samples size in \"%s\"", |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3149 mp4->file.name.data); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3150 return NGX_ERROR; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3151 } |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3152 } |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3153 |
4085 | 3154 atom_size = sizeof(ngx_mp4_stsz_atom_t) + (data->last - data->pos); |
3155 trak->size += atom_size; | |
3156 | |
3157 atom = trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf; | |
3158 stsz_atom = (ngx_mp4_stsz_atom_t *) atom->pos; | |
3159 | |
3160 ngx_mp4_set_32value(stsz_atom->size, atom_size); | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3161 ngx_mp4_set_32value(stsz_atom->entries, entries); |
4085 | 3162 } |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3163 |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3164 return NGX_OK; |
4085 | 3165 } |
3166 | |
3167 | |
3168 typedef struct { | |
3169 u_char size[4]; | |
3170 u_char name[4]; | |
3171 u_char version[1]; | |
3172 u_char flags[3]; | |
3173 u_char entries[4]; | |
3174 } ngx_mp4_stco_atom_t; | |
3175 | |
3176 | |
3177 static ngx_int_t | |
3178 ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
3179 { | |
3180 u_char *atom_header, *atom_table, *atom_end; | |
3181 uint32_t entries; | |
3182 ngx_buf_t *atom, *data; | |
3183 ngx_mp4_stco_atom_t *stco_atom; | |
3184 ngx_http_mp4_trak_t *trak; | |
3185 | |
3186 /* chunk offsets atom */ | |
3187 | |
3188 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stco atom"); | |
3189 | |
3190 atom_header = ngx_mp4_atom_header(mp4); | |
3191 stco_atom = (ngx_mp4_stco_atom_t *) atom_header; | |
3192 ngx_mp4_set_atom_name(stco_atom, 's', 't', 'c', 'o'); | |
3193 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3194 if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3195 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3196 "\"%s\" mp4 stco atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3197 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3198 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3199 |
4085 | 3200 entries = ngx_mp4_get_32value(stco_atom->entries); |
3201 | |
3202 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); | |
3203 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3204 if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3205 + entries * sizeof(uint32_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3206 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3207 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3208 "\"%s\" mp4 stco atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3209 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3210 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3211 |
4085 | 3212 atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t); |
3213 atom_end = atom_table + entries * sizeof(uint32_t); | |
3214 | |
3215 trak = ngx_mp4_last_trak(mp4); | |
3216 trak->chunks = entries; | |
3217 | |
4107 | 3218 atom = &trak->stco_atom_buf; |
4085 | 3219 atom->temporary = 1; |
3220 atom->pos = atom_header; | |
3221 atom->last = atom_table; | |
3222 | |
4107 | 3223 data = &trak->stco_data_buf; |
4085 | 3224 data->temporary = 1; |
3225 data->pos = atom_table; | |
3226 data->last = atom_end; | |
3227 | |
3228 trak->out[NGX_HTTP_MP4_STCO_ATOM].buf = atom; | |
3229 trak->out[NGX_HTTP_MP4_STCO_DATA].buf = data; | |
3230 | |
3231 ngx_mp4_atom_next(mp4, atom_data_size); | |
3232 | |
3233 return NGX_OK; | |
3234 } | |
3235 | |
3236 | |
3237 static ngx_int_t | |
3238 ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4, | |
3239 ngx_http_mp4_trak_t *trak) | |
3240 { | |
3241 size_t atom_size; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3242 uint32_t entries; |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3243 uint64_t chunk_offset, samples_size; |
4085 | 3244 ngx_buf_t *atom, *data; |
3245 ngx_mp4_stco_atom_t *stco_atom; | |
3246 | |
3247 /* | |
3248 * mdia.minf.stbl.stco updating requires trak->start_chunk | |
3249 * from mdia.minf.stbl.stsc which depends on value from mdia.mdhd | |
3250 * atom which may reside after mdia.minf | |
3251 */ | |
3252 | |
3253 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3254 "mp4 stco atom update"); | |
3255 | |
3256 data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf; | |
3257 | |
3258 if (data == NULL) { | |
3259 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
3260 "no mp4 stco atoms were found in \"%s\"", | |
3261 mp4->file.name.data); | |
3262 return NGX_ERROR; | |
3263 } | |
3264 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3265 if (trak->start_chunk > trak->chunks) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3266 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3267 "start time is out mp4 stco chunks in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3268 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3269 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3270 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3271 |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3272 data->pos += trak->start_chunk * sizeof(uint32_t); |
4085 | 3273 |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3274 chunk_offset = ngx_mp4_get_32value(data->pos); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3275 samples_size = trak->start_chunk_samples_size; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3276 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3277 if (chunk_offset > (uint64_t) mp4->end - samples_size |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3278 || chunk_offset + samples_size > NGX_MAX_UINT32_VALUE) |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3279 { |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3280 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3281 "too large chunk offset in \"%s\"", |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3282 mp4->file.name.data); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3283 return NGX_ERROR; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3284 } |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3285 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3286 trak->start_offset = chunk_offset + samples_size; |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3287 ngx_mp4_set_32value(data->pos, trak->start_offset); |
4085 | 3288 |
3289 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
3290 "start chunk offset:%O", trak->start_offset); |
4085 | 3291 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3292 if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3293 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3294 if (trak->end_chunk > trak->chunks) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3295 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3296 "end time is out mp4 stco chunks in \"%s\"", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3297 mp4->file.name.data); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3298 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3299 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3300 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3301 entries = trak->end_chunk - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3302 data->last = data->pos + entries * sizeof(uint32_t); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3303 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3304 if (entries) { |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3305 chunk_offset = ngx_mp4_get_32value(data->last - sizeof(uint32_t)); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3306 samples_size = trak->end_chunk_samples_size; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3307 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3308 if (chunk_offset > (uint64_t) mp4->end - samples_size |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3309 || chunk_offset + samples_size > NGX_MAX_UINT32_VALUE) |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3310 { |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3311 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3312 "too large chunk offset in \"%s\"", |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3313 mp4->file.name.data); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3314 return NGX_ERROR; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3315 } |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3316 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3317 trak->end_offset = chunk_offset + samples_size; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3318 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3319 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3320 "end chunk offset:%O", trak->end_offset); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3321 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3322 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3323 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3324 entries = trak->chunks - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3325 trak->end_offset = mp4->mdat_data.buf->file_last; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3326 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3327 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3328 if (entries == 0) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3329 trak->start_offset = mp4->end; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3330 trak->end_offset = 0; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3331 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3332 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3333 atom_size = sizeof(ngx_mp4_stco_atom_t) + (data->last - data->pos); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3334 trak->size += atom_size; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3335 |
4085 | 3336 atom = trak->out[NGX_HTTP_MP4_STCO_ATOM].buf; |
3337 stco_atom = (ngx_mp4_stco_atom_t *) atom->pos; | |
3338 | |
3339 ngx_mp4_set_32value(stco_atom->size, atom_size); | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3340 ngx_mp4_set_32value(stco_atom->entries, entries); |
4085 | 3341 |
3342 return NGX_OK; | |
3343 } | |
3344 | |
3345 | |
3346 static void | |
3347 ngx_http_mp4_adjust_stco_atom(ngx_http_mp4_file_t *mp4, | |
3348 ngx_http_mp4_trak_t *trak, int32_t adjustment) | |
3349 { | |
3350 uint32_t offset, *entry, *end; | |
3351 ngx_buf_t *data; | |
3352 | |
3353 /* | |
3354 * moov.trak.mdia.minf.stbl.stco adjustment requires | |
3355 * minimal start offset of all traks and new moov atom size | |
3356 */ | |
3357 | |
3358 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3359 "mp4 stco atom adjustment"); | |
3360 | |
3361 data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf; | |
3362 entry = (uint32_t *) data->pos; | |
3363 end = (uint32_t *) data->last; | |
3364 | |
3365 while (entry < end) { | |
3366 offset = ngx_mp4_get_32value(entry); | |
3367 offset += adjustment; | |
3368 ngx_mp4_set_32value(entry, offset); | |
3369 entry++; | |
3370 } | |
3371 } | |
3372 | |
3373 | |
4112 | 3374 typedef struct { |
3375 u_char size[4]; | |
3376 u_char name[4]; | |
3377 u_char version[1]; | |
3378 u_char flags[3]; | |
3379 u_char entries[4]; | |
3380 } ngx_mp4_co64_atom_t; | |
3381 | |
3382 | |
3383 static ngx_int_t | |
3384 ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
3385 { | |
3386 u_char *atom_header, *atom_table, *atom_end; | |
3387 uint32_t entries; | |
3388 ngx_buf_t *atom, *data; | |
3389 ngx_mp4_co64_atom_t *co64_atom; | |
3390 ngx_http_mp4_trak_t *trak; | |
3391 | |
3392 /* chunk offsets atom */ | |
3393 | |
3394 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 co64 atom"); | |
3395 | |
3396 atom_header = ngx_mp4_atom_header(mp4); | |
3397 co64_atom = (ngx_mp4_co64_atom_t *) atom_header; | |
3398 ngx_mp4_set_atom_name(co64_atom, 'c', 'o', '6', '4'); | |
3399 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3400 if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3401 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3402 "\"%s\" mp4 co64 atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3403 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3404 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3405 |
4112 | 3406 entries = ngx_mp4_get_32value(co64_atom->entries); |
3407 | |
3408 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); | |
3409 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3410 if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3411 + entries * sizeof(uint64_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3412 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3413 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3414 "\"%s\" mp4 co64 atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3415 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3416 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3417 |
4112 | 3418 atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t); |
3419 atom_end = atom_table + entries * sizeof(uint64_t); | |
3420 | |
3421 trak = ngx_mp4_last_trak(mp4); | |
3422 trak->chunks = entries; | |
3423 | |
3424 atom = &trak->co64_atom_buf; | |
3425 atom->temporary = 1; | |
3426 atom->pos = atom_header; | |
3427 atom->last = atom_table; | |
3428 | |
3429 data = &trak->co64_data_buf; | |
3430 data->temporary = 1; | |
3431 data->pos = atom_table; | |
3432 data->last = atom_end; | |
3433 | |
3434 trak->out[NGX_HTTP_MP4_CO64_ATOM].buf = atom; | |
3435 trak->out[NGX_HTTP_MP4_CO64_DATA].buf = data; | |
3436 | |
3437 ngx_mp4_atom_next(mp4, atom_data_size); | |
3438 | |
3439 return NGX_OK; | |
3440 } | |
3441 | |
3442 | |
3443 static ngx_int_t | |
3444 ngx_http_mp4_update_co64_atom(ngx_http_mp4_file_t *mp4, | |
3445 ngx_http_mp4_trak_t *trak) | |
3446 { | |
3447 size_t atom_size; | |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3448 uint64_t entries, chunk_offset, samples_size; |
4112 | 3449 ngx_buf_t *atom, *data; |
3450 ngx_mp4_co64_atom_t *co64_atom; | |
3451 | |
3452 /* | |
3453 * mdia.minf.stbl.co64 updating requires trak->start_chunk | |
3454 * from mdia.minf.stbl.stsc which depends on value from mdia.mdhd | |
3455 * atom which may reside after mdia.minf | |
3456 */ | |
3457 | |
3458 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3459 "mp4 co64 atom update"); | |
3460 | |
3461 data = trak->out[NGX_HTTP_MP4_CO64_DATA].buf; | |
3462 | |
3463 if (data == NULL) { | |
3464 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
3465 "no mp4 co64 atoms were found in \"%s\"", | |
3466 mp4->file.name.data); | |
3467 return NGX_ERROR; | |
3468 } | |
3469 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3470 if (trak->start_chunk > trak->chunks) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3471 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3472 "start time is out mp4 co64 chunks in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3473 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3474 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3475 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3476 |
4112 | 3477 data->pos += trak->start_chunk * sizeof(uint64_t); |
3478 | |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3479 chunk_offset = ngx_mp4_get_64value(data->pos); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3480 samples_size = trak->start_chunk_samples_size; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3481 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3482 if (chunk_offset > (uint64_t) mp4->end - samples_size) { |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3483 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3484 "too large chunk offset in \"%s\"", |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3485 mp4->file.name.data); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3486 return NGX_ERROR; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3487 } |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3488 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3489 trak->start_offset = chunk_offset + samples_size; |
4112 | 3490 ngx_mp4_set_64value(data->pos, trak->start_offset); |
3491 | |
3492 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
3493 "start chunk offset:%O", trak->start_offset); |
4112 | 3494 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3495 if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3496 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3497 if (trak->end_chunk > trak->chunks) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3498 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3499 "end time is out mp4 co64 chunks in \"%s\"", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3500 mp4->file.name.data); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3501 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3502 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3503 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3504 entries = trak->end_chunk - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3505 data->last = data->pos + entries * sizeof(uint64_t); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3506 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3507 if (entries) { |
7629
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3508 chunk_offset = ngx_mp4_get_64value(data->last - sizeof(uint64_t)); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3509 samples_size = trak->end_chunk_samples_size; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3510 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3511 if (chunk_offset > (uint64_t) mp4->end - samples_size) { |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3512 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3513 "too large chunk offset in \"%s\"", |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3514 mp4->file.name.data); |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3515 return NGX_ERROR; |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3516 } |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3517 |
f47f7d3d1bfa
Mp4: fixed possible chunk offset overflow.
Roman Arutyunyan <arut@nginx.com>
parents:
7400
diff
changeset
|
3518 trak->end_offset = chunk_offset + samples_size; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3519 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3520 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3521 "end chunk offset:%O", trak->end_offset); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3522 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3523 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3524 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3525 entries = trak->chunks - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3526 trak->end_offset = mp4->mdat_data.buf->file_last; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3527 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3528 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3529 if (entries == 0) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3530 trak->start_offset = mp4->end; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3531 trak->end_offset = 0; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3532 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3533 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3534 atom_size = sizeof(ngx_mp4_co64_atom_t) + (data->last - data->pos); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3535 trak->size += atom_size; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3536 |
4112 | 3537 atom = trak->out[NGX_HTTP_MP4_CO64_ATOM].buf; |
3538 co64_atom = (ngx_mp4_co64_atom_t *) atom->pos; | |
3539 | |
3540 ngx_mp4_set_32value(co64_atom->size, atom_size); | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3541 ngx_mp4_set_32value(co64_atom->entries, entries); |
4112 | 3542 |
3543 return NGX_OK; | |
3544 } | |
3545 | |
3546 | |
3547 static void | |
3548 ngx_http_mp4_adjust_co64_atom(ngx_http_mp4_file_t *mp4, | |
3549 ngx_http_mp4_trak_t *trak, off_t adjustment) | |
3550 { | |
3551 uint64_t offset, *entry, *end; | |
3552 ngx_buf_t *data; | |
3553 | |
3554 /* | |
3555 * moov.trak.mdia.minf.stbl.co64 adjustment requires | |
3556 * minimal start offset of all traks and new moov atom size | |
3557 */ | |
3558 | |
3559 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3560 "mp4 co64 atom adjustment"); | |
3561 | |
3562 data = trak->out[NGX_HTTP_MP4_CO64_DATA].buf; | |
3563 entry = (uint64_t *) data->pos; | |
3564 end = (uint64_t *) data->last; | |
3565 | |
3566 while (entry < end) { | |
3567 offset = ngx_mp4_get_64value(entry); | |
3568 offset += adjustment; | |
3569 ngx_mp4_set_64value(entry, offset); | |
3570 entry++; | |
3571 } | |
3572 } | |
3573 | |
3574 | |
4085 | 3575 static char * |
3576 ngx_http_mp4(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
3577 { | |
3578 ngx_http_core_loc_conf_t *clcf; | |
3579 | |
3580 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
3581 clcf->handler = ngx_http_mp4_handler; | |
3582 | |
3583 return NGX_CONF_OK; | |
3584 } | |
3585 | |
3586 | |
3587 static void * | |
3588 ngx_http_mp4_create_conf(ngx_conf_t *cf) | |
3589 { | |
3590 ngx_http_mp4_conf_t *conf; | |
3591 | |
3592 conf = ngx_palloc(cf->pool, sizeof(ngx_http_mp4_conf_t)); | |
3593 if (conf == NULL) { | |
3594 return NULL; | |
3595 } | |
3596 | |
3597 conf->buffer_size = NGX_CONF_UNSET_SIZE; | |
4089
e27670e1ab70
mp4_max_moov_size directive has been renamed to mp4_max_buffer_size.
Igor Sysoev <igor@sysoev.ru>
parents:
4088
diff
changeset
|
3598 conf->max_buffer_size = NGX_CONF_UNSET_SIZE; |
4085 | 3599 |
3600 return conf; | |
3601 } | |
3602 | |
3603 | |
3604 static char * | |
3605 ngx_http_mp4_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
3606 { | |
3607 ngx_http_mp4_conf_t *prev = parent; | |
3608 ngx_http_mp4_conf_t *conf = child; | |
3609 | |
3610 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, 512 * 1024); | |
4089
e27670e1ab70
mp4_max_moov_size directive has been renamed to mp4_max_buffer_size.
Igor Sysoev <igor@sysoev.ru>
parents:
4088
diff
changeset
|
3611 ngx_conf_merge_size_value(conf->max_buffer_size, prev->max_buffer_size, |
4085 | 3612 10 * 1024 * 1024); |
3613 | |
3614 return NGX_CONF_OK; | |
3615 } |