Mercurial > libavformat.hg
comparison mpeg.c @ 335:b0ac206f232d libavformat
better and simpler logic for MPEG muxing - fixed rare MPEG muxing PTS generation bug (stuffing is added in such rare cases) - fixed AC3 payload size generation - generate correct AC3 frame header (need spec checking)
author | bellard |
---|---|
date | Tue, 16 Dec 2003 11:25:30 +0000 |
parents | 4530681af424 |
children | d75fd4c6ab62 |
comparison
equal
deleted
inserted
replaced
334:7f089db11f9a | 335:b0ac206f232d |
---|---|
22 //#define DEBUG_SEEK | 22 //#define DEBUG_SEEK |
23 | 23 |
24 typedef struct { | 24 typedef struct { |
25 uint8_t buffer[MAX_PAYLOAD_SIZE]; | 25 uint8_t buffer[MAX_PAYLOAD_SIZE]; |
26 int buffer_ptr; | 26 int buffer_ptr; |
27 int nb_frames; /* number of starting frame encountered (AC3) */ | |
28 int frame_start_offset; /* starting offset of the frame + 1 (0 if none) */ | |
27 uint8_t id; | 29 uint8_t id; |
28 int max_buffer_size; /* in bytes */ | 30 int max_buffer_size; /* in bytes */ |
29 int packet_number; | 31 int packet_number; |
30 int64_t start_pts; | 32 int64_t start_pts; |
31 int64_t start_dts; | 33 int64_t start_dts; |
32 } StreamInfo; | 34 } StreamInfo; |
33 | 35 |
34 typedef struct { | 36 typedef struct { |
35 int packet_size; /* required packet size */ | 37 int packet_size; /* required packet size */ |
36 int packet_data_max_size; /* maximum data size inside a packet */ | |
37 int packet_number; | 38 int packet_number; |
38 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ | 39 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ |
39 int system_header_freq; | 40 int system_header_freq; |
41 int system_header_size; | |
40 int mux_rate; /* bitrate in units of 50 bytes/s */ | 42 int mux_rate; /* bitrate in units of 50 bytes/s */ |
41 /* stream info */ | 43 /* stream info */ |
42 int audio_bound; | 44 int audio_bound; |
43 int video_bound; | 45 int video_bound; |
44 int is_mpeg2; | 46 int is_mpeg2; |
164 buf[5] = (size - 6) & 0xff; | 166 buf[5] = (size - 6) & 0xff; |
165 | 167 |
166 return size; | 168 return size; |
167 } | 169 } |
168 | 170 |
171 static int get_system_header_size(AVFormatContext *ctx) | |
172 { | |
173 int buf_index, i, private_stream_coded; | |
174 StreamInfo *stream; | |
175 | |
176 buf_index = 12; | |
177 private_stream_coded = 0; | |
178 for(i=0;i<ctx->nb_streams;i++) { | |
179 stream = ctx->streams[i]->priv_data; | |
180 if (stream->id < 0xc0) { | |
181 if (private_stream_coded) | |
182 continue; | |
183 private_stream_coded = 1; | |
184 } | |
185 buf_index += 3; | |
186 } | |
187 return buf_index; | |
188 } | |
189 | |
169 static int mpeg_mux_init(AVFormatContext *ctx) | 190 static int mpeg_mux_init(AVFormatContext *ctx) |
170 { | 191 { |
171 MpegMuxContext *s = ctx->priv_data; | 192 MpegMuxContext *s = ctx->priv_data; |
172 int bitrate, i, mpa_id, mpv_id, ac3_id; | 193 int bitrate, i, mpa_id, mpv_id, ac3_id; |
173 AVStream *st; | 194 AVStream *st; |
180 if (s->is_vcd) | 201 if (s->is_vcd) |
181 s->packet_size = 2324; /* VCD packet size */ | 202 s->packet_size = 2324; /* VCD packet size */ |
182 else | 203 else |
183 s->packet_size = 2048; | 204 s->packet_size = 2048; |
184 | 205 |
185 /* startcode(4) + length(2) + flags(1) */ | |
186 s->packet_data_max_size = s->packet_size - 7; | |
187 if (s->is_mpeg2) | |
188 s->packet_data_max_size -= 2; | |
189 s->audio_bound = 0; | 206 s->audio_bound = 0; |
190 s->video_bound = 0; | 207 s->video_bound = 0; |
191 mpa_id = AUDIO_ID; | 208 mpa_id = AUDIO_ID; |
192 ac3_id = 0x80; | 209 ac3_id = 0x80; |
193 mpv_id = VIDEO_ID; | 210 mpv_id = VIDEO_ID; |
258 stream->buffer_ptr = 0; | 275 stream->buffer_ptr = 0; |
259 stream->packet_number = 0; | 276 stream->packet_number = 0; |
260 stream->start_pts = AV_NOPTS_VALUE; | 277 stream->start_pts = AV_NOPTS_VALUE; |
261 stream->start_dts = AV_NOPTS_VALUE; | 278 stream->start_dts = AV_NOPTS_VALUE; |
262 } | 279 } |
280 s->system_header_size = get_system_header_size(ctx); | |
263 s->last_scr = 0; | 281 s->last_scr = 0; |
264 return 0; | 282 return 0; |
265 fail: | 283 fail: |
266 for(i=0;i<ctx->nb_streams;i++) { | 284 for(i=0;i<ctx->nb_streams;i++) { |
267 av_free(ctx->streams[i]->priv_data); | 285 av_free(ctx->streams[i]->priv_data); |
277 1); | 295 1); |
278 put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); | 296 put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); |
279 put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); | 297 put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); |
280 } | 298 } |
281 | 299 |
300 | |
301 /* return the exact available payload size for the next packet for | |
302 stream 'stream_index'. 'pts' and 'dts' are only used to know if | |
303 timestamps are needed in the packet header. */ | |
304 static int get_packet_payload_size(AVFormatContext *ctx, int stream_index, | |
305 int64_t pts, int64_t dts) | |
306 { | |
307 MpegMuxContext *s = ctx->priv_data; | |
308 int buf_index; | |
309 StreamInfo *stream; | |
310 | |
311 buf_index = 0; | |
312 if (((s->packet_number % s->pack_header_freq) == 0)) { | |
313 /* pack header size */ | |
314 if (s->is_mpeg2) | |
315 buf_index += 14; | |
316 else | |
317 buf_index += 12; | |
318 if ((s->packet_number % s->system_header_freq) == 0) | |
319 buf_index += s->system_header_size; | |
320 } | |
321 | |
322 /* packet header size */ | |
323 buf_index += 6; | |
324 if (s->is_mpeg2) | |
325 buf_index += 3; | |
326 if (pts != AV_NOPTS_VALUE) { | |
327 if (dts != AV_NOPTS_VALUE) | |
328 buf_index += 5 + 5; | |
329 else | |
330 buf_index += 5; | |
331 } else { | |
332 if (!s->is_mpeg2) | |
333 buf_index++; | |
334 } | |
335 | |
336 stream = ctx->streams[stream_index]->priv_data; | |
337 if (stream->id < 0xc0) { | |
338 /* AC3 private data header */ | |
339 buf_index += 4; | |
340 } | |
341 return s->packet_size - buf_index; | |
342 } | |
343 | |
282 /* flush the packet on stream stream_index */ | 344 /* flush the packet on stream stream_index */ |
283 static void flush_packet(AVFormatContext *ctx, int stream_index, | 345 static void flush_packet(AVFormatContext *ctx, int stream_index, |
284 int64_t pts, int64_t dts, int64_t scr) | 346 int64_t pts, int64_t dts, int64_t scr) |
285 { | 347 { |
286 MpegMuxContext *s = ctx->priv_data; | 348 MpegMuxContext *s = ctx->priv_data; |
287 StreamInfo *stream = ctx->streams[stream_index]->priv_data; | 349 StreamInfo *stream = ctx->streams[stream_index]->priv_data; |
288 uint8_t *buf_ptr; | 350 uint8_t *buf_ptr; |
289 int size, payload_size, startcode, id, len, stuffing_size, i, header_len; | 351 int size, payload_size, startcode, id, stuffing_size, i, header_len; |
352 int packet_size; | |
290 uint8_t buffer[128]; | 353 uint8_t buffer[128]; |
291 | 354 |
292 id = stream->id; | 355 id = stream->id; |
293 | 356 |
294 #if 0 | 357 #if 0 |
323 } else { | 386 } else { |
324 if (!s->is_mpeg2) | 387 if (!s->is_mpeg2) |
325 header_len++; | 388 header_len++; |
326 } | 389 } |
327 | 390 |
328 payload_size = s->packet_size - (size + 6 + header_len); | 391 packet_size = s->packet_size - (size + 6); |
392 payload_size = packet_size - header_len; | |
329 if (id < 0xc0) { | 393 if (id < 0xc0) { |
330 startcode = PRIVATE_STREAM_1; | 394 startcode = PRIVATE_STREAM_1; |
331 payload_size -= 4; | 395 payload_size -= 4; |
332 } else { | 396 } else { |
333 startcode = 0x100 + id; | 397 startcode = 0x100 + id; |
334 } | 398 } |
399 | |
335 stuffing_size = payload_size - stream->buffer_ptr; | 400 stuffing_size = payload_size - stream->buffer_ptr; |
336 if (stuffing_size < 0) | 401 if (stuffing_size < 0) |
337 stuffing_size = 0; | 402 stuffing_size = 0; |
338 | |
339 put_be32(&ctx->pb, startcode); | 403 put_be32(&ctx->pb, startcode); |
340 | 404 |
341 put_be16(&ctx->pb, payload_size + header_len); | 405 put_be16(&ctx->pb, packet_size); |
342 /* stuffing */ | 406 /* stuffing */ |
343 for(i=0;i<stuffing_size;i++) | 407 for(i=0;i<stuffing_size;i++) |
344 put_byte(&ctx->pb, 0xff); | 408 put_byte(&ctx->pb, 0xff); |
345 | 409 |
346 if (s->is_mpeg2) { | 410 if (s->is_mpeg2) { |
375 } | 439 } |
376 | 440 |
377 if (startcode == PRIVATE_STREAM_1) { | 441 if (startcode == PRIVATE_STREAM_1) { |
378 put_byte(&ctx->pb, id); | 442 put_byte(&ctx->pb, id); |
379 if (id >= 0x80 && id <= 0xbf) { | 443 if (id >= 0x80 && id <= 0xbf) { |
380 /* XXX: need to check AC3 spec */ | 444 put_byte(&ctx->pb, stream->nb_frames); |
381 put_byte(&ctx->pb, 1); | 445 put_be16(&ctx->pb, stream->frame_start_offset); |
382 put_byte(&ctx->pb, 0); | |
383 put_byte(&ctx->pb, 2); | |
384 } | 446 } |
385 } | 447 } |
386 | 448 |
387 /* output data */ | 449 /* output data */ |
388 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); | 450 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); |
389 put_flush_packet(&ctx->pb); | 451 put_flush_packet(&ctx->pb); |
390 | 452 |
391 /* preserve remaining data */ | |
392 len = stream->buffer_ptr - payload_size; | |
393 if (len < 0) | |
394 len = 0; | |
395 memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len); | |
396 stream->buffer_ptr = len; | |
397 | |
398 s->packet_number++; | 453 s->packet_number++; |
399 stream->packet_number++; | 454 stream->packet_number++; |
455 stream->nb_frames = 0; | |
456 stream->frame_start_offset = 0; | |
400 } | 457 } |
401 | 458 |
402 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, | 459 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, |
403 const uint8_t *buf, int size, int64_t pts) | 460 const uint8_t *buf, int size, int64_t pts) |
404 { | 461 { |
405 MpegMuxContext *s = ctx->priv_data; | 462 MpegMuxContext *s = ctx->priv_data; |
406 AVStream *st = ctx->streams[stream_index]; | 463 AVStream *st = ctx->streams[stream_index]; |
407 StreamInfo *stream = st->priv_data; | 464 StreamInfo *stream = st->priv_data; |
408 int64_t dts; | 465 int64_t dts, new_start_pts, new_start_dts; |
409 int len; | 466 int len, avail_size; |
410 | 467 |
411 /* XXX: system clock should be computed precisely, especially for | 468 /* XXX: system clock should be computed precisely, especially for |
412 CBR case. The current mode gives at least something coherent */ | 469 CBR case. The current mode gives at least something coherent */ |
413 if (stream_index == s->scr_stream_index) | 470 if (stream_index == s->scr_stream_index) |
414 s->last_scr = pts; | 471 s->last_scr = pts; |
420 | 477 |
421 /* XXX: currently no way to pass dts, will change soon */ | 478 /* XXX: currently no way to pass dts, will change soon */ |
422 dts = AV_NOPTS_VALUE; | 479 dts = AV_NOPTS_VALUE; |
423 | 480 |
424 /* we assume here that pts != AV_NOPTS_VALUE */ | 481 /* we assume here that pts != AV_NOPTS_VALUE */ |
482 new_start_pts = stream->start_pts; | |
483 new_start_dts = stream->start_dts; | |
484 | |
425 if (stream->start_pts == AV_NOPTS_VALUE) { | 485 if (stream->start_pts == AV_NOPTS_VALUE) { |
426 stream->start_pts = pts; | 486 new_start_pts = pts; |
427 stream->start_dts = dts; | 487 new_start_dts = dts; |
428 } | 488 } |
489 avail_size = get_packet_payload_size(ctx, stream_index, | |
490 new_start_pts, | |
491 new_start_dts); | |
492 if (stream->buffer_ptr >= avail_size) { | |
493 /* unlikely case: outputing the pts or dts increase the packet | |
494 size so that we cannot write the start of the next | |
495 packet. In this case, we must flush the current packet with | |
496 padding */ | |
497 flush_packet(ctx, stream_index, | |
498 stream->start_pts, stream->start_dts, s->last_scr); | |
499 stream->buffer_ptr = 0; | |
500 } | |
501 stream->start_pts = new_start_pts; | |
502 stream->start_dts = new_start_dts; | |
503 stream->nb_frames++; | |
504 if (stream->frame_start_offset == 0) | |
505 stream->frame_start_offset = stream->buffer_ptr; | |
429 while (size > 0) { | 506 while (size > 0) { |
430 len = s->packet_data_max_size - stream->buffer_ptr; | 507 avail_size = get_packet_payload_size(ctx, stream_index, |
508 stream->start_pts, | |
509 stream->start_dts); | |
510 len = avail_size - stream->buffer_ptr; | |
431 if (len > size) | 511 if (len > size) |
432 len = size; | 512 len = size; |
433 memcpy(stream->buffer + stream->buffer_ptr, buf, len); | 513 memcpy(stream->buffer + stream->buffer_ptr, buf, len); |
434 stream->buffer_ptr += len; | 514 stream->buffer_ptr += len; |
435 buf += len; | 515 buf += len; |
436 size -= len; | 516 size -= len; |
437 while (stream->buffer_ptr >= s->packet_data_max_size) { | 517 if (stream->buffer_ptr >= avail_size) { |
438 /* output the packet */ | 518 /* if packet full, we send it now */ |
439 flush_packet(ctx, stream_index, | 519 flush_packet(ctx, stream_index, |
440 stream->start_pts, stream->start_dts, s->last_scr); | 520 stream->start_pts, stream->start_dts, s->last_scr); |
521 stream->buffer_ptr = 0; | |
441 /* Make sure only the FIRST pes packet for this frame has | 522 /* Make sure only the FIRST pes packet for this frame has |
442 a timestamp */ | 523 a timestamp */ |
443 stream->start_pts = AV_NOPTS_VALUE; | 524 stream->start_pts = AV_NOPTS_VALUE; |
444 stream->start_dts = AV_NOPTS_VALUE; | 525 stream->start_dts = AV_NOPTS_VALUE; |
445 } | 526 } |
446 } | 527 } |
528 | |
447 return 0; | 529 return 0; |
448 } | 530 } |
449 | 531 |
450 static int mpeg_mux_end(AVFormatContext *ctx) | 532 static int mpeg_mux_end(AVFormatContext *ctx) |
451 { | 533 { |
454 int i; | 536 int i; |
455 | 537 |
456 /* flush each packet */ | 538 /* flush each packet */ |
457 for(i=0;i<ctx->nb_streams;i++) { | 539 for(i=0;i<ctx->nb_streams;i++) { |
458 stream = ctx->streams[i]->priv_data; | 540 stream = ctx->streams[i]->priv_data; |
459 while (stream->buffer_ptr > 0) { | 541 if (stream->buffer_ptr > 0) { |
460 flush_packet(ctx, i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, s->last_scr); | 542 /* NOTE: we can always write the remaining data as it was |
543 tested before in mpeg_mux_write_packet() */ | |
544 flush_packet(ctx, i, stream->start_pts, stream->start_dts, | |
545 s->last_scr); | |
461 } | 546 } |
462 } | 547 } |
463 | 548 |
464 /* End header according to MPEG1 systems standard. We do not write | 549 /* End header according to MPEG1 systems standard. We do not write |
465 it as it is usually not needed by decoders and because it | 550 it as it is usually not needed by decoders and because it |
753 if (st->id == startcode) | 838 if (st->id == startcode) |
754 goto found; | 839 goto found; |
755 } | 840 } |
756 if (startcode >= 0x1e0 && startcode <= 0x1ef) { | 841 if (startcode >= 0x1e0 && startcode <= 0x1ef) { |
757 type = CODEC_TYPE_VIDEO; | 842 type = CODEC_TYPE_VIDEO; |
758 codec_id = CODEC_ID_MPEG1VIDEO; | 843 codec_id = CODEC_ID_MPEG2VIDEO; |
759 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { | 844 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { |
760 type = CODEC_TYPE_AUDIO; | 845 type = CODEC_TYPE_AUDIO; |
761 codec_id = CODEC_ID_MP2; | 846 codec_id = CODEC_ID_MP2; |
762 } else if (startcode >= 0x80 && startcode <= 0x9f) { | 847 } else if (startcode >= 0x80 && startcode <= 0x9f) { |
763 type = CODEC_TYPE_AUDIO; | 848 type = CODEC_TYPE_AUDIO; |
992 "MPEG2 PS format (VOB)", | 1077 "MPEG2 PS format (VOB)", |
993 "video/mpeg", | 1078 "video/mpeg", |
994 "vob", | 1079 "vob", |
995 sizeof(MpegMuxContext), | 1080 sizeof(MpegMuxContext), |
996 CODEC_ID_MP2, | 1081 CODEC_ID_MP2, |
997 CODEC_ID_MPEG1VIDEO, | 1082 CODEC_ID_MPEG2VIDEO, |
998 mpeg_mux_init, | 1083 mpeg_mux_init, |
999 mpeg_mux_write_packet, | 1084 mpeg_mux_write_packet, |
1000 mpeg_mux_end, | 1085 mpeg_mux_end, |
1001 }; | 1086 }; |
1002 #endif //CONFIG_ENCODERS | 1087 #endif //CONFIG_ENCODERS |