frm_count = 0;
nudge = AV_NOPTS_VALUE;
seek_pos = curr_pos = 0;
- seeked = 1; eof = 0;
+ seeking = 0; seeked = 1;
+ eof = 0;
reading = writing = 0;
hw_pixfmt = AV_PIX_FMT_NONE;
hw_device_ctx = 0;
}
}
if( pos == curr_pos ) return 0;
+ seeking = -1;
double secs = pos < 0 ? 0. : pos / rate;
AVRational time_base = st->time_base;
int64_t tstmp = time_base.num > 0 ? secs * time_base.den/time_base.num : 0;
return -1;
}
int i = MAX_RETRY + pos - curr_pos;
+ int64_t cache_start = 0;
while( ret>=0 && !flushed && curr_pos<=pos && --i>=0 ) {
ret = read_frame(frame);
- if( ret > 0 ) ++curr_pos;
+ if( ret > 0 ) {
+ if( frame->key_frame && seeking < 0 ) {
+ int use_cache = ffmpeg->get_use_cache();
+ if( use_cache < 0 ) {
+// for reverse read, reload file frame_cache from keyframe to pos
+ ffmpeg->purge_cache();
+ int count = preferences->cache_size /
+ vframe->get_data_size() / 2; // try to burn only 1/2 of cache
+ cache_start = pos - count + 1;
+ seeking = 1;
+ }
+ else
+ seeking = 0;
+ }
+ if( seeking > 0 && curr_pos >= cache_start && curr_pos < pos ) {
+ int vw =vframe->get_w(), vh = vframe->get_h();
+ int vcolor_model = vframe->get_color_model();
+// do not use shm here, puts too much pressure on 32bit systems
+ VFrame *cache_frame = new VFrame(vw, vh, vcolor_model, 0);
+ ret = convert_cmodel(cache_frame, frame);
+ if( ret > 0 )
+ ffmpeg->put_cache_frame(cache_frame, curr_pos);
+ }
+ ++curr_pos;
+ }
}
+ seeking = 0;
if( frame->format == AV_PIX_FMT_NONE || frame->width <= 0 || frame->height <= 0 )
ret = -1;
if( ret >= 0 ) {
return ret;
}
+void FFMPEG::put_cache_frame(VFrame *frame, int64_t position)
+{
+ file_base->file->put_cache_frame(frame, position, 0);
+}
+
+int FFMPEG::get_use_cache()
+{
+ return file_base->file->get_use_cache();
+}
+
+void FFMPEG::purge_cache()
+{
+ file_base->file->purge_cache();
+}
+
FFCodecRemap::FFCodecRemap()
{
old_codec = 0;
fidx = aud->fidx;
nudge = aud->nudge;
st = aud->st;
+ AVDictionaryEntry *tref = av_dict_get(fmt_ctx->metadata, "time_reference", 0, 0);
+ if( tref && aud && aud->sample_rate )
+ return strtod(tref->value, 0) / aud->sample_rate;
break; }
case TRACK_VIDEO: {
codec_type = AVMEDIA_TYPE_VIDEO;