Exemplo n.º 1
0
static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *user, int flag, int postprocess_flag)
{
	MovieClipCache *cache = clip->cache;
	int framenr = user->framenr;
	short proxy = IMB_PROXY_NONE;
	int render_flag = 0;

	if (flag & MCLIP_USE_PROXY) {
		proxy = rendersize_to_proxy(user, flag);
		render_flag = user->render_flag;
	}

	/* no cache or no cached postprocessed image */
	if (!clip->cache || !clip->cache->postprocessed.ibuf)
		return NULL;

	/* postprocessing happened for other frame */
	if (cache->postprocessed.framenr != framenr)
		return NULL;

	/* cached ibuf used different proxy settings */
	if (cache->postprocessed.render_flag != render_flag || cache->postprocessed.proxy != proxy)
		return NULL;

	if (cache->postprocessed.flag != postprocess_flag)
		return NULL;

	if (need_undistortion_postprocess(user)) {
		if (!check_undistortion_cache_flags(clip))
			return NULL;
	}
	else if (cache->postprocessed.undistortion_used)
		return NULL;

	IMB_refImBuf(cache->postprocessed.ibuf);

	return cache->postprocessed.ibuf;
}
Exemplo n.º 2
0
ImBuf *IMB_moviecache_get(MovieCache *cache, void *userkey)
{
	MovieCacheKey key;
	MovieCacheItem *item;

	key.cache_owner = cache;
	key.userkey = userkey;
	item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key);

	if (item) {
		if (item->ibuf) {
			BLI_mutex_lock(&limitor_lock);
			MEM_CacheLimiter_touch(item->c_handle);
			BLI_mutex_unlock(&limitor_lock);

			IMB_refImBuf(item->ibuf);

			return item->ibuf;
		}
	}

	return NULL;
}
Exemplo n.º 3
0
static void put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf,
                                               int flag, int postprocess_flag)
{
	MovieClipCache *cache = clip->cache;
	MovieTrackingCamera *camera = &clip->tracking.camera;

	cache->postprocessed.framenr = user->framenr;
	cache->postprocessed.flag = postprocess_flag;

	if (flag & MCLIP_USE_PROXY) {
		cache->postprocessed.proxy = rendersize_to_proxy(user, flag);
		cache->postprocessed.render_flag = user->render_flag;
	}
	else {
		cache->postprocessed.proxy = IMB_PROXY_NONE;
		cache->postprocessed.render_flag = 0;
	}

	if (need_undistortion_postprocess(user)) {
		cache->postprocessed.distortion_model = camera->distortion_model;
		copy_v2_v2(cache->postprocessed.principal, camera->principal);
		copy_v3_v3(&cache->postprocessed.polynomial_k1, &camera->k1);
		copy_v2_v2(&cache->postprocessed.division_k1, &camera->division_k1);
		cache->postprocessed.undistortion_used = true;
	}
	else {
		cache->postprocessed.undistortion_used = false;
	}

	IMB_refImBuf(ibuf);

	if (cache->postprocessed.ibuf)
		IMB_freeImBuf(cache->postprocessed.ibuf);

	cache->postprocessed.ibuf = ibuf;
}
Exemplo n.º 4
0
static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position,
                               IMB_Timecode_Type tc)
{
	int64_t pts_to_search = 0;
	double frame_rate;
	double pts_time_base;
	long long st_time; 
	struct anim_index *tc_index = 0;
	AVStream *v_st;
	int new_frame_index = 0; /* To quiet gcc barking... */
	int old_frame_index = 0; /* To quiet gcc barking... */

	if (anim == 0) return (0);

	av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: pos=%d\n", position);

	if (tc != IMB_TC_NONE) {
		tc_index = IMB_anim_open_index(anim, tc);
	}

	v_st = anim->pFormatCtx->streams[anim->videoStream];

	frame_rate = av_q2d(v_st->r_frame_rate);

	st_time = anim->pFormatCtx->start_time;
	pts_time_base = av_q2d(v_st->time_base);

	if (tc_index) {
		new_frame_index = IMB_indexer_get_frame_index(
		        tc_index, position);
		old_frame_index = IMB_indexer_get_frame_index(
		        tc_index, anim->curposition);
		pts_to_search = IMB_indexer_get_pts(
		        tc_index, new_frame_index);
	}
	else {
		pts_to_search = (long long) 
		                floor(((double) position) /
		                      pts_time_base / frame_rate + 0.5);

		if (st_time != AV_NOPTS_VALUE) {
			pts_to_search += st_time / pts_time_base / AV_TIME_BASE;
		}
	}

	av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
	       "FETCH: looking for PTS=%lld "
	       "(pts_timebase=%g, frame_rate=%g, st_time=%lld)\n", 
	       (long long int)pts_to_search, pts_time_base, frame_rate, st_time);

	if (anim->last_frame && 
	    anim->last_pts <= pts_to_search && anim->next_pts > pts_to_search)
	{
		av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
		       "FETCH: frame repeat: last: %lld next: %lld\n",
		       (long long int)anim->last_pts, 
		       (long long int)anim->next_pts);
		IMB_refImBuf(anim->last_frame);
		anim->curposition = position;
		return anim->last_frame;
	}
	 
	if (position > anim->curposition + 1 &&
	    anim->preseek &&
	    !tc_index &&
	    position - (anim->curposition + 1) < anim->preseek)
	{
		av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
		       "FETCH: within preseek interval (no index)\n");

		ffmpeg_decode_video_frame_scan(anim, pts_to_search);
	}
	else if (tc_index &&
	         IMB_indexer_can_scan(tc_index, old_frame_index,
	                              new_frame_index))
	{
		av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
		       "FETCH: within preseek interval "
		       "(index tells us)\n");

		ffmpeg_decode_video_frame_scan(anim, pts_to_search);
	}
	else if (position != anim->curposition + 1) {
		long long pos;
		int ret;

		if (tc_index) {
			unsigned long long dts;

			pos = IMB_indexer_get_seek_pos(
			    tc_index, new_frame_index);
			dts = IMB_indexer_get_seek_pos_dts(
			    tc_index, new_frame_index);

			av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
			       "TC INDEX seek pos = %lld\n", pos);
			av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
			       "TC INDEX seek dts = %lld\n", dts);

			if (ffmpeg_seek_by_byte(anim->pFormatCtx)) {
				av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
				       "... using BYTE pos\n");

				ret = av_seek_frame(anim->pFormatCtx, 
				                    -1,
				                    pos, AVSEEK_FLAG_BYTE);
				av_update_cur_dts(anim->pFormatCtx, v_st, dts);
			}
			else {
				av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
				       "... using DTS pos\n");
				ret = av_seek_frame(anim->pFormatCtx, 
				                    anim->videoStream,
				                    dts, AVSEEK_FLAG_BACKWARD);
			}
		}
		else {
			pos = (long long) (position - anim->preseek) *
			      AV_TIME_BASE / frame_rate;

			av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
			       "NO INDEX seek pos = %lld, st_time = %lld\n", 
			       pos, (st_time != AV_NOPTS_VALUE) ? st_time : 0);

			if (pos < 0) {
				pos = 0;
			}
		
			if (st_time != AV_NOPTS_VALUE) {
				pos += st_time;
			}

			av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
			       "NO INDEX final seek pos = %lld\n", pos);

			ret = av_seek_frame(anim->pFormatCtx, -1, 
			                    pos, AVSEEK_FLAG_BACKWARD);
		}

		if (ret < 0) {
			av_log(anim->pFormatCtx, AV_LOG_ERROR,
			       "FETCH: "
			       "error while seeking to DTS = %lld "
			       "(frameno = %d, PTS = %lld): errcode = %d\n",
			       pos, position, (long long int)pts_to_search, ret);
		}

		avcodec_flush_buffers(anim->pCodecCtx);

		anim->next_pts = -1;

		if (anim->next_packet.stream_index == anim->videoStream) {
			av_free_packet(&anim->next_packet);
			anim->next_packet.stream_index = -1;
		}

		/* memset(anim->pFrame, ...) ?? */

		if (ret >= 0) {
			ffmpeg_decode_video_frame_scan(anim, pts_to_search);
		}
	}
	else if (position == 0 && anim->curposition == -1) {
		/* first frame without seeking special case... */
		ffmpeg_decode_video_frame(anim);
	}
	else {
		av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
		       "FETCH: no seek necessary, just continue...\n");
	}

	IMB_freeImBuf(anim->last_frame);
	anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
	anim->last_frame->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);

	ffmpeg_postprocess(anim);

	anim->last_pts = anim->next_pts;
	
	ffmpeg_decode_video_frame(anim);
	
	anim->curposition = position;
	
	IMB_refImBuf(anim->last_frame);

	return anim->last_frame;
}