Mercurial > mplayer.hg
comparison libmpdemux/muxer_mpeg.c @ 14753:70c446099f40
new mpeg muxer compatible with dvd/[s]vcd; small changes in the muxer layer (sanity checks in the muxer_init functions)
author | nicodvb |
---|---|
date | Mon, 21 Feb 2005 21:45:49 +0000 |
parents | 0db4a3a5b01d |
children | 70f0de24b30a |
comparison
equal
deleted
inserted
replaced
14752:eddd61a68410 | 14753:70c446099f40 |
---|---|
12 | 12 |
13 #include "aviheader.h" | 13 #include "aviheader.h" |
14 #include "ms_hdr.h" | 14 #include "ms_hdr.h" |
15 | 15 |
16 #include "muxer.h" | 16 #include "muxer.h" |
17 | 17 #include "stream.h" |
18 // 18 bytes reserved for block headers and STD | 18 #include "demuxer.h" |
19 #define MUXER_MPEG_DATASIZE (MUXER_MPEG_BLOCKSIZE-18) | 19 #include "stheader.h" |
20 | 20 #include "../m_option.h" |
21 // ISO-11172 requirements | 21 #include "mpeg_hdr.h" |
22 #define MPEG_MAX_PTS_DELAY 90000 /* 1s */ | 22 |
23 #define MPEG_MAX_SCR_INTERVAL 63000 /* 0.7s */ | 23 #define PACK_HEADER_START_CODE 0x01ba |
24 | 24 #define SYSTEM_HEADER_START_CODE 0x01bb |
25 // suggestions | 25 #define PSM_START_CODE 0x01bc |
26 #define MPEG_STARTPTS 45000 /* 0.5s */ | 26 |
27 #define MPEG_MIN_PTS_DELAY 9000 /* 0.1s */ | 27 #define PES_PRIVATE1 0x01bd |
28 #define MPEG_STARTSCR 9 /* 0.1ms */ | 28 #define PES_PRIVATE2 0x01bf |
29 | 29 |
30 //static unsigned int mpeg_min_delay; | 30 #define MUX_MPEG1 1 |
31 //static unsigned int mpeg_max_delay; | 31 #define MUX_MPEG2 2 |
32 | |
33 #define VIDEO_MPEG1 0x10000001 | |
34 #define VIDEO_MPEG2 0x10000002 | |
35 #define AUDIO_MP2 0x50 | |
36 #define AUDIO_MP3 0x55 | |
37 #define AUDIO_A52 0x2000 | |
38 #define AUDIO_LPCM 0x10001 /* only a placeholder at the moment */ | |
39 | |
40 #define ASPECT_1_1 1 | |
41 #define ASPECT_4_3 2 | |
42 #define ASPECT_16_9 3 | |
43 #define ASPECT_2_21_1 4 | |
44 | |
45 #define FRAMERATE_23976 1 | |
46 #define FRAMERATE_24 2 | |
47 #define FRAMERATE_25 3 | |
48 #define FRAMERATE_2997 4 | |
49 #define FRAMERATE_30 5 | |
50 #define FRAMERATE_50 6 | |
51 #define FRAMERATE_5994 7 | |
52 #define FRAMERATE_60 8 | |
53 | |
54 static char ftypes[] = {'?', 'I', 'P', 'B'}; | |
55 #define FTYPE(x) (ftypes[(x)]) | |
56 | |
57 | |
58 static const char *framerates[] = { | |
59 "unchanged", "23.976", "24", "25", "29.97", "30", "50", "59.94", "60" | |
60 }; | |
61 | |
62 static const char *aspect_ratios[] = { | |
63 "unchanged", "1/1", "4/3", "16/9", "2.21/1" | |
64 }; | |
65 | |
66 static char *conf_mux = "mpeg2"; | |
67 static uint16_t conf_packet_size = 0; //dvd | |
68 static uint32_t conf_muxrate = 0; //kb/s | |
69 static char *conf_vaspect = NULL, *conf_vframerate = NULL; | |
70 static uint32_t conf_vwidth = 0, conf_vheight = 0, conf_panscan_width = 0, conf_panscan_height = 0; | |
71 static uint32_t conf_vbitrate = 0; | |
72 static int conf_init_vpts = 200, conf_init_apts = 200; | |
73 static int conf_ts_allframes = 0; | |
74 static int conf_init_adelay = 0; | |
75 static int conf_drop = 0; | |
76 static int conf_skip_padding = 0; | |
77 static int conf_noreorder = 0; | |
78 | |
79 enum FRAME_TYPE { | |
80 I_FRAME = 1, | |
81 P_FRAME = 2, | |
82 B_FRAME = 3 | |
83 }; | |
84 | |
85 typedef struct { | |
86 uint8_t *buffer; | |
87 size_t size; | |
88 size_t alloc_size; | |
89 uint8_t type; | |
90 uint32_t temp_ref; | |
91 uint64_t pts, dts, idur; | |
92 } mpeg_frame_t; | |
93 | |
94 typedef struct { | |
95 uint8_t cnt; // how many entries we use | |
96 struct { | |
97 uint8_t id, type; | |
98 uint32_t bufsize; | |
99 uint32_t format; | |
100 } streams[50]; //16 video + 16 audio mpa + 16 audio private + bd/bf for dvd | |
101 } sys_info_t; | |
102 | |
103 typedef struct { | |
104 uint8_t cnt; // how many entries we use | |
105 struct { | |
106 uint8_t id; | |
107 uint8_t type; | |
108 uint32_t format; | |
109 } streams[50]; //16 video + 16 audio mpa + 16 audio private + bd/bf for dvd | |
110 } psm_info_t; | |
111 | |
112 | |
113 typedef struct { | |
114 int mux; | |
115 sys_info_t sys_info; | |
116 psm_info_t psm_info; | |
117 uint16_t packet_size; | |
118 int is_dvd, is_xvcd, is_xsvcd, is_genmpeg1, is_genmpeg2, ts_allframes, has_video, has_audio; | |
119 int skip_padding; | |
120 int update_system_header, use_psm; | |
121 off_t headers_size, data_size; | |
122 uint64_t scr, vbytes, abytes, init_delay_pts; | |
123 uint32_t muxrate; | |
124 uint8_t *buff, *tmp, *residual; | |
125 uint32_t residual_cnt, headers_cnt; | |
126 double init_adelay; | |
127 int drop; | |
128 | |
129 //video patching parameters | |
130 uint8_t vaspect, vframerate; | |
131 uint16_t vwidth, vheight, panscan_width, panscan_height; | |
132 uint32_t vbitrate; | |
133 int patch_seq, patch_sde; | |
134 int psm_streams_cnt; | |
135 } muxer_priv_t; | |
136 | |
137 | |
138 typedef struct { | |
139 int has_pts, has_dts, pes_is_aligned, type, is_late, min_pes_hlen, psm_fixed; | |
140 uint64_t pts, last_pts, last_dts, dts, init_pts, init_dts, size, frame_duration, delta_pts, nom_delta_pts, frame_size, last_saved_pts; | |
141 uint32_t buffer_size; | |
142 uint8_t pes_priv_headers[4], has_pes_priv_headers; //for A52 and LPCM | |
143 uint32_t bitrate, rest; | |
144 int32_t compensate; | |
145 double delta_clock, timer, aframe_delta_pts, last_dpts; | |
146 mpeg_frame_t *framebuf; | |
147 uint16_t framebuf_cnt; | |
148 uint16_t framebuf_used; | |
149 uint16_t max_pl_size; | |
150 int32_t last_tr; | |
151 uint32_t max_tr; | |
152 uint8_t id, reorder, is_mpeg12; | |
153 mp_mpeg_header_t picture; | |
154 } muxer_headers_t; | |
155 | |
156 | |
157 m_option_t mpegopts_conf[] = { | |
158 {"format", &(conf_mux), CONF_TYPE_STRING, 0, 0 ,0, NULL}, | |
159 {"size", &(conf_packet_size), CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL}, | |
160 {"muxrate", &(conf_muxrate), CONF_TYPE_INT, CONF_RANGE, 0, 12000000, NULL}, //12 Mb/s | |
161 {"vaspect", &(conf_vaspect), CONF_TYPE_STRING, 0, 0, 0, NULL}, | |
162 {"vframerate", &(conf_vframerate), CONF_TYPE_STRING, 0, 0, 0, NULL}, | |
163 {"vwidth", &(conf_vwidth), CONF_TYPE_INT, CONF_RANGE, 1, 4095, NULL}, | |
164 {"vheight", &(conf_vheight), CONF_TYPE_INT, CONF_RANGE, 1, 4095, NULL}, | |
165 {"vpswidth", &(conf_panscan_width), CONF_TYPE_INT, CONF_RANGE, 1, 16383, NULL}, | |
166 {"vpsheight", &(conf_panscan_height), CONF_TYPE_INT, CONF_RANGE, 1, 16383, NULL}, | |
167 {"vbitrate", &(conf_vbitrate), CONF_TYPE_INT, CONF_RANGE, 1, 104857599, NULL}, | |
168 {"init_vpts", &(conf_init_vpts), CONF_TYPE_INT, CONF_RANGE, 100, 700, NULL}, //2*frametime at 60fps | |
169 {"init_apts", &(conf_init_apts), CONF_TYPE_INT, CONF_RANGE, 100, 700, NULL}, | |
170 {"init_adelay", &conf_init_adelay, CONF_TYPE_INT, CONF_RANGE, -32760, -1, NULL}, | |
171 {"drop", &conf_drop, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
172 {"tsaf", &conf_ts_allframes, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
173 {"skip_padding", &conf_skip_padding, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
174 {"noreorder", &conf_noreorder, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
175 {NULL, NULL, 0, 0, 0, 0, NULL} | |
176 }; | |
177 | |
178 static void fix_audio_sys_header(muxer_priv_t *priv, uint8_t id, uint8_t newid, uint32_t size) | |
179 { | |
180 uint8_t i; | |
181 | |
182 for(i = 0; i < priv->sys_info.cnt; i++) | |
183 { | |
184 if(priv->sys_info.streams[i].id == id) | |
185 { | |
186 priv->sys_info.streams[i].id = newid; | |
187 priv->sys_info.streams[i].type = 1; | |
188 priv->sys_info.streams[i].bufsize = size; | |
189 } | |
190 } | |
191 } | |
192 | |
193 static void fix_buffer_params(muxer_priv_t *priv, uint8_t id, uint32_t size) | |
194 { | |
195 uint8_t i; | |
196 | |
197 for(i = 0; i < priv->sys_info.cnt; i++) | |
198 if(priv->sys_info.streams[i].id == id) | |
199 priv->sys_info.streams[i].bufsize = size; | |
200 } | |
201 | |
202 static inline int is_mpeg1(uint32_t x) | |
203 { | |
204 return ( | |
205 (x == 0x10000001) || | |
206 (x == mmioFOURCC('m','p','g','1')) || | |
207 (x == mmioFOURCC('M','P','G','1')) | |
208 ); | |
209 } | |
210 | |
211 static inline int is_mpeg2(uint32_t x) | |
212 { | |
213 return ( | |
214 (x == 0x10000002) || | |
215 (x == mmioFOURCC('m','p','g','2')) || | |
216 (x == mmioFOURCC('M','P','G','2')) || | |
217 (x == mmioFOURCC('m','p','e','g')) || | |
218 (x == mmioFOURCC('M','P','E','G')) | |
219 ); | |
220 } | |
221 | |
222 static inline int is_mpeg4(uint32_t x) | |
223 { | |
224 return ( | |
225 (x == 0x10000004) || | |
226 (x == mmioFOURCC('d','i','v','x')) || | |
227 (x == mmioFOURCC('D','I','V','X')) || | |
228 (x == mmioFOURCC('x','v','i','d')) || | |
229 (x == mmioFOURCC('X','V','I','D')) || | |
230 (x == mmioFOURCC('X','v','i','D')) || | |
231 (x == mmioFOURCC('x','v','i','x')) || | |
232 (x == mmioFOURCC('X','V','I','X')) || | |
233 (x == mmioFOURCC('m','p','4','v')) || | |
234 (x == mmioFOURCC('M','P','4','V')) | |
235 ); | |
236 } | |
237 | |
238 //from unrarlib.c | |
239 static uint32_t CalcCRC32(uint8_t *buff, uint32_t size) | |
240 { | |
241 uint32_t i, j, CRCTab[256], crc; | |
242 | |
243 for(i = 0;i < 256; i++) | |
244 { | |
245 for(crc = i, j = 0; j < 8; j++) | |
246 crc= (crc & 1) ? (crc >> 1)^0xEDB88320L : (crc >> 1); | |
247 CRCTab[i] = crc; | |
248 } | |
249 | |
250 | |
251 crc = 0xffffffff; | |
252 for(i = 0; i < size; i++) | |
253 crc = (crc << 8) ^ CRCTab[((crc >> 24) ^ buff[i]) & 0xff]; | |
254 | |
255 return crc; | |
256 } | |
257 | |
258 | |
259 static void add_to_psm(muxer_priv_t *priv, uint8_t id, uint32_t format) | |
260 { | |
261 uint8_t i; | |
262 | |
263 i = priv->psm_info.cnt; | |
264 priv->psm_info.streams[i].id = id; | |
265 priv->psm_info.streams[i].format = format; | |
266 | |
267 if(is_mpeg1(format)) | |
268 priv->psm_info.streams[i].type = 0x01; | |
269 else if(is_mpeg2(format)) | |
270 priv->psm_info.streams[i].type = 0x02; | |
271 else if(is_mpeg4(format)) | |
272 priv->psm_info.streams[i].type = 0x10; | |
273 else if(format == AUDIO_MP2 || format == AUDIO_MP3) | |
274 priv->psm_info.streams[i].type = 0x03; | |
275 else | |
276 priv->psm_info.streams[i].type = 0x81; | |
277 | |
278 if(format == AUDIO_A52) | |
279 memcpy((char*) &(priv->psm_info.streams[i].format), "AC-3", 4); | |
280 | |
281 priv->psm_info.cnt++; | |
282 } | |
283 | |
284 | |
285 static mpeg_frame_t *init_frames(uint16_t num, size_t size) | |
286 { | |
287 mpeg_frame_t *tmp; | |
288 uint16_t i; | |
289 | |
290 tmp = (mpeg_frame_t *) calloc(num, sizeof(mpeg_frame_t)); | |
291 if(tmp == NULL) | |
292 return NULL; | |
293 | |
294 for(i=0; i < num; i++) | |
295 { | |
296 tmp[i].buffer = (uint8_t *) calloc(1, size); | |
297 if(tmp[i].buffer == NULL) | |
298 return NULL; | |
299 tmp[i].size = 0; | |
300 tmp[i].alloc_size = size; | |
301 tmp[i].pts = 0; | |
302 } | |
303 | |
304 return tmp; | |
305 } | |
306 | |
307 static uint32_t calc_pack_hlen(muxer_priv_t *priv, muxer_headers_t *h); | |
32 | 308 |
33 static muxer_stream_t* mpegfile_new_stream(muxer_t *muxer,int type){ | 309 static muxer_stream_t* mpegfile_new_stream(muxer_t *muxer,int type){ |
310 muxer_priv_t *priv = (muxer_priv_t*) muxer->priv; | |
34 muxer_stream_t *s; | 311 muxer_stream_t *s; |
312 muxer_headers_t *spriv; | |
35 | 313 |
36 if (!muxer) return NULL; | 314 if (!muxer) return NULL; |
37 if(muxer->avih.dwStreams>=MUXER_MAX_STREAMS){ | 315 if(muxer->avih.dwStreams>=MUXER_MAX_STREAMS){ |
38 printf("Too many streams! increase MUXER_MAX_STREAMS !\n"); | 316 mp_msg(MSGT_MUXER, MSGL_ERR, "Too many streams! increase MUXER_MAX_STREAMS !\n"); |
39 return NULL; | 317 return NULL; |
40 } | 318 } |
41 switch (type) { | 319 switch (type) { |
42 case MUXER_TYPE_VIDEO: | 320 case MUXER_TYPE_VIDEO: |
43 if (muxer->num_videos >= 15) { | 321 if (muxer->num_videos >= 16) { |
44 printf ("MPEG stream can't contain above of 15 video streams!\n"); | 322 mp_msg(MSGT_MUXER, MSGL_ERR, "MPEG files can't contain more than 16 video streams!\n"); |
45 return NULL; | 323 return NULL; |
46 } | 324 } |
47 break; | 325 break; |
48 case MUXER_TYPE_AUDIO: | 326 case MUXER_TYPE_AUDIO: |
49 if (muxer->avih.dwStreams - muxer->num_videos >= 31) { | 327 if (muxer->num_audios >= 16) { |
50 printf ("MPEG stream can't contain above of 31 audio streams!\n"); | 328 mp_msg(MSGT_MUXER, MSGL_ERR, "MPEG files can't contain more than 16 audio streams!\n"); |
51 return NULL; | 329 return NULL; |
52 } | 330 } |
53 break; | 331 break; |
54 default: | 332 default: |
55 printf ("Unknown stream type!\n"); | 333 mp_msg(MSGT_MUXER, MSGL_ERR, "Unknown stream type!\n"); |
56 return NULL; | 334 return NULL; |
57 } | 335 } |
58 s=malloc(sizeof(muxer_stream_t)); | 336 s = (muxer_stream_t*) calloc(1, sizeof(muxer_stream_t)); |
59 memset(s,0,sizeof(muxer_stream_t)); | |
60 if(!s) return NULL; // no mem!? | 337 if(!s) return NULL; // no mem!? |
61 if (!(s->b_buffer = malloc (MUXER_MPEG_BLOCKSIZE))) { | 338 if (!(s->b_buffer = malloc(priv->packet_size))) { |
62 free (s); | 339 free (s); |
63 return NULL; // no mem?! | 340 return NULL; // no mem?! |
64 } | 341 } |
342 s->b_buffer_size = priv->packet_size; | |
343 s->b_buffer_ptr = 0; | |
344 s->b_buffer_len = 0; | |
345 s->priv = (muxer_headers_t*) calloc(1, sizeof(muxer_headers_t)); | |
346 if(s->priv == NULL) { | |
347 free(s); | |
348 return NULL; | |
349 } | |
350 spriv = (muxer_headers_t *) s->priv; | |
65 muxer->streams[muxer->avih.dwStreams]=s; | 351 muxer->streams[muxer->avih.dwStreams]=s; |
66 s->type=type; | 352 s->type=type; |
67 s->id=muxer->avih.dwStreams; | 353 s->id=muxer->avih.dwStreams; |
68 s->timer=0.0; | |
69 s->size=0; | |
70 s->muxer=muxer; | 354 s->muxer=muxer; |
355 | |
71 if (type == MUXER_TYPE_VIDEO) { | 356 if (type == MUXER_TYPE_VIDEO) { |
72 s->ckid = be2me_32 (0x1e0 + muxer->num_videos); | 357 spriv->type = 1; |
358 spriv->init_dts = 0; | |
359 spriv->init_pts = conf_init_vpts * 90 * 1024; | |
360 spriv->last_pts = spriv->init_pts; | |
361 spriv->last_saved_pts = 0; | |
362 spriv->init_dts = spriv->last_dts = spriv->init_pts; | |
363 spriv->pts = spriv->dts = 0; | |
364 spriv->last_dpts = spriv->timer; | |
365 spriv->delta_pts = spriv->nom_delta_pts = 0; | |
366 spriv->id = 0xe0 + muxer->num_videos; | |
367 s->ckid = be2me_32 (0x100 + spriv->id); | |
368 if(priv->is_genmpeg1 || priv->is_genmpeg2) { | |
369 int n = priv->sys_info.cnt; | |
370 | |
371 priv->sys_info.streams[n].id = spriv->id; | |
372 priv->sys_info.streams[n].type = 1; | |
373 priv->sys_info.streams[n].bufsize = (s->h.dwSuggestedBufferSize > 0 ? s->h.dwSuggestedBufferSize : 46*1024); | |
374 priv->sys_info.cnt++; | |
375 } | |
73 muxer->num_videos++; | 376 muxer->num_videos++; |
377 priv->has_video++; | |
74 s->h.fccType=streamtypeVIDEO; | 378 s->h.fccType=streamtypeVIDEO; |
75 if(!muxer->def_v) muxer->def_v=s; | 379 if(!muxer->def_v) muxer->def_v=s; |
380 spriv->framebuf_cnt = 30; | |
381 spriv->framebuf_used = 0; | |
382 spriv->framebuf = init_frames(spriv->framebuf_cnt, (size_t) 5000); | |
383 bzero(&(spriv->picture), sizeof(spriv->picture)); | |
384 if(spriv->framebuf == NULL) { | |
385 mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't allocate initial frames structure, abort!\n"); | |
386 return NULL; | |
387 } | |
388 if(priv->is_xvcd) | |
389 spriv->min_pes_hlen = 18; | |
390 else if(priv->is_xsvcd) | |
391 spriv->min_pes_hlen = 22; | |
392 if(conf_noreorder) | |
393 spriv->reorder = 0; | |
394 else | |
395 spriv->reorder = 1; | |
76 mp_msg (MSGT_MUXER, MSGL_DBG2, "Added video stream %d, ckid=%X\n", muxer->num_videos, s->ckid); | 396 mp_msg (MSGT_MUXER, MSGL_DBG2, "Added video stream %d, ckid=%X\n", muxer->num_videos, s->ckid); |
77 } else { // MUXER_TYPE_AUDIO | 397 } else { // MUXER_TYPE_AUDIO |
78 s->ckid = be2me_32 (0x1c0 + s->id - muxer->num_videos); | 398 spriv->type = 0; |
399 spriv->pts = 1; | |
400 spriv->dts = 0; | |
401 spriv->max_pl_size = priv->packet_size - calc_pack_hlen(priv, spriv); | |
402 spriv->init_pts = conf_init_apts * 90 * 1024; | |
403 spriv->pts = spriv->init_pts; | |
404 spriv->dts = 0; | |
405 spriv->id = 0xc0 + muxer->num_audios; | |
406 s->ckid = be2me_32 (0x100 + spriv->id); | |
407 if(priv->is_genmpeg1 || priv->is_genmpeg2) { | |
408 int n = priv->sys_info.cnt; | |
409 | |
410 priv->sys_info.streams[n].id = spriv->id; | |
411 priv->sys_info.streams[n].type = 0; | |
412 priv->sys_info.streams[n].bufsize = (s->h.dwSuggestedBufferSize > 0 ? s->h.dwSuggestedBufferSize : 4*1024); | |
413 priv->sys_info.cnt++; | |
414 } | |
415 if(priv->is_xvcd) | |
416 spriv->min_pes_hlen = 13; | |
417 else if(priv->is_xsvcd) | |
418 spriv->min_pes_hlen = 17; | |
419 | |
420 muxer->num_audios++; | |
421 priv->has_audio++; | |
79 s->h.fccType=streamtypeAUDIO; | 422 s->h.fccType=streamtypeAUDIO; |
80 mp_msg (MSGT_MUXER, MSGL_DBG2, "Added audio stream %d, ckid=%X\n", s->id - muxer->num_videos + 1, s->ckid); | 423 mp_msg (MSGT_MUXER, MSGL_DBG2, "Added audio stream %d, ckid=%X\n", s->id - muxer->num_videos + 1, s->ckid); |
81 } | 424 } |
82 muxer->avih.dwStreams++; | 425 muxer->avih.dwStreams++; |
83 return s; | 426 return s; |
84 } | 427 } |
85 | 428 |
86 static void write_mpeg_ts(unsigned char *b, unsigned int ts, char mod) { | 429 static void write_mpeg_ts(unsigned char *b, uint64_t ts, uint8_t mod) { |
87 b[0] = ((ts >> 29) & 0xf) | 1 | mod; | 430 ts >>= 10; |
431 b[0] = mod | ((ts >> 29) & 0xf) | 1; | |
88 b[1] = (ts >> 22) & 0xff; | 432 b[1] = (ts >> 22) & 0xff; |
89 b[2] = ((ts >> 14) & 0xff) | 1; | 433 b[2] = ((ts >> 14) & 0xff) | 1; |
90 b[3] = (ts >> 7) & 0xff; | 434 b[3] = (ts >> 7) & 0xff; |
91 b[4] = ((ts << 1) & 0xff) | 1; | 435 b[4] = ((ts << 1) & 0xff) | 1; |
92 } | 436 } |
93 | 437 |
94 static void write_mpeg_rate(unsigned char *b, unsigned int rate) { | 438 |
95 if (rate) | 439 static void write_mpeg_rate(int type, unsigned char *b, unsigned int rate) |
96 rate--; // for round upward | 440 { |
97 rate /= 50; | 441 rate = (rate+49) / 50; |
98 rate++; // round upward | 442 |
99 b[0] = ((rate >> 15) & 0x7f) | 0x80; | 443 if(type == MUX_MPEG1) |
100 b[1] = (rate >> 7) & 0xff; | 444 { |
101 b[2] = ((rate << 1) & 0xff) | 1; | 445 b[0] = ((rate >> 15) & 0x7f) | 0x80; |
102 } | 446 b[1] = (rate >> 7) & 0xff; |
103 | 447 b[2] = ((rate << 1) & 0xff) | 1; |
104 static void write_mpeg_std(unsigned char *b, unsigned int size, char mod) { | 448 } |
105 if (size) | 449 else |
106 size--; // for round upward | 450 { |
107 if (size < (128 << 8)) | 451 b[0] = (rate >> 14); |
108 size >>= 7; // by 128 bytes | 452 b[1] = (rate >> 6) & 0xff; |
109 else { | 453 b[2] = ((rate & 0x3f) << 2) | 0x03; |
110 size >>= 10; | 454 } |
111 size |= 0x2000; // by 1kbyte | 455 } |
112 } | 456 |
113 size++; // round upward | 457 |
114 b[0] = ((size >> 8) & 0x3f) | 0x40 | mod; | 458 static void write_mpeg_std(unsigned char *b, unsigned int size, unsigned int type, uint8_t mod) |
115 b[1] = size & 0xff; | 459 { |
116 } | 460 //type = 0:mpeg audio/128, 1:video and pes private streams (including ac3/dts/lpcm)/1024 |
117 | 461 if(type == 0) //audio |
118 static int write_mpeg_block(muxer_t *muxer, muxer_stream_t *s, FILE *f, char *bl, size_t len, int isoend){ | 462 size = (size + 127) / 128; |
119 size_t sz; // rest in block buffer | 463 else //video or other |
120 unsigned char buff[12]; // 0x1ba header | 464 size = ((size + 1023) / 1024); |
121 unsigned int mints=0; | 465 |
122 uint16_t l1; | 466 if(! size) |
123 | 467 size++; |
124 mp_dbg(MSGT_MUXER, MSGL_DBG3, " MPEG block: size=%u, scr=%u, rate=%u, id=%X;", len, muxer->file_end, muxer->sysrate, s->ckid); | 468 |
125 if (s->b_buffer_ptr == 0) { // 00001111 if no PTS | 469 b[0] = ((size >> 8) & 0x3f) | (type==1 ? 0x60 : 0x40) | mod; |
126 s->b_buffer[0] = 0xf; | 470 b[1] = size & 0xff; |
127 s->b_buffer_ptr = 1; | 471 } |
128 sz = MUXER_MPEG_DATASIZE-1; | 472 |
129 } else if (s->b_buffer_ptr > MUXER_MPEG_DATASIZE) { | 473 static void write_mpeg2_scr(unsigned char *b, uint64_t ts) |
130 printf ("Unknown error in write_mpeg_block()!\n"); | 474 { |
131 return 0; | 475 uint16_t t1, t2, t3; |
132 } else { | 476 ts >>= 10; |
133 sz = MUXER_MPEG_DATASIZE - s->b_buffer_ptr; | 477 ts &= 0x1FFFFFFFFULL; //33 bits, no extension; input must be * 92160000 |
134 if (s->b_buffer[7] == 0xff) // PTS not set yet | 478 t1 = (ts >> 30) & 0x7;; |
135 s->b_buffer[11] = 0xf; // terminate stuFFing bytes | 479 t2 = (ts >> 15) & 0x7fff; |
136 } | 480 t3 = ts & 0x7fff; |
137 if (len > sz) | 481 |
138 len = sz; | 482 b[0] = (t1 << 3 ) | 0x44 | ((t2 >> 13) & 0x3); |
139 *(uint32_t *)buff = be2me_32 (0x1ba); | 483 b[1] = (t2 >> 5); |
140 write_mpeg_ts (buff+4, muxer->file_end, 0x20); // 0010 and SCR | 484 b[2] = (t2 & 0x1f) << 3 | 0x4 | ((t3 >> 13) & 0x3); |
141 write_mpeg_rate (buff+9, muxer->sysrate); | 485 b[3] = (t3 >> 5); |
142 fwrite (buff, 12, 1, f); | 486 b[4] = (t3 & 0x1f) << 3 | 0x4; |
143 fwrite (&s->ckid, 4, 1, f); // stream_id | 487 b[5] = 1; |
144 memset (buff, 0xff, 12); // stuFFing bytes | 488 } |
145 sz -= len; | 489 |
146 // calculate padding bytes in buffer | 490 |
147 while (mints < s->b_buffer_ptr && s->b_buffer[mints] == 0xff) mints++; | 491 static int write_mpeg_pack_header(muxer_t *muxer, char *buff) |
148 if (mints+sz < 12) { // cannot write padding block so write up to 12 stuFFing bytes | 492 { |
149 l1 = be2me_16 (MUXER_MPEG_DATASIZE); | 493 int len; |
150 fwrite (&l1, 2, 1, f); | 494 muxer_priv_t *priv; |
151 mints = 0; // so stuFFed bytes will be written all | 495 |
152 if (sz) | 496 priv = (muxer_priv_t *) muxer->priv; |
153 fwrite (buff, sz, 1, f); | 497 *(uint32_t *)buff = be2me_32(PACK_HEADER_START_CODE); |
154 sz = 0; // no padding block anyway | 498 if(priv->mux==MUX_MPEG1) |
155 } else { // use padding block | 499 { |
156 if (sz > 6) // sufficient for PAD header so don't shorter data | 500 write_mpeg_ts(&buff[4], priv->scr, 0x20); // 0010 and SCR |
157 mints = 0; | 501 write_mpeg_rate(priv->mux, &buff[9], muxer->sysrate); |
158 else | 502 len = 12; |
159 sz += mints; // skip stuFFing bytes (sz>8 here) | 503 } |
160 l1 = be2me_16 (s->b_buffer_ptr+len-mints); | 504 else |
161 fwrite (&l1, 2, 1, f); | 505 { |
162 } | 506 write_mpeg2_scr(&buff[4], priv->scr); // 0010 and SCR |
163 if (s->b_buffer_ptr) | 507 write_mpeg_rate(priv->mux, &buff[10], muxer->sysrate); |
164 fwrite (s->b_buffer+mints, s->b_buffer_ptr-mints, 1, f); | 508 buff[13] = 0xf8; //5 bits reserved + 3 set to 0 to indicate 0 stuffing bytes |
165 if (len) | 509 len = 14; |
166 fwrite (bl, len, 1, f); | 510 } |
167 if (sz > 6) { // padding block (0x1be) | 511 |
168 uint32_t l0; | 512 return len; |
169 | 513 } |
170 if (isoend) | 514 |
171 l0 = be2me_32 (0x1b9); | 515 |
172 else | 516 static int write_mpeg_system_header(muxer_t *muxer, char *buff) |
173 l0 = be2me_32 (0x1be); | 517 { |
174 sz -= 6; | 518 int len; |
175 l1 = be2me_16 (sz); | 519 uint8_t i; |
176 fwrite (&l0, 4, 1, f); | 520 muxer_priv_t *priv; |
177 fwrite (&l1, 2, 1, f); | 521 priv = (muxer_priv_t *) muxer->priv; |
178 memset (s->b_buffer, 0xff, sz); // stuFFing bytes | 522 |
179 fwrite (s->b_buffer, sz, 1, f); | 523 len = 0; |
180 } | 524 *(uint32_t *)(&buff[len]) = be2me_32(SYSTEM_HEADER_START_CODE); |
181 s->b_buffer_ptr = 0; | 525 len += 4; |
182 muxer->movi_end += MUXER_MPEG_BLOCKSIZE; | 526 *(uint16_t *)(&buff[len]) = 0; //fake length, we'll fix it later |
183 // prepare timestamps for next pack | 527 len += 2; |
184 mints = (MUXER_MPEG_BLOCKSIZE*90000/muxer->sysrate)+1; // min ts delta | 528 write_mpeg_rate(MUX_MPEG1, &buff[len], muxer->sysrate); |
185 sz = (int)(s->timer*90000) + MPEG_STARTPTS; // new PTS | 529 len += 3; |
186 if (sz > muxer->file_end) | 530 |
187 sz -= muxer->file_end; // suggested ts delta | 531 buff[len++] = 0x4 | (priv->is_xvcd ? 1 : 0); //1 audio stream bound, no fixed, CSPS only for xvcd |
188 else | 532 buff[len++] = 0xe1; //system_audio_lock, system_video_lock, marker, 1 video stream bound |
189 { | 533 |
190 sz = 0; | 534 buff[len++] = ((priv->mux == MUX_MPEG1) ? 0xff : 0x7f); //in mpeg2 there's the packet rate restriction |
191 printf ("Error in stream: PTS earlier than SCR!\n"); | 535 |
192 } | 536 for(i = 0; i < priv->sys_info.cnt; i++) |
193 if (sz > MPEG_MAX_PTS_DELAY) { | 537 { |
194 // printf ("Warning: attempt to set PTS to SCR delay to %u \n", sz); | 538 buff[len++] = priv->sys_info.streams[i].id; |
195 mints = sz-MPEG_MAX_PTS_DELAY; // try to compensate | 539 write_mpeg_std(&buff[len], priv->sys_info.streams[i].bufsize, priv->sys_info.streams[i].type, |
196 if (mints > MPEG_MAX_SCR_INTERVAL) { | 540 (priv->sys_info.streams[i].type == 1 ? 0xe0: 0xc0)); |
197 printf ("Error in stream: SCR interval %u is too big!\n", mints); | 541 len += 2; |
542 } | |
543 | |
544 *(uint16_t *)(&buff[4]) = be2me_16(len - 6); // length field fixed | |
545 | |
546 return len; | |
547 } | |
548 | |
549 static int write_mpeg_psm(muxer_t *muxer, char *buff) | |
550 { | |
551 int len; | |
552 uint8_t i; | |
553 uint16_t dlen; | |
554 muxer_priv_t *priv; | |
555 priv = (muxer_priv_t *) muxer->priv; | |
556 | |
557 len = 0; | |
558 *(uint32_t *)(&buff[len]) = be2me_32(PSM_START_CODE); | |
559 len += 4; | |
560 *(uint16_t *)(&buff[len]) = 0; //fake length, we'll fix it later | |
561 len += 2; | |
562 buff[len++] = 0xe0; //1 current, 2 bits reserved, 5 version 0 | |
563 buff[len++] = 0xff; //7 reserved, 1 marker | |
564 buff[len] = buff[len+1] = 0; //length of the program descriptors (unused) | |
565 len += 2; | |
566 *(uint16_t *)(&buff[len]) = 0; //length of the es descriptors | |
567 len += 2; | |
568 | |
569 dlen = 0; | |
570 for(i = 0; i < priv->psm_info.cnt; i++) | |
571 { | |
572 if( | |
573 (priv->psm_info.streams[i].id == 0xbd) || | |
574 (priv->psm_info.streams[i].id >= 0xe0 && priv->psm_info.streams[i].id <= 0xef) || | |
575 (priv->psm_info.streams[i].id >= 0xc0 && priv->psm_info.streams[i].id <= 0xcf) | |
576 ) | |
577 { | |
578 buff[len++] = priv->psm_info.streams[i].type; | |
579 buff[len++] = priv->psm_info.streams[i].id; | |
580 buff[len++] = 0; //len of descriptor upper ... | |
581 buff[len++] = 6; //... lower | |
582 | |
583 //registration descriptor | |
584 buff[len++] = 0x5; //tag | |
585 buff[len++] = 4; //length: 4 bytes | |
586 memcpy(&(buff[len]), (char*) &(priv->psm_info.streams[i].format), 4); | |
587 len += 4; | |
588 dlen += 10; | |
589 } | |
590 } | |
591 *(uint16_t *)(&buff[10]) = be2me_16(dlen); //length of the es descriptors | |
592 | |
593 *(uint16_t *)(&buff[4]) = be2me_16(len - 6 + 4); // length field fixed, including size of CRC32 | |
594 | |
595 *(uint32_t *)(&buff[len]) = CalcCRC32(buff, len); | |
596 | |
597 len += 4; //for crc | |
598 | |
599 return len; | |
600 } | |
601 | |
602 static int write_mpeg_pes_header(muxer_headers_t *h, uint8_t *pes_id, uint8_t *buff, uint16_t plen, int stuffing_len, int mux_type) | |
603 { | |
604 int len; | |
605 | |
606 len = 0; | |
607 memcpy(&buff[len], pes_id, 4); | |
608 len += 4; | |
609 | |
610 buff[len] = buff[len+1] = 0; //fake len | |
611 len += 2; | |
612 | |
613 if(mux_type == MUX_MPEG1) | |
614 { | |
615 if(stuffing_len > 0) | |
616 { | |
617 memset(&buff[len], 0xff, stuffing_len); | |
618 len += stuffing_len; | |
619 } | |
620 | |
621 if(h->buffer_size > 0) | |
622 { | |
623 write_mpeg_std(&buff[len], h->buffer_size, h->type, 0x40); // 01 is pes1 format | |
624 len += 2; | |
625 } | |
626 } | |
627 else //MPEG2 | |
628 { | |
629 buff[len] = (h->pes_is_aligned ? 0x84 : 0x80); //0x10... | |
630 len++; | |
631 buff[len] = ((h->buffer_size > 0) ? 1 : 0) | (h->pts ? (h->dts ? 0xC0 : 0x80) : 0); //pes extension + pts/dts flags | |
632 len++; | |
633 buff[len] = (h->pts ? (h->dts ? 10 : 5) : 0) + ((h->buffer_size > 0) ? 3 : 0) + stuffing_len;//pts + std + stuffing | |
634 len++; | |
635 } | |
636 | |
637 | |
638 if(h->pts) | |
639 { | |
640 write_mpeg_ts(&buff[len], h->pts, (h->dts ? 0x30 : 0x20)); // 001x and both PTS/DTS | |
641 len += 5; | |
642 | |
643 if(h->dts) | |
644 { | |
645 write_mpeg_ts(&buff[len], h->dts, 0x10); // 0001 before DTS | |
646 len += 5; | |
647 } | |
648 } | |
649 else | |
650 { | |
651 if(mux_type == MUX_MPEG1) | |
652 { | |
653 buff[len] = 0x0f; | |
654 len += 1; | |
655 } | |
656 } | |
657 | |
658 | |
659 if(mux_type == MUX_MPEG2) | |
660 { | |
661 if(h->buffer_size > 0) | |
662 { | |
663 buff[len] = 0x10; //std flag | |
664 len++; | |
665 | |
666 write_mpeg_std(&buff[len], h->buffer_size, h->type, 0x40); | |
667 len += 2; | |
668 } | |
669 | |
670 if(stuffing_len > 0) | |
671 { | |
672 memset(&buff[len], 0xff, stuffing_len); | |
673 len += stuffing_len; | |
674 } | |
675 } | |
676 | |
677 if(h->has_pes_priv_headers > 0) | |
678 { | |
679 memcpy(&buff[len], h->pes_priv_headers, h->has_pes_priv_headers); | |
680 len += h->has_pes_priv_headers; | |
681 } | |
682 | |
683 *((uint16_t*) &buff[4]) = be2me_16(len + plen - 6); //fix pes packet size | |
684 return len; | |
685 } | |
686 | |
687 | |
688 static void write_pes_padding(uint8_t *buff, uint16_t len) | |
689 { | |
690 //6 header bytes + len-6 0xff chars | |
691 buff[0] = buff[1] = 0; | |
692 buff[2] = 1; | |
693 buff[3] = 0xbe; | |
694 *((uint16_t*) &buff[4]) = be2me_16(len - 6); | |
695 memset(&buff[6], 0xff, len - 6); | |
696 } | |
697 | |
698 static void write_psm_block(muxer_t *muxer, FILE *f) | |
699 { | |
700 uint16_t offset, stuffing_len; | |
701 muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; | |
702 uint8_t *buff = priv->buff; | |
703 | |
704 offset = write_mpeg_pack_header(muxer, buff); | |
705 offset += write_mpeg_psm(muxer, &buff[offset]); | |
706 stuffing_len = priv->packet_size - offset; | |
707 if(stuffing_len > 0) | |
708 { | |
709 //insert a PES padding packet | |
710 write_pes_padding(&buff[offset], stuffing_len); | |
711 offset += stuffing_len; | |
712 } | |
713 fwrite(buff, offset, 1, f); | |
714 priv->headers_size += offset; | |
715 } | |
716 | |
717 | |
718 static int write_nav_pack(uint8_t *buff) | |
719 { | |
720 // concatenation of pes_private2 + 03d4 x 0 and pes_private2 + 03fa x 0 | |
721 int len; | |
722 | |
723 mp_msg(MSGT_MUXER, MSGL_V, "NAV\n"); | |
724 len = 0; | |
725 *(uint32_t *)(&buff[len]) = be2me_32(PES_PRIVATE2); | |
726 len += 4; | |
727 buff[len++] = 0x3; | |
728 buff[len++] = 0xd4; | |
729 memset(&buff[len], 0, 0x03d4); | |
730 len += 0x03d4; | |
731 | |
732 *(uint32_t *)(&buff[len]) = be2me_32(PES_PRIVATE2); | |
733 len += 4; | |
734 buff[len++] = 0x3; | |
735 buff[len++] = 0xfa; | |
736 memset(&buff[len], 0, 0x03fa); | |
737 len += 0x03fa; | |
738 | |
739 return len; | |
740 } | |
741 | |
742 static uint32_t calc_pes_hlen(int format, muxer_headers_t *h, muxer_priv_t *priv) | |
743 { | |
744 uint32_t len; | |
745 | |
746 if(format == MUX_MPEG1) | |
747 len = 6; | |
748 else | |
749 len = 9; //era 12 | |
750 | |
751 if(h->pts) | |
752 { | |
753 len += 5; | |
754 if(h->dts) | |
755 len += 5; | |
756 } | |
757 else if(format == MUX_MPEG1) | |
758 len += 1; | |
759 | |
760 if(h->buffer_size > 0) | |
761 { | |
762 if(format == MUX_MPEG2) | |
763 len += 3; | |
764 else | |
765 len += 2; | |
766 } | |
767 | |
768 len += h->has_pes_priv_headers; | |
769 | |
770 return len; | |
771 } | |
772 | |
773 static uint32_t calc_pack_hlen(muxer_priv_t *priv, muxer_headers_t *h) | |
774 { | |
775 uint32_t len; | |
776 | |
777 if(priv->mux == MUX_MPEG1) | |
778 len = 12; | |
779 else | |
780 len = 14; | |
781 | |
782 /*if((priv->is_genmpeg1 || priv->is_genmpeg2) && priv->update_system_header) | |
783 len += (6 + (3*priv->sys_info.cnt));*/ | |
784 | |
785 if(h->min_pes_hlen > 0) | |
786 len += h->min_pes_hlen; | |
787 else | |
788 len += calc_pes_hlen(priv->mux, h, priv); | |
789 | |
790 return len; | |
791 } | |
792 | |
793 | |
794 static int write_mpeg_pack(muxer_t *muxer, muxer_stream_t *s, FILE *f, char *bl, uint32_t len, int isoend) | |
795 { | |
796 size_t tot, offset, pes_hlen, pack_hlen; | |
797 muxer_priv_t *priv; | |
798 uint8_t *buff; | |
799 int stuffing_len = 0, stflen; | |
800 muxer_headers_t *spriv; | |
801 | |
802 priv = (muxer_priv_t *) muxer->priv; | |
803 buff = priv->buff; | |
804 | |
805 if(isoend) | |
806 { | |
807 buff[0] = buff[1] = 0; | |
808 buff[2] = 1; | |
809 buff[3] = 0xb9; | |
810 fwrite(buff, 4, 1, f); | |
811 return 1; | |
812 } | |
813 | |
814 if((len == 0) || (bl == NULL)) //PACK headers only | |
815 { | |
816 offset = write_mpeg_pack_header(muxer, buff); | |
817 offset += write_mpeg_system_header(muxer, &buff[offset]); | |
818 | |
819 //priv->update_system_header = 0; | |
820 | |
821 if(priv->is_dvd) | |
822 offset += write_nav_pack(&buff[offset]); | |
823 | |
824 stuffing_len = priv->packet_size - offset; | |
825 if(stuffing_len > 0) | |
826 { | |
827 //insert a PES padding packet | |
828 write_pes_padding(&buff[offset], stuffing_len); | |
829 offset += stuffing_len; | |
830 } | |
831 | |
832 fwrite(buff, offset, 1, f); | |
833 priv->headers_size += offset; | |
834 tot = offset; | |
835 muxer->movi_end += tot; | |
836 | |
837 return tot; | |
838 } | |
839 else | |
840 { | |
841 spriv = (muxer_headers_t *) s->priv; | |
842 | |
843 mp_msg(MSGT_MUXER, MSGL_V, "\nwrite_mpeg_pack(MUX=%d, len=%u, rate=%u, id=%X, pts: %llu, dts: %llu, scr: %llu, PACK_size:%u\n", | |
844 priv->mux, len, muxer->sysrate, s->ckid, spriv->pts, spriv->dts, priv->scr, priv->packet_size); | |
845 | |
846 //stflen is the count of stuffing bytes in the pes header itself, | |
847 //stuffing_len is the size of the stuffing pes stream (must be at least 7 bytes long) | |
848 stflen = stuffing_len = 0; | |
849 offset = 0; | |
850 offset = pack_hlen = write_mpeg_pack_header(muxer, &buff[offset]); | |
851 | |
852 if(priv->update_system_header && (priv->is_genmpeg1 || priv->is_genmpeg2)) | |
853 { | |
854 pack_hlen += write_mpeg_system_header(muxer, &buff[offset]); | |
855 priv->update_system_header = 0; | |
856 } | |
857 | |
858 offset = pack_hlen; | |
859 | |
860 pes_hlen = calc_pes_hlen(priv->mux, spriv, priv); | |
861 if(spriv->min_pes_hlen > 0) | |
862 { | |
863 if(spriv->min_pes_hlen > pes_hlen) | |
864 stflen = spriv->min_pes_hlen - pes_hlen; | |
865 } | |
866 | |
867 if((len >= priv->packet_size - pack_hlen - max(pes_hlen, spriv->min_pes_hlen))) | |
868 stuffing_len = 0; | |
869 else | |
870 stuffing_len = priv->packet_size - pack_hlen - max(pes_hlen, spriv->min_pes_hlen) - len; | |
871 | |
872 if(stuffing_len > 0) | |
873 { | |
874 if(stuffing_len < 7) | |
875 { | |
876 if(stflen + stuffing_len > 16) | |
877 { | |
878 int x = 7 - stuffing_len; | |
879 stflen -= x; | |
880 stuffing_len += x; | |
881 } | |
882 else | |
883 { | |
884 stflen += stuffing_len; | |
885 stuffing_len = 0; | |
886 } | |
887 } | |
888 } | |
889 | |
890 if(priv->skip_padding) //variable packet size, just for fun and to reduce file size | |
891 { | |
892 stuffing_len = 0; | |
893 len = min(len, priv->packet_size - pack_hlen - pes_hlen - stflen); | |
894 } | |
895 else | |
896 len = priv->packet_size - pack_hlen - pes_hlen - stflen - stuffing_len; | |
897 | |
898 mp_msg(MSGT_MUXER, MSGL_V, "LEN=%d, pack: %d, pes: %d, stf: %d, stf2: %d\n", len, pack_hlen, pes_hlen, stflen, stuffing_len); | |
899 | |
900 pes_hlen = write_mpeg_pes_header(spriv, (uint8_t *) &s->ckid, &buff[offset], len, stflen, priv->mux); | |
901 | |
902 offset += pes_hlen; | |
903 | |
904 fwrite(buff, offset, 1, f); | |
905 mp_msg(MSGT_MUXER, MSGL_V, "pack_len = %u, pes_hlen = %u, stuffing_len: %d+%d, SCRIVO: %d bytes di payload\n", | |
906 pack_hlen, pes_hlen, stuffing_len, stflen, len); | |
907 fwrite(bl, len, 1, f); | |
908 | |
909 offset += len; | |
910 | |
911 if(stuffing_len > 0) | |
912 { | |
913 //insert a PES padding packet | |
914 mp_msg(MSGT_MUXER, MSGL_V, "STUFFING: %d\n", stuffing_len); | |
915 write_pes_padding(buff, stuffing_len); | |
916 fwrite(buff, stuffing_len, 1, f); | |
917 } | |
918 else | |
919 stuffing_len = 0; | |
920 | |
921 offset += stuffing_len; | |
922 | |
923 mp_msg(MSGT_MUXER, MSGL_V, "\nwritten len=%d, spriv: pack(%d), pes(%d), stuffing(%d) tot(%d), offset: %d\n", | |
924 len, pack_hlen, pes_hlen, stuffing_len, pack_hlen + pes_hlen + stuffing_len, offset); | |
925 | |
926 priv->headers_size += pack_hlen + pes_hlen + stuffing_len + stflen; | |
927 priv->data_size += len; | |
928 muxer->movi_end += offset; | |
929 | |
930 return len; | |
931 } | |
932 } | |
933 | |
934 | |
935 static void patch_seq(muxer_priv_t *priv, unsigned char *buf) | |
936 { | |
937 if(priv->vwidth > 0) | |
938 { | |
939 buf[4] = (priv->vwidth >> 4) & 0xff; | |
940 buf[5] &= 0x0f; | |
941 buf[5] |= (priv->vwidth & 0x0f) << 4; | |
942 } | |
943 | |
944 if(priv->vheight > 0) | |
945 { | |
946 buf[5] &= 0xf0; | |
947 buf[5] |= (priv->vheight >> 8) & 0x0f; | |
948 buf[6] = priv->vheight & 0xff; | |
949 } | |
950 | |
951 if(priv->vaspect > 0) | |
952 buf[7] = (buf[7] & 0x0f) | (priv->vaspect << 4); | |
953 | |
954 if(priv->vframerate > 0) | |
955 buf[7] = (buf[7] & 0xf0) | priv->vframerate; | |
956 | |
957 if(priv->vbitrate > 0) | |
958 { | |
959 buf[8] = (priv->vbitrate >> 10); | |
960 buf[9] = (priv->vbitrate >> 2); | |
961 buf[10] = (buf[10] & 0x3f) | (unsigned char) ((priv->vbitrate & 0x4) << 2); | |
962 } | |
963 } | |
964 | |
965 static void patch_panscan(muxer_priv_t *priv, unsigned char *buf) | |
966 { //patches sequence display extension (display_horizontal_size and display_vertical_size) | |
967 //1: | |
968 int offset = 1; | |
969 | |
970 if(buf[0] & 0x01) | |
971 offset += 3; | |
972 | |
973 if(priv->panscan_width > 0) | |
974 { | |
975 buf[offset] = (priv->panscan_width >> 6); | |
976 buf[offset+1] = ((priv->panscan_width & 0x3F) << 2) | (buf[offset + 1] & 0x03); | |
977 } | |
978 | |
979 offset++; | |
980 | |
981 if(priv->panscan_height > 0) | |
982 { | |
983 buf[offset] = (priv->panscan_height >> 13) << 7; | |
984 buf[offset+1] = (priv->panscan_height >> 5) & 0xFF; | |
985 buf[offset+2] = ((priv->panscan_height & 0x1F) << 3) | (buf[offset+2] & 0x07); | |
986 } | |
987 } | |
988 | |
989 | |
990 #define max(a, b) ((a) >= (b) ? (a) : (b)) | |
991 #define min(a, b) ((a) <= (b) ? (a) : (b)) | |
992 | |
993 | |
994 static uint32_t get_audio_frame_size(muxer_headers_t *spriv, uint8_t *buf, int format, int samples_ps) | |
995 { | |
996 uint32_t sz, tmp; | |
997 | |
998 #ifdef USE_LIBA52 | |
999 #include "../liba52/a52.h" | |
1000 if(format == 0x2000) | |
1001 { | |
1002 int t1, t2, t3; | |
1003 sz = (uint32_t) a52_syncinfo(buf, &t1, &t2, &t3); | |
1004 if(sz) | |
1005 return sz; | |
1006 } | |
1007 #endif | |
1008 tmp = spriv->bitrate * (format == 0x2000 ? 1536 : 1152); | |
1009 sz = tmp / samples_ps; | |
1010 if(sz % 2) | |
1011 sz++; | |
1012 | |
1013 return sz; | |
1014 } | |
1015 | |
1016 | |
1017 static int reorder_frame(muxer_headers_t *spriv, uint8_t *ptr, size_t len, uint8_t pt, uint32_t temp_ref, uint64_t idur) | |
1018 { | |
1019 uint16_t idx = 0, move=0; | |
1020 | |
1021 /* HOW TO REORDER FRAMES IN DECODING ORDER: | |
1022 current frame is n | |
1023 IF pt(n)==I or P and | |
1024 n>0 && temp_ref(n) > temp_ref(n-1) && pt(n-1 .. n-m)==B | |
1025 then insert frame n before frame n-m | |
1026 and shift forward the others | |
1027 */ | |
1028 | |
1029 idx = spriv->framebuf_used; | |
1030 if(spriv->reorder) | |
1031 { | |
1032 //stores the frame in decoding order | |
1033 if((idx > 0) && ((pt == I_FRAME) || (pt == P_FRAME))) | |
1034 { | |
1035 if((spriv->framebuf[idx - 1].type == B_FRAME) && (spriv->framebuf[idx - 1].temp_ref == temp_ref-1)) | |
1036 { | |
1037 while((spriv->framebuf[idx - 1].type == B_FRAME) && (spriv->framebuf[idx - 1].temp_ref < temp_ref) && (idx > 0)) | |
1038 idx--; | |
1039 move = spriv->framebuf_used - idx; //from idx there are 'move' frames to move forward | |
1040 } | |
1041 } | |
1042 } | |
1043 | |
1044 //now idx is the position where we should store the frame | |
1045 if(idx+move >= spriv->framebuf_cnt) | |
1046 { //realloc | |
1047 //fprintf(stderr, "\nREALLOC1: %d\n", (int) spriv->framebuf_cnt+1); | |
1048 spriv->framebuf = (mpeg_frame_t*) realloc(spriv->framebuf, (spriv->framebuf_cnt+1)*sizeof(mpeg_frame_t)); | |
1049 if(spriv->framebuf == NULL) | |
1050 { | |
1051 mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(idx), abort\n"); | |
1052 return 0; | |
1053 } | |
1054 | |
1055 spriv->framebuf[spriv->framebuf_cnt].size = 0; | |
1056 spriv->framebuf[spriv->framebuf_cnt].alloc_size = 0; | |
1057 | |
1058 spriv->framebuf[spriv->framebuf_cnt].buffer = (uint8_t*) malloc(len); | |
1059 if(spriv->framebuf[spriv->framebuf_cnt].buffer == NULL) | |
1060 { | |
1061 mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(frame), abort\n"); | |
1062 return 0; | |
1063 } | |
1064 spriv->framebuf[spriv->framebuf_cnt].alloc_size = len; | |
1065 spriv->framebuf_cnt++; | |
1066 } | |
1067 | |
1068 | |
1069 | |
1070 while(move > 0) | |
1071 { | |
1072 mpeg_frame_t f; | |
1073 | |
1074 f = spriv->framebuf[move + idx]; | |
1075 spriv->framebuf[move + idx] = spriv->framebuf[move + idx - 1]; | |
1076 spriv->framebuf[move + idx - 1] = f; | |
1077 move--; | |
1078 } | |
1079 | |
1080 if(spriv->framebuf[idx].alloc_size < len) | |
1081 { | |
1082 spriv->framebuf[idx].buffer = realloc(spriv->framebuf[idx].buffer, len); | |
1083 if(spriv->framebuf[idx].buffer == NULL) | |
1084 { | |
1085 mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(frame), abort\n"); | |
1086 return 0; | |
1087 } | |
1088 spriv->framebuf[idx].alloc_size = len; | |
1089 } | |
1090 | |
1091 mp_msg(MSGT_MUXER, MSGL_DBG2, "\nIDX: %u, type: %c, temp_ref: %u, ptr: %p, len: %u, alloc: %u, buffer: %p\n", | |
1092 (uint32_t) idx, FTYPE(pt), temp_ref, ptr, (uint32_t) len, (uint32_t) spriv->framebuf[idx].alloc_size, spriv->framebuf[idx].buffer); | |
1093 | |
1094 memcpy(spriv->framebuf[idx].buffer, ptr, len); | |
1095 spriv->framebuf[idx].size = len; | |
1096 spriv->framebuf[idx].temp_ref = temp_ref; | |
1097 spriv->framebuf[idx].type = pt; | |
1098 spriv->framebuf[idx].idur = idur; | |
1099 spriv->framebuf_used++; | |
1100 | |
1101 return 1; | |
1102 } | |
1103 | |
1104 | |
1105 static uint32_t dump_audio(muxer_t *muxer, muxer_stream_t *as, uint32_t abytes, int force) | |
1106 { | |
1107 uint32_t len = 0, sz; | |
1108 uint64_t num_frames = 0, next_pts; | |
1109 uint16_t rest; | |
1110 int64_t tmp; | |
1111 double delta_pts; | |
1112 muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; | |
1113 muxer_headers_t *apriv = (muxer_headers_t*) as->priv; | |
1114 | |
1115 if((abytes < apriv->frame_size) && (! force)) //pl_size | |
1116 //if((abytes < apriv->max_pl_size) && (! force)) //pl_size | |
1117 { | |
1118 apriv->is_late = 1; | |
1119 mp_msg(MSGT_MUXER, MSGL_V, "NOT SAVING: %u bytes\n", abytes); | |
1120 return 0; | |
1121 } | |
1122 | |
1123 abytes = min(abytes, as->b_buffer_len); //available bytes | |
1124 if(! abytes) | |
1125 return 0; | |
1126 | |
1127 if(as->ckid == be2me_32(0x1bd)) | |
1128 apriv->has_pes_priv_headers = 4; | |
1129 else | |
1130 apriv->has_pes_priv_headers = 0; | |
1131 | |
1132 rest = (apriv->size % apriv->frame_size); | |
1133 if(rest) | |
1134 rest = apriv->frame_size - rest; | |
1135 | |
1136 sz = priv->packet_size - calc_pack_hlen(priv, apriv); //how many payload bytes we are about to write | |
1137 num_frames = (sz + apriv->frame_size - 1 - rest) / apriv->frame_size; | |
1138 | |
1139 mp_msg(MSGT_MUXER, MSGL_V, "\nAUDIO: tot=%llu, sz=%u bytes, FRAMES: %llu * %u, REST: %u, DELTA_PTS: %u\n", | |
1140 apriv->size, sz, num_frames, (uint32_t) apriv->frame_size, (uint32_t) rest, (uint32_t) ((num_frames * apriv->delta_pts) >> 10)); | |
1141 | |
1142 next_pts = ((uint64_t) (num_frames * apriv->delta_pts)) + apriv->pts; | |
1143 if(((priv->scr + (63000*1024)) < next_pts) && (priv->scr < apriv->pts) && (! force)) | |
1144 { | |
1145 apriv->is_late = 1; | |
1146 return 0; | |
1147 } | |
1148 | |
1149 if(as->ckid == be2me_32(0x1bd)) | |
1150 { | |
1151 apriv->pes_priv_headers[0] = 0x80; | |
1152 apriv->pes_priv_headers[1] = num_frames; | |
1153 apriv->pes_priv_headers[2] = ((rest+1) >> 8) & 0xff; //256 * 0 ... | |
1154 apriv->pes_priv_headers[3] = (rest+1) & 0xff; // + 1 byte(s) to skip | |
1155 } | |
1156 | |
1157 if((priv->is_xsvcd || priv->is_xvcd) && apriv->size == 0) | |
1158 apriv->buffer_size = 4*1024; | |
1159 | |
1160 if(apriv->pts < priv->scr) | |
1161 mp_msg(MSGT_MUXER, MSGL_ERR, "\nERROR: SCR: %llu, APTS: %llu, DELTA=-%.3lf secs\n", | |
1162 priv->scr, apriv->pts, (double) ((priv->scr - apriv->pts)/92160000.0)); | |
1163 | |
1164 len = write_mpeg_pack(muxer, as, muxer->file, &(as->b_buffer[as->b_buffer_ptr]), abytes, 0); | |
1165 if((priv->is_xsvcd || priv->is_xvcd) && apriv->size == 0) | |
1166 apriv->buffer_size = 0; | |
1167 | |
1168 apriv->size += len; | |
1169 apriv->pts = next_pts; | |
1170 | |
1171 mp_msg(MSGT_MUXER, MSGL_DBG2, "NUM_FRAMES: %llu\n", num_frames); | |
1172 | |
1173 tmp = apriv->pts - priv->scr; | |
1174 if((abs(tmp) > (63000*1024)) || (apriv->pts <= priv->scr)) | |
1175 { | |
1176 double d; | |
1177 d = (double) apriv->frame_size / (double) apriv->bitrate; | |
1178 d *= (tmp - (63000*1024)); | |
1179 apriv->compensate = (uint32_t) d; | |
1180 | |
1181 if(abs(tmp) > 92160000) //usually up to 1 second it still acceptable | |
1182 mp_msg(MSGT_MUXER, MSGL_ERR, "\nWARNING: SCR: %llu, APTS: %llu, DELTA=%.3lf secs, BYTES=%d\n", priv->scr, apriv->pts, | |
1183 (((double) tmp)/92160000.0), apriv->compensate); | |
1184 } | |
1185 | |
1186 mp_msg(MSGT_MUXER, MSGL_V, "\nWRITTEN AUDIO: %u bytes, TIMER: %.3lf, FRAMES: %llu * %u, DELTA_PTS: %.3lf\n", | |
1187 len, (double) (apriv->pts/92160000), num_frames, (uint32_t) apriv->frame_size, delta_pts); | |
1188 | |
1189 as->b_buffer_ptr += len; | |
1190 as->b_buffer_len -= len; | |
1191 | |
1192 if(as->b_buffer_len > 0) | |
1193 memmove(as->b_buffer, &(as->b_buffer[as->b_buffer_ptr]), as->b_buffer_len); | |
1194 as->b_buffer_ptr = 0; | |
1195 | |
1196 return len; | |
1197 } | |
1198 | |
1199 static void drop_delayed_audio(muxer_t *muxer, muxer_stream_t *as, int64_t size) | |
1200 { | |
1201 //muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; | |
1202 muxer_headers_t *apriv = (muxer_headers_t *) as->priv; | |
1203 int64_t size1, div, rest; //initial value | |
1204 double rest_pts; | |
1205 | |
1206 div = size / apriv->frame_size; | |
1207 rest = size % apriv->frame_size; | |
1208 if(rest >= apriv->frame_size / 2) | |
1209 size1 = (div+1) * apriv->frame_size; | |
1210 else | |
1211 size1 = (div) * apriv->frame_size; | |
1212 | |
1213 fprintf(stderr, "SIZE1: %llu, LEN: %llu\n", size1, (uint64_t)as->b_buffer_len); | |
1214 size1 = min(size1, as->b_buffer_len); | |
1215 memmove(as->b_buffer, &(as->b_buffer[size]), as->b_buffer_len - size1); | |
1216 as->b_buffer_len -= size1; | |
1217 | |
1218 rest = size1 - size; | |
1219 rest_pts = (double) rest / (double) apriv->bitrate; | |
1220 apriv->pts += (int64_t) (92160000.0 * rest_pts); | |
1221 mp_msg(MSGT_MUXER, MSGL_V, "DROPPED: %lld bytes, REST= %lld, REST_PTS: %.3lf, AUDIO_PTS%.3lf\n", size1, rest, rest_pts, (double) (apriv->pts/92160000.0)); | |
1222 } | |
1223 | |
1224 | |
1225 static void save_delayed_audio(muxer_t *muxer, muxer_stream_t *as, uint64_t dur) | |
1226 { | |
1227 muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; | |
1228 muxer_headers_t *apriv = (muxer_headers_t *) as->priv; | |
1229 uint64_t init_pts, last_pts; //initial value | |
1230 | |
1231 init_pts = apriv->pts; | |
1232 mp_msg(MSGT_MUXER, MSGL_V, "DUR: %llu, DIFF: %llu\n", dur, apriv->pts - init_pts); | |
1233 while(dur > apriv->pts - init_pts) | |
1234 { | |
1235 priv->scr = (92160000 * apriv->size) / apriv->bitrate; | |
1236 last_pts = apriv->pts; | |
1237 dump_audio(muxer, as, as->b_buffer_len, 0); | |
1238 mp_msg(MSGT_MUXER, MSGL_V, "DUR: %llu, DIFF: %llu, SCR: %llu\n", dur, apriv->pts - init_pts, priv->scr); | |
1239 } | |
1240 | |
1241 //priv->init_delay_pts = last_pts; | |
1242 priv->init_delay_pts = (90 * 1024 * abs(conf_init_adelay)) + apriv->init_pts - (90 * 1024 * abs(conf_init_vpts)); | |
1243 if(priv->init_delay_pts <= priv->scr) | |
1244 priv->init_delay_pts = last_pts; | |
1245 mp_msg(MSGT_MUXER, MSGL_INFO, "INIT_VPTS: %llu (%.3lf)\n", priv->init_delay_pts, (double) (priv->init_delay_pts/92160000.0)); | |
1246 } | |
1247 | |
1248 | |
1249 static inline void update_scr(muxer_priv_t *priv, uint32_t len, uint32_t totlen, double mult) | |
1250 { | |
1251 uint64_t delta_scr; | |
1252 double perc; | |
1253 | |
1254 perc = (double) len / (double) totlen; | |
1255 | |
1256 delta_scr = (uint64_t) (mult * perc); | |
1257 priv->scr += delta_scr; | |
1258 | |
1259 mp_msg(MSGT_MUXER, MSGL_V, "UPDATE SCR TO %llu (%.3lf): mult is %.3lf, perc: %.3lf, %u/%u, delta: %llu\n", | |
1260 priv->scr, (double) (priv->scr/92160000.0), mult, perc, len, totlen, delta_scr); | |
1261 } | |
1262 | |
1263 | |
1264 static int calc_frames_to_flush(muxer_headers_t *vpriv) | |
1265 { | |
1266 int n, found = 0; | |
1267 | |
1268 if(vpriv->framebuf_used > 0) | |
1269 { | |
1270 n = 0; | |
1271 //let's count how many frames we'll store in the next pack sequence | |
1272 mp_msg(MSGT_MUXER, MSGL_V, "\n"); | |
1273 while(n < vpriv->framebuf_used) | |
1274 { | |
1275 mp_msg(MSGT_MUXER, MSGL_V, "n=%d, type=%c, temp_ref=%u\n", n, FTYPE(vpriv->framebuf[n].type), vpriv->framebuf[n].temp_ref); | |
1276 if(n+1 < vpriv->framebuf_used) | |
1277 mp_msg(MSGT_MUXER, MSGL_V, "n+1=%d, type=%c, temp_ref=%u\n", n+1, FTYPE(vpriv->framebuf[n+1].type), vpriv->framebuf[n+1].temp_ref); | |
1278 | |
1279 if(vpriv->framebuf[n].type == I_FRAME) | |
1280 { | |
1281 if(n > 0) | |
1282 { | |
1283 found = 1; | |
1284 break; | |
1285 } | |
1286 } | |
1287 | |
1288 n++; | |
1289 } | |
1290 } | |
1291 | |
1292 if(found && (n < vpriv->framebuf_used+1)) | |
1293 return n; | |
1294 else | |
1295 return 0; | |
1296 } | |
1297 | |
1298 | |
1299 static uint64_t fix_pts(muxer_priv_t *priv, muxer_headers_t *vpriv, int n) | |
1300 { | |
1301 int i, j, fixed = 0; | |
1302 uint64_t last_dts, last_idur, ret; | |
1303 uint32_t mintr, maxtr; | |
1304 | |
1305 ret = 0; | |
1306 if((vpriv->size == 0) && (fixed == 0)) //first pts adjustment, only at the beginning of the stream to manage BBI structures | |
1307 { | |
1308 int delay = 0; | |
1309 for(i = 0; i < n; i++) | |
1310 { | |
1311 if(vpriv->framebuf[i].type == I_FRAME) | |
1312 { | |
1313 for(j = i + 1; j < n; j++) | |
1314 { | |
1315 if(vpriv->framebuf[i].temp_ref >= vpriv->framebuf[j].temp_ref) | |
1316 { | |
1317 ret += vpriv->framebuf[j].idur; | |
1318 delay++; | |
1319 fixed = 1; | |
1320 } | |
1321 } | |
1322 if(fixed) | |
1323 break; | |
1324 } | |
1325 } | |
1326 | |
1327 if(! fixed) | |
1328 ret = 0; | |
1329 else | |
1330 vpriv->last_pts += ret; | |
1331 | |
1332 mp_msg(MSGT_MUXER, MSGL_INFO, "INITIAL DELAY of %d frames\n", delay); | |
1333 } | |
1334 | |
1335 //KLUDGE BEGINS: Gop header (0x000001b8 in the video stream that signals a temp_ref wraparound) is _not_ mandatory, | |
1336 //so if we don't detect the right wraparound we will have a totally wrong timestamps assignment; let's go on | |
1337 mintr = vpriv->framebuf[0].temp_ref; | |
1338 maxtr = vpriv->framebuf[0].temp_ref; | |
1339 for(i = 0; i < n; i++) | |
1340 { | |
1341 mintr = min(vpriv->framebuf[i].temp_ref, mintr); | |
1342 maxtr = max(vpriv->framebuf[i].temp_ref, maxtr); | |
1343 } | |
1344 if(maxtr - mintr > 600) //there must be a temp_ref wraparound | |
1345 { | |
1346 mp_msg(MSGT_MUXER, MSGL_INFO, "\nDETECTED possible temp_ref wraparound in the videostreams: n=%d, mintr=%u, maxtr=%u\n", n, mintr, maxtr); | |
1347 for(i = 0; i < n; i++) | |
1348 { | |
1349 if(vpriv->framebuf[i].temp_ref < 1000) | |
1350 vpriv->framebuf[i].temp_ref += 1024; | |
1351 } | |
1352 } | |
1353 //KLUDGE ENDS | |
1354 | |
1355 | |
1356 for(i = 0; i < n; i++) | |
1357 { | |
1358 vpriv->framebuf[i].pts = vpriv->last_pts; | |
1359 | |
1360 for(j = 0; j < n; j++) | |
1361 { | |
1362 if((vpriv->framebuf[i].temp_ref >= vpriv->framebuf[j].temp_ref) && (i != j)) | |
1363 { | |
1364 vpriv->framebuf[i].pts += vpriv->framebuf[j].idur; | |
1365 } | |
1366 } | |
1367 } | |
1368 | |
1369 if(vpriv->size == 0) | |
1370 last_dts = vpriv->init_dts = vpriv->framebuf[0].pts - (ret + vpriv->framebuf[0].idur); | |
1371 else | |
1372 last_dts = vpriv->last_dts; | |
1373 | |
1374 last_idur = 0; | |
1375 | |
1376 mp_msg(MSGT_MUXER, MSGL_V, "\n"); | |
1377 for(i = 0; i < n; i++) | |
1378 { | |
1379 vpriv->framebuf[i].dts = last_dts + last_idur; | |
1380 last_idur = vpriv->framebuf[i].idur; | |
1381 last_dts = vpriv->framebuf[i].dts; | |
1382 mp_msg(MSGT_MUXER, MSGL_V, "I=%d, type: %c, TR: %u, pts=%.3lf, dts=%.3lf, size=%u\n", | |
1383 i, FTYPE(vpriv->framebuf[i].type), vpriv->framebuf[i].temp_ref, (double) (vpriv->framebuf[i].pts/92160000.0), | |
1384 (double) (vpriv->framebuf[i].dts/92160000.0), vpriv->framebuf[i].size); | |
1385 } | |
1386 | |
1387 if((vpriv->size == 0) && (priv->init_delay_pts > 0)) | |
1388 { | |
1389 uint64_t diff; | |
1390 | |
1391 for(i = 0; i < vpriv->framebuf_used; i++) | |
1392 { | |
1393 vpriv->framebuf[i].pts += priv->init_delay_pts; | |
1394 vpriv->framebuf[i].dts += priv->init_delay_pts; | |
1395 } | |
1396 | |
1397 diff = vpriv->framebuf[0].pts - vpriv->framebuf[0].dts; | |
1398 if(vpriv->init_pts >= diff) | |
1399 vpriv->init_dts = vpriv->init_pts - diff; | |
1400 else | |
1401 vpriv->init_dts = diff; | |
1402 | |
1403 vpriv->last_dts += priv->init_delay_pts; | |
1404 | |
1405 vpriv->init_pts = 0; | |
1406 vpriv->last_pts += priv->init_delay_pts; | |
1407 | |
1408 priv->init_delay_pts = 0; | |
1409 mp_msg(MSGT_MUXER, MSGL_INFO, "INIT delayed video timestamps: PTS=%.3lf, DTS=%.3lf, DUR=%.3lf\n", | |
1410 (double) (vpriv->last_pts/92160000.0), (double) (vpriv->last_dts/92160000.0), (double) (vpriv->framebuf[0].idur/92160000.0)); | |
1411 } | |
1412 | |
1413 return ret; | |
1414 } | |
1415 | |
1416 | |
1417 static void check_pts(muxer_priv_t *priv, muxer_headers_t *vpriv, int i) | |
1418 { | |
1419 uint64_t dpts; | |
1420 | |
1421 dpts = max(vpriv->last_saved_pts, vpriv->pts) - min(vpriv->last_saved_pts, vpriv->pts); | |
1422 dpts += vpriv->framebuf[i].idur; | |
1423 | |
1424 if((!priv->ts_allframes) && ( | |
1425 (priv->is_dvd && (vpriv->framebuf[i].type != I_FRAME)) || | |
1426 ((priv->is_genmpeg1 || priv->is_genmpeg2) && (vpriv->framebuf[i].type != I_FRAME) && (dpts < 64512000))) //0.7 seconds | |
1427 ) | |
1428 vpriv->pts = vpriv->dts = 0; | |
1429 | |
1430 if(vpriv->dts && ((vpriv->dts < priv->scr) || (vpriv->pts <= vpriv->dts))) | |
1431 { | |
1432 mp_msg(MSGT_MUXER, MSGL_V, "\nWARNING, SCR: %.3lf, DTS: %.3lf, PTS: %.3lf\n", | |
1433 (double) priv->scr/92160000.0,(double) vpriv->dts/92160000.0, (double) vpriv->pts/92160000.0); | |
1434 vpriv->dts = 0; | |
1435 } | |
1436 | |
1437 if(vpriv->pts && (vpriv->pts <= priv->scr)) | |
1438 { | |
1439 mp_msg(MSGT_MUXER, MSGL_ERR, "ERROR: SCR: %.3lf, VPTS: %.3lf, DELTA=-%.3lf secs\n", | |
1440 (double) (priv->scr/92160000.0), (double)(vpriv->pts/92160000.0), (double) ((priv->scr - vpriv->pts)/92160000.0)); | |
1441 vpriv->pts = vpriv->dts = 0; | |
1442 } | |
1443 | |
1444 if(vpriv->pts) | |
1445 vpriv->last_saved_pts = vpriv->pts; | |
1446 } | |
1447 | |
1448 static uint32_t calc_audio_chunk_size(muxer_stream_t *as, double duration, int finalize) | |
1449 { | |
1450 muxer_headers_t *apriv; | |
1451 uint32_t x, div, rest, abytes; | |
1452 double adur; | |
1453 uint64_t iaduration; | |
1454 | |
1455 apriv = (muxer_headers_t*) as->priv; | |
1456 abytes = (uint32_t) (duration * apriv->bitrate); //size of audio data to write | |
1457 x = (abytes + apriv->max_pl_size - 1) / apriv->max_pl_size; | |
1458 x *= apriv->max_pl_size; | |
1459 adur = (double) x / (double) apriv->bitrate; | |
1460 iaduration = (uint64_t) ((double) 92160000 * adur); | |
1461 | |
1462 abytes -= apriv->compensate; | |
1463 div = abytes / apriv->max_pl_size; | |
1464 rest = abytes % apriv->max_pl_size; | |
1465 if(apriv->compensate > 0) | |
1466 abytes = apriv->max_pl_size * (div - 1); | |
1467 else if(apriv->compensate < 0) | |
1468 abytes = apriv->max_pl_size * (div + 1); | |
1469 else | |
1470 abytes = apriv->max_pl_size * (rest ? div + 1 : div); | |
1471 apriv->compensate = 0; | |
1472 | |
1473 if(finalize) | |
1474 abytes = as->b_buffer_len; | |
1475 | |
1476 return abytes; | |
1477 } | |
1478 | |
1479 static int flush_buffers(muxer_t *muxer, int finalize) | |
1480 { | |
1481 int i, n, pl_size, found; | |
1482 size_t saved; | |
1483 uint32_t abytes, vbytes, bytes = 0, frame_bytes = 0, audio_rest = 0, tot = 0, muxrate; | |
1484 uint32_t offset; | |
1485 uint64_t idur, init_delay = 0; | |
1486 muxer_stream_t *s, *vs, *as; | |
1487 muxer_headers_t *vpriv = NULL, *apriv = NULL; | |
1488 muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; | |
1489 uint8_t *tmp; | |
1490 double mult, duration; | |
1491 uint64_t iduration; | |
1492 mpeg_frame_t temp_frame; | |
1493 | |
1494 /* | |
1495 analyzes all streams and decides what to flush | |
1496 trying to respect an interleaving distribution | |
1497 equal to the v_bitrate/a_bitrate proportion | |
1498 */ | |
1499 init: | |
1500 n = 0; | |
1501 vs = as = NULL; | |
1502 abytes = vbytes = found = 0; | |
1503 for(i = 0; i < muxer->avih.dwStreams; i++) | |
1504 { | |
1505 s = muxer->streams[i]; | |
1506 if(s->type == MUXER_TYPE_VIDEO) | |
1507 { | |
1508 vs = muxer->streams[i]; | |
1509 vpriv = (muxer_headers_t*) vs->priv; | |
1510 n = found = calc_frames_to_flush(vpriv); | |
1511 } | |
1512 else if(s->type == MUXER_TYPE_AUDIO) | |
1513 as = s; | |
1514 } | |
1515 | |
1516 if((! found) && finalize) | |
1517 { | |
1518 if(vpriv != NULL) | |
1519 found = n = vpriv->framebuf_used; | |
1520 } | |
1521 | |
1522 if(found) | |
1523 { | |
1524 mp_msg(MSGT_MUXER, MSGL_V, "\nVIDEO, FLUSH %d frames (of %d), 0 to %d\n", n, vpriv->framebuf_used, n-1); | |
1525 | |
1526 tmp = priv->tmp; | |
1527 vbytes = 0; | |
1528 vpriv = (muxer_headers_t*) vs->priv; | |
1529 | |
1530 if(priv->residual_cnt) | |
1531 { | |
1532 mpeg_frame_t *f = &(vpriv->framebuf[0]); | |
1533 size_t sz = f->size + priv->residual_cnt; | |
1534 | |
1535 if(f->alloc_size < sz) | |
1536 { | |
1537 f->buffer = (uint8_t *) realloc(f->buffer, sz); | |
1538 f->alloc_size = sz; | |
1539 } | |
1540 memmove(&(f->buffer[priv->residual_cnt]), f->buffer, f->size); | |
1541 memcpy(f->buffer, priv->residual, priv->residual_cnt); | |
1542 f->size += priv->residual_cnt; | |
1543 priv->residual_cnt = 0; | |
1544 } | |
1545 | |
1546 duration = 0; | |
1547 iduration = 0; | |
1548 for(i = 0; i < n; i++) | |
1549 { | |
1550 vbytes += vpriv->framebuf[i].size; | |
1551 iduration += vpriv->framebuf[i].idur; | |
1552 } | |
1553 duration = (double) (iduration / 92160000.0); | |
1554 | |
1555 if(vpriv->is_mpeg12) | |
1556 init_delay = fix_pts(priv, vpriv, n); | |
1557 else | |
1558 init_delay = 0; | |
1559 | |
1560 if(as != NULL) | |
1561 { | |
1562 apriv = (muxer_headers_t*) as->priv; | |
1563 abytes = calc_audio_chunk_size(as, duration, finalize); | |
1564 | |
1565 if((abytes / apriv->max_pl_size) > n) | |
1566 audio_rest = (abytes - (apriv->max_pl_size * n)) / n; | |
1567 else | |
1568 audio_rest = 0; | |
1569 | |
1570 if(as->b_buffer_len < abytes) | |
1571 { | |
1572 mp_msg(MSGT_MUXER, MSGL_V, "Not enough audio data (%u < %u), exit\n", as->b_buffer_len, abytes); | |
1573 return 0; | |
1574 } | |
1575 } | |
1576 | |
1577 if((as != NULL) && (init_delay > 0)) | |
1578 { | |
1579 if(apriv->size == 0) | |
1580 apriv->pts += init_delay; | |
1581 } | |
1582 | |
1583 saved = 0; | |
1584 bytes = vbytes + abytes; | |
1585 muxrate = (uint32_t) ((double) bytes/duration); | |
1586 if(muxrate > muxer->sysrate && (priv->is_genmpeg1 || priv->is_genmpeg2)) | |
1587 { | |
1588 mp_msg(MSGT_MUXER, MSGL_V, "NEW MUXRATE: %u -> %u\n", muxrate, muxer->sysrate); | |
1589 muxer->sysrate = muxrate; | |
1590 } | |
1591 | |
1592 idur = 0; | |
1593 offset = 0; | |
1594 priv->scr = vpriv->framebuf[0].dts - vpriv->init_dts; | |
1595 | |
1596 if((priv->is_xvcd || priv->is_xsvcd) && (vpriv->size == 0)) | |
1597 vpriv->buffer_size = (priv->is_xvcd ? 46 : 230)*1024; | |
1598 | |
1599 i = 0; | |
1600 while(i < n) | |
1601 { | |
1602 int frame_begin = 1, update; | |
1603 uint32_t pl_size = 0, target_size; | |
1604 uint8_t *buf; | |
1605 | |
1606 mp_msg(MSGT_MUXER, MSGL_V, "FRAME: %d, type: %c, TEMP_REF: %u, SIZE: %u\n", | |
1607 i, FTYPE(vpriv->framebuf[i].type), vpriv->framebuf[i].temp_ref, vpriv->framebuf[i].size); | |
1608 | |
1609 vpriv->pts = vpriv->framebuf[i].pts; | |
1610 vpriv->dts = vpriv->framebuf[i].dts; | |
1611 check_pts(priv, vpriv, i); | |
1612 | |
1613 if(priv->is_dvd && (vpriv->framebuf[i].type == I_FRAME) && (offset == 0)) | |
1614 { | |
1615 write_mpeg_pack(muxer, NULL, muxer->file, NULL, 0, 0); //insert fake Nav Packet | |
1616 vpriv->pes_is_aligned = 1; | |
1617 } | |
1618 | |
1619 offset = 0; | |
1620 vbytes = vpriv->framebuf[i].size; | |
1621 while(vbytes > 0 && (i < n)) | |
1622 { | |
1623 target_size = priv->packet_size - calc_pack_hlen(priv, vpriv); | |
1624 if((vbytes >= target_size) || ((vbytes < target_size) && (i == n-1))) | |
1625 { | |
1626 buf = &(vpriv->framebuf[i].buffer[offset]); | |
1627 pl_size = vbytes; | |
1628 update = 1; | |
1629 } | |
1630 else | |
1631 { | |
1632 uint32_t tmp_offset = 0; | |
1633 | |
1634 if(offset == 0) | |
1635 { | |
1636 vpriv->pts = vpriv->framebuf[i].pts; | |
1637 vpriv->dts = vpriv->framebuf[i].dts; | |
1638 check_pts(priv, vpriv, i); | |
1639 } | |
1640 else if(i < n-1) | |
1641 { | |
1642 vpriv->pts = vpriv->framebuf[i+1].pts; | |
1643 vpriv->dts = vpriv->framebuf[i+1].dts; | |
1644 check_pts(priv, vpriv, i+1); | |
1645 } | |
1646 else | |
1647 vpriv->pts = vpriv->dts = 0; | |
1648 | |
1649 target_size = priv->packet_size - calc_pack_hlen(priv, vpriv); //it was only priv->packet_size | |
1650 update = 0; | |
1651 | |
1652 while((tmp_offset < target_size) && (i < n)) | |
1653 { | |
1654 pl_size = min(target_size - tmp_offset, vbytes); | |
1655 memcpy(&(tmp[tmp_offset]), &(vpriv->framebuf[i].buffer[offset]), pl_size); | |
1656 tmp_offset += pl_size; | |
1657 offset += pl_size; | |
1658 vbytes -= pl_size; | |
1659 | |
1660 if(vbytes == 0) //current frame is saved, pass to the next | |
1661 { | |
1662 i++; | |
1663 vbytes = vpriv->framebuf[i].size; | |
1664 offset = 0; | |
1665 frame_begin = 1; | |
1666 } | |
1667 } | |
1668 buf = tmp; | |
1669 pl_size = tmp_offset; | |
1670 } | |
1671 | |
1672 | |
1673 if((pl_size < priv->packet_size - calc_pack_hlen(priv, vpriv)) && !finalize && (i >= n - 1)) | |
1674 { | |
1675 memcpy(priv->residual, buf, pl_size); | |
1676 priv->residual_cnt = pl_size; | |
1677 pl_size = update = vbytes = 0; | |
1678 } | |
1679 if(pl_size) | |
1680 pl_size = write_mpeg_pack(muxer, vs, muxer->file, buf, pl_size, 0); | |
1681 vpriv->pes_is_aligned = 0; | |
1682 vpriv->pts = vpriv->dts = 0; | |
1683 vpriv->buffer_size = 0; | |
1684 vpriv->size += pl_size; | |
1685 if(update) | |
1686 { | |
1687 vbytes -= pl_size; | |
1688 offset += pl_size; | |
1689 } | |
1690 | |
1691 /* this is needed to calculate SCR */ | |
1692 frame_bytes = max(vpriv->framebuf[i].size, priv->packet_size) + priv->packet_size; | |
1693 if(abytes > 0) | |
1694 //frame_bytes += min(apriv->max_pl_size, priv->packet_size) + audio_rest; | |
1695 frame_bytes += min(apriv->max_pl_size, abytes) + audio_rest; | |
1696 | |
1697 if(priv->ts_allframes) | |
1698 { | |
1699 tot = frame_bytes; | |
1700 mult = (double) vpriv->framebuf[min(i, n-1)].idur; | |
1701 } | |
1702 else | |
1703 { | |
1704 tot = bytes; | |
1705 //mult = (double) (max(iduration, iaduration)); | |
1706 mult = (double) (iduration); | |
1707 } | |
1708 update_scr(priv, pl_size, tot, mult); | |
1709 | |
1710 | |
1711 if(abytes > 0 && frame_begin) //it's time to save audio | |
1712 { | |
1713 pl_size = dump_audio(muxer, as, abytes, finalize); | |
1714 if(pl_size > 0) | |
1715 { | |
1716 abytes -= pl_size; | |
1717 update_scr(priv, pl_size, tot, mult); | |
1718 } | |
1719 } | |
1720 | |
1721 frame_begin = 0; | |
1722 } | |
1723 | |
1724 i++; | |
1725 } | |
1726 | |
1727 | |
1728 if(vpriv->is_mpeg12) | |
1729 { | |
1730 for(i = 0; i < n; i++) | |
1731 { | |
1732 vpriv->last_dts = vpriv->framebuf[i].dts; | |
1733 if(vpriv->framebuf[i].pts >= vpriv->last_pts) | |
1734 { | |
1735 vpriv->last_pts = vpriv->framebuf[i].pts; | |
1736 idur = vpriv->framebuf[i].idur; | |
1737 } | |
1738 } | |
1739 | |
1740 vpriv->last_dts += vpriv->framebuf[n-1].idur; | |
1741 vpriv->last_pts += idur; | |
1742 } | |
1743 | |
1744 for(i = n; i < vpriv->framebuf_used; i++) | |
1745 { | |
1746 temp_frame = vpriv->framebuf[i - n]; | |
1747 vpriv->framebuf[i - n] = vpriv->framebuf[i]; | |
1748 vpriv->framebuf[i] = temp_frame; | |
1749 } | |
1750 vpriv->framebuf_used -= n; | |
1751 | |
1752 | |
1753 if((as != NULL) && priv->has_audio) | |
1754 { | |
1755 while(abytes > 0) | |
1756 { | |
1757 mult = iduration; | |
1758 pl_size = dump_audio(muxer, as, abytes, finalize); | |
1759 if(pl_size > 0) | |
1760 { | |
1761 update_scr(priv, pl_size, bytes, mult); | |
1762 abytes -= pl_size; | |
1763 } | |
1764 else | |
1765 break; | |
1766 } | |
1767 } | |
1768 | |
1769 //goto init; | |
1770 } | |
1771 | |
1772 muxer->file_end = priv->scr; | |
1773 return found; | |
1774 } | |
1775 | |
1776 | |
1777 static uint64_t parse_fps(int fps) | |
1778 { | |
1779 // 90000 * 1024 / fps | |
1780 switch(fps) | |
1781 { | |
1782 case 239760: | |
1783 return 3843844; | |
1784 case 240000: | |
1785 return 3840000; | |
1786 case 250000: | |
1787 return 3686400; | |
1788 case 299700: | |
1789 return 3075075; | |
1790 case 300000: | |
1791 return 3072000; | |
1792 case 500000: | |
1793 return 1843200; | |
1794 case 599400: | |
1795 return 1537538; | |
1796 case 600000: | |
1797 return 1536000; | |
1798 default: | |
1799 mp_msg(MSGT_MUXER, MSGL_ERR, "ERROR! unknown fps code: %d", fps); | |
1800 return 0; | |
1801 } | |
1802 } | |
1803 | |
1804 static size_t parse_mpeg12_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_headers_t *spriv, float fps, size_t len) | |
1805 { | |
1806 size_t ptr = 0, sz = 0, tmp = 0; | |
1807 | |
1808 mp_msg(MSGT_MUXER, MSGL_V,"parse_mpeg12_video, len=%u\n", (uint32_t) len); | |
1809 if(s->buffer[0] != 0 || s->buffer[1] != 0 || s->buffer[2] != 1 || len<6) | |
1810 { | |
1811 mp_msg(MSGT_MUXER, MSGL_ERR,"Unknown video format, possibly non-MPEG1/2 stream, len=%d!\n", len); | |
1812 return 0; | |
1813 } | |
1814 | |
1815 if(s->buffer[3] == 0 || s->buffer[3] == 0xb3 || s->buffer[3] == 0xb8) | |
1816 { // Video (0) Sequence header (b3) or GOP (b8) | |
1817 uint32_t temp_ref; | |
1818 int pt; | |
1819 | |
1820 if(s->buffer[3] == 0xb3) //sequence | |
1821 { | |
1822 //uint8_t fps = s->buffer[7] & 0x0f; | |
1823 mp_header_process_sequence_header(&(spriv->picture), &(s->buffer[4])); | |
1824 spriv->delta_pts = spriv->nom_delta_pts = parse_fps(spriv->picture.fps); | |
1825 | |
1826 spriv->delta_clock = (double) 1/fps; | |
1827 mp_msg(MSGT_MUXER, MSGL_V, "\nFPS: %.3f, FRAMETIME: %.3lf\n", fps, (double)1/fps); | |
1828 if(priv->patch_seq) | |
1829 patch_seq(priv, s->buffer); | |
1830 | |
1831 tmp = 12; | |
1832 if(s->buffer[tmp-1] & 2) | |
1833 tmp += 64; | |
1834 | |
1835 if(s->buffer[tmp-1] & 1) | |
1836 tmp += 64; | |
1837 | |
1838 if(s->buffer[tmp] == 0 && s->buffer[tmp+1] == 0 && s->buffer[tmp+2] == 1 && s->buffer[tmp+3] == 0xb5) | |
1839 mp_header_process_extension(&(spriv->picture), &(s->buffer[tmp+4])); | |
1840 } | |
1841 | |
1842 | |
1843 if(spriv->picture.mpeg1 == 0 && priv->patch_sde) | |
1844 { | |
1845 while((s->buffer[tmp] != 0 || s->buffer[tmp+1] != 0 || s->buffer[tmp+2] != 1 || s->buffer[tmp+3] != 0xb5 || | |
1846 ((s->buffer[tmp+4] & 0xf0) != 0x20)) && | |
1847 (tmp < len-5)) | |
1848 tmp++; | |
1849 | |
1850 if(tmp < len-5) //found | |
1851 patch_panscan(priv, &(s->buffer[tmp+4])); | |
1852 } | |
1853 | |
1854 | |
1855 | |
1856 if(s->buffer[3]) | |
1857 { // Sequence or GOP -- scan for Picture | |
1858 s->gop_start = s->h.dwLength; | |
1859 while (ptr < len-5 && | |
1860 (s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0)) | |
1861 ptr++; | |
1862 } | |
1863 | |
1864 if (ptr >= len-5) | |
1865 { | |
1866 pt = 0; // Picture not found?! | |
1867 temp_ref = 0; | |
1868 mp_msg(MSGT_MUXER, MSGL_ERR,"Warning: picture not found in GOP!\n"); | |
1869 } | |
1870 else | |
1871 { | |
1872 pt = (s->buffer[ptr+5] & 0x1c) >> 3; | |
1873 temp_ref = (s->buffer[ptr+4]<<2)+(s->buffer[ptr+5]>>6); | |
1874 mp_msg(MSGT_MUXER, MSGL_V, "Video frame type: %c, TR: %d\n", FTYPE(pt), temp_ref); | |
1875 if(spriv->picture.mpeg1 == 0) | |
1876 { | |
1877 size_t tmp = ptr; | |
1878 | |
1879 while (ptr < len-5 && | |
1880 (s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0xb5)) | |
1881 ptr++; | |
1882 if(ptr < len-5) | |
1883 { | |
1884 mp_header_process_extension(&(spriv->picture), &(s->buffer[ptr+4])); | |
1885 if(spriv->picture.display_time >= 50 && spriv->picture.display_time <= 300) | |
1886 spriv->delta_pts = (spriv->nom_delta_pts * spriv->picture.display_time) / 100; | |
1887 } | |
1888 else | |
1889 spriv->delta_pts = spriv->nom_delta_pts; | |
1890 | |
1891 ptr = tmp; | |
1892 } | |
1893 } | |
1894 | |
1895 switch (pt) { | |
1896 case 2: // predictive | |
1897 if (s->ipb[0]) { | |
1898 sz = len + s->ipb[0]; | |
1899 s->ipb[0] = max(s->ipb[0], s->ipb[2]); | |
1900 s->ipb[2] = 0; | |
1901 } else if (s->ipb[2]) { | |
1902 sz = len + s->ipb[2]; | |
1903 s->ipb[0] = s->ipb[2]; | |
1904 s->ipb[2] = 0; | |
1905 } else | |
1906 sz = 4 * len; // no bidirectional frames yet? | |
1907 | |
1908 s->ipb[1] = len; | |
1909 break; | |
1910 case 3: // bidirectional | |
1911 s->ipb[2] += len; | |
1912 sz = s->ipb[1] + s->ipb[2]; | |
1913 break; | |
1914 default: // intra-coded | |
1915 sz = len; // no extra buffer for it... | |
1916 } | |
1917 | |
1918 reorder_frame(spriv, s->buffer, len, pt, temp_ref, spriv->delta_pts); | |
1919 } | |
1920 | |
1921 mp_msg(MSGT_MUXER, MSGL_V,"parse_mpeg12_video, return %u\n", (uint32_t) len); | |
1922 return sz; | |
1923 } | |
1924 | |
1925 | |
1926 static uint64_t fix_mp4_frame_duration(muxer_headers_t *vpriv) | |
1927 { | |
1928 uint64_t mn, md, mx, diff; | |
1929 uint32_t i; | |
1930 | |
1931 mn = mx = vpriv->framebuf[0].pts; | |
1932 for(i = 0; i < 3; i++) | |
1933 { | |
1934 mp_msg(MSGT_DECVIDEO,MSGL_V, "PTS: %llu\n", vpriv->framebuf[i].pts); | |
1935 if(vpriv->framebuf[i].pts < mn) | |
1936 mn = vpriv->framebuf[i].pts; | |
1937 if(vpriv->framebuf[i].pts > mx) | |
1938 mx = vpriv->framebuf[i].pts; | |
1939 } | |
1940 md = mn; | |
1941 for(i=0; i<3; i++) | |
1942 { | |
1943 if((vpriv->framebuf[i].pts > mn) && (vpriv->framebuf[i].pts < mx)) | |
1944 md = vpriv->framebuf[i].pts; | |
1945 } | |
1946 mp_msg(MSGT_DECVIDEO,MSGL_V, "MIN: %llu, mid: %llu, max: %llu\n", mn, md, mx); | |
1947 | |
1948 if(mx - md > md - mn) | |
1949 diff = md - mn; | |
1950 else | |
1951 diff = mx - md; | |
1952 | |
1953 if(diff > 0) | |
1954 { | |
1955 for(i=0; i<3; i++) | |
1956 { | |
1957 vpriv->framebuf[i].pts += diff; | |
1958 vpriv->framebuf[i].dts += i * diff; | |
1959 mp_msg(MSGT_MUXER, MSGL_V, "FIXED_PTS: %.3lf, FIXED_DTS: %.3lf\n", | |
1960 (double) (vpriv->framebuf[i].pts/92160000.0), (double) (vpriv->framebuf[i].dts/92160000.0)); | |
1961 } | |
1962 return diff; | |
1963 } | |
1964 else | |
1965 return 0; | |
1966 } | |
1967 | |
1968 | |
1969 static size_t parse_mpeg4_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_headers_t *vpriv, float fps, size_t len) | |
1970 { | |
1971 size_t ptr = 0; | |
1972 int64_t delta_pts; | |
1973 uint8_t pt; | |
1974 | |
1975 mp_msg(MSGT_MUXER, MSGL_V,"parse_mpeg4_video, len=%u\n", (uint32_t) len); | |
1976 if(len<6) | |
1977 { | |
1978 mp_msg(MSGT_MUXER, MSGL_ERR,"Frame too short: %d, exit!\n", len); | |
1979 return 0; | |
1980 } | |
1981 | |
1982 while(ptr < len - 5) | |
1983 { | |
1984 if(s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1) | |
1985 { | |
1986 ptr++; | |
1987 continue; | |
1988 } | |
1989 | |
1990 if(s->buffer[ptr+3] >= 0x20 && s->buffer[ptr+3] <= 0x2f) //VOL | |
1991 { | |
1992 mp4_header_process_vol(&(vpriv->picture), &(s->buffer[ptr+4])); | |
1993 } | |
1994 else if(s->buffer[ptr+3] == 0xb3) //gov | |
1995 { | |
1996 //fprintf(stderr, "\nGOV\n"); | |
1997 } | |
1998 else if(s->buffer[ptr+3] == 0xb6) //vop | |
1999 { | |
2000 int32_t delta; | |
2001 mp4_header_process_vop(&(vpriv->picture), &(s->buffer[ptr+4])); | |
2002 | |
2003 delta = vpriv->picture.timeinc_unit - vpriv->last_tr; | |
2004 if((delta > 0) && (delta > (vpriv->picture.timeinc_resolution/2))) | |
2005 delta -= vpriv->picture.timeinc_resolution; | |
2006 else if((delta < 0) && (delta < (-vpriv->picture.timeinc_resolution/2))) | |
2007 delta += vpriv->picture.timeinc_resolution; | |
2008 | |
2009 delta_pts = (92160000 * (int64_t) delta) / vpriv->picture.timeinc_resolution; | |
2010 | |
2011 pt = vpriv->picture.picture_type + 1; | |
2012 mp_msg(MSGT_MUXER, MSGL_V, "\nTYPE: %c, RESOLUTION: %d, TEMP: %d, delta: %d, delta_pts: %lld = %.3lf, delta2: %.3lf\n", | |
2013 FTYPE(pt), vpriv->picture.timeinc_resolution, vpriv->picture.timeinc_unit, delta, delta_pts, (double) (delta_pts/92160000.0), | |
2014 (double) delta / (double) vpriv->picture.timeinc_resolution); | |
2015 | |
2016 vpriv->last_tr = vpriv->picture.timeinc_unit; | |
2017 | |
2018 break; | |
2019 } | |
2020 | |
2021 ptr++; | |
2022 } | |
2023 | |
2024 vpriv->last_dts += vpriv->frame_duration; | |
2025 vpriv->last_pts += delta_pts; | |
2026 | |
2027 reorder_frame(vpriv, s->buffer, len, pt, 0, delta_pts); | |
2028 vpriv->framebuf[vpriv->framebuf_used-1].pts = vpriv->last_pts; | |
2029 vpriv->framebuf[vpriv->framebuf_used-1].dts = vpriv->last_dts; | |
2030 vpriv->framebuf[vpriv->framebuf_used-1].idur = vpriv->frame_duration; | |
2031 | |
2032 /*mp_msg(MSGT_MUXER, MSGL_V, "\nMPEG4V, PT: %c, LEN=%u, DELTA_PTS: %.3lf, PTS: %.3lf, DTS: %.3lf\n", | |
2033 FTYPE(pt), len, (delta_pts/92160000.0), | |
2034 (double) (vpriv->framebuf[vpriv->framebuf_used-1].pts/92160000.0), | |
2035 (double) (vpriv->framebuf[vpriv->framebuf_used-1].dts/92160000.0), len);*/ | |
2036 | |
2037 if(!vpriv->frame_duration && vpriv->framebuf_used == 3) | |
2038 { | |
2039 vpriv->frame_duration = fix_mp4_frame_duration(vpriv); | |
2040 if(vpriv->frame_duration) | |
2041 { | |
2042 vpriv->last_pts += vpriv->frame_duration; | |
2043 vpriv->last_dts = vpriv->framebuf[vpriv->framebuf_used-1].dts; | |
2044 vpriv->delta_clock = ((double) vpriv->frame_duration)/92160000.0; | |
2045 mp_msg(MSGT_MUXER, MSGL_INFO, "FRAME DURATION: %llu %.3lf\n", | |
2046 vpriv->frame_duration, (double) (vpriv->frame_duration/92160000.0)); | |
2047 } | |
2048 } | |
2049 | |
2050 mp_msg(MSGT_MUXER, MSGL_V, "LAST_PTS: %.3lf, LAST_DTS: %.3lf\n", | |
2051 (double) (vpriv->last_pts/92160000.0), (double) (vpriv->last_dts/92160000.0)); | |
2052 | |
2053 return len; | |
2054 } | |
2055 | |
2056 static void mpegfile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags){ | |
2057 size_t ptr=0, sz = 0; | |
2058 uint64_t pts, tmp; | |
2059 muxer_t *muxer = s->muxer; | |
2060 muxer_priv_t *priv = (muxer_priv_t *)muxer->priv; | |
2061 muxer_headers_t *spriv = (muxer_headers_t*) s->priv; | |
2062 FILE *f; | |
2063 float fps; | |
2064 uint32_t stream_format; | |
2065 | |
2066 f = muxer->file; | |
2067 | |
2068 if(s->buffer == NULL) | |
2069 return; | |
2070 | |
2071 pts = 0; | |
2072 if (s->type == MUXER_TYPE_VIDEO) { // try to recognize frame type... | |
2073 fps = (float) s->h.dwRate/ (float) s->h.dwScale; | |
2074 spriv->type = 1; | |
2075 spriv->has_pes_priv_headers = 0; | |
2076 stream_format = s->bih->biCompression; | |
2077 | |
2078 if(is_mpeg1(stream_format) || is_mpeg2(stream_format)) | |
2079 { | |
2080 spriv->is_mpeg12 = 1; | |
2081 if(len) | |
2082 sz = parse_mpeg12_video(s, priv, spriv, fps, len); | |
2083 else { | |
2084 tmp = (uint64_t) (92160000 / fps); | |
2085 spriv->last_pts += tmp; | |
2086 spriv->last_dts += tmp; | |
2087 } | |
198 } | 2088 } |
199 } else if (sz > 54000) // assume 0.3...0.7s is optimal | 2089 else if(is_mpeg4(stream_format)) |
200 mints += (sz-45000)>>2; // reach 0.5s in 4 blocks ? | 2090 { |
201 else if (sz < 27000) { | 2091 spriv->is_mpeg12 = 0; |
202 unsigned int newsysrate = 0; | 2092 spriv->reorder = 0; |
203 | 2093 if(spriv->size == 0) |
204 if (s->timer > 0.5) // too early to calculate??? | 2094 priv->use_psm = 1; |
205 newsysrate = muxer->movi_end/(s->timer*0.4); // pike-factor 2.5 (8dB) | 2095 if(len) |
206 if (sz < MPEG_MIN_PTS_DELAY) | 2096 sz = parse_mpeg4_video(s, priv, spriv, fps, len); |
207 printf ("Error in stream: PTS to SCR delay %u is too little!\n", sz); | 2097 else { |
208 if (muxer->sysrate < newsysrate) | 2098 tmp = (uint64_t) (92160000 / fps); |
209 muxer->sysrate = newsysrate; // increase next rate to current rate | 2099 spriv->last_pts += tmp; |
210 else if (!newsysrate) | 2100 spriv->last_dts += tmp; |
211 muxer->sysrate += muxer->sysrate>>3; // increase next rate by 25% | |
212 } | |
213 muxer->file_end += mints; // update the system timestamp | |
214 return len; | |
215 } | |
216 | |
217 static void set_mpeg_pts(muxer_t *muxer, muxer_stream_t *s, unsigned int pts) { | |
218 unsigned int dts, nts; | |
219 | |
220 if (s->b_buffer_ptr != 0 && s->b_buffer[7] != 0xff) | |
221 return; // already set | |
222 if (s->b_buffer_ptr == 0) { | |
223 memset (s->b_buffer, 0xff, 7); // reserved for PTS or STD, stuFFing for now | |
224 s->b_buffer_ptr = 12; | |
225 } | |
226 dts = (int)(s->timer*90000) + MPEG_STARTPTS; // PTS | |
227 if (pts) { | |
228 write_mpeg_ts (s->b_buffer+2, pts, 0x30); // 0011 and both PTS/DTS | |
229 } else { | |
230 write_mpeg_ts (s->b_buffer+7, dts, 0x20); // 0010 and PTS only | |
231 return; | |
232 } | |
233 nts = dts - muxer->file_end; | |
234 // if (nts < mpeg_min_delay) mpeg_min_delay = nts; | |
235 // if (nts > mpeg_max_delay) mpeg_max_delay = nts; | |
236 nts = 180000*s->h.dwScale/s->h.dwRate; // two frames | |
237 if (dts-nts < muxer->file_end) { | |
238 dts += muxer->file_end; | |
239 dts /= 2; // calculate average time | |
240 printf ("Warning: DTS to SCR delay is too small\n"); | |
241 } | |
242 else | |
243 dts -= nts/2; // one frame :) | |
244 mp_dbg(MSGT_MUXER, MSGL_DBG3, ", dts=%u", dts); | |
245 write_mpeg_ts (s->b_buffer+7, dts, 0x10); | |
246 } | |
247 | |
248 static void mpegfile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags){ | |
249 size_t ptr=0, sz; | |
250 unsigned int pts=0; | |
251 muxer_t *muxer = s->muxer; | |
252 FILE *f; | |
253 | |
254 f = muxer->file; | |
255 if (s->type == MUXER_TYPE_VIDEO) { // try to recognize frame type... | |
256 if (s->buffer[0] != 0 || s->buffer[1] != 0 || s->buffer[2] != 1 || len<6) { | |
257 printf ("Unknown block type, possibly non-MPEG stream!\n"); | |
258 sz = len; | |
259 // return; | |
260 } else if (s->buffer[3] == 0 || s->buffer[3] == 0xb3 || | |
261 s->buffer[3] == 0xb8) { // Picture or GOP | |
262 int temp_ref; | |
263 int pt; | |
264 | |
265 if (s->buffer[3]) { // GOP -- scan for Picture | |
266 s->gop_start = s->h.dwLength; | |
267 while (ptr < len-5 && (s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || | |
268 s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0)) ptr++; | |
269 if (s->b_buffer_ptr > MUXER_MPEG_DATASIZE-39-12) { // 39 bytes for Gop+Pic+Slice headers | |
270 write_mpeg_block (muxer, s, f, NULL, 0, 0); | |
271 } | |
272 } | 2101 } |
273 if (ptr >= len-5) { | |
274 pt = 0; // Picture not found?! | |
275 temp_ref = 0; | |
276 printf ("Warning: picture not found in GOP!\n"); | |
277 } else { | |
278 pt = (s->buffer[ptr+5]>>3) & 7; | |
279 temp_ref = (s->buffer[ptr+4]<<2)+(s->buffer[ptr+5]>>6); | |
280 } | |
281 ptr = 0; | |
282 temp_ref += s->gop_start; | |
283 switch (pt) { | |
284 case 2: // predictive | |
285 if (s->ipb[0]) { | |
286 sz = len + s->ipb[0]; | |
287 if (s->ipb[0] < s->ipb[2]) | |
288 s->ipb[0] = s->ipb[2]; | |
289 s->ipb[2] = 0; | |
290 } else if (s->ipb[2]) { | |
291 sz = len + s->ipb[2]; | |
292 s->ipb[0] = s->ipb[2]; | |
293 s->ipb[2] = 0; | |
294 } else | |
295 sz = 4 * len; // no bidirectional frames yet? | |
296 s->ipb[1] = len; | |
297 // pictires may be not in frame sequence so recalculate timer | |
298 pts = (int)(90000*((double)temp_ref*s->h.dwScale/s->h.dwRate)) + MPEG_STARTPTS; | |
299 break; | |
300 case 3: // bidirectional | |
301 s->ipb[2] += len; | |
302 sz = s->ipb[1] + s->ipb[2]; | |
303 // pictires may be not in frame sequence so recalculate timer | |
304 s->timer = (double)temp_ref*s->h.dwScale/s->h.dwRate; | |
305 break; | |
306 default: // intra-coded | |
307 // pictires may be not in frame sequence so recalculate timer | |
308 pts = (int)(90000*((double)temp_ref*s->h.dwScale/s->h.dwRate)) + MPEG_STARTPTS; | |
309 sz = len; // no extra buffer for it... | |
310 } | |
311 } else { | |
312 printf ("Unknown block type, possibly non-MPEG stream!\n"); | |
313 sz = len; | |
314 // return; | |
315 } | 2102 } |
2103 | |
2104 mp_msg(MSGT_MUXER, MSGL_V,"mpegfile_write_chunk, Video codec=%x, len=%u, mpeg12 returned %u\n", stream_format, (uint32_t) len, (uint32_t) sz); | |
2105 | |
2106 ptr = 0; | |
2107 priv->vbytes += len; | |
2108 | |
316 sz <<= 1; | 2109 sz <<= 1; |
317 } else { // MUXER_TYPE_AUDIO | 2110 } else { // MUXER_TYPE_AUDIO |
318 if (len < 2*MUXER_MPEG_DATASIZE) | 2111 spriv->type = 0; |
319 sz = 2*MUXER_MPEG_DATASIZE; // min requirement | 2112 stream_format = s->wf->wFormatTag; |
2113 | |
2114 mp_msg(MSGT_MUXER, MSGL_V,"\nmpegfile_write_chunk, Audio codec=%x, len=%u, frame size=%u\n", | |
2115 stream_format, (uint32_t) len, (uint32_t) spriv->frame_size); | |
2116 if(spriv->bitrate == 0) | |
2117 spriv->bitrate = s->wf->nAvgBytesPerSec; | |
2118 // I need to know the audio frame size | |
2119 if(spriv->frame_size == 0) | |
2120 { | |
2121 spriv->frame_size = get_audio_frame_size(spriv, s->buffer, stream_format, s->wf->nSamplesPerSec); | |
2122 spriv->aframe_delta_pts = ((double) spriv->frame_size / (double) spriv->bitrate); | |
2123 //spriv->delta_pts = (uint64_t) (spriv->aframe_delta_pts * 92160000); | |
2124 spriv->delta_pts = (uint64_t) (92160000 * spriv->frame_size) / spriv->bitrate; | |
2125 mp_msg(MSGT_MUXER, MSGL_INFO, "AUDIO FRAME SIZE: %u, DELTA_PTS: %llu (%.3lf)\n", (uint32_t) spriv->frame_size, spriv->delta_pts, spriv->aframe_delta_pts); | |
2126 } | |
2127 | |
2128 | |
2129 if(s->b_buffer_size - s->b_buffer_len < len) | |
2130 { | |
2131 s->b_buffer = realloc(s->b_buffer, len + s->b_buffer_len); | |
2132 if(s->b_buffer == NULL) | |
2133 { | |
2134 mp_msg(MSGT_MUXER, MSGL_FATAL, "\nFATAL! couldn't realloc %d bytes\n", len + s->b_buffer_len); | |
2135 return; | |
2136 } | |
2137 | |
2138 s->b_buffer_size = len + s->b_buffer_len; | |
2139 mp_msg(MSGT_MUXER, MSGL_DBG2, "REALLOC(%d) bytes to AUDIO backbuffer\n", s->b_buffer_size); | |
2140 } | |
2141 memcpy(&(s->b_buffer[s->b_buffer_ptr + s->b_buffer_len]), s->buffer, len); | |
2142 s->b_buffer_len += len; | |
2143 | |
2144 if(stream_format == AUDIO_A52) | |
2145 { | |
2146 s->type = 1; | |
2147 s->ckid = be2me_32 (0x1bd); | |
2148 if(s->size == 0) | |
2149 { | |
2150 spriv->max_pl_size -= 4; | |
2151 if(priv->is_genmpeg1 || priv->is_genmpeg2) | |
2152 fix_audio_sys_header(priv, spriv->id, 0xbd, 58*1024); //only one audio at the moment | |
2153 spriv->id = 0xbd; | |
2154 } | |
2155 } | |
2156 | |
2157 if(priv->init_adelay < 0) | |
2158 { | |
2159 uint64_t delay_len; | |
2160 priv->abytes += len; | |
2161 delay_len = (uint64_t) abs((priv->init_adelay * (double) spriv->bitrate)); | |
2162 if(priv->abytes >= delay_len) | |
2163 { | |
2164 if(priv->drop) | |
2165 { | |
2166 mp_msg(MSGT_MUXER, MSGL_V, "\nDROPPING %llu AUDIO BYTES, DELAY: %.3lf, BR: %u\n", delay_len, priv->init_adelay, spriv->bitrate); | |
2167 drop_delayed_audio(muxer, s, (int64_t) delay_len); | |
2168 } | |
2169 else | |
2170 { | |
2171 mp_msg(MSGT_MUXER, MSGL_V, "\nWRITING %llu EARLY AUDIO BYTES, DELAY: %.3lf, BR: %u\n", delay_len, priv->init_adelay, spriv->bitrate); | |
2172 save_delayed_audio(muxer, s, (uint64_t) (92160000 * (-priv->init_adelay))); | |
2173 } | |
2174 priv->init_adelay = 0.0; | |
2175 conf_init_adelay = 0; | |
2176 priv->drop = 0; | |
2177 } | |
2178 } | |
2179 | |
2180 sz = max(len, 2 * priv->packet_size); | |
2181 } | |
2182 | |
2183 if (s->h.dwSampleSize) { | |
2184 // CBR | |
2185 s->h.dwLength += len/s->h.dwSampleSize; | |
2186 if (len%s->h.dwSampleSize) mp_msg(MSGT_MUXER, MSGL_ERR, "Warning! len isn't divisable by samplesize!\n"); | |
2187 } else { | |
2188 // VBR | |
2189 s->h.dwLength++; | |
2190 } | |
2191 | |
2192 s->size += len; | |
2193 s->timer = (double)s->h.dwLength*s->h.dwScale/s->h.dwRate; | |
2194 | |
2195 //if genmpeg1/2 and sz > last buffer size in the system header we must write the new sysheader | |
2196 if(sz > s->h.dwSuggestedBufferSize) { // increase and set STD | |
2197 s->h.dwSuggestedBufferSize = sz; | |
2198 if(priv->is_genmpeg1 || priv->is_genmpeg2) { | |
2199 fix_buffer_params(priv, spriv->id, s->h.dwSuggestedBufferSize); | |
2200 priv->update_system_header = 1; | |
2201 } | |
2202 } | |
2203 | |
2204 if(spriv->psm_fixed == 0) { | |
2205 add_to_psm(priv, spriv->id, stream_format); | |
2206 spriv->psm_fixed = 1; | |
2207 priv->psm_streams_cnt++; | |
2208 if((priv->psm_streams_cnt == muxer->num_videos + muxer->num_audios) && priv->use_psm) | |
2209 write_psm_block(muxer, muxer->file); | |
2210 } | |
2211 | |
2212 | |
2213 if(priv->init_adelay != 0) | |
2214 return; | |
2215 | |
2216 flush_buffers(muxer, 0); | |
2217 } | |
2218 | |
2219 | |
2220 static void mpegfile_write_index(muxer_t *muxer) | |
2221 { | |
2222 muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; | |
2223 while(flush_buffers(muxer, 0) > 0); | |
2224 flush_buffers(muxer, 1); | |
2225 if(priv->is_genmpeg1 || priv->is_genmpeg2) | |
2226 write_mpeg_pack(muxer, NULL, muxer->file, NULL, 0, 1); //insert fake Nav Packet | |
2227 | |
2228 mp_msg(MSGT_MUXER, MSGL_INFO, "\nOverhead: %.3lf%% (%llu / %llu)\n", 100.0 * (double)priv->headers_size / (double)priv->data_size, priv->headers_size, priv->data_size); | |
2229 } | |
2230 | |
2231 static void mpegfile_write_header(muxer_t *muxer) | |
2232 { | |
2233 muxer_priv_t *priv = (muxer_priv_t*) muxer->priv; | |
2234 | |
2235 priv->headers_cnt++; | |
2236 | |
2237 if((priv->is_genmpeg1 || priv->is_genmpeg2) && (priv->headers_cnt == muxer->avih.dwStreams)) | |
2238 { | |
2239 int i; | |
2240 for(i = 0; i < muxer->avih.dwStreams; i++) | |
2241 { | |
2242 priv->sys_info.streams[i].bufsize = muxer->streams[i]->h.dwSuggestedBufferSize; | |
2243 mp_msg(MSGT_MUXER, MSGL_V, "IDX: %d, BUFSIZE: %u\n", i, priv->sys_info.streams[i].bufsize); | |
2244 } | |
2245 } | |
2246 | |
2247 //write the first system header only for generic mpeg1/2 muxes, and only when we have collected all necessary infos | |
2248 if(priv->is_genmpeg1 || priv->is_genmpeg2 || ((priv->is_xvcd || priv->is_xsvcd) && (priv->headers_cnt == 1))) | |
2249 { | |
2250 write_mpeg_pack(muxer, NULL, muxer->file, NULL, 0, 0); | |
2251 priv->update_system_header = 0; | |
2252 } | |
2253 | |
2254 return; | |
2255 } | |
2256 | |
2257 static void setup_sys_params(muxer_priv_t *priv) | |
2258 { | |
2259 if(priv->is_dvd) | |
2260 { | |
2261 priv->sys_info.cnt = 4; | |
2262 | |
2263 priv->sys_info.streams[0].id = 0xb9; | |
2264 priv->sys_info.streams[0].type = 1; | |
2265 priv->sys_info.streams[0].bufsize = 232*1024; | |
2266 | |
2267 priv->sys_info.streams[1].id = 0xb8; | |
2268 priv->sys_info.streams[1].type = 0; | |
2269 priv->sys_info.streams[1].bufsize = 4*1024; | |
2270 | |
2271 priv->sys_info.streams[2].id = 0xbd; | |
2272 priv->sys_info.streams[2].type = 1; | |
2273 priv->sys_info.streams[2].bufsize = 58*1024; | |
2274 | |
2275 priv->sys_info.streams[3].id = 0xbf; | |
2276 priv->sys_info.streams[3].type = 1; | |
2277 priv->sys_info.streams[3].bufsize = 2*1024; | |
2278 } | |
2279 else if(priv->is_xvcd || priv->is_xsvcd) | |
2280 { | |
2281 priv->sys_info.cnt = 2; | |
2282 | |
2283 priv->sys_info.streams[0].id = 0xe0; | |
2284 priv->sys_info.streams[0].type = 1; | |
2285 priv->sys_info.streams[0].bufsize = (priv->is_xvcd ? 46: 230)*1024; | |
2286 | |
2287 priv->sys_info.streams[1].id = 0xc0; | |
2288 priv->sys_info.streams[1].type = 0; | |
2289 priv->sys_info.streams[1].bufsize = 4*1024; | |
2290 } | |
2291 else | |
2292 priv->sys_info.cnt = 0; | |
2293 } | |
2294 | |
2295 | |
2296 int muxer_init_muxer_mpeg(muxer_t *muxer){ | |
2297 muxer_priv_t *priv; | |
2298 priv = (muxer_priv_t *) calloc(1, sizeof(muxer_priv_t)); | |
2299 if(priv == NULL) | |
2300 return 0; | |
2301 priv->update_system_header = 1; | |
2302 | |
2303 //calloc() already zero-ed all flags, so we assign only the ones we need | |
2304 | |
2305 if(conf_mux != NULL) { | |
2306 if(! strcasecmp(conf_mux, "mpeg2")) | |
2307 { | |
2308 priv->mux = MUX_MPEG2; | |
2309 priv->packet_size = 2048; | |
2310 priv->is_genmpeg2 = 1; | |
2311 priv->muxrate = 1800 * 125; //Constrained parameters | |
2312 } | |
2313 else if(! strcasecmp(conf_mux, "dvd")) | |
2314 { | |
2315 priv->mux = MUX_MPEG2; | |
2316 priv->is_dvd = 1; | |
2317 priv->packet_size = 2048; | |
2318 priv->muxrate = 10080 * 125; | |
2319 } | |
2320 else if(! strcasecmp(conf_mux, "xsvcd")) | |
2321 { | |
2322 priv->mux = MUX_MPEG2; | |
2323 priv->is_xsvcd = 1; | |
2324 priv->packet_size = 2324; | |
2325 //what's the right muxrate? | |
2326 priv->muxrate = 2788 * 125; | |
2327 priv->ts_allframes = 1; | |
2328 } | |
2329 else if(! strcasecmp(conf_mux, "xvcd")) | |
2330 { | |
2331 priv->mux = MUX_MPEG1; | |
2332 priv->is_xvcd = 1; | |
2333 priv->packet_size = 2324; | |
2334 //what's the right muxrate? | |
2335 priv->muxrate = 1394 * 125; | |
2336 priv->ts_allframes = 1; | |
2337 } | |
320 else | 2338 else |
321 sz = len; | 2339 { |
2340 priv->mux = MUX_MPEG1; | |
2341 priv->is_genmpeg1 = 1; | |
2342 priv->packet_size = 2048; | |
2343 priv->muxrate = 1800 * 125; //Constrained parameters | |
2344 } | |
322 } | 2345 } |
323 mp_dbg(MSGT_MUXER, MSGL_DBG3, "\nMPEG chunk: size=%u, pts=%f", len, s->timer); | 2346 |
324 set_mpeg_pts (muxer, s, pts); | 2347 if(conf_ts_allframes) |
325 // alter counters: | 2348 priv->ts_allframes = 1; |
326 if (s->h.dwSampleSize) { | 2349 if(conf_muxrate > 0) |
327 // CBR | 2350 priv->muxrate = conf_muxrate * 125; // * 1000 / 8 |
328 s->h.dwLength += len/s->h.dwSampleSize; | 2351 if(conf_packet_size) |
329 if (len%s->h.dwSampleSize) printf("Warning! len isn't divisable by samplesize!\n"); | 2352 priv->packet_size = conf_packet_size; |
330 } else { | 2353 mp_msg(MSGT_MUXER, MSGL_INFO, "PACKET SIZE: %u bytes\n", priv->packet_size); |
331 // VBR | 2354 setup_sys_params(priv); |
332 s->h.dwLength++; | 2355 |
2356 priv->skip_padding = conf_skip_padding; | |
2357 if(conf_vaspect != NULL) | |
2358 { | |
2359 if(! strcmp(conf_vaspect, "1/1")) | |
2360 priv->vaspect = ASPECT_1_1; | |
2361 else if(! strcmp(conf_vaspect, "4/3")) | |
2362 priv->vaspect = ASPECT_4_3; | |
2363 else if(! strcmp(conf_vaspect, "16/9")) | |
2364 priv->vaspect = ASPECT_16_9; | |
2365 else if(! strcmp(conf_vaspect, "2.21/1")) | |
2366 priv->vaspect = ASPECT_2_21_1; | |
333 } | 2367 } |
334 if (!muxer->sysrate) { | 2368 |
335 muxer->sysrate = 2108000/8; // constrained stream parameter | 2369 priv->vframerate = 0; // no change |
336 muxer->file_end = MUXER_MPEG_BLOCKSIZE*90000/muxer->sysrate + MPEG_STARTSCR+1; | 2370 if(conf_vframerate != NULL) |
2371 { | |
2372 if(! strcmp(conf_vframerate, "23.976")) | |
2373 priv->vframerate = FRAMERATE_23976; | |
2374 else if(! strcmp(conf_vframerate, "24")) | |
2375 priv->vframerate = FRAMERATE_24; | |
2376 else if(! strcmp(conf_vframerate, "25")) | |
2377 priv->vframerate = FRAMERATE_25; | |
2378 else if(! strcmp(conf_vframerate, "29.97")) | |
2379 priv->vframerate = FRAMERATE_2997; | |
2380 else if(! strcmp(conf_vframerate, "30")) | |
2381 priv->vframerate = FRAMERATE_30; | |
2382 else if(! strcmp(conf_vframerate, "50")) | |
2383 priv->vframerate = FRAMERATE_50; | |
2384 else if(! strcmp(conf_vframerate, "59.94")) | |
2385 priv->vframerate = FRAMERATE_5994; | |
2386 else if(! strcmp(conf_vframerate, "60")) | |
2387 priv->vframerate = FRAMERATE_60; | |
337 } | 2388 } |
338 if (sz > s->h.dwSuggestedBufferSize) { // increase and set STD | 2389 |
339 s->h.dwSuggestedBufferSize = sz; | 2390 priv->vwidth = (uint16_t) conf_vwidth; |
340 if (s->b_buffer[2] != 0xff) // has both PTS and DTS | 2391 priv->vheight = (uint16_t) conf_vheight; |
341 write_mpeg_std (s->b_buffer, s->h.dwSuggestedBufferSize, 0x40); // 01 | 2392 priv->panscan_width = (uint16_t) conf_panscan_width; |
342 else // has only PTS | 2393 priv->panscan_height = (uint16_t) conf_panscan_height; |
343 write_mpeg_std (s->b_buffer+5, s->h.dwSuggestedBufferSize, 0x40); // 01 | 2394 priv->vbitrate = ((conf_vbitrate) * 10) >> 2; //*1000 / 400 |
2395 | |
2396 if(priv->vaspect || priv->vframerate || priv->vwidth || priv->vheight || priv->vbitrate || priv->panscan_width || priv->panscan_height) | |
2397 { | |
2398 priv->patch_seq = priv->vaspect || priv->vframerate || priv->vwidth || priv->vheight || priv->vbitrate; | |
2399 priv->patch_sde = priv->panscan_width || priv->panscan_height; | |
2400 mp_msg(MSGT_MUXER, MSGL_INFO, "MPEG MUXER, patching"); | |
2401 if(priv->vwidth || priv->vheight) | |
2402 mp_msg(MSGT_MUXER, MSGL_INFO, " resolution to %dx%d", priv->vwidth, priv->vheight); | |
2403 if(priv->panscan_width || priv->panscan_height) | |
2404 mp_msg(MSGT_MUXER, MSGL_INFO, " panscan to to %dx%d", priv->panscan_width, priv->panscan_height); | |
2405 if(priv->vframerate) | |
2406 mp_msg(MSGT_MUXER, MSGL_INFO, " framerate to %s fps", framerates[priv->vframerate]); | |
2407 if(priv->vaspect) | |
2408 mp_msg(MSGT_MUXER, MSGL_INFO, " aspect ratio to %s", aspect_ratios[priv->vaspect]); | |
2409 if(priv->vbitrate) | |
2410 mp_msg(MSGT_MUXER, MSGL_INFO, " bitrate to %u", conf_vbitrate); | |
2411 mp_msg(MSGT_MUXER, MSGL_INFO, "\n"); | |
344 } | 2412 } |
345 s->size += len; | 2413 |
346 // write out block(s) if it's ready | 2414 priv->has_video = priv->has_audio = 0; |
347 while (s->b_buffer_ptr+len >= MUXER_MPEG_DATASIZE-12) { // reserved for std and pts | 2415 |
348 // write out the block | 2416 |
349 sz = write_mpeg_block (muxer, s, f, &s->buffer[ptr], len, 0); | 2417 muxer->sysrate = priv->muxrate; // initial muxrate = constrained stream parameter |
350 // recalculate the rest of chunk | 2418 priv->scr = muxer->file_end = 0; |
351 ptr += sz; | 2419 |
352 len -= sz; | 2420 if(conf_init_adelay) |
2421 priv->init_adelay = (double) conf_init_adelay / (double) 1000.0; | |
2422 | |
2423 priv->drop = conf_drop; | |
2424 | |
2425 priv->buff = (uint8_t *) malloc(priv->packet_size); | |
2426 priv->tmp = (uint8_t *) malloc(priv->packet_size); | |
2427 priv->residual = (uint8_t *) malloc(priv->packet_size); | |
2428 if((priv->buff == NULL) || (priv->tmp == NULL) || (priv->residual == NULL)) | |
2429 { | |
2430 mp_msg(MSGT_MUXER, MSGL_ERR, "\nCouldn't allocate %d bytes, exit\n", priv->packet_size); | |
2431 return 0; | |
353 } | 2432 } |
354 s->timer = (double)s->h.dwLength*s->h.dwScale/s->h.dwRate; | 2433 |
355 if (len) { // save rest in buffer | 2434 muxer->priv = (void *) priv; |
356 if (s->b_buffer_ptr == 0) { | |
357 memset (s->b_buffer, 0xff, 12); // stuFFing bytes for now | |
358 if (s->type == MUXER_TYPE_AUDIO && s->h.dwSampleSize) { // CBR audio | |
359 sz = s->h.dwLength - len/s->h.dwSampleSize; // first sample number | |
360 write_mpeg_ts (s->b_buffer+7, | |
361 (int)(90000*((double)sz*s->h.dwScale/s->h.dwRate)) + MPEG_STARTPTS, | |
362 0x20); // 0010 and PTS only | |
363 } | |
364 s->b_buffer_ptr = 12; | |
365 } | |
366 memcpy (s->b_buffer+s->b_buffer_ptr, s->buffer+ptr, len); | |
367 s->b_buffer_ptr += len; | |
368 } | |
369 mp_dbg(MSGT_MUXER, MSGL_DBG3, " next pts=%f\n", s->timer); | |
370 } | |
371 | |
372 static void mpegfile_write_header(muxer_t *muxer){ | |
373 unsigned int i; | |
374 size_t sz = MUXER_MPEG_BLOCKSIZE-24; | |
375 unsigned char buff[12]; | |
376 muxer_stream_t *s = muxer->streams[0]; | |
377 uint32_t l1; | |
378 uint16_t l2; | |
379 FILE *f = muxer->file; | |
380 | |
381 if (s == NULL) | |
382 return; // no streams!? | |
383 // packet header (0x1ba) -- rewrite first stream buffer | |
384 *(uint32_t *)buff = be2me_32 (0x1ba); | |
385 write_mpeg_ts (buff+4, MPEG_STARTSCR, 0x20); // 0010 -- pack | |
386 write_mpeg_rate (buff+9, muxer->sysrate); | |
387 fwrite (buff, 12, 1, f); | |
388 // start system stream (in own block): Sys (0x1bb) | |
389 l1 = be2me_32 (0x1bb); | |
390 l2 = be2me_16 (6 + 3*muxer->avih.dwStreams); // header_length | |
391 fwrite (&l1, 4, 1, f); | |
392 fwrite (&l2, 2, 1, f); | |
393 write_mpeg_rate (buff, muxer->sysrate); // rate_bound | |
394 // set number of audio/video, fixed_flag=CSPS_flag=system_*_lock_flag=0 | |
395 buff[3] = (muxer->avih.dwStreams - muxer->num_videos) << 2; // audio_bound | |
396 buff[4] = muxer->num_videos | 0x20; | |
397 buff[5] = 0xff; // reserved_byte | |
398 fwrite (buff, 6, 1, f); | |
399 for (i = 0; i < muxer->avih.dwStreams; i++) { | |
400 buff[0] = ((char *)&muxer->streams[i]->ckid)[3]; // last char in big endian | |
401 //fprintf (stderr, "... stream 0x1%02x; bufsize %u", (int)buff[0], muxer->streams[i]->h.dwSuggestedBufferSize); | |
402 write_mpeg_std (buff+1, muxer->streams[i]->h.dwSuggestedBufferSize, 0xc0); // 11 | |
403 fwrite (buff, 3, 1, f); | |
404 sz -= 3; | |
405 } | |
406 if (sz >= 6) { // padding block | |
407 l1 = be2me_32 (0x1be); | |
408 sz -= 6; | |
409 l2 = be2me_16 (sz); | |
410 fwrite (&l1, 4, 1, f); | |
411 fwrite (&l2, 2, 1, f); | |
412 } | |
413 s->b_buffer[0] = 0x0f; // end of list - next bit has to be 0 | |
414 // stuFFing bytes -- rewrite first stream buffer | |
415 if (sz > 1) | |
416 memset (s->b_buffer+1, 0xff, sz-1); | |
417 fwrite (s->b_buffer, sz, 1, f); | |
418 muxer->movi_start = 0; | |
419 muxer->movi_end = MUXER_MPEG_BLOCKSIZE; | |
420 } | |
421 | |
422 static void mpegfile_write_index(muxer_t *muxer){ | |
423 unsigned int i; | |
424 unsigned int rsr; | |
425 | |
426 if (!muxer->avih.dwStreams) return; // no streams?! | |
427 // finish all but one video and audio streams | |
428 rsr = muxer->sysrate; // reserve it since it's silly change it at that point | |
429 for (i = 0; i < muxer->avih.dwStreams-1; i++) | |
430 write_mpeg_block (muxer, muxer->streams[i], muxer->file, NULL, 0, 0); | |
431 // end sequence: ISO-11172-End (0x1b9) and finish very last block | |
432 write_mpeg_block (muxer, muxer->streams[i], muxer->file, NULL, 0, 1); | |
433 //fprintf (stderr, "PTS to SCR delay: min %u.%03u, max %u.%03u\n", | |
434 // mpeg_min_delay/90000, (mpeg_min_delay/90)%1000, | |
435 // mpeg_max_delay/90000, (mpeg_max_delay/90)%1000); | |
436 muxer->sysrate = rsr; | |
437 } | |
438 | |
439 void muxer_init_muxer_mpeg(muxer_t *muxer){ | |
440 muxer->cont_new_stream = &mpegfile_new_stream; | 2435 muxer->cont_new_stream = &mpegfile_new_stream; |
441 muxer->cont_write_chunk = &mpegfile_write_chunk; | 2436 muxer->cont_write_chunk = &mpegfile_write_chunk; |
442 muxer->cont_write_header = &mpegfile_write_header; | 2437 muxer->cont_write_header = &mpegfile_write_header; |
443 muxer->cont_write_index = &mpegfile_write_index; | 2438 muxer->cont_write_index = &mpegfile_write_index; |
444 // mpeg_min_delay = mpeg_max_delay = MPEG_STARTPTS-MPEG_STARTSCR; | 2439 return 1; |
445 } | 2440 } |
446 | 2441 |