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