Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_mp4_module.c @ 8669:f17ba8ecaaf0
Mp4: mp4_start_key_frame directive.
The directive enables including all frames from start time to the most recent
key frame in the result. Those frames are removed from presentation timeline
using mp4 edit lists.
Edit lists are currently supported by popular players and browsers such as
Chrome, Safari, QuickTime and ffmpeg. Among those not supporting them properly
is Firefox[1].
Based on a patch by Tracey Jaquith, Internet Archive.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1735300
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 28 Oct 2021 14:14:25 +0300 |
parents | 24f7904dbfa0 |
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 } |