diff --git a/ffmpeg.c b/ffmpeg.c
index b1052c0..509b945 100644
|
a
|
b
|
static void update_benchmark(const char *fmt, ...)
|
| 544 | 544 | } |
| 545 | 545 | } |
| 546 | 546 | |
| | 547 | #define STAMP(pkt) ( ((pkt)->dts == AV_NOPTS_VALUE) ? (pkt)->pts : (pkt)->dts) |
| | 548 | |
| | 549 | static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost); |
| | 550 | static void queue_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) |
| | 551 | { |
| | 552 | PacketQueue *last = ost->queue, *new; |
| | 553 | new = av_mallocz(sizeof(PacketQueue)); |
| | 554 | new->s = s; |
| | 555 | new->pkt = av_memdup(pkt, sizeof(AVPacket)); |
| | 556 | new->ost = ost; |
| | 557 | |
| | 558 | if(STAMP(pkt) == AV_NOPTS_VALUE) { |
| | 559 | write_frame(s, pkt, ost); |
| | 560 | return; |
| | 561 | } |
| | 562 | |
| | 563 | if(!last) { |
| | 564 | ost->queue = new; |
| | 565 | return; |
| | 566 | } |
| | 567 | |
| | 568 | while(last && last->next && STAMP(last->next->pkt) < STAMP(pkt)) { |
| | 569 | last = last->next; |
| | 570 | } |
| | 571 | |
| | 572 | new->next = last->next; |
| | 573 | last->next = new; |
| | 574 | } |
| | 575 | |
| | 576 | static void flush_queue(OutputStream *ost, int64_t ts) |
| | 577 | { |
| | 578 | PacketQueue *last; |
| | 579 | |
| | 580 | if(ts == AV_NOPTS_VALUE) |
| | 581 | return; |
| | 582 | |
| | 583 | while(ost->queue && STAMP(ost->queue->pkt) <= ts) { |
| | 584 | last = ost->queue; |
| | 585 | ost->queue = ost->queue->next; |
| | 586 | write_frame(last->s, last->pkt, last->ost); |
| | 587 | av_free(last->pkt); |
| | 588 | av_free(last); |
| | 589 | } |
| | 590 | } |
| | 591 | |
| 547 | 592 | static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) |
| 548 | 593 | { |
| 549 | 594 | AVBitStreamFilterContext *bsfc = ost->bitstream_filters; |
| … |
… |
static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
|
| 605 | 650 | bsfc = bsfc->next; |
| 606 | 651 | } |
| 607 | 652 | |
| | 653 | flush_queue(ost, STAMP(pkt)); |
| | 654 | |
| 608 | 655 | if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) && |
| 609 | 656 | (avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) && |
| 610 | 657 | pkt->dts != AV_NOPTS_VALUE && |
| … |
… |
static void close_output_stream(OutputStream *ost)
|
| 652 | 699 | { |
| 653 | 700 | OutputFile *of = output_files[ost->file_index]; |
| 654 | 701 | |
| | 702 | flush_queue(ost, INT64_MAX); |
| | 703 | |
| 655 | 704 | ost->finished = 1; |
| 656 | 705 | if (of->shortest) { |
| 657 | 706 | int64_t end = av_rescale_q(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, AV_TIME_BASE_Q); |
| … |
… |
static void do_subtitle_out(AVFormatContext *s,
|
| 789 | 838 | pkt.pts += 90 * sub->end_display_time; |
| 790 | 839 | } |
| 791 | 840 | subtitle_size += pkt.size; |
| 792 | | write_frame(s, &pkt, ost); |
| | 841 | if(i == 0) |
| | 842 | write_frame(s, &pkt, ost); |
| | 843 | else |
| | 844 | queue_frame(s, &pkt, ost); |
| 793 | 845 | } |
| 794 | 846 | } |
| 795 | 847 | |
diff --git a/ffmpeg.h b/ffmpeg.h
index c001d2c..d614c79 100644
|
a
|
b
|
enum forced_keyframes_const {
|
| 312 | 312 | |
| 313 | 313 | extern const char *const forced_keyframes_const_names[]; |
| 314 | 314 | |
| | 315 | struct OutputStream; |
| | 316 | typedef struct PacketQueue { |
| | 317 | AVFormatContext *s; |
| | 318 | AVPacket *pkt; |
| | 319 | struct OutputStream *ost; |
| | 320 | struct PacketQueue *next; |
| | 321 | } PacketQueue; |
| | 322 | |
| 315 | 323 | typedef struct OutputStream { |
| 316 | 324 | int file_index; /* file index */ |
| 317 | 325 | int index; /* stream index in the output file */ |
| … |
… |
typedef struct OutputStream {
|
| 373 | 381 | int keep_pix_fmt; |
| 374 | 382 | |
| 375 | 383 | AVCodecParserContext *parser; |
| | 384 | PacketQueue *queue; |
| 376 | 385 | } OutputStream; |
| 377 | 386 | |
| 378 | 387 | typedef struct OutputFile { |