Mercurial > hg > nginx
annotate src/http/modules/ngx_http_mp4_module.c @ 5638:0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
If start time is within the track but end time is out of it, error
"end time is out mp4 stts samples" is generated. However it's
better to ignore the error and output the track until its end.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 01 Apr 2014 20:53:18 +0400 |
parents | 02584b335727 |
children | 6d468b45f40e |
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 | |
5638
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2157 if (start) { |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2158 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2159 "start time is out mp4 stts samples in \"%s\"", |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2160 mp4->file.name.data); |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2161 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2162 return NGX_ERROR; |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2163 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2164 } else { |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2165 trak->end_sample = trak->start_sample + start_sample; |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2166 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2167 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2168 "end_sample:%ui", trak->end_sample); |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2169 |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2170 return NGX_OK; |
0c0dd1aacdf5
Mp4: allow end values bigger than track duration.
Roman Arutyunyan <arut@nginx.com>
parents:
5630
diff
changeset
|
2171 } |
4085 | 2172 |
2173 found: | |
2174 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2175 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2176 ngx_mp4_set_32value(entry->count, count - rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2177 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2178 trak->time_to_sample_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2179 trak->start_sample = start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2180 |
5630
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 "start_sample:%ui, new count:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2183 trak->start_sample, count - rest); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2184 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2185 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2186 ngx_mp4_set_32value(entry->count, rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2187 data->last = (u_char *) (entry + 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2188 trak->time_to_sample_entries -= entries - 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2189 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
|
2190 |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2191 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
|
2192 "end_sample:%ui, new count:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2193 trak->end_sample, rest); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2194 } |
4085 | 2195 |
2196 return NGX_OK; | |
2197 } | |
2198 | |
2199 | |
2200 typedef struct { | |
2201 u_char size[4]; | |
2202 u_char name[4]; | |
2203 u_char version[1]; | |
2204 u_char flags[3]; | |
2205 u_char entries[4]; | |
2206 } ngx_http_mp4_stss_atom_t; | |
2207 | |
2208 | |
2209 static ngx_int_t | |
2210 ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2211 { | |
2212 u_char *atom_header, *atom_table, *atom_end; | |
2213 uint32_t entries; | |
2214 ngx_buf_t *atom, *data; | |
2215 ngx_http_mp4_trak_t *trak; | |
2216 ngx_http_mp4_stss_atom_t *stss_atom; | |
2217 | |
2218 /* sync samples atom */ | |
2219 | |
2220 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stss atom"); | |
2221 | |
2222 atom_header = ngx_mp4_atom_header(mp4); | |
2223 stss_atom = (ngx_http_mp4_stss_atom_t *) atom_header; | |
2224 ngx_mp4_set_atom_name(stss_atom, 's', 't', 's', 's'); | |
2225 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2226 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
|
2227 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2228 "\"%s\" mp4 stss atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2229 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2230 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2231 |
4085 | 2232 entries = ngx_mp4_get_32value(stss_atom->entries); |
2233 | |
2234 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
4096 | 2235 "sync sample entries:%uD", entries); |
4085 | 2236 |
2237 trak = ngx_mp4_last_trak(mp4); | |
2238 trak->sync_samples_entries = entries; | |
2239 | |
2240 atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t); | |
2241 | |
2242 atom = &trak->stss_atom_buf; | |
2243 atom->temporary = 1; | |
2244 atom->pos = atom_header; | |
2245 atom->last = atom_table; | |
2246 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2247 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
|
2248 + entries * sizeof(uint32_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2249 { |
4085 | 2250 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
|
2251 "\"%s\" mp4 stss atom too small", mp4->file.name.data); |
4085 | 2252 return NGX_ERROR; |
2253 } | |
2254 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2255 atom_end = atom_table + entries * sizeof(uint32_t); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2256 |
4085 | 2257 data = &trak->stss_data_buf; |
2258 data->temporary = 1; | |
2259 data->pos = atom_table; | |
2260 data->last = atom_end; | |
2261 | |
2262 trak->out[NGX_HTTP_MP4_STSS_ATOM].buf = atom; | |
2263 trak->out[NGX_HTTP_MP4_STSS_DATA].buf = data; | |
2264 | |
2265 ngx_mp4_atom_next(mp4, atom_data_size); | |
2266 | |
2267 return NGX_OK; | |
2268 } | |
2269 | |
2270 | |
2271 static ngx_int_t | |
2272 ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4, | |
2273 ngx_http_mp4_trak_t *trak) | |
2274 { | |
2275 size_t atom_size; | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2276 uint32_t sample, start_sample, *entry, *end; |
4085 | 2277 ngx_buf_t *atom, *data; |
2278 ngx_http_mp4_stss_atom_t *stss_atom; | |
2279 | |
2280 /* | |
2281 * mdia.minf.stbl.stss updating requires trak->start_sample | |
2282 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
2283 * atom which may reside after mdia.minf | |
2284 */ | |
2285 | |
2286 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2287 "mp4 stss atom update"); | |
2288 | |
2289 data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf; | |
2290 | |
2291 if (data == NULL) { | |
2292 return NGX_OK; | |
2293 } | |
2294 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2295 ngx_http_mp4_crop_stss_data(mp4, trak, 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2296 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
|
2297 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2298 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
|
2299 "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
|
2300 |
5622
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2301 if (trak->sync_samples_entries) { |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2302 entry = (uint32_t *) data->pos; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2303 end = (uint32_t *) data->last; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2304 |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2305 start_sample = trak->start_sample; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2306 |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2307 while (entry < end) { |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2308 sample = ngx_mp4_get_32value(entry); |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2309 sample -= start_sample; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2310 ngx_mp4_set_32value(entry, sample); |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2311 entry++; |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2312 } |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2313 |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2314 } else { |
a23c35496c2f
Mp4: skipped empty stss atom table in output.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5621
diff
changeset
|
2315 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
|
2316 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2317 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2318 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
|
2319 trak->size += atom_size; |
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 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
|
2322 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
|
2323 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2324 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
|
2325 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
|
2326 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2327 return NGX_OK; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2328 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2329 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2330 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2331 static void |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2332 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
|
2333 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
|
2334 { |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2335 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
|
2336 ngx_buf_t *data; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2337 ngx_uint_t entries; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2338 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2339 /* sync samples starts from 1 */ |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2340 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2341 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2342 start_sample = trak->start_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2343 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2344 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
|
2345 "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
|
2346 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2347 } else if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2348 start_sample = trak->end_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2349 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2350 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
|
2351 "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
|
2352 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2353 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2354 return; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2355 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2356 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2357 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
|
2358 |
4085 | 2359 entries = trak->sync_samples_entries; |
2360 entry = (uint32_t *) data->pos; | |
2361 end = (uint32_t *) data->last; | |
2362 | |
2363 while (entry < end) { | |
2364 sample = ngx_mp4_get_32value(entry); | |
2365 | |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2366 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
|
2367 "sync:%uD", sample); |
4085 | 2368 |
2369 if (sample >= start_sample) { | |
2370 goto found; | |
2371 } | |
2372 | |
2373 entries--; | |
2374 entry++; | |
2375 } | |
2376 | |
5542
847c308917af
Mp4: fix seeks after the last key frame.
Roman Arutyunyan <arut@nginx.com>
parents:
5496
diff
changeset
|
2377 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
|
2378 "sample is out of mp4 stss atom"); |
4085 | 2379 |
2380 found: | |
2381 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2382 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2383 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2384 trak->sync_samples_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2385 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2386 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2387 data->last = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2388 trak->sync_samples_entries -= entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2389 } |
4085 | 2390 } |
2391 | |
2392 | |
2393 typedef struct { | |
2394 u_char size[4]; | |
2395 u_char name[4]; | |
2396 u_char version[1]; | |
2397 u_char flags[3]; | |
2398 u_char entries[4]; | |
2399 } ngx_mp4_ctts_atom_t; | |
2400 | |
2401 typedef struct { | |
2402 u_char count[4]; | |
2403 u_char offset[4]; | |
2404 } ngx_mp4_ctts_entry_t; | |
2405 | |
2406 | |
2407 static ngx_int_t | |
2408 ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2409 { | |
2410 u_char *atom_header, *atom_table, *atom_end; | |
2411 uint32_t entries; | |
2412 ngx_buf_t *atom, *data; | |
2413 ngx_mp4_ctts_atom_t *ctts_atom; | |
2414 ngx_http_mp4_trak_t *trak; | |
2415 | |
2416 /* composition offsets atom */ | |
2417 | |
2418 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ctts atom"); | |
2419 | |
2420 atom_header = ngx_mp4_atom_header(mp4); | |
2421 ctts_atom = (ngx_mp4_ctts_atom_t *) atom_header; | |
2422 ngx_mp4_set_atom_name(ctts_atom, 'c', 't', 't', 's'); | |
2423 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2424 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
|
2425 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2426 "\"%s\" mp4 ctts atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2427 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2428 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2429 |
4085 | 2430 entries = ngx_mp4_get_32value(ctts_atom->entries); |
2431 | |
2432 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
4096 | 2433 "composition offset entries:%uD", entries); |
4085 | 2434 |
2435 trak = ngx_mp4_last_trak(mp4); | |
2436 trak->composition_offset_entries = entries; | |
2437 | |
2438 atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t); | |
2439 | |
2440 atom = &trak->ctts_atom_buf; | |
2441 atom->temporary = 1; | |
2442 atom->pos = atom_header; | |
2443 atom->last = atom_table; | |
2444 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2445 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
|
2446 + entries * sizeof(ngx_mp4_ctts_entry_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2447 { |
4085 | 2448 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
|
2449 "\"%s\" mp4 ctts atom too small", mp4->file.name.data); |
4085 | 2450 return NGX_ERROR; |
2451 } | |
2452 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2453 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
|
2454 |
4085 | 2455 data = &trak->ctts_data_buf; |
2456 data->temporary = 1; | |
2457 data->pos = atom_table; | |
2458 data->last = atom_end; | |
2459 | |
2460 trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = atom; | |
2461 trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = data; | |
2462 | |
2463 ngx_mp4_atom_next(mp4, atom_data_size); | |
2464 | |
2465 return NGX_OK; | |
2466 } | |
2467 | |
2468 | |
2469 static void | |
2470 ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4, | |
2471 ngx_http_mp4_trak_t *trak) | |
2472 { | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2473 size_t atom_size; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2474 ngx_buf_t *atom, *data; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2475 ngx_mp4_ctts_atom_t *ctts_atom; |
4085 | 2476 |
2477 /* | |
2478 * mdia.minf.stbl.ctts updating requires trak->start_sample | |
2479 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
2480 * atom which may reside after mdia.minf | |
2481 */ | |
2482 | |
2483 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2484 "mp4 ctts atom update"); | |
2485 | |
2486 data = trak->out[NGX_HTTP_MP4_CTTS_DATA].buf; | |
2487 | |
2488 if (data == NULL) { | |
2489 return; | |
2490 } | |
2491 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2492 ngx_http_mp4_crop_ctts_data(mp4, trak, 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2493 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
|
2494 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2495 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
|
2496 "composition offset entries:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2497 trak->composition_offset_entries); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2498 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2499 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
|
2500 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
|
2501 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
|
2502 return; |
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 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2505 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
|
2506 trak->size += atom_size; |
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 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
|
2509 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
|
2510 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2511 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
|
2512 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
|
2513 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2514 return; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2515 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2516 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2517 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2518 static void |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2519 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
|
2520 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
|
2521 { |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2522 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
|
2523 ngx_buf_t *data; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2524 ngx_uint_t entries; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2525 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
|
2526 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2527 /* sync samples starts from 1 */ |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2528 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2529 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2530 start_sample = trak->start_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2531 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2532 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
|
2533 "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
|
2534 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2535 } else if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2536 start_sample = trak->end_sample - trak->start_sample + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2537 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2538 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
|
2539 "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
|
2540 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2541 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2542 return; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2543 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2544 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2545 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
|
2546 |
4085 | 2547 entries = trak->composition_offset_entries; |
2548 entry = (ngx_mp4_ctts_entry_t *) data->pos; | |
2549 end = (ngx_mp4_ctts_entry_t *) data->last; | |
2550 | |
2551 while (entry < end) { | |
2552 count = ngx_mp4_get_32value(entry->count); | |
2553 | |
4088
8fe1da7b8386
bugfix of r4086: nginx could not be built without debug log.
Igor Sysoev <igor@sysoev.ru>
parents:
4087
diff
changeset
|
2554 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
|
2555 "sample:%uD, count:%uD, offset:%uD", |
4085 | 2556 start_sample, count, ngx_mp4_get_32value(entry->offset)); |
2557 | |
2558 if (start_sample <= count) { | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2559 rest = start_sample - 1; |
4085 | 2560 goto found; |
2561 } | |
2562 | |
2563 start_sample -= count; | |
2564 entries--; | |
2565 entry++; | |
2566 } | |
2567 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2568 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2569 data->pos = (u_char *) end; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2570 trak->composition_offset_entries = 0; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2571 } |
4085 | 2572 |
2573 return; | |
2574 | |
2575 found: | |
2576 | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2577 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2578 ngx_mp4_set_32value(entry->count, count - rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2579 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2580 trak->composition_offset_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2581 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2582 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2583 ngx_mp4_set_32value(entry->count, rest); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2584 data->last = (u_char *) (entry + 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2585 trak->composition_offset_entries -= entries - 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2586 } |
4085 | 2587 } |
2588 | |
2589 | |
2590 typedef struct { | |
2591 u_char size[4]; | |
2592 u_char name[4]; | |
2593 u_char version[1]; | |
2594 u_char flags[3]; | |
2595 u_char entries[4]; | |
2596 } ngx_mp4_stsc_atom_t; | |
2597 | |
2598 | |
2599 static ngx_int_t | |
2600 ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2601 { | |
2602 u_char *atom_header, *atom_table, *atom_end; | |
2603 uint32_t entries; | |
2604 ngx_buf_t *atom, *data; | |
2605 ngx_mp4_stsc_atom_t *stsc_atom; | |
2606 ngx_http_mp4_trak_t *trak; | |
2607 | |
2608 /* sample-to-chunk atom */ | |
2609 | |
2610 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsc atom"); | |
2611 | |
2612 atom_header = ngx_mp4_atom_header(mp4); | |
2613 stsc_atom = (ngx_mp4_stsc_atom_t *) atom_header; | |
2614 ngx_mp4_set_atom_name(stsc_atom, 's', 't', 's', 'c'); | |
2615 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2616 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
|
2617 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2618 "\"%s\" mp4 stsc atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2619 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2620 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2621 |
4085 | 2622 entries = ngx_mp4_get_32value(stsc_atom->entries); |
2623 | |
2624 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
4096 | 2625 "sample-to-chunk entries:%uD", entries); |
4085 | 2626 |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2627 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
|
2628 + entries * sizeof(ngx_mp4_stsc_entry_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2629 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2630 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2631 "\"%s\" mp4 stsc atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2632 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2633 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2634 |
4085 | 2635 atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t); |
2636 atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t); | |
2637 | |
2638 trak = ngx_mp4_last_trak(mp4); | |
2639 trak->sample_to_chunk_entries = entries; | |
2640 | |
2641 atom = &trak->stsc_atom_buf; | |
2642 atom->temporary = 1; | |
2643 atom->pos = atom_header; | |
2644 atom->last = atom_table; | |
2645 | |
2646 data = &trak->stsc_data_buf; | |
2647 data->temporary = 1; | |
2648 data->pos = atom_table; | |
2649 data->last = atom_end; | |
2650 | |
2651 trak->out[NGX_HTTP_MP4_STSC_ATOM].buf = atom; | |
2652 trak->out[NGX_HTTP_MP4_STSC_DATA].buf = data; | |
2653 | |
2654 ngx_mp4_atom_next(mp4, atom_data_size); | |
2655 | |
2656 return NGX_OK; | |
2657 } | |
2658 | |
2659 | |
2660 static ngx_int_t | |
2661 ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4, | |
2662 ngx_http_mp4_trak_t *trak) | |
2663 { | |
2664 size_t atom_size; | |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2665 uint32_t chunk; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2666 ngx_buf_t *atom, *data; |
4085 | 2667 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
|
2668 ngx_mp4_stsc_entry_t *entry, *end; |
4085 | 2669 |
2670 /* | |
2671 * mdia.minf.stbl.stsc updating requires trak->start_sample | |
2672 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
2673 * atom which may reside after mdia.minf | |
2674 */ | |
2675 | |
2676 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2677 "mp4 stsc atom update"); | |
2678 | |
2679 data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf; | |
2680 | |
2681 if (data == NULL) { | |
2682 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
2683 "no mp4 stsc atoms were found in \"%s\"", | |
2684 mp4->file.name.data); | |
2685 return NGX_ERROR; | |
2686 } | |
2687 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2688 if (trak->sample_to_chunk_entries == 0) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2689 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2690 "zero number of entries in stsc atom in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2691 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2692 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2693 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2694 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2695 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
|
2696 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2697 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2698 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2699 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
|
2700 return NGX_ERROR; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2701 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2702 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2703 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
|
2704 "sample-to-chunk entries:%uD", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2705 trak->sample_to_chunk_entries); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2706 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2707 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
|
2708 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
|
2709 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2710 while (entry < end) { |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2711 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
|
2712 chunk -= trak->start_chunk; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2713 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
|
2714 entry++; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2715 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2716 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2717 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
|
2718 + 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
|
2719 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2720 trak->size += atom_size; |
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 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
|
2723 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
|
2724 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2725 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
|
2726 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
|
2727 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2728 return NGX_OK; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2729 } |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2730 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2731 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2732 static ngx_int_t |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2733 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
|
2734 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
|
2735 { |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2736 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
|
2737 prev_samples; |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2738 ngx_buf_t *data, *buf; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2739 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
|
2740 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
|
2741 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2742 entries = trak->sample_to_chunk_entries - 1; |
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 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2745 start_sample = (uint32_t) trak->start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2746 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2747 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
|
2748 "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
|
2749 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2750 } else if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2751 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
|
2752 samples = 0; |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2753 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2754 data = trak->out[NGX_HTTP_MP4_STSC_START].buf; |
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 if (data) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2757 entry = (ngx_mp4_stsc_entry_t *) data->pos; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2758 samples = ngx_mp4_get_32value(entry->samples); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2759 entries--; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2760 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2761 if (samples > start_sample) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2762 samples = start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2763 ngx_mp4_set_32value(entry->samples, samples); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2764 } |
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 start_sample -= samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2767 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2768 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2769 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
|
2770 "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
|
2771 start_sample, samples); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2772 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2773 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2774 return NGX_OK; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2775 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2776 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2777 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
|
2778 |
4085 | 2779 entry = (ngx_mp4_stsc_entry_t *) data->pos; |
2780 end = (ngx_mp4_stsc_entry_t *) data->last; | |
2781 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2782 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
|
2783 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
|
2784 id = ngx_mp4_get_32value(entry->id); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2785 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
|
2786 entry++; |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2787 |
4085 | 2788 while (entry < end) { |
2789 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2790 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
|
2791 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2792 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
|
2793 "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
|
2794 "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
|
2795 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
|
2796 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2797 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
|
2798 |
5578
e280ece17020
Mp4: remove useless leading stsc entry in result mp4.
Roman Arutyunyan <arut@nginx.com>
parents:
5544
diff
changeset
|
2799 if (start_sample < n) { |
4085 | 2800 goto found; |
2801 } | |
2802 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2803 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
|
2804 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2805 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
|
2806 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
|
2807 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
|
2808 id = ngx_mp4_get_32value(entry->id); |
4085 | 2809 entries--; |
2810 entry++; | |
2811 } | |
2812 | |
5544
2f586f1684fa
Mp4: fix seeks to standalone last chunk.
Roman Arutyunyan <arut@nginx.com>
parents:
5543
diff
changeset
|
2813 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
|
2814 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2815 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
|
2816 "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
|
2817 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
|
2818 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2819 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
|
2820 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2821 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
|
2822 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
|
2823 "%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
|
2824 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
|
2825 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
|
2826 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2827 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2828 found: |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2829 |
4085 | 2830 entries++; |
2831 entry--; | |
2832 | |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2833 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
|
2834 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
|
2835 "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
|
2836 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
|
2837 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
|
2838 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2839 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2840 target_chunk = chunk - 1; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2841 target_chunk += start_sample / samples; |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2842 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
|
2843 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2844 if (start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2845 data->pos = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2846 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2847 trak->sample_to_chunk_entries = entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2848 trak->start_chunk = target_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2849 trak->start_chunk_samples = chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2850 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2851 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
|
2852 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2853 samples -= chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2854 |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2855 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
|
2856 "start_chunk:%ui, start_chunk_samples:%ui", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2857 trak->start_chunk, trak->start_chunk_samples); |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2858 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2859 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2860 if (start_sample) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2861 data->last = (u_char *) (entry + 1); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2862 trak->sample_to_chunk_entries -= entries - 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2863 trak->end_chunk_samples = 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 data->last = (u_char *) entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2867 trak->sample_to_chunk_entries -= entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2868 trak->end_chunk_samples = prev_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2869 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2870 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2871 if (chunk_samples) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2872 trak->end_chunk = target_chunk + 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2873 trak->end_chunk_samples = chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2874 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2875 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2876 trak->end_chunk = target_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2877 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2878 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2879 samples = chunk_samples; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2880 next_chunk = chunk + 1; |
5630
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2881 |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2882 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
|
2883 "end_chunk:%ui, end_chunk_samples:%ui", |
02584b335727
Mp4: improved logging after adding "end" support.
Roman Arutyunyan <arut@nginx.com>
parents:
5629
diff
changeset
|
2884 trak->end_chunk, trak->end_chunk_samples); |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2885 } |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2886 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2887 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
|
2888 |
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2889 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
|
2890 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2891 } else if (chunk_samples && start) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2892 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2893 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
|
2894 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
|
2895 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
|
2896 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
|
2897 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2898 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
|
2899 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
|
2900 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
|
2901 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
|
2902 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2903 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
|
2904 |
5619
517b5b599e3f
Mp4: moved atom cropping code out of update functions.
Roman Arutyunyan <arut@nginx.com>
parents:
5578
diff
changeset
|
2905 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
|
2906 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2907 trak->sample_to_chunk_entries++; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2908 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2909 } else if (chunk_samples) { |
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 first = &trak->stsc_end_chunk_entry; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2912 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
|
2913 ngx_mp4_set_32value(first->samples, samples); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2914 ngx_mp4_set_32value(first->id, id); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2915 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2916 buf = &trak->stsc_end_chunk_buf; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2917 buf->temporary = 1; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2918 buf->pos = (u_char *) first; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2919 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
|
2920 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2921 trak->out[NGX_HTTP_MP4_STSC_END].buf = buf; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2922 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
2923 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
|
2924 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
2925 |
4085 | 2926 return NGX_OK; |
2927 } | |
2928 | |
2929 | |
2930 typedef struct { | |
2931 u_char size[4]; | |
2932 u_char name[4]; | |
2933 u_char version[1]; | |
2934 u_char flags[3]; | |
2935 u_char uniform_size[4]; | |
2936 u_char entries[4]; | |
2937 } ngx_mp4_stsz_atom_t; | |
2938 | |
2939 | |
2940 static ngx_int_t | |
2941 ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
2942 { | |
2943 u_char *atom_header, *atom_table, *atom_end; | |
2944 size_t atom_size; | |
2945 uint32_t entries, size; | |
2946 ngx_buf_t *atom, *data; | |
2947 ngx_mp4_stsz_atom_t *stsz_atom; | |
2948 ngx_http_mp4_trak_t *trak; | |
2949 | |
2950 /* sample sizes atom */ | |
2951 | |
2952 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsz atom"); | |
2953 | |
2954 atom_header = ngx_mp4_atom_header(mp4); | |
2955 stsz_atom = (ngx_mp4_stsz_atom_t *) atom_header; | |
2956 ngx_mp4_set_atom_name(stsz_atom, 's', 't', 's', 'z'); | |
2957 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2958 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
|
2959 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2960 "\"%s\" mp4 stsz atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2961 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2962 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2963 |
4085 | 2964 size = ngx_mp4_get_32value(stsz_atom->uniform_size); |
2965 entries = ngx_mp4_get_32value(stsz_atom->entries); | |
2966 | |
2967 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
2968 "sample uniform size:%uD, entries:%uD", size, entries); | |
2969 | |
2970 trak = ngx_mp4_last_trak(mp4); | |
2971 trak->sample_sizes_entries = entries; | |
2972 | |
2973 atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t); | |
2974 | |
2975 atom = &trak->stsz_atom_buf; | |
2976 atom->temporary = 1; | |
2977 atom->pos = atom_header; | |
2978 atom->last = atom_table; | |
2979 | |
2980 trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf = atom; | |
2981 | |
2982 if (size == 0) { | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2983 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
|
2984 + entries * sizeof(uint32_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2985 { |
4085 | 2986 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
|
2987 "\"%s\" mp4 stsz atom too small", |
4085 | 2988 mp4->file.name.data); |
2989 return NGX_ERROR; | |
2990 } | |
2991 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2992 atom_end = atom_table + entries * sizeof(uint32_t); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
2993 |
4085 | 2994 data = &trak->stsz_data_buf; |
2995 data->temporary = 1; | |
2996 data->pos = atom_table; | |
2997 data->last = atom_end; | |
2998 | |
2999 trak->out[NGX_HTTP_MP4_STSZ_DATA].buf = data; | |
3000 | |
3001 } else { | |
3002 /* 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
|
3003 /* TODO : chunk samples */ |
4085 | 3004 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; |
3005 ngx_mp4_set_32value(atom_header, atom_size); | |
3006 trak->size += atom_size; | |
3007 } | |
3008 | |
3009 ngx_mp4_atom_next(mp4, atom_data_size); | |
3010 | |
3011 return NGX_OK; | |
3012 } | |
3013 | |
3014 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3015 static ngx_int_t |
4085 | 3016 ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4, |
3017 ngx_http_mp4_trak_t *trak) | |
3018 { | |
3019 size_t atom_size; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3020 uint32_t *pos, *end, entries; |
4085 | 3021 ngx_buf_t *atom, *data; |
3022 ngx_mp4_stsz_atom_t *stsz_atom; | |
3023 | |
3024 /* | |
3025 * mdia.minf.stbl.stsz updating requires trak->start_sample | |
3026 * from mdia.minf.stbl.stts which depends on value from mdia.mdhd | |
3027 * atom which may reside after mdia.minf | |
3028 */ | |
3029 | |
3030 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3031 "mp4 stsz atom update"); | |
3032 | |
3033 data = trak->out[NGX_HTTP_MP4_STSZ_DATA].buf; | |
3034 | |
3035 if (data) { | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3036 entries = trak->sample_sizes_entries; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3037 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3038 if (trak->start_sample > entries) { |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3039 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3040 "start time is out mp4 stsz samples in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3041 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3042 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3043 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3044 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3045 entries -= trak->start_sample; |
4085 | 3046 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
|
3047 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
|
3048 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3049 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
|
3050 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
|
3051 } |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3052 |
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3053 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
|
3054 "chunk samples sizes:%uL", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3055 trak->start_chunk_samples_size); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3056 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3057 if (mp4->length) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3058 if (trak->end_sample - trak->start_sample > entries) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3059 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
|
3060 "end time is out mp4 stsz samples in \"%s\"", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3061 mp4->file.name.data); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3062 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3063 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3064 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3065 entries = trak->end_sample - trak->start_sample; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3066 data->last = data->pos + entries * sizeof(uint32_t); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3067 end = (uint32_t *) data->last; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3068 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3069 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
|
3070 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
|
3071 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3072 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3073 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
|
3074 "mp4 stsz end_chunk_samples_size:%uL", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3075 trak->end_chunk_samples_size); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3076 } |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3077 |
4085 | 3078 atom_size = sizeof(ngx_mp4_stsz_atom_t) + (data->last - data->pos); |
3079 trak->size += atom_size; | |
3080 | |
3081 atom = trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf; | |
3082 stsz_atom = (ngx_mp4_stsz_atom_t *) atom->pos; | |
3083 | |
3084 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
|
3085 ngx_mp4_set_32value(stsz_atom->entries, entries); |
4085 | 3086 } |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3087 |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3088 return NGX_OK; |
4085 | 3089 } |
3090 | |
3091 | |
3092 typedef struct { | |
3093 u_char size[4]; | |
3094 u_char name[4]; | |
3095 u_char version[1]; | |
3096 u_char flags[3]; | |
3097 u_char entries[4]; | |
3098 } ngx_mp4_stco_atom_t; | |
3099 | |
3100 | |
3101 static ngx_int_t | |
3102 ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
3103 { | |
3104 u_char *atom_header, *atom_table, *atom_end; | |
3105 uint32_t entries; | |
3106 ngx_buf_t *atom, *data; | |
3107 ngx_mp4_stco_atom_t *stco_atom; | |
3108 ngx_http_mp4_trak_t *trak; | |
3109 | |
3110 /* chunk offsets atom */ | |
3111 | |
3112 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stco atom"); | |
3113 | |
3114 atom_header = ngx_mp4_atom_header(mp4); | |
3115 stco_atom = (ngx_mp4_stco_atom_t *) atom_header; | |
3116 ngx_mp4_set_atom_name(stco_atom, 's', 't', 'c', 'o'); | |
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) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3119 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3120 "\"%s\" mp4 stco atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3121 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3122 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3123 |
4085 | 3124 entries = ngx_mp4_get_32value(stco_atom->entries); |
3125 | |
3126 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); | |
3127 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3128 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
|
3129 + entries * sizeof(uint32_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3130 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3131 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3132 "\"%s\" mp4 stco atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3133 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3134 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3135 |
4085 | 3136 atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t); |
3137 atom_end = atom_table + entries * sizeof(uint32_t); | |
3138 | |
3139 trak = ngx_mp4_last_trak(mp4); | |
3140 trak->chunks = entries; | |
3141 | |
4107 | 3142 atom = &trak->stco_atom_buf; |
4085 | 3143 atom->temporary = 1; |
3144 atom->pos = atom_header; | |
3145 atom->last = atom_table; | |
3146 | |
4107 | 3147 data = &trak->stco_data_buf; |
4085 | 3148 data->temporary = 1; |
3149 data->pos = atom_table; | |
3150 data->last = atom_end; | |
3151 | |
3152 trak->out[NGX_HTTP_MP4_STCO_ATOM].buf = atom; | |
3153 trak->out[NGX_HTTP_MP4_STCO_DATA].buf = data; | |
3154 | |
3155 ngx_mp4_atom_next(mp4, atom_data_size); | |
3156 | |
3157 return NGX_OK; | |
3158 } | |
3159 | |
3160 | |
3161 static ngx_int_t | |
3162 ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4, | |
3163 ngx_http_mp4_trak_t *trak) | |
3164 { | |
3165 size_t atom_size; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3166 uint32_t entries; |
4085 | 3167 ngx_buf_t *atom, *data; |
3168 ngx_mp4_stco_atom_t *stco_atom; | |
3169 | |
3170 /* | |
3171 * mdia.minf.stbl.stco updating requires trak->start_chunk | |
3172 * from mdia.minf.stbl.stsc which depends on value from mdia.mdhd | |
3173 * atom which may reside after mdia.minf | |
3174 */ | |
3175 | |
3176 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3177 "mp4 stco atom update"); | |
3178 | |
3179 data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf; | |
3180 | |
3181 if (data == NULL) { | |
3182 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
3183 "no mp4 stco atoms were found in \"%s\"", | |
3184 mp4->file.name.data); | |
3185 return NGX_ERROR; | |
3186 } | |
3187 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3188 if (trak->start_chunk > trak->chunks) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3189 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3190 "start time is out mp4 stco chunks in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3191 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3192 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3193 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3194 |
4098
a3e07fab98a3
Fix of case when start sample does not reside on chunk boundary.
Igor Sysoev <igor@sysoev.ru>
parents:
4096
diff
changeset
|
3195 data->pos += trak->start_chunk * sizeof(uint32_t); |
4085 | 3196 |
3197 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
|
3198 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
|
3199 ngx_mp4_set_32value(data->pos, trak->start_offset); |
4085 | 3200 |
3201 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
|
3202 "start chunk offset:%O", trak->start_offset); |
4085 | 3203 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3204 if (mp4->length) { |
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 (trak->end_chunk > trak->chunks) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3207 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
|
3208 "end time is out mp4 stco chunks in \"%s\"", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3209 mp4->file.name.data); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3210 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3211 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3212 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3213 entries = trak->end_chunk - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3214 data->last = data->pos + entries * sizeof(uint32_t); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3215 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3216 if (entries) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3217 trak->end_offset = |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3218 ngx_mp4_get_32value(data->last - sizeof(uint32_t)); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3219 trak->end_offset += trak->end_chunk_samples_size; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3220 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3221 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
|
3222 "end chunk offset:%O", trak->end_offset); |
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 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3226 entries = trak->chunks - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3227 trak->end_offset = mp4->mdat_data.buf->file_last; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3228 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3229 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3230 if (entries == 0) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3231 trak->start_offset = mp4->end; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3232 trak->end_offset = 0; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3233 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3234 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3235 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
|
3236 trak->size += atom_size; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3237 |
4085 | 3238 atom = trak->out[NGX_HTTP_MP4_STCO_ATOM].buf; |
3239 stco_atom = (ngx_mp4_stco_atom_t *) atom->pos; | |
3240 | |
3241 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
|
3242 ngx_mp4_set_32value(stco_atom->entries, entries); |
4085 | 3243 |
3244 return NGX_OK; | |
3245 } | |
3246 | |
3247 | |
3248 static void | |
3249 ngx_http_mp4_adjust_stco_atom(ngx_http_mp4_file_t *mp4, | |
3250 ngx_http_mp4_trak_t *trak, int32_t adjustment) | |
3251 { | |
3252 uint32_t offset, *entry, *end; | |
3253 ngx_buf_t *data; | |
3254 | |
3255 /* | |
3256 * moov.trak.mdia.minf.stbl.stco adjustment requires | |
3257 * minimal start offset of all traks and new moov atom size | |
3258 */ | |
3259 | |
3260 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3261 "mp4 stco atom adjustment"); | |
3262 | |
3263 data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf; | |
3264 entry = (uint32_t *) data->pos; | |
3265 end = (uint32_t *) data->last; | |
3266 | |
3267 while (entry < end) { | |
3268 offset = ngx_mp4_get_32value(entry); | |
3269 offset += adjustment; | |
3270 ngx_mp4_set_32value(entry, offset); | |
3271 entry++; | |
3272 } | |
3273 } | |
3274 | |
3275 | |
4112 | 3276 typedef struct { |
3277 u_char size[4]; | |
3278 u_char name[4]; | |
3279 u_char version[1]; | |
3280 u_char flags[3]; | |
3281 u_char entries[4]; | |
3282 } ngx_mp4_co64_atom_t; | |
3283 | |
3284 | |
3285 static ngx_int_t | |
3286 ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) | |
3287 { | |
3288 u_char *atom_header, *atom_table, *atom_end; | |
3289 uint32_t entries; | |
3290 ngx_buf_t *atom, *data; | |
3291 ngx_mp4_co64_atom_t *co64_atom; | |
3292 ngx_http_mp4_trak_t *trak; | |
3293 | |
3294 /* chunk offsets atom */ | |
3295 | |
3296 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 co64 atom"); | |
3297 | |
3298 atom_header = ngx_mp4_atom_header(mp4); | |
3299 co64_atom = (ngx_mp4_co64_atom_t *) atom_header; | |
3300 ngx_mp4_set_atom_name(co64_atom, 'c', 'o', '6', '4'); | |
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) > atom_data_size) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3303 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3304 "\"%s\" mp4 co64 atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3305 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3306 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3307 |
4112 | 3308 entries = ngx_mp4_get_32value(co64_atom->entries); |
3309 | |
3310 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); | |
3311 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3312 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
|
3313 + entries * sizeof(uint64_t) > atom_data_size) |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3314 { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3315 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3316 "\"%s\" mp4 co64 atom too small", mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3317 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3318 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3319 |
4112 | 3320 atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t); |
3321 atom_end = atom_table + entries * sizeof(uint64_t); | |
3322 | |
3323 trak = ngx_mp4_last_trak(mp4); | |
3324 trak->chunks = entries; | |
3325 | |
3326 atom = &trak->co64_atom_buf; | |
3327 atom->temporary = 1; | |
3328 atom->pos = atom_header; | |
3329 atom->last = atom_table; | |
3330 | |
3331 data = &trak->co64_data_buf; | |
3332 data->temporary = 1; | |
3333 data->pos = atom_table; | |
3334 data->last = atom_end; | |
3335 | |
3336 trak->out[NGX_HTTP_MP4_CO64_ATOM].buf = atom; | |
3337 trak->out[NGX_HTTP_MP4_CO64_DATA].buf = data; | |
3338 | |
3339 ngx_mp4_atom_next(mp4, atom_data_size); | |
3340 | |
3341 return NGX_OK; | |
3342 } | |
3343 | |
3344 | |
3345 static ngx_int_t | |
3346 ngx_http_mp4_update_co64_atom(ngx_http_mp4_file_t *mp4, | |
3347 ngx_http_mp4_trak_t *trak) | |
3348 { | |
3349 size_t atom_size; | |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3350 uint64_t entries; |
4112 | 3351 ngx_buf_t *atom, *data; |
3352 ngx_mp4_co64_atom_t *co64_atom; | |
3353 | |
3354 /* | |
3355 * mdia.minf.stbl.co64 updating requires trak->start_chunk | |
3356 * from mdia.minf.stbl.stsc which depends on value from mdia.mdhd | |
3357 * atom which may reside after mdia.minf | |
3358 */ | |
3359 | |
3360 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3361 "mp4 co64 atom update"); | |
3362 | |
3363 data = trak->out[NGX_HTTP_MP4_CO64_DATA].buf; | |
3364 | |
3365 if (data == NULL) { | |
3366 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
3367 "no mp4 co64 atoms were found in \"%s\"", | |
3368 mp4->file.name.data); | |
3369 return NGX_ERROR; | |
3370 } | |
3371 | |
4585
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3372 if (trak->start_chunk > trak->chunks) { |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3373 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3374 "start time is out mp4 co64 chunks in \"%s\"", |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3375 mp4->file.name.data); |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3376 return NGX_ERROR; |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3377 } |
3f874d645f45
Mp4: sanity checks cleanup.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4579
diff
changeset
|
3378 |
4112 | 3379 data->pos += trak->start_chunk * sizeof(uint64_t); |
3380 | |
3381 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
|
3382 trak->start_offset += trak->start_chunk_samples_size; |
4112 | 3383 ngx_mp4_set_64value(data->pos, trak->start_offset); |
3384 | |
3385 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
|
3386 "start chunk offset:%O", trak->start_offset); |
4112 | 3387 |
5620
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3388 if (mp4->length) { |
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 (trak->end_chunk > trak->chunks) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3391 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
|
3392 "end time is out mp4 co64 chunks in \"%s\"", |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3393 mp4->file.name.data); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3394 return NGX_ERROR; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3395 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3396 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3397 entries = trak->end_chunk - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3398 data->last = data->pos + entries * sizeof(uint64_t); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3399 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3400 if (entries) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3401 trak->end_offset = |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3402 ngx_mp4_get_64value(data->last - sizeof(uint64_t)); |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3403 trak->end_offset += trak->end_chunk_samples_size; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3404 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3405 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
|
3406 "end chunk offset:%O", trak->end_offset); |
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 } else { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3410 entries = trak->chunks - trak->start_chunk; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3411 trak->end_offset = mp4->mdat_data.buf->file_last; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3412 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3413 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3414 if (entries == 0) { |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3415 trak->start_offset = mp4->end; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3416 trak->end_offset = 0; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3417 } |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3418 |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3419 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
|
3420 trak->size += atom_size; |
0a567878254b
Mp4: added "end" argument support.
Roman Arutyunyan <arut@nginx.com>
parents:
5619
diff
changeset
|
3421 |
4112 | 3422 atom = trak->out[NGX_HTTP_MP4_CO64_ATOM].buf; |
3423 co64_atom = (ngx_mp4_co64_atom_t *) atom->pos; | |
3424 | |
3425 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
|
3426 ngx_mp4_set_32value(co64_atom->entries, entries); |
4112 | 3427 |
3428 return NGX_OK; | |
3429 } | |
3430 | |
3431 | |
3432 static void | |
3433 ngx_http_mp4_adjust_co64_atom(ngx_http_mp4_file_t *mp4, | |
3434 ngx_http_mp4_trak_t *trak, off_t adjustment) | |
3435 { | |
3436 uint64_t offset, *entry, *end; | |
3437 ngx_buf_t *data; | |
3438 | |
3439 /* | |
3440 * moov.trak.mdia.minf.stbl.co64 adjustment requires | |
3441 * minimal start offset of all traks and new moov atom size | |
3442 */ | |
3443 | |
3444 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | |
3445 "mp4 co64 atom adjustment"); | |
3446 | |
3447 data = trak->out[NGX_HTTP_MP4_CO64_DATA].buf; | |
3448 entry = (uint64_t *) data->pos; | |
3449 end = (uint64_t *) data->last; | |
3450 | |
3451 while (entry < end) { | |
3452 offset = ngx_mp4_get_64value(entry); | |
3453 offset += adjustment; | |
3454 ngx_mp4_set_64value(entry, offset); | |
3455 entry++; | |
3456 } | |
3457 } | |
3458 | |
3459 | |
4085 | 3460 static char * |
3461 ngx_http_mp4(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
3462 { | |
3463 ngx_http_core_loc_conf_t *clcf; | |
3464 | |
3465 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
3466 clcf->handler = ngx_http_mp4_handler; | |
3467 | |
3468 return NGX_CONF_OK; | |
3469 } | |
3470 | |
3471 | |
3472 static void * | |
3473 ngx_http_mp4_create_conf(ngx_conf_t *cf) | |
3474 { | |
3475 ngx_http_mp4_conf_t *conf; | |
3476 | |
3477 conf = ngx_palloc(cf->pool, sizeof(ngx_http_mp4_conf_t)); | |
3478 if (conf == NULL) { | |
3479 return NULL; | |
3480 } | |
3481 | |
3482 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
|
3483 conf->max_buffer_size = NGX_CONF_UNSET_SIZE; |
4085 | 3484 |
3485 return conf; | |
3486 } | |
3487 | |
3488 | |
3489 static char * | |
3490 ngx_http_mp4_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
3491 { | |
3492 ngx_http_mp4_conf_t *prev = parent; | |
3493 ngx_http_mp4_conf_t *conf = child; | |
3494 | |
3495 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
|
3496 ngx_conf_merge_size_value(conf->max_buffer_size, prev->max_buffer_size, |
4085 | 3497 10 * 1024 * 1024); |
3498 | |
3499 return NGX_CONF_OK; | |
3500 } |