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