From 51c9b8b53656b750a60677cece1db52fed084290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sat, 21 Sep 2013 06:39:09 +0200 Subject: [PATCH] avformat/vobsub/WIP: fix packet size calc. --- libavformat/mpeg.c | 35 +++++++++++++++++++++++++++++++---- tests/ref/fate/sub2video | 10 +--------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 0b4fc23..83fd3dd 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -114,6 +114,7 @@ typedef struct MpegDemuxContext { #if CONFIG_VOBSUB_DEMUXER AVFormatContext *sub_ctx; FFDemuxSubtitlesQueue q; + int64_t *sub_pos; #endif } MpegDemuxContext; @@ -643,6 +644,15 @@ static int vobsub_probe(AVProbeData *p) return 0; } +static int cmp_sub_pos(const void *a, const void *b) +{ + const int64_t *s1 = a; + const int64_t *s2 = b; + if (*s1 == *s2) + return 0; + return *s1 > *s2 ? 1 : -1; +} + static int vobsub_read_header(AVFormatContext *s) { int i, ret = 0, header_parsed = 0, langidx = 0; @@ -769,6 +779,17 @@ static int vobsub_read_header(AVFormatContext *s) ff_subtitles_queue_finalize(&vobsub->q); + /* create an ordered list of positions which will be used to define the + * maximum size of each packet */ + vobsub->sub_pos = av_calloc(vobsub->q.nb_subs, sizeof(*vobsub->sub_pos)); + if (!vobsub->sub_pos) { + ret = AVERROR(ENOMEM); + goto end; + } + for (i = 0; i < vobsub->q.nb_subs; i++) + vobsub->sub_pos[i] = vobsub->q.subs[i].pos; + qsort(vobsub->sub_pos, vobsub->q.nb_subs, sizeof(*vobsub->sub_pos), cmp_sub_pos); + if (!av_bprint_is_complete(&header)) { av_bprint_finalize(&header, NULL); ret = AVERROR(ENOMEM); @@ -794,7 +815,8 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) MpegDemuxContext *vobsub = s->priv_data; FFDemuxSubtitlesQueue *q = &vobsub->q; AVIOContext *pb = vobsub->sub_ctx->pb; - int ret, psize, len16 = -1; + int ret, psize, len16 = -1, idx; + const int64_t *pos_ptr; AVPacket idx_pkt; ret = ff_subtitles_queue_read_packet(q, &idx_pkt); @@ -803,8 +825,12 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) /* compute maximum packet size using the next packet position. This is * useful when the len in the header is non-sense */ - if (q->current_sub_idx < q->nb_subs) { - psize = q->subs[q->current_sub_idx].pos - idx_pkt.pos; + pos_ptr = bsearch(&q->subs[q->current_sub_idx - 1].pos, vobsub->sub_pos, + q->nb_subs, sizeof(*vobsub->sub_pos), cmp_sub_pos); + av_assert0(pos_ptr); + idx = (ptrdiff_t)(pos_ptr - vobsub->sub_pos) + 1; + if (idx < q->nb_subs) { + psize = q->subs[idx].pos - idx_pkt.pos; } else { int64_t fsize = avio_size(pb); psize = fsize < 0 ? 0xffff : fsize - idx_pkt.pos; @@ -826,7 +852,7 @@ static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) to_read = ret & 0xffff; /* this prevents reads above the current packet */ - if (pkt->size + to_read > psize) + if (len16 == -1 && pkt->size + to_read > psize) break; /* if the len is computed, we check for overread */ @@ -891,6 +917,7 @@ static int vobsub_read_close(AVFormatContext *s) ff_subtitles_queue_clean(&vobsub->q); if (vobsub->sub_ctx) avformat_close_input(&vobsub->sub_ctx); + av_freep(&vobsub->sub_pos); return 0; } diff --git a/tests/ref/fate/sub2video b/tests/ref/fate/sub2video index f866c21..f05bb9e 100644 --- a/tests/ref/fate/sub2video +++ b/tests/ref/fate/sub2video @@ -54,7 +54,6 @@ 1, 15355, 15355, 4733, 2094, 0x3c171425, F=0x0 1, 48797, 48797, 2560, 2480, 0x7c0edf21, F=0x0 1, 51433, 51433, 2366, 3059, 0xc95b8a05, F=0x0 -1, 53919, 53919, 2696, 2095, 0x61bb15ed, F=0x0 1, 56663, 56663, 1262, 1013, 0xc9ae89b7, F=0x0 1, 58014, 58014, 1661, 969, 0xe01878f0, F=0x0 1, 67724, 67724, 1365, 844, 0xe7db4fc1, F=0x0 @@ -77,6 +76,7 @@ 1, 141556, 141556, 1661, 1088, 0xde20aa20, F=0x0 1, 163445, 163445, 1331, 339, 0x8bd186ef, F=0x0 1, 168049, 168049, 1900, 1312, 0x0bf20e8d, F=0x0 +1, 170018, 170018, 1524, 1279, 0xb6c2dafe, F=0x0 1, 172203, 172203, 1695, 1826, 0x9a1ac769, F=0x0 1, 173947, 173947, 1934, 1474, 0xa9b03cdc, F=0x0 1, 175957, 175957, 1763, 1019, 0x20409355, F=0x0 @@ -84,11 +84,3 @@ 1, 191356, 191356, 1228, 1517, 0xae8c5c2b, F=0x0 1, 192640, 192640, 1763, 2506, 0xa458d6d4, F=0x0 1, 195193, 195193, 1092, 1074, 0x397ba9a8, F=0x0 -1, 196369, 196369, 1524, 1715, 0x695ca41e, F=0x0 -1, 197946, 197946, 1160, 789, 0xc63a189e, F=0x0 -1, 199230, 199230, 1627, 1846, 0xeea8c599, F=0x0 -1, 200924, 200924, 1763, 922, 0xd4a87222, F=0x0 -1, 210600, 210600, 1831, 665, 0x55580135, F=0x0 -1, 214771, 214771, 1558, 1216, 0x50d1f6c5, F=0x0 -1, 225640, 225640, 2127, 2133, 0x670c11a5, F=0x0 -1, 227834, 227834, 1262, 1264, 0xc1d9fc57, F=0x0 -- 1.8.4