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