@@ -725,6 +725,7 @@ static int vobsub_read_header(AVFormatContext *s)
 | 
				
			|||||||
            st->id = stream_id;
 | 
					            st->id = stream_id;
 | 
				
			||||||
            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
 | 
					            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
 | 
				
			||||||
            st->codec->codec_id   = AV_CODEC_ID_DVD_SUBTITLE;
 | 
					            st->codec->codec_id   = AV_CODEC_ID_DVD_SUBTITLE;
 | 
				
			||||||
 | 
					            avpriv_set_pts_info(st, 64, 1, 1000);
 | 
				
			||||||
            av_dict_set(&st->metadata, "language", id, 0);
 | 
					            av_dict_set(&st->metadata, "language", id, 0);
 | 
				
			||||||
            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);
 | 
					            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);
 | 
				
			||||||
            header_parsed = 1;
 | 
					            header_parsed = 1;
 | 
				
			||||||
@@ -889,6 +890,21 @@ static int vobsub_read_seek(AVFormatContext *s, int stream_index,
 | 
				
			|||||||
                            int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
 | 
					                            int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MpegDemuxContext *vobsub = s->priv_data;
 | 
					    MpegDemuxContext *vobsub = s->priv_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Rescale requested timestamps based on the first stream (timebase is the
 | 
				
			||||||
 | 
					     * same for all subtitles stream within a .idx/.sub). Rescaling is done just
 | 
				
			||||||
 | 
					     * like in avformat_seek_file(). */
 | 
				
			||||||
 | 
					    if (stream_index == -1 && s->nb_streams != 1) {
 | 
				
			||||||
 | 
					        AVRational time_base = s->streams[0]->time_base;
 | 
				
			||||||
 | 
					        ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
 | 
				
			||||||
 | 
					        min_ts = av_rescale_rnd(min_ts, time_base.den,
 | 
				
			||||||
 | 
					                                time_base.num * (int64_t)AV_TIME_BASE,
 | 
				
			||||||
 | 
					                                AV_ROUND_UP   | AV_ROUND_PASS_MINMAX);
 | 
				
			||||||
 | 
					        max_ts = av_rescale_rnd(max_ts, time_base.den,
 | 
				
			||||||
 | 
					                                time_base.num * (int64_t)AV_TIME_BASE,
 | 
				
			||||||
 | 
					                                AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ff_subtitles_queue_seek(&vobsub->q, s, stream_index,
 | 
					    return ff_subtitles_queue_seek(&vobsub->q, s, stream_index,
 | 
				
			||||||
                                   min_ts, ts, max_ts, flags);
 | 
					                                   min_ts, ts, max_ts, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,7 +109,8 @@ int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int st
 | 
				
			|||||||
        for (i = 0; i < q->nb_subs; i++) {
 | 
					        for (i = 0; i < q->nb_subs; i++) {
 | 
				
			||||||
            int64_t pts = q->subs[i].pts;
 | 
					            int64_t pts = q->subs[i].pts;
 | 
				
			||||||
            uint64_t ts_diff = FFABS(pts - ts);
 | 
					            uint64_t ts_diff = FFABS(pts - ts);
 | 
				
			||||||
            if (pts >= min_ts && pts <= max_ts && ts_diff < min_ts_diff) {
 | 
					            if ((stream_index == -1 || q->subs[i].stream_index == stream_index) &&
 | 
				
			||||||
 | 
					                pts >= min_ts && pts <= max_ts && ts_diff < min_ts_diff) {
 | 
				
			||||||
                min_ts_diff = ts_diff;
 | 
					                min_ts_diff = ts_diff;
 | 
				
			||||||
                idx = i;
 | 
					                idx = i;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -119,13 +120,24 @@ int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int st
 | 
				
			|||||||
        /* look back in the latest subtitles for overlapping subtitles */
 | 
					        /* look back in the latest subtitles for overlapping subtitles */
 | 
				
			||||||
        ts_selected = q->subs[idx].pts;
 | 
					        ts_selected = q->subs[idx].pts;
 | 
				
			||||||
        for (i = idx - 1; i >= 0; i--) {
 | 
					        for (i = idx - 1; i >= 0; i--) {
 | 
				
			||||||
            if (q->subs[i].duration <= 0)
 | 
					            if (q->subs[i].duration <= 0 ||
 | 
				
			||||||
 | 
					                (stream_index != -1 && q->subs[i].stream_index != stream_index))
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            if (q->subs[i].pts > ts_selected - q->subs[i].duration)
 | 
					            if (q->subs[i].pts > ts_selected - q->subs[i].duration)
 | 
				
			||||||
                idx = i;
 | 
					                idx = i;
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* If the queue is used to store multiple subtitles streams (like with
 | 
				
			||||||
 | 
					         * VobSub) and the stream index is not specified, we need to make sure
 | 
				
			||||||
 | 
					         * to focus on the smallest file position offset for a same timestamp;
 | 
				
			||||||
 | 
					         * queue is ordered by pts and then filepos, so we can take the first
 | 
				
			||||||
 | 
					         * entry for a given timestamp. */
 | 
				
			||||||
 | 
					        if (stream_index == -1)
 | 
				
			||||||
 | 
					            while (idx > 0 && q->subs[idx - 1].pts == q->subs[idx].pts)
 | 
				
			||||||
 | 
					                idx--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        q->current_sub_idx = idx;
 | 
					        q->current_sub_idx = idx;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user