diff --git a/ffmpeg.c b/ffmpeg.c
index 4d12f80..c48aec7 100644
|
a
|
b
|
static void sub2video_push_ref(InputStream *ist, int64_t pts) |
| 202 | 202 | AV_BUFFERSRC_FLAG_PUSH); |
| 203 | 203 | } |
| 204 | 204 | |
| 205 | | static void sub2video_update(InputStream *ist, AVSubtitle *sub, int64_t pts) |
| | 205 | static void sub2video_update(InputStream *ist, AVSubtitle *sub) |
| 206 | 206 | { |
| 207 | 207 | int w = ist->sub2video.w, h = ist->sub2video.h; |
| 208 | 208 | AVFilterBufferRef *ref = ist->sub2video.ref; |
| 209 | 209 | int8_t *dst; |
| 210 | 210 | int dst_linesize; |
| 211 | 211 | int i; |
| | 212 | int64_t pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ist->st->time_base); |
| 212 | 213 | |
| 213 | 214 | if (!ref) |
| 214 | 215 | return; |
| … |
… |
static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void * |
| 693 | 694 | static void do_subtitle_out(AVFormatContext *s, |
| 694 | 695 | OutputStream *ost, |
| 695 | 696 | InputStream *ist, |
| 696 | | AVSubtitle *sub, |
| 697 | | int64_t pts) |
| | 697 | AVSubtitle *sub) |
| 698 | 698 | { |
| 699 | 699 | int subtitle_out_max_size = 1024 * 1024; |
| 700 | 700 | int subtitle_out_size, nb, i; |
| 701 | 701 | AVCodecContext *enc; |
| 702 | 702 | AVPacket pkt; |
| | 703 | int64_t pts; |
| 703 | 704 | |
| 704 | | if (pts == AV_NOPTS_VALUE) { |
| | 705 | if (sub->pts == AV_NOPTS_VALUE) { |
| 705 | 706 | av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); |
| 706 | 707 | if (exit_on_error) |
| 707 | 708 | exit_program(1); |
| … |
… |
static void do_subtitle_out(AVFormatContext *s, |
| 723 | 724 | nb = 1; |
| 724 | 725 | |
| 725 | 726 | /* shift timestamp to honor -ss and make check_recording_time() work with -t */ |
| 726 | | pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q) |
| 727 | | - output_files[ost->file_index]->start_time; |
| | 727 | pts = sub->pts - output_files[ost->file_index]->start_time; |
| 728 | 728 | for (i = 0; i < nb; i++) { |
| 729 | 729 | ost->sync_opts = av_rescale_q(pts, AV_TIME_BASE_Q, enc->time_base); |
| 730 | 730 | if (!check_recording_time(ost)) |
| … |
… |
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) |
| 1657 | 1657 | static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) |
| 1658 | 1658 | { |
| 1659 | 1659 | AVSubtitle subtitle; |
| 1660 | | int64_t pts = pkt->pts; |
| 1661 | 1660 | int i, ret = avcodec_decode_subtitle2(ist->st->codec, |
| 1662 | 1661 | &subtitle, got_output, pkt); |
| 1663 | 1662 | if (ret < 0 || !*got_output) { |
| … |
… |
static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) |
| 1668 | 1667 | |
| 1669 | 1668 | if (ist->fix_sub_duration) { |
| 1670 | 1669 | if (ist->prev_sub.got_output) { |
| 1671 | | int end = av_rescale_q(pts - ist->prev_sub.pts, ist->st->time_base, |
| 1672 | | (AVRational){ 1, 1000 }); |
| | 1670 | int end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts, |
| | 1671 | 1000, AV_TIME_BASE); |
| 1673 | 1672 | if (end < ist->prev_sub.subtitle.end_display_time) { |
| 1674 | 1673 | av_log(ist->st->codec, AV_LOG_DEBUG, |
| 1675 | 1674 | "Subtitle duration reduced from %d to %d\n", |
| … |
… |
static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) |
| 1677 | 1676 | ist->prev_sub.subtitle.end_display_time = end; |
| 1678 | 1677 | } |
| 1679 | 1678 | } |
| 1680 | | FFSWAP(int64_t, pts, ist->prev_sub.pts); |
| 1681 | 1679 | FFSWAP(int, *got_output, ist->prev_sub.got_output); |
| 1682 | 1680 | FFSWAP(int, ret, ist->prev_sub.ret); |
| 1683 | 1681 | FFSWAP(AVSubtitle, subtitle, ist->prev_sub.subtitle); |
| 1684 | 1682 | } |
| 1685 | 1683 | |
| | 1684 | sub2video_update(ist, &subtitle); |
| | 1685 | |
| 1686 | 1686 | if (!*got_output || !subtitle.num_rects) |
| 1687 | 1687 | return ret; |
| 1688 | 1688 | |
| 1689 | 1689 | rate_emu_sleep(ist); |
| 1690 | 1690 | |
| 1691 | | sub2video_update(ist, &subtitle, pkt->pts); |
| 1692 | | |
| 1693 | 1691 | for (i = 0; i < nb_output_streams; i++) { |
| 1694 | 1692 | OutputStream *ost = output_streams[i]; |
| 1695 | 1693 | |
| 1696 | 1694 | if (!check_output_constraints(ist, ost) || !ost->encoding_needed) |
| 1697 | 1695 | continue; |
| 1698 | 1696 | |
| 1699 | | do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle, pts); |
| | 1697 | do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle); |
| 1700 | 1698 | } |
| 1701 | 1699 | |
| 1702 | 1700 | avsubtitle_free(&subtitle); |
diff --git a/ffmpeg.h b/ffmpeg.h
index cd849c9..85a11a0 100644
|
a
|
b
|
typedef struct InputStream { |
| 232 | 232 | |
| 233 | 233 | int fix_sub_duration; |
| 234 | 234 | struct { /* previous decoded subtitle and related variables */ |
| 235 | | int64_t pts; |
| 236 | 235 | int got_output; |
| 237 | 236 | int ret; |
| 238 | 237 | AVSubtitle subtitle; |
diff --git a/ffplay.c b/ffplay.c
index 42f03b8..408c82c 100644
|
a
|
b
|
static int subtitle_thread(void *arg) |
| 1840 | 1840 | |
| 1841 | 1841 | avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub, |
| 1842 | 1842 | &got_subtitle, pkt); |
| | 1843 | if (sp->sub.pts != AV_NOPTS_VALUE) |
| | 1844 | pts = sp->sub.pts / (double)AV_TIME_BASE; |
| 1843 | 1845 | |
| 1844 | 1846 | if (got_subtitle && sp->sub.format == 0) { |
| 1845 | 1847 | sp->pts = pts; |
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index 79ebb55..64d20df 100644
|
a
|
b
|
typedef struct PGSSubContext { |
| 67 | 67 | PGSSubPresentation presentation; |
| 68 | 68 | uint32_t clut[256]; |
| 69 | 69 | PGSSubPicture pictures[UINT16_MAX]; |
| | 70 | int64_t pts; |
| 70 | 71 | int forced_subs_only; |
| 71 | 72 | } PGSSubContext; |
| 72 | 73 | |
| … |
… |
static int display_end_segment(AVCodecContext *avctx, void *data, |
| 387 | 388 | * not been cleared by a subsequent empty display command. |
| 388 | 389 | */ |
| 389 | 390 | |
| | 391 | if (ctx->pts == AV_NOPTS_VALUE) /* if no presentation segment to set it */ |
| | 392 | ctx->pts = sub->pts; |
| 390 | 393 | memset(sub, 0, sizeof(*sub)); |
| | 394 | sub->pts = ctx->pts; |
| | 395 | ctx->pts = AV_NOPTS_VALUE; |
| 391 | 396 | |
| 392 | 397 | // Blank if last object_count was 0. |
| 393 | 398 | if (!ctx->presentation.object_count) |
| … |
… |
static int display_end_segment(AVCodecContext *avctx, void *data, |
| 436 | 441 | static int decode(AVCodecContext *avctx, void *data, int *data_size, |
| 437 | 442 | AVPacket *avpkt) |
| 438 | 443 | { |
| | 444 | PGSSubContext *ctx = avctx->priv_data; |
| 439 | 445 | const uint8_t *buf = avpkt->data; |
| 440 | 446 | int buf_size = avpkt->size; |
| | 447 | AVSubtitle *sub = data; |
| 441 | 448 | |
| 442 | 449 | const uint8_t *buf_end; |
| 443 | 450 | uint8_t segment_type; |
| … |
… |
static int decode(AVCodecContext *avctx, void *data, int *data_size, |
| 482 | 489 | break; |
| 483 | 490 | case PRESENTATION_SEGMENT: |
| 484 | 491 | parse_presentation_segment(avctx, buf, segment_length); |
| | 492 | ctx->pts = sub->pts; |
| 485 | 493 | break; |
| 486 | 494 | case WINDOW_SEGMENT: |
| 487 | 495 | /* |
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 99e012a..30b0d21 100644
|
a
|
b
|
int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, |
| 1701 | 1701 | avctx->pkt = avpkt; |
| 1702 | 1702 | *got_sub_ptr = 0; |
| 1703 | 1703 | avcodec_get_subtitle_defaults(sub); |
| | 1704 | if (avctx->pkt_timebase.den && avpkt->pts != AV_NOPTS_VALUE) |
| | 1705 | sub->pts = av_rescale_q(avpkt->pts, |
| | 1706 | avctx->pkt_timebase, AV_TIME_BASE_Q); |
| 1704 | 1707 | ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); |
| 1705 | 1708 | if (*got_sub_ptr) |
| 1706 | 1709 | avctx->frame_number++; |