Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/movieclip.c')
-rw-r--r--source/blender/blenkernel/intern/movieclip.c125
1 files changed, 112 insertions, 13 deletions
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index fe7c2055aef..5b4dbc66cc2 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -129,6 +129,23 @@ static void movie_clip_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void movie_clip_foreach_cache(ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ MovieClip *movie_clip = (MovieClip *)id;
+ IDCacheKey key = {
+ .id_session_uuid = id->session_uuid,
+ .offset_in_ID = offsetof(MovieClip, cache),
+ .cache_v = movie_clip->cache,
+ };
+ function_callback(id, &key, (void **)&movie_clip->cache, 0, user_data);
+
+ key.offset_in_ID = offsetof(MovieClip, tracking.camera.intrinsics);
+ key.cache_v = movie_clip->tracking.camera.intrinsics;
+ function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, 0, user_data);
+}
+
IDTypeInfo IDType_ID_MC = {
.id_code = ID_MC,
.id_filter = FILTER_ID_MC,
@@ -144,6 +161,7 @@ IDTypeInfo IDType_ID_MC = {
.free_data = movie_clip_free_data,
.make_local = NULL,
.foreach_id = movie_clip_foreach_id,
+ .foreach_cache = movie_clip_foreach_cache,
};
/*********************** movieclip buffer loaders *************************/
@@ -220,19 +238,19 @@ static void get_sequence_fname(const MovieClip *clip, const int framenr, char *n
char head[FILE_MAX], tail[FILE_MAX];
int offset;
- BLI_strncpy(name, clip->name, sizeof(clip->name));
+ BLI_strncpy(name, clip->filepath, sizeof(clip->filepath));
BLI_path_sequence_decode(name, head, tail, &numlen);
/* Movie-clips always points to first image from sequence, auto-guess offset for now.
* Could be something smarter in the future. */
- offset = sequence_guess_offset(clip->name, strlen(head), numlen);
+ offset = sequence_guess_offset(clip->filepath, strlen(head), numlen);
if (numlen) {
BLI_path_sequence_encode(
name, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset);
}
else {
- BLI_strncpy(name, clip->name, sizeof(clip->name));
+ BLI_strncpy(name, clip->filepath, sizeof(clip->filepath));
}
BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
@@ -246,7 +264,7 @@ static void get_proxy_fname(
char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
int proxynr = framenr - clip->start_frame + 1 + clip->frame_offset;
- BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX);
+ BLI_split_dirfile(clip->filepath, clipdir, clipfile, FILE_MAX, FILE_MAX);
if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
BLI_strncpy(dir, clip->proxy.dir, sizeof(dir));
@@ -395,7 +413,7 @@ static void movieclip_open_anim_file(MovieClip *clip)
char str[FILE_MAX];
if (!clip->anim) {
- BLI_strncpy(str, clip->name, FILE_MAX);
+ BLI_strncpy(str, clip->filepath, FILE_MAX);
BLI_path_abs(str, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
/* FIXME: make several stream accessible in image editor, too */
@@ -445,7 +463,7 @@ static void movieclip_calc_length(MovieClip *clip)
unsigned short numlen;
char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
- BLI_path_sequence_decode(clip->name, head, tail, &numlen);
+ BLI_path_sequence_decode(clip->filepath, head, tail, &numlen);
if (numlen == 0) {
/* there's no number group in file name, assume it's single framed sequence */
@@ -531,10 +549,10 @@ static int user_frame_to_cache_frame(MovieClip *clip, int framenr)
unsigned short numlen;
char head[FILE_MAX], tail[FILE_MAX];
- BLI_path_sequence_decode(clip->name, head, tail, &numlen);
+ BLI_path_sequence_decode(clip->filepath, head, tail, &numlen);
/* see comment in get_sequence_fname */
- clip->cache->sequence_offset = sequence_guess_offset(clip->name, strlen(head), numlen);
+ clip->cache->sequence_offset = sequence_guess_offset(clip->filepath, strlen(head), numlen);
}
index += clip->cache->sequence_offset;
@@ -674,7 +692,7 @@ static bool put_imbuf_cache(
clip->cache->sequence_offset = -1;
if (clip->source == MCLIP_SRC_SEQUENCE) {
unsigned short numlen;
- BLI_path_sequence_decode(clip->name, NULL, NULL, &numlen);
+ BLI_path_sequence_decode(clip->filepath, NULL, NULL, &numlen);
clip->cache->is_still_sequence = (numlen == 0);
}
}
@@ -758,7 +776,7 @@ static void detect_clip_source(Main *bmain, MovieClip *clip)
ImBuf *ibuf;
char name[FILE_MAX];
- BLI_strncpy(name, clip->name, sizeof(name));
+ BLI_strncpy(name, clip->filepath, sizeof(name));
BLI_path_abs(name, BKE_main_blendfile_path(bmain));
ibuf = IMB_testiffname(name, IB_rect | IB_multilayer);
@@ -795,7 +813,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
/* create a short library name */
clip = movieclip_alloc(bmain, BLI_path_basename(name));
- BLI_strncpy(clip->name, name, sizeof(clip->name));
+ BLI_strncpy(clip->filepath, name, sizeof(clip->filepath));
detect_clip_source(bmain, clip);
@@ -821,7 +839,7 @@ MovieClip *BKE_movieclip_file_add_exists_ex(Main *bmain, const char *filepath, b
/* first search an identical filepath */
for (clip = bmain->movieclips.first; clip; clip = clip->id.next) {
- BLI_strncpy(strtest, clip->name, sizeof(clip->name));
+ BLI_strncpy(strtest, clip->filepath, sizeof(clip->filepath));
BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &clip->id));
if (BLI_path_cmp(strtest, str) == 0) {
@@ -1739,7 +1757,7 @@ void BKE_movieclip_filename_for_frame(MovieClip *clip, MovieClipUser *user, char
}
}
else {
- BLI_strncpy(name, clip->name, FILE_MAX);
+ BLI_strncpy(name, clip->filepath, FILE_MAX);
BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
}
}
@@ -1848,3 +1866,84 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip
DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
movieclip_selection_sync(clip, (MovieClip *)clip->id.orig_id);
}
+
+/* -------------------------------------------------------------------- */
+/** \name GPU textures
+ * \{ */
+
+static GPUTexture **movieclip_get_gputexture_ptr(MovieClip *clip,
+ MovieClipUser *cuser,
+ eGPUTextureTarget textarget)
+{
+ LISTBASE_FOREACH (MovieClip_RuntimeGPUTexture *, tex, &clip->runtime.gputextures) {
+ if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) {
+ if (tex == NULL) {
+ tex = (MovieClip_RuntimeGPUTexture *)MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture),
+ __func__);
+
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ tex->gputexture[i] = NULL;
+ }
+
+ memcpy(&tex->user, cuser, sizeof(MovieClipUser));
+ BLI_addtail(&clip->runtime.gputextures, tex);
+ }
+
+ return &tex->gputexture[textarget];
+ }
+ }
+ return NULL;
+}
+
+GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser)
+{
+ if (clip == NULL) {
+ return NULL;
+ }
+
+ GPUTexture **tex = movieclip_get_gputexture_ptr(clip, cuser, TEXTARGET_2D);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser);
+ if (ibuf == NULL) {
+ *tex = GPU_texture_create_error(2, false);
+ return *tex;
+ }
+
+ /* This only means RGBA16F instead of RGBA32F. */
+ const bool high_bitdepth = false;
+ const bool store_premultiplied = ibuf->rect_float ? false : true;
+ *tex = IMB_create_gpu_texture(ibuf, high_bitdepth, store_premultiplied);
+
+ /* Do not generate mips for movieclips... too slow. */
+ GPU_texture_mipmap_mode(*tex, false, true);
+
+ IMB_freeImBuf(ibuf);
+
+ return *tex;
+}
+
+void BKE_movieclip_free_gputexture(struct MovieClip *clip)
+{
+ /* number of gpu textures to keep around as cache
+ * We don't want to keep too many GPU textures for
+ * movie clips around, as they can be large.*/
+ const int MOVIECLIP_NUM_GPUTEXTURES = 1;
+
+ while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
+ MovieClip_RuntimeGPUTexture *tex = (MovieClip_RuntimeGPUTexture *)BLI_pophead(
+ &clip->runtime.gputextures);
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ /* free glsl image binding */
+ if (tex->gputexture[i]) {
+ GPU_texture_free(tex->gputexture[i]);
+ tex->gputexture[i] = NULL;
+ }
+ }
+ MEM_freeN(tex);
+ }
+}
+/** \} */ \ No newline at end of file