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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-10-25 02:51:44 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-10-25 02:51:44 +0400
commit47463742e264d5bfbf81215ea7d907c4e9a3a1e1 (patch)
treebab7eea6ec1903c5922d3d9dcea9c99a4b1cc42e /source/blender
parent4cd1e6337e516015383f3c47886b180ee16d2e3a (diff)
parent5b6224c84719213883334bcd9d2c46216053fe35 (diff)
Cycles: svn merge -r41232:41266 ^/trunk/blender
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h6
-rw-r--r--source/blender/blenkernel/BKE_library.h1
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/intern/action.c2
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/fcurve.c54
-rw-r--r--source/blender/blenkernel/intern/library.c18
-rw-r--r--source/blender/blenkernel/intern/seqcache.c170
-rw-r--r--source/blender/blenkernel/intern/sequencer.c10
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c31
-rw-r--r--source/blender/blenlib/BLI_math_vector.h2
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c12
-rw-r--r--source/blender/editors/interface/interface_handlers.c26
-rw-r--r--source/blender/editors/space_action/action_edit.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c14
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c22
-rw-r--r--source/blender/imbuf/CMakeLists.txt2
-rw-r--r--source/blender/imbuf/IMB_imbuf.h13
-rw-r--r--source/blender/imbuf/IMB_moviecache.h56
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c56
-rw-r--r--source/blender/imbuf/intern/indexer.c2
-rw-r--r--source/blender/imbuf/intern/module.c1
-rw-r--r--source/blender/imbuf/intern/moviecache.c382
-rw-r--r--source/blender/makesdna/DNA_ID.h8
-rw-r--r--source/blender/makesrna/intern/rna_ID.c8
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c2
-rw-r--r--source/blender/render/intern/source/convertblender.c33
27 files changed, 651 insertions, 286 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index b5e4cde53ca..27e9140ba77 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -213,10 +213,12 @@ struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop,
int binarysearch_bezt_index(struct BezTriple array[], float frame, int arraylen, short *replace);
/* get the time extents for F-Curve */
-void calc_fcurve_range(struct FCurve *fcu, float *min, float *max, const short selOnly);
+void calc_fcurve_range(struct FCurve *fcu, float *min, float *max,
+ const short do_sel_only, const short do_min_length);
/* get the bounding-box extents for F-Curve */
-void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, const short selOnly);
+void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
+ const short do_sel_only);
/* .............. */
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index a44618dcbe8..947eafa9dd3 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -50,6 +50,7 @@ void *copy_libblock(void *rt);
void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action);
void id_lib_extern(struct ID *id);
+void BKE_library_filepath_set(struct Library *lib, const char *filepath);
void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
int id_make_local(struct ID *id, int test);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 759060d408e..e64de965db5 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -215,9 +215,7 @@ typedef enum {
SEQ_STRIPELEM_IBUF_ENDSTILL
} seq_stripelem_ibuf_t;
-void seq_stripelem_cache_init(void);
void seq_stripelem_cache_destruct(void);
-
void seq_stripelem_cache_cleanup(void);
/* returned ImBuf is properly refed and has to be freed */
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 8d18a1c27e7..e46e2df8353 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -881,7 +881,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
/* get extents for this curve */
// TODO: allow enabling/disabling this?
- calc_fcurve_range(fcu, &nmin, &nmax, FALSE);
+ calc_fcurve_range(fcu, &nmin, &nmax, FALSE, TRUE);
/* compare to the running tally */
min= MIN2(min, nmin);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 5e38e06ed0c..4cbdbeb890d 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -61,6 +61,7 @@
#include "BLI_callbacks.h"
#include "IMB_imbuf.h"
+#include "IMB_moviecache.h"
#include "BKE_blender.h"
#include "BKE_context.h"
@@ -111,6 +112,7 @@ void free_blender(void)
BLI_cb_finalize();
seq_stripelem_cache_destruct();
+ IMB_moviecache_destruct();
free_nodesystem();
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 737baa1ddc4..3529b7b9e6d 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -433,7 +433,8 @@ int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short
/* ...................................... */
/* helper for calc_fcurve_* functions -> find first and last BezTriple to be used */
-static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple **last, const short selOnly)
+static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple **last,
+ const short do_sel_only)
{
/* init outputs */
*first = NULL;
@@ -444,7 +445,7 @@ static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple
return;
/* only include selected items? */
- if (selOnly) {
+ if (do_sel_only) {
BezTriple *bezt;
unsigned int i;
@@ -475,11 +476,12 @@ static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple
/* Calculate the extents of F-Curve's data */
-void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, const short selOnly)
+void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
+ const short do_sel_only)
{
float xminv=999999999.0f, xmaxv=-999999999.0f;
float yminv=999999999.0f, ymaxv=-999999999.0f;
- short foundvert=0;
+ short foundvert= FALSE;
unsigned int i;
if (fcu->totvert) {
@@ -488,7 +490,7 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
if (xmin || xmax) {
/* get endpoint keyframes */
- get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
+ get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
if (bezt_first) {
BLI_assert(bezt_last != NULL);
@@ -503,11 +505,12 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
BezTriple *bezt;
for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
- if ((selOnly == 0) || BEZSELECTED(bezt)) {
+ if ((do_sel_only == 0) || BEZSELECTED(bezt)) {
if (bezt->vec[1][1] < yminv)
yminv= bezt->vec[1][1];
if (bezt->vec[1][1] > ymaxv)
ymaxv= bezt->vec[1][1];
+ foundvert= TRUE;
}
}
}
@@ -528,11 +531,11 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
yminv= fpt->vec[1];
if (fpt->vec[1] > ymaxv)
ymaxv= fpt->vec[1];
+
+ foundvert= TRUE;
}
}
}
-
- foundvert=1;
}
if (foundvert) {
@@ -555,43 +558,50 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
}
/* Calculate the extents of F-Curve's keyframes */
-void calc_fcurve_range (FCurve *fcu, float *start, float *end, const short selOnly)
+void calc_fcurve_range (FCurve *fcu, float *start, float *end,
+ const short do_sel_only, const short do_min_length)
{
float min=999999999.0f, max=-999999999.0f;
- short foundvert=0;
+ short foundvert= FALSE;
if (fcu->totvert) {
if (fcu->bezt) {
BezTriple *bezt_first= NULL, *bezt_last= NULL;
/* get endpoint keyframes */
- get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
-
+ get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
+
if (bezt_first) {
BLI_assert(bezt_last != NULL);
-
+
min= MIN2(min, bezt_first->vec[1][0]);
max= MAX2(max, bezt_last->vec[1][0]);
+
+ foundvert= TRUE;
}
}
else if (fcu->fpt) {
min= MIN2(min, fcu->fpt[0].vec[0]);
max= MAX2(max, fcu->fpt[fcu->totvert-1].vec[0]);
+
+ foundvert= TRUE;
}
- foundvert=1;
}
- /* minimum length is 1 frame */
- if (foundvert) {
- if (min == max) max += 1.0f;
- *start= min;
- *end= max;
+ if (foundvert == FALSE) {
+ min= max= 0.0f;
}
- else {
- *start= 0.0f;
- *end= 1.0f;
+
+ if (do_min_length) {
+ /* minimum length is 1 frame */
+ if (min == max) {
+ max += 1.0f;
+ }
}
+
+ *start= min;
+ *end= max;
}
/* ----------------- Status Checks -------------------------- */
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 6cde2511a47..c44ccd7aa57 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1461,3 +1461,21 @@ void name_uiprefix_id(char *name, ID *id)
strcpy(name+3, id->name+2);
}
+
+void BKE_library_filepath_set(Library *lib, const char *filepath)
+{
+ BLI_strncpy(lib->name, filepath, sizeof(lib->name));
+ BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath));
+
+ /* not essential but set filepath is an absolute copy of value which
+ * is more useful if its kept in sync */
+ if (strncmp(lib->filepath, "//", 2) == 0) {
+ /* note that the file may be unsaved, in this case, setting the
+ * filepath on an indirectly linked path is not allowed from the
+ * outliner, and its not really supported but allow from here for now
+ * since making local could cause this to be directly linked - campbell
+ */
+ const char *basepath= lib->parent ? lib->parent->filepath : G.main->name;
+ BLI_path_abs(lib->filepath, basepath);
+ }
+}
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index 31a780aa977..c5761dcc456 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -17,6 +17,8 @@
*
* Peter Schlaile <peter [at] schlaile [dot] de> 2010
*
+ * Contributor(s): Sergey Sharybin
+ *
* ***** END GPL LICENSE BLOCK *****
*/
@@ -26,22 +28,15 @@
#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
+
+#include "BLO_sys_types.h" /* for intptr_t */
#include "MEM_guardedalloc.h"
-#include "MEM_CacheLimiterC-Api.h"
#include "DNA_sequence_types.h"
#include "BKE_sequencer.h"
-#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-#include "BLI_mempool.h"
-#include <pthread.h>
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
+#include "IMB_moviecache.h"
typedef struct seqCacheKey
{
@@ -51,20 +46,9 @@ typedef struct seqCacheKey
seq_stripelem_ibuf_t type;
} seqCacheKey;
-typedef struct seqCacheEntry
-{
- ImBuf * ibuf;
- MEM_CacheLimiterHandleC * c_handle;
-} seqCacheEntry;
-
-static GHash * hash = NULL;
-static MEM_CacheLimiterC * limitor = NULL;
-static struct BLI_mempool * entrypool = NULL;
-static struct BLI_mempool * keypool = NULL;
-static int ibufs_in = 0;
-static int ibufs_rem = 0;
-
-static unsigned int HashHash(const void *key_)
+static struct MovieCache *moviecache = NULL;
+
+static unsigned int seqcache_hashhash(const void *key_)
{
const seqCacheKey *key = (seqCacheKey*) key_;
unsigned int rval = seq_hash_render_data(&key->context);
@@ -76,7 +60,7 @@ static unsigned int HashHash(const void *key_)
return rval;
}
-static int HashCmp(const void *a_, const void *b_)
+static int seqcache_hashcmp(const void *a_, const void *b_)
{
const seqCacheKey * a = (seqCacheKey*) a_;
const seqCacheKey * b = (seqCacheKey*) b_;
@@ -105,109 +89,37 @@ static int HashCmp(const void *a_, const void *b_)
return seq_cmp_render_data(&a->context, &b->context);
}
-static void HashKeyFree(void *key)
-{
- BLI_mempool_free(keypool, key);
-}
-
-static void HashValFree(void *val)
-{
- seqCacheEntry* e = (seqCacheEntry*) val;
-
- if (e->ibuf) {
- /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf,
- e->ibuf->refcounter); */
- IMB_freeImBuf(e->ibuf);
- MEM_CacheLimiter_unmanage(e->c_handle);
- ibufs_rem++;
- }
-
- e->ibuf = NULL;
- e->c_handle = NULL;
-
- BLI_mempool_free(entrypool, e);
-}
-
-static void IMB_seq_cache_destructor(void * p)
-{
- seqCacheEntry* e = (seqCacheEntry*) p;
-
- if (e && e->ibuf) {
- /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf,
- e->ibuf->refcounter); */
- IMB_freeImBuf(e->ibuf);
- ibufs_rem++;
-
- e->ibuf = NULL;
- e->c_handle = NULL;
- }
-}
-
-void seq_stripelem_cache_init(void)
-{
- hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
- limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor );
-
- entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0);
- keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0);
-}
-
void seq_stripelem_cache_destruct(void)
{
- if (!entrypool) {
- return;
- }
- BLI_ghash_free(hash, HashKeyFree, HashValFree);
- delete_MEM_CacheLimiter(limitor);
- BLI_mempool_destroy(entrypool);
- BLI_mempool_destroy(keypool);
+ if(moviecache)
+ IMB_moviecache_free(moviecache);
}
void seq_stripelem_cache_cleanup(void)
{
- if (!entrypool) {
- seq_stripelem_cache_init();
+ if(moviecache) {
+ IMB_moviecache_free(moviecache);
+ moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash,
+ seqcache_hashcmp, NULL);
}
-
- /* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n",
- ibufs_in, ibufs_rem); */
-
- BLI_ghash_free(hash, HashKeyFree, HashValFree);
- hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
-
- /* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n",
- ibufs_in, ibufs_rem); */
-
}
struct ImBuf * seq_stripelem_cache_get(
SeqRenderData context, struct Sequence * seq,
float cfra, seq_stripelem_ibuf_t type)
{
- seqCacheKey key;
- seqCacheEntry * e;
-
- if (!seq) {
- return NULL;
- }
-
- if (!entrypool) {
- seq_stripelem_cache_init();
- }
- key.seq = seq;
- key.context = context;
- key.cfra = cfra - seq->start;
- key.type = type;
-
- e = (seqCacheEntry*) BLI_ghash_lookup(hash, &key);
+ if(moviecache && seq) {
+ seqCacheKey key;
- if (e && e->ibuf) {
- IMB_refImBuf(e->ibuf);
+ key.seq = seq;
+ key.context = context;
+ key.cfra = cfra - seq->start;
+ key.type = type;
- MEM_CacheLimiter_touch(e->c_handle);
- return e->ibuf;
+ return IMB_moviecache_get(moviecache, &key);
}
+
return NULL;
}
@@ -215,39 +127,21 @@ void seq_stripelem_cache_put(
SeqRenderData context, struct Sequence * seq,
float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i)
{
- seqCacheKey * key;
- seqCacheEntry * e;
+ seqCacheKey key;
if (!i) {
return;
}
- ibufs_in++;
-
- if (!entrypool) {
- seq_stripelem_cache_init();
+ if(!moviecache) {
+ moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash,
+ seqcache_hashcmp, NULL);
}
- key = (seqCacheKey*) BLI_mempool_alloc(keypool);
-
- key->seq = seq;
- key->context = context;
- key->cfra = cfra - seq->start;
- key->type = type;
-
- IMB_refImBuf(i);
-
- e = (seqCacheEntry*) BLI_mempool_alloc(entrypool);
-
- e->ibuf = i;
- e->c_handle = NULL;
-
- BLI_ghash_remove(hash, key, HashKeyFree, HashValFree);
- BLI_ghash_insert(hash, key, e);
-
- e->c_handle = MEM_CacheLimiter_insert(limitor, e);
+ key.seq = seq;
+ key.context = context;
+ key.cfra = cfra - seq->start;
+ key.type = type;
- MEM_CacheLimiter_ref(e->c_handle);
- MEM_CacheLimiter_enforce_limits(limitor);
- MEM_CacheLimiter_unref(e->c_handle);
+ IMB_moviecache_put(moviecache, &key, i);
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 5d52874b3b3..6b319e6b5e1 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1324,6 +1324,10 @@ static void seq_proxy_build_frame(SeqRenderData context,
quality = seq->strip->proxy->quality;
ibuf->ftype= JPG | quality;
+ /* unsupported feature only confuses other s/w */
+ if(ibuf->depth==32)
+ ibuf->depth= 24;
+
BLI_make_existing_file(name);
ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
@@ -2501,9 +2505,6 @@ static void *seq_prefetch_thread(void * This_)
for (e = prefetch_done.first; e; e = e->next) {
if (s_last > e->monoton_cfra) {
- if (e->ibuf) {
- IMB_cache_limiter_unref(e->ibuf);
- }
BLI_remlink(&prefetch_done, e);
MEM_freeN(e);
}
@@ -2581,9 +2582,6 @@ static void seq_stop_threads()
}
for (e = prefetch_done.first; e; e = e->next) {
- if (e->ibuf) {
- IMB_cache_limiter_unref(e->ibuf);
- }
BLI_remlink(&prefetch_done, e);
MEM_freeN(e);
}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index ed0a351716c..bdca3c8e618 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -396,6 +396,20 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
}
}
+static int ffmpeg_proprty_valid(AVCodecContext *c, const char *prop_name, IDProperty *curr)
+{
+ int valid= 1;
+
+ if(strcmp(prop_name, "video")==0) {
+ if(strcmp(curr->name, "bf")==0) {
+ /* flash codec doesn't support b frames */
+ valid&= c->codec_id!=CODEC_ID_FLV1;
+ }
+ }
+
+ return valid;
+}
+
static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char * prop_name)
{
IDProperty * prop;
@@ -414,7 +428,8 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
iter = IDP_GetGroupIterator(prop);
while ((curr = IDP_GroupIterNext(iter)) != NULL) {
- set_ffmpeg_property_option(c, curr);
+ if(ffmpeg_proprty_valid(c, prop_name, curr))
+ set_ffmpeg_property_option(c, curr);
}
}
@@ -1187,6 +1202,9 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
{
int isntsc = (rd->frs_sec != 25);
+ if(rd->ffcodecdata.properties)
+ IDP_FreeProperty(rd->ffcodecdata.properties);
+
switch (preset) {
case FFMPEG_PRESET_VCD:
rd->ffcodecdata.type = FFMPEG_MPEG1;
@@ -1217,8 +1235,11 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
case FFMPEG_PRESET_DVD:
rd->ffcodecdata.type = FFMPEG_MPEG2;
rd->ffcodecdata.video_bitrate = 6000;
- rd->xsch = 720;
- rd->ysch = isntsc ? 480 : 576;
+
+ /* Don't set resolution, see [#21351]
+ * rd->xsch = 720;
+ * rd->ysch = isntsc ? 480 : 576; */
+
rd->ffcodecdata.gop_size = isntsc ? 18 : 15;
rd->ffcodecdata.rc_max_rate = 9000;
rd->ffcodecdata.rc_min_rate = 0;
@@ -1321,8 +1342,8 @@ void ffmpeg_verify_image_type(RenderData *rd)
rd->ffcodecdata.video_bitrate <= 1) {
rd->ffcodecdata.codec = CODEC_ID_MPEG2VIDEO;
- /* Don't set preset, disturbs render resolution.
- * ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD); */
+
+ ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD);
}
if(rd->ffcodecdata.type == FFMPEG_OGG) {
rd->ffcodecdata.type = FFMPEG_MPEG2;
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 2bb51870fd6..e259071a27a 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -92,6 +92,8 @@ MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], floa
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f);
+MINLINE void negate_v2(float r[2]);
+MINLINE void negate_v2_v2(float r[2], const float a[2]);
MINLINE void negate_v3(float r[3]);
MINLINE void negate_v3_v3(float r[3], const float a[3]);
MINLINE void negate_v4(float r[4]);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 5f5a0acc427..c460b69679b 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -308,6 +308,18 @@ MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
r[2] = v1[2] * v2[2];
}
+MINLINE void negate_v2(float r[3])
+{
+ r[0]= -r[0];
+ r[1]= -r[1];
+}
+
+MINLINE void negate_v2_v2(float r[2], const float a[2])
+{
+ r[0]= -a[0];
+ r[1]= -a[1];
+}
+
MINLINE void negate_v3(float r[3])
{
r[0]= -r[0];
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 9f77317292c..9d8e2f33f5c 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1437,8 +1437,11 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data,
ui_check_but(but);
}
-/* note: utf8 & ascii funcs should be merged */
-static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const char utf8_buf[6])
+/* this is used for both utf8 and ascii, its meant to be used for single keys,
+ * notie the buffer is either copied or not, so its not suitable for pasting in
+ * - campbell */
+static int ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data,
+ const char *utf8_buf, int utf8_buf_len)
{
char *str;
int len, changed= 0;
@@ -1447,7 +1450,7 @@ static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const cha
len= strlen(str);
if(len-(but->selend - but->selsta)+1 <= data->maxlen) {
- int step= BLI_str_utf8_size(utf8_buf);
+ int step= utf8_buf_len;
/* type over the current selection */
if ((but->selend - but->selsta) > 0) {
@@ -1468,8 +1471,17 @@ static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const cha
static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char ascii)
{
- char utf8_buf[6]= {ascii, '\0'};
- return ui_textedit_type_utf8(but, data, utf8_buf);
+ char buf[2]= {ascii, '\0'};
+
+ if (ui_is_but_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
+ printf("%s: entering invalid ascii char into an ascii key (%d)\n",
+ __func__, (int)(unsigned char)ascii);
+
+ return 0;
+ }
+
+ /* in some cases we want to allow invalid utf8 chars */
+ return ui_textedit_type_buf(but, data, buf, 1);
}
static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, uiButtonJumpType jump)
@@ -1941,9 +1953,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
if(event->utf8_buf[0]) {
/* keep this printf until utf8 is well tested */
- printf("%s: utf8 char '%s'\n", __func__, event->utf8_buf);
+ printf("%s: utf8 char '%.*s'\n", __func__, BLI_str_utf8_size(event->utf8_buf), event->utf8_buf);
// strcpy(event->utf8_buf, "12345");
- changed= ui_textedit_type_utf8(but, data, event->utf8_buf);
+ changed= ui_textedit_type_buf(but, data, event->utf8_buf, BLI_str_utf8_size(event->utf8_buf));
}
else {
changed= ui_textedit_type_ascii(but, data, ascii);
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 7bf0f98b471..eb29dfb2ce1 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -261,7 +261,7 @@ static void get_keyframe_extents (bAnimContext *ac, float *min, float *max, cons
float tmin, tmax;
/* get range and apply necessary scaling before processing */
- calc_fcurve_range(fcu, &tmin, &tmax, onlySel);
+ calc_fcurve_range(fcu, &tmin, &tmax, onlySel, TRUE);
if (adt) {
tmin= BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 10ca482ae0e..608a3c4c0b2 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -310,11 +310,19 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
}
/* Check the library target exists */
if (te->idcode == ID_LI) {
- char expanded[FILE_MAXDIR + FILE_MAXFILE];
- BLI_strncpy(expanded, ((Library *)tselem->id)->name, FILE_MAXDIR + FILE_MAXFILE);
+ Library *lib= (Library *)tselem->id;
+ char expanded[FILE_MAX];
+
+ BLI_strncpy(expanded, lib->name, sizeof(expanded));
+
+ /* even though we already set the name this syncs the absolute
+ * path, this is intentionally not already expanded yet to
+ * avoid copying lib->name to its self. */
+ BKE_library_filepath_set(lib, expanded);
+
BLI_path_abs(expanded, G.main->name);
if (!BLI_exists(expanded)) {
- BKE_report(CTX_wm_reports(C), RPT_ERROR, "This path does not exist, correct this before saving");
+ BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Library path '%s' does not exist, correct this before saving", expanded);
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 5df61619ece..6e26fb15873 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -161,17 +161,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0); /* only without camera view */
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1);
- /* 3D mouse */
- WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
- RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
- RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
- RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT);
- RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
- RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
- RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
-
/* numpad view hotkeys*/
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
@@ -220,6 +209,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+
+ /* 3D mouse */
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
/* 3D mouse align */
kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index 76c69292b0f..6aef9a4254e 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -61,6 +61,7 @@ set(SRC
intern/md5.c
intern/metadata.c
intern/module.c
+ intern/moviecache.c
intern/openimageio.cpp
intern/png.c
intern/readimage.c
@@ -75,6 +76,7 @@ set(SRC
IMB_imbuf.h
IMB_imbuf_types.h
+ IMB_moviecache.h
IMB_thumbs.h
intern/IMB_allocimbuf.h
intern/IMB_anim.h
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index e57130c7c35..5f03ca9ba28 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -137,19 +137,6 @@ struct ImBuf * IMB_makeSingleUser(struct ImBuf *ibuf);
*
* @attention Defined in allocimbuf.c
*/
-void IMB_cache_limiter_insert(struct ImBuf *i);
-void IMB_cache_limiter_unmanage(struct ImBuf *i);
-void IMB_cache_limiter_touch(struct ImBuf *i);
-void IMB_cache_limiter_ref(struct ImBuf *i);
-void IMB_cache_limiter_unref(struct ImBuf *i);
-int IMB_cache_limiter_get_refcount(struct ImBuf *i);
-
-void IMB_free_cache_limiter(void);
-
-/**
- *
- * @attention Defined in allocimbuf.c
- */
struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1);
/**
diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h
new file mode 100644
index 00000000000..309c6ee550e
--- /dev/null
+++ b/source/blender/imbuf/IMB_moviecache.h
@@ -0,0 +1,56 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef IMB_MOVIECACHE_H
+#define IMB_MOVIECACHE_H
+
+/** \file IMB_moviecache.h
+ * \ingroup imbuf
+ * \author Sergey Sharybin
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+/* Cache system for movie data - now supports stoting ImBufs only
+ Supposed to provide unified cache system for movie clips, sequencer and
+ other movie-related areas */
+
+struct ImBuf;
+struct MovieCache;
+
+typedef void (*MovieCacheGetKeyDataFP) (void *userkey, int *framenr, int *proxy, int *render_flags);
+
+void IMB_moviecache_init(void);
+void IMB_moviecache_destruct(void);
+
+struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp, MovieCacheGetKeyDataFP getdatafp);
+void IMB_moviecache_put(struct MovieCache *cache, void *userkey, struct ImBuf *ibuf);
+struct ImBuf* IMB_moviecache_get(struct MovieCache *cache, void *userkey);
+void IMB_moviecache_free(struct MovieCache *cache);
+void IMB_moviecache_get_cache_segments(struct MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r);
+
+#endif
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 077d907dda0..98828c58511 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -164,7 +164,6 @@ void IMB_freeImBuf(ImBuf *ibuf)
IMB_freezbufImBuf(ibuf);
IMB_freezbuffloatImBuf(ibuf);
freeencodedbufferImBuf(ibuf);
- IMB_cache_limiter_unmanage(ibuf);
IMB_metadata_free(ibuf);
MEM_freeN(ibuf);
}
@@ -467,60 +466,7 @@ static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
static MEM_CacheLimiterC *c = NULL;
if(!c)
- c = new_MEM_CacheLimiter(imbuf_cache_destructor);
+ c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
return &c;
}
-
-void IMB_free_cache_limiter(void)
-{
- delete_MEM_CacheLimiter(*get_imbuf_cache_limiter());
- *get_imbuf_cache_limiter() = NULL;
-}
-
-void IMB_cache_limiter_insert(ImBuf *i)
-{
- if(!i->c_handle) {
- i->c_handle = MEM_CacheLimiter_insert(
- *get_imbuf_cache_limiter(), i);
- MEM_CacheLimiter_ref(i->c_handle);
- MEM_CacheLimiter_enforce_limits(
- *get_imbuf_cache_limiter());
- MEM_CacheLimiter_unref(i->c_handle);
- }
-}
-
-void IMB_cache_limiter_unmanage(ImBuf *i)
-{
- if(i->c_handle) {
- MEM_CacheLimiter_unmanage(i->c_handle);
- i->c_handle = NULL;
- }
-}
-
-void IMB_cache_limiter_touch(ImBuf *i)
-{
- if(i->c_handle)
- MEM_CacheLimiter_touch(i->c_handle);
-}
-
-void IMB_cache_limiter_ref(ImBuf *i)
-{
- if(i->c_handle)
- MEM_CacheLimiter_ref(i->c_handle);
-}
-
-void IMB_cache_limiter_unref(ImBuf *i)
-{
- if(i->c_handle)
- MEM_CacheLimiter_unref(i->c_handle);
-}
-
-int IMB_cache_limiter_get_refcount(ImBuf *i)
-{
- if(i->c_handle)
- return MEM_CacheLimiter_get_refcount(i->c_handle);
-
- return 0;
-}
-
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 242d7dcb700..3a94c79f48d 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -452,7 +452,7 @@ static int round_up(int x, int mod)
static struct proxy_output_ctx * alloc_proxy_output_ffmpeg(
struct anim * anim,
AVStream * st, int proxy_size, int width, int height,
- int quality)
+ int UNUSED(quality))
{
struct proxy_output_ctx * rv = MEM_callocN(
sizeof(struct proxy_output_ctx), "alloc_proxy_output");
diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c
index f787a6c777e..55a29333620 100644
--- a/source/blender/imbuf/intern/module.c
+++ b/source/blender/imbuf/intern/module.c
@@ -37,7 +37,6 @@ void IMB_init(void)
void IMB_exit(void)
{
- IMB_free_cache_limiter();
imb_tile_cache_exit();
imb_filetypes_exit();
}
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
new file mode 100644
index 00000000000..7492b6aec44
--- /dev/null
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -0,0 +1,382 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin,
+ * Peter Schlaile
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/moviecache.c
+ * \ingroup bke
+ */
+
+#include <stdlib.h> /* for qsort */
+#include <memory.h>
+
+#include "MEM_guardedalloc.h"
+#include "MEM_CacheLimiterC-Api.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_mempool.h"
+
+#include "IMB_moviecache.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+static MEM_CacheLimiterC *limitor= NULL;
+
+typedef struct MovieCache {
+ GHash *hash;
+ GHashHashFP hashfp;
+ GHashCmpFP cmpfp;
+ MovieCacheGetKeyDataFP getdatafp;
+
+ struct BLI_mempool *keys_pool;
+ struct BLI_mempool *items_pool;
+ struct BLI_mempool *userkeys_pool;
+
+ int keysize;
+ unsigned long curtime;
+
+ int totseg, *points, proxy, render_flags; /* for visual statistics optimization */
+ int pad;
+} MovieCache;
+
+typedef struct MovieCacheKey {
+ MovieCache *cache_owner;
+ void *userkey;
+} MovieCacheKey;
+
+typedef struct MovieCacheItem {
+ MovieCache *cache_owner;
+ ImBuf *ibuf;
+ MEM_CacheLimiterHandleC * c_handle;
+ unsigned long last_access;
+} MovieCacheItem;
+
+static unsigned int moviecache_hashhash(const void *keyv)
+{
+ MovieCacheKey *key= (MovieCacheKey*)keyv;
+
+ return key->cache_owner->hashfp(key->userkey);
+}
+
+static int moviecache_hashcmp(const void *av, const void *bv)
+{
+ const MovieCacheKey *a= (MovieCacheKey*)av;
+ const MovieCacheKey *b= (MovieCacheKey*)bv;
+
+ return a->cache_owner->cmpfp(a->userkey, b->userkey);
+}
+
+static void moviecache_keyfree(void *val)
+{
+ MovieCacheKey *key= (MovieCacheKey*)val;
+
+ BLI_mempool_free(key->cache_owner->keys_pool, key);
+}
+
+static void moviecache_valfree(void *val)
+{
+ MovieCacheItem *item= (MovieCacheItem*)val;
+
+ if (item->ibuf) {
+ MEM_CacheLimiter_unmanage(item->c_handle);
+ IMB_freeImBuf(item->ibuf);
+ }
+
+ BLI_mempool_free(item->cache_owner->items_pool, item);
+}
+
+static void check_unused_keys(MovieCache *cache)
+{
+ GHashIterator *iter;
+
+ iter= BLI_ghashIterator_new(cache->hash);
+ while(!BLI_ghashIterator_isDone(iter)) {
+ MovieCacheKey *key= BLI_ghashIterator_getKey(iter);
+ MovieCacheItem *item= BLI_ghashIterator_getValue(iter);
+
+ BLI_ghashIterator_step(iter);
+
+ if(!item->ibuf)
+ BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
+ }
+
+ BLI_ghashIterator_free(iter);
+}
+
+static int compare_int(const void *av, const void *bv)
+{
+ const int *a= (int *)av;
+ const int *b= (int *)bv;
+ return *a-*b;
+}
+
+static void IMB_moviecache_destructor(void *p)
+{
+ MovieCacheItem *item= (MovieCacheItem *) p;
+
+ if (item && item->ibuf) {
+ IMB_freeImBuf(item->ibuf);
+
+ item->ibuf= NULL;
+ item->c_handle= NULL;
+ }
+}
+
+/* approximate size of ImBuf in memory */
+static intptr_t IMB_get_size_in_memory(ImBuf *ibuf)
+{
+ int a;
+ intptr_t size= 0, channel_size= 0;
+
+ size+= sizeof(ImBuf);
+
+ if(ibuf->rect)
+ channel_size+= sizeof(char);
+
+ if(ibuf->rect_float)
+ channel_size+= sizeof(float);
+
+ size+= channel_size*ibuf->x*ibuf->y*ibuf->channels;
+
+ if(ibuf->miptot) {
+ for(a= 0; a<ibuf->miptot; a++) {
+ if(ibuf->mipmap[a])
+ size+= IMB_get_size_in_memory(ibuf->mipmap[a]);
+ }
+ }
+
+ if(ibuf->tiles) {
+ size+= sizeof(unsigned int)*ibuf->ytiles*ibuf->xtiles;
+ }
+
+ return size;
+}
+
+static intptr_t get_item_size (void *p)
+{
+ intptr_t size= sizeof(MovieCacheItem);
+ MovieCacheItem *item= (MovieCacheItem *) p;
+
+ if(item->ibuf)
+ size+= IMB_get_size_in_memory(item->ibuf);
+
+ return size;
+}
+
+void IMB_moviecache_init(void)
+{
+ limitor= new_MEM_CacheLimiter(IMB_moviecache_destructor, get_item_size);
+}
+
+void IMB_moviecache_destruct(void)
+{
+ if(limitor)
+ delete_MEM_CacheLimiter(limitor);
+}
+
+struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp,
+ MovieCacheGetKeyDataFP getdatafp)
+{
+ MovieCache *cache;
+
+ cache= MEM_callocN(sizeof(MovieCache), "MovieCache");
+ cache->keys_pool= BLI_mempool_create(sizeof(MovieCacheKey), 64, 64, 0);
+ cache->items_pool= BLI_mempool_create(sizeof(MovieCacheItem), 64, 64, 0);
+ cache->userkeys_pool= BLI_mempool_create(keysize, 64, 64, 0);
+ cache->hash= BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
+
+ cache->keysize= keysize;
+ cache->hashfp= hashfp;
+ cache->cmpfp= cmpfp;
+ cache->getdatafp= getdatafp;
+ cache->proxy= -1;
+
+ return cache;
+}
+
+void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf)
+{
+ MovieCacheKey *key;
+ MovieCacheItem *item;
+
+ if(!limitor)
+ IMB_moviecache_init();
+
+ IMB_refImBuf(ibuf);
+
+ key= BLI_mempool_alloc(cache->keys_pool);
+ key->cache_owner= cache;
+ key->userkey= BLI_mempool_alloc(cache->userkeys_pool);;
+ memcpy(key->userkey, userkey, cache->keysize);
+
+ item= BLI_mempool_alloc(cache->items_pool);
+ item->ibuf= ibuf;
+ item->cache_owner= cache;
+ item->last_access= cache->curtime++;
+ item->c_handle= NULL;
+
+ BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
+ BLI_ghash_insert(cache->hash, key, item);
+
+ item->c_handle= MEM_CacheLimiter_insert(limitor, item);
+
+ MEM_CacheLimiter_ref(item->c_handle);
+ MEM_CacheLimiter_enforce_limits(limitor);
+ MEM_CacheLimiter_unref(item->c_handle);
+
+ /* cache limiter can't remove unused keys which points to destoryed values */
+ check_unused_keys(cache);
+
+ if(cache->points) {
+ MEM_freeN(cache->points);
+ cache->points= NULL;
+ }
+}
+
+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) {
+ item->last_access= cache->curtime++;
+
+ if(item->ibuf) {
+ MEM_CacheLimiter_touch(item->c_handle);
+ IMB_refImBuf(item->ibuf);
+
+ return item->ibuf;
+ }
+ }
+
+ return NULL;
+}
+
+void IMB_moviecache_free(MovieCache *cache)
+{
+ BLI_ghash_free(cache->hash, moviecache_keyfree, moviecache_valfree);
+
+ BLI_mempool_destroy(cache->keys_pool);
+ BLI_mempool_destroy(cache->items_pool);
+ BLI_mempool_destroy(cache->userkeys_pool);
+
+ if(cache->points)
+ MEM_freeN(cache->points);
+
+ MEM_freeN(cache);
+}
+
+/* get segments of cached frames. useful for debugging cache policies */
+void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r)
+{
+ *totseg_r= 0;
+ *points_r= NULL;
+
+ if(!cache->getdatafp)
+ return;
+
+ if(cache->proxy!=proxy || cache->render_flags!=render_flags) {
+ if(cache->points)
+ MEM_freeN(cache->points);
+
+ cache->points= NULL;
+ }
+
+ if(cache->points) {
+ *totseg_r= cache->totseg;
+ *points_r= cache->points;
+ } else {
+ int totframe= BLI_ghash_size(cache->hash);
+ int *frames= MEM_callocN(totframe*sizeof(int), "movieclip cache frames");
+ int a, totseg= 0;
+ GHashIterator *iter;
+
+ iter= BLI_ghashIterator_new(cache->hash);
+ a= 0;
+ while(!BLI_ghashIterator_isDone(iter)) {
+ MovieCacheKey *key= BLI_ghashIterator_getKey(iter);
+ MovieCacheItem *item= BLI_ghashIterator_getValue(iter);
+ int framenr, curproxy, curflags;
+
+ if(item->ibuf) {
+ cache->getdatafp(key->userkey, &framenr, &curproxy, &curflags);
+
+ if(curproxy==proxy && curflags==render_flags)
+ frames[a++]= framenr;
+ }
+
+ BLI_ghashIterator_step(iter);
+ }
+
+ BLI_ghashIterator_free(iter);
+
+ qsort(frames, totframe, sizeof(int), compare_int);
+
+ /* count */
+ for(a= 0; a<totframe; a++) {
+ if(a && frames[a]-frames[a-1]!=1)
+ totseg++;
+
+ if(a==totframe-1)
+ totseg++;
+ }
+
+ if(totseg) {
+ int b, *points;
+
+ points= MEM_callocN(2*sizeof(int)*totseg, "movieclip cache segments");
+
+ /* fill */
+ for(a= 0, b= 0; a<totframe; a++) {
+ if(a==0)
+ points[b++]= frames[a];
+
+ if(a && frames[a]-frames[a-1]!=1) {
+ points[b++]= frames[a-1];
+ points[b++]= frames[a];
+ }
+
+ if(a==totframe-1)
+ points[b++]= frames[a];
+ }
+
+ *totseg_r= totseg;
+ *points_r= points;
+
+ cache->totseg= totseg;
+ cache->points= points;
+ cache->proxy= proxy;
+ cache->render_flags= render_flags;
+ }
+
+ MEM_freeN(frames);
+ }
+}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 48ad8a0c017..6f2933d154b 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -116,7 +116,13 @@ typedef struct Library {
ID *idblock;
struct FileData *filedata;
char name[240]; /* path name used for reading, can be relative and edited in the outliner */
- char filepath[240]; /* temp. absolute filepath, only used while reading */
+ char filepath[240]; /* absolute filepath, this is only for convenience,
+ * 'name' is the real path used on file read but in
+ * some cases its useful to access the absolute one,
+ * This is set on file read.
+ * Use BKE_library_filepath_set() rather than
+ * setting 'name' directly and it will be kepk in
+ * sync - campbell */
int tot, pad; /* tot, idblock and filedata are only fo read and write */
struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
} Library;
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 71b34d31e96..ba7d2881ad8 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -326,6 +326,12 @@ int rna_IDMaterials_assign_int(PointerRNA *ptr, int key, const PointerRNA *assig
}
}
+void rna_Library_filepath_set(PointerRNA *ptr, const char *value)
+{
+ Library *lib= (Library*)ptr->data;
+ BKE_library_filepath_set(lib, value);
+}
+
#else
static void rna_def_ID_properties(BlenderRNA *brna)
@@ -531,7 +537,7 @@ static void rna_def_library(BlenderRNA *brna)
prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "File Path", "Path to the library .blend file");
- /* TODO - lib->filename isnt updated, however the outliner also skips this, probably only needed on read. */
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Library_filepath_set");
prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Library");
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 08a71e0cd4f..c651dca4b31 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -621,7 +621,7 @@ static void rna_FKeyframe_points_remove(FCurve *fcu, ReportList *reports, BezTri
static void rna_fcurve_range(FCurve *fcu, float range[2])
{
- calc_fcurve_range(fcu, range, range+1, FALSE);
+ calc_fcurve_range(fcu, range, range+1, FALSE, FALSE);
}
#else
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 369272e0be6..5968a6e64f8 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -3345,9 +3345,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
mul_m4_v3(mat, ver->co);
mul_transposed_m3_v3(imat, ver->n);
normalize_v3(ver->n);
-
- if(!negative_scale)
- negate_v3(ver->n);
+ negate_v3(ver->n);
}
if(orco) {
@@ -3405,10 +3403,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if( mface->mat_nr==a1 ) {
float len;
-
- v1= mface->v1;
+ int reverse_verts = negative_scale!=0 && do_autosmooth==0;
+ int rev_tab[] = {reverse_verts==0 ? 0 : 2, 1, reverse_verts==0 ? 2 : 0, 3};
+ v1= reverse_verts==0 ? mface->v1 : mface->v3;
v2= mface->v2;
- v3= mface->v3;
+ v3= reverse_verts==0 ? mface->v3 : mface->v1;
v4= mface->v4;
flag= mface->flag & ME_SMOOTH;
@@ -3445,36 +3444,40 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataLayer *layer;
MTFace *mtface, *mtf;
MCol *mcol, *mc;
- int index, mtfn= 0, mcn= 0, mtng=0;
+ int index, mtfn= 0, mcn= 0, mtng=0, vindex;
char *name;
+ int nr_verts = v4!=0 ? 4 : 3;
for(index=0; index<dm->faceData.totlayer; index++) {
layer= &dm->faceData.layers[index];
name= layer->name;
if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
+ int t;
mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
mtface= (MTFace*)layer->data;
- *mtf= mtface[a];
+ *mtf= mtface[a]; // copy face info
+ for(vindex=0; vindex<nr_verts; vindex++)
+ for(t=0; t<2; t++)
+ mtf->uv[vindex][t]=mtface[a].uv[rev_tab[vindex]][t];
}
else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
mcol= (MCol*)layer->data;
- memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
+ for(vindex=0; vindex<nr_verts; vindex++)
+ mc[vindex]=mcol[a*4+rev_tab[vindex]];
}
else if(layer->type == CD_TANGENT && mtng < 1)
{
if(need_nmap_tangent!=0)
{
const float * tangent = (const float *) layer->data;
- int t;
- int nr_verts = v4!=0 ? 4 : 3;
float * ftang = RE_vlakren_get_nmap_tangent(obr, vlr, 1);
- for(t=0; t<nr_verts; t++)
+ for(vindex=0; vindex<nr_verts; vindex++)
{
- QUATCOPY(ftang+t*4, tangent+a*16+t*4);
- mul_mat3_m4_v3(mat, ftang+t*4);
- normalize_v3(ftang+t*4);
+ QUATCOPY(ftang+vindex*4, tangent+a*16+rev_tab[vindex]*4);
+ mul_mat3_m4_v3(mat, ftang+vindex*4);
+ normalize_v3(ftang+vindex*4);
}
}
}