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