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