예제 #1
0
static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *reports,
                                         const char *name, const char *file, int channel,
                                         int frame_start)
{
	Scene *scene = (Scene *)id;
	Sequence *seq;
	StripAnim *sanim;

	struct anim *an = openanim(file, IB_rect, 0, NULL);

	if (an == NULL) {
		BKE_report(reports, RPT_ERROR, "Sequences.new_movie: unable to open movie file");
		return NULL;
	}

	seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file);

	sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
	BLI_addtail(&seq->anims, sanim);
	sanim->anim = an;

	seq->anim_preseek = IMB_anim_get_preseek(an);
	seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);

	BKE_sequence_calc_disp(scene, seq);

	WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);

	return seq;
}
예제 #2
0
static void movieclip_calc_length(MovieClip *clip)
{
	if (clip->source == MCLIP_SRC_MOVIE) {
		movieclip_open_anim_file(clip);

		if (clip->anim) {
			clip->len = IMB_anim_get_duration(clip->anim, clip->proxy.tc);
		}
	}
	else if (clip->source == MCLIP_SRC_SEQUENCE) {
		unsigned short numlen;
		char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];

		BLI_stringdec(clip->name, head, tail, &numlen);

		if (numlen == 0) {
			/* there's no number group in file name, assume it's single framed sequence */
			clip->len = 1;
		}
		else {
			clip->len = 0;
			for (;;) {
				get_sequence_fname(clip, clip->len + clip->start_frame, name);

				if (BLI_exists(name))
					clip->len++;
				else
					break;
			}
		}
	}
}
예제 #3
0
static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, int framenr, int flag)
{
    ImBuf *ibuf = NULL;
    int tc = get_timecode(clip, flag);
    int proxy = rendersize_to_proxy(user, flag);

    movieclip_open_anim_file(clip);

    if (clip->anim) {
        int dur;
        int fra;

        dur = IMB_anim_get_duration(clip->anim, tc);
        fra = framenr - 1;

        if (fra < 0)
            fra = 0;

        if (fra > (dur - 1))
            fra = dur - 1;

        ibuf = IMB_anim_absolute(clip->anim, fra, tc, proxy);
    }

    return ibuf;
}
예제 #4
0
static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str, size_t len)
{
	size_t ofs = 0;

	str[0] = 0;
	if (ima == NULL)
		return;

	if (ibuf == NULL) {
		ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Can't Load Image"), len - ofs);
	}
	else {
		if (ima->source == IMA_SRC_MOVIE) {
			ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Movie"), len - ofs);
			if (ima->anim)
				ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(" %d frs"),
				                    IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
		}
		else {
			ofs += BLI_strncpy_rlen(str, IFACE_("Image"), len - ofs);
		}

		ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);

		if (ibuf->rect_float) {
			if (ibuf->channels != 4) {
				ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels);
			}
			else if (ibuf->planes == R_IMF_PLANES_RGBA)
				ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs);
			else
				ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs);
		}
		else {
			if (ibuf->planes == R_IMF_PLANES_RGBA)
				ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs);
			else
				ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs);
		}
		if (ibuf->zbuf || ibuf->zbuf_float)
			ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs);

		if (ima->source == IMA_SRC_SEQUENCE) {
			const char *file = BLI_last_slash(ibuf->name);
			if (file == NULL)
				file = ibuf->name;
			else
				file++;
			ofs += BLI_snprintf(str + ofs, len - ofs, ", %s", file);
		}
	}

	/* the frame number, even if we cant */
	if (ima->source == IMA_SRC_SEQUENCE) {
		/* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
		const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0, NULL);
		ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(", Frame: %d"), framenr);
	}
}
예제 #5
0
static int rna_Image_frame_duration_get(PointerRNA *ptr)
{
	Image *im = (Image *)ptr->data;

	if (im->anim)
		return IMB_anim_get_duration(im->anim, IMB_TC_RECORD_RUN);
	return 1;
}
예제 #6
0
/* only this runs inside thread */
static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
{
    ProxyJob *pj = pjv;
    Scene *scene = pj->scene;
    MovieClip *clip = pj->clip;
    struct MovieDistortion *distortion = NULL;
    short size_flag;
    int cfra, sfra = SFRA, efra = EFRA;
    int build_sizes[4], build_count = 0;
    int build_undistort_sizes[4], build_undistort_count = 0;

    size_flag = clip->proxy.build_size_flag;

    build_count = proxy_bitflag_to_array(size_flag, build_sizes, 0);
    build_undistort_count = proxy_bitflag_to_array(size_flag, build_undistort_sizes, 1);

    if (clip->source == MCLIP_SRC_MOVIE) {
        if (pj->index_context)
            IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);

        if (!build_undistort_count) {
            if (*stop)
                pj->stop = 1;

            return;
        }
        else {
            sfra = 1;
            efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
        }
    }

    if (build_undistort_count)
        distortion = BKE_tracking_distortion_new();

    for (cfra = sfra; cfra <= efra; cfra++) {
        if (clip->source != MCLIP_SRC_MOVIE)
            BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, NULL, cfra, build_sizes, build_count, 0);

        BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra,
                                        build_undistort_sizes, build_undistort_count, 1);

        if (*stop || G.afbreek)
            break;

        *do_update = TRUE;
        *progress = ((float) cfra - sfra) / (efra - sfra);
    }

    if (distortion)
        BKE_tracking_distortion_free(distortion);

    if (*stop)
        pj->stop = 1;
}
예제 #7
0
static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v)
{
	Scene *scene = CTX_data_scene(C);
	Image *ima = ima_v;
	ImageUser *iuser = iuser_v;
	
	if (ima->anim) {
		iuser->frames = IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN);
		BKE_image_user_calc_frame(iuser, scene->r.cfra, 0);
	}
}
예제 #8
0
static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
                                   short *stop, short *do_update, float *progress)
{
	int cnt = IMB_anim_get_duration(context->anim, IMB_TC_NONE);
	int i, pos;
	struct anim *anim = context->anim;

	for (pos = 0; pos < cnt; pos++) {
		struct ImBuf *ibuf = IMB_anim_absolute(anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
		struct ImBuf *tmp_ibuf = IMB_dupImBuf(ibuf);
		float next_progress = (float) pos / (float) cnt;

		if (*progress != next_progress) {
			*progress = next_progress;
			*do_update = TRUE;
		}
		
		if (*stop) {
			break;
		}

		IMB_flipy(tmp_ibuf);

		for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
			if (context->proxy_sizes_in_use & proxy_sizes[i]) {
				int x = anim->x * proxy_fac[i];
				int y = anim->y * proxy_fac[i];

				struct ImBuf *s_ibuf = IMB_dupImBuf(tmp_ibuf);

				IMB_scalefastImBuf(s_ibuf, x, y);

				IMB_convert_rgba_to_abgr(s_ibuf);
	
				AVI_write_frame(context->proxy_ctx[i], pos,
				                AVI_FORMAT_RGB32,
				                s_ibuf->rect, x * y * 4);

				/* note that libavi free's the buffer... */
				s_ibuf->rect = NULL;

				IMB_freeImBuf(s_ibuf);
			}
		}

		IMB_freeImBuf(tmp_ibuf);
		IMB_freeImBuf(ibuf);
	}
}
예제 #9
0
/* simple case for movies -- handle frame-by-frame, do threading within single frame */
static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build_count),
                           int *build_undistort_sizes, int build_undistort_count,
                           short *stop, short *do_update, float *progress)
{
	ProxyJob *pj = pjv;
	Scene *scene = pj->scene;
	MovieClip *clip = pj->clip;
	struct MovieDistortion *distortion = NULL;
	int cfra, sfra = SFRA, efra = EFRA;

	if (pj->index_context)
		IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);

	if (!build_undistort_count) {
		if (*stop)
			pj->stop = 1;

		return;
	}
	else {
		sfra = 1;
		efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
	}

	if (build_undistort_count) {
		int threads = BLI_system_thread_count();

		distortion = BKE_tracking_distortion_new();
		BKE_tracking_distortion_set_threads(distortion, threads);
	}

	for (cfra = sfra; cfra <= efra; cfra++) {
		BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra,
		                                build_undistort_sizes, build_undistort_count, 1);

		if (*stop || G.is_break)
			break;

		*do_update = TRUE;
		*progress = ((float) cfra - sfra) / (efra - sfra);
	}

	if (distortion)
		BKE_tracking_distortion_free(distortion);

	if (*stop)
		pj->stop = 1;
}
예제 #10
0
static int rna_Image_frame_duration_get(PointerRNA *ptr)
{
	Image *ima = ptr->id.data;
	int duration = 1;

	if (BKE_image_has_anim(ima)) {
		duration = IMB_anim_get_duration(((ImageAnim *)ima->anims.first)->anim, IMB_TC_RECORD_RUN);
	}
	else {
		/* acquire ensures ima->anim is set, if possible! */
		void *lock;
		ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
		BKE_image_release_ibuf(ima, ibuf, lock);
	}

	return duration;
}
예제 #11
0
static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep, int fontid)
{
	char *mem, filepath[FILE_MAX];
//	short val;
	PlayAnimPict *picture = NULL;
	struct ImBuf *ibuf = NULL;
	char str[32 + FILE_MAX];
	struct anim *anim;

	if (IMB_isanim(first)) {
		/* OCIO_TODO: support different input color space */
		anim = IMB_open_anim(first, IB_rect, 0, NULL);
		if (anim) {
			int pic;
			ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
			if (ibuf) {
				playanim_toscreen(ps, NULL, ibuf, fontid, fstep);
				IMB_freeImBuf(ibuf);
			}

			for (pic = 0; pic < IMB_anim_get_duration(anim, IMB_TC_NONE); pic++) {
				picture = (PlayAnimPict *)MEM_callocN(sizeof(PlayAnimPict), "Pict");
				picture->anim = anim;
				picture->frame = pic;
				picture->IB_flags = IB_rect;
				BLI_snprintf(str, sizeof(str), "%s : %4.d", first, pic + 1);
				picture->name = strdup(str);
				BLI_addtail(&picsbase, picture);
			}
		}
		else {
			printf("couldn't open anim %s\n", first);
		}
	}
	else {
		int count = 0;

		BLI_strncpy(filepath, first, sizeof(filepath));

		pupdate_time();
		ptottime = 1.0;

		/* O_DIRECT
		 *
		 * If set, all reads and writes on the resulting file descriptor will
		 * be performed directly to or from the user program buffer, provided
		 * appropriate size and alignment restrictions are met.  Refer to the
		 * F_SETFL and F_DIOINFO commands in the fcntl(2) manual entry for
		 * information about how to determine the alignment constraints.
		 * O_DIRECT is a Silicon Graphics extension and is only supported on
		 * local EFS and XFS file systems.
		 */

		while (IMB_ispic(filepath) && totframes) {
			size_t size;
			int file;

			file = open(filepath, O_BINARY | O_RDONLY, 0);
			if (file < 0) {
				/* print errno? */
				return;
			}

			picture = (PlayAnimPict *)MEM_callocN(sizeof(PlayAnimPict), "picture");
			if (picture == NULL) {
				printf("Not enough memory for pict struct '%s'\n", filepath);
				close(file);
				return;
			}
			size = BLI_file_descriptor_size(file);

			if (size < 1) {
				close(file);
				MEM_freeN(picture);
				return;
			}

			picture->size = size;
			picture->IB_flags = IB_rect;

			if (fromdisk == FALSE) {
				mem = (char *)MEM_mallocN(size, "build pic list");
				if (mem == NULL) {
					printf("Couldn't get memory\n");
					close(file);
					MEM_freeN(picture);
					return;
				}

				if (read(file, mem, size) != size) {
					printf("Error while reading %s\n", filepath);
					close(file);
					MEM_freeN(picture);
					MEM_freeN(mem);
					return;
				}
			}
			else {
				mem = NULL;
			}

			picture->mem = mem;
			picture->name = strdup(filepath);
			close(file);
			BLI_addtail(&picsbase, picture);
			count++;

			pupdate_time();

			if (ptottime > 1.0) {
				/* OCIO_TODO: support different input color space */
				if (picture->mem) {
					ibuf = IMB_ibImageFromMemory((unsigned char *)picture->mem, picture->size,
					                             picture->IB_flags, NULL, picture->name);
				}
				else {
					ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL);
				}
				if (ibuf) {
					playanim_toscreen(ps, picture, ibuf, fontid, fstep);
					IMB_freeImBuf(ibuf);
				}
				pupdate_time();
				ptottime = 0.0;
			}

			BLI_newname(filepath, +fstep);

#if 0 // XXX25
			while (qtest()) {
				switch (qreadN(&val)) {
					case ESCKEY:
						if (val) return;
						break;
				}
			}
#endif
			totframes--;
		}
	}
	return;
}
예제 #12
0
static void index_rebuild_fallback(struct anim * anim,
                                   IMB_Timecode_Type UNUSED(tcs_in_use),
                                   IMB_Proxy_Size proxy_sizes_in_use,
                                   int quality,
                                   short *stop, short *do_update,
                                   float *progress)
{
    int cnt = IMB_anim_get_duration(anim, IMB_TC_NONE);
    int i, pos;
    AviMovie * proxy_ctx[IMB_PROXY_MAX_SLOT];
    char fname[FILE_MAXDIR+FILE_MAXFILE];
    char fname_tmp[FILE_MAXDIR+FILE_MAXFILE];

    memset(proxy_ctx, 0, sizeof(proxy_ctx));

    /* since timecode indices only work with ffmpeg right now,
       don't know a sensible fallback here...

       so no proxies, no game to play...
    */
    if (proxy_sizes_in_use == IMB_PROXY_NONE) {
        return;
    }

    for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
        if (proxy_sizes_in_use & proxy_sizes[i]) {
            char fname[FILE_MAXDIR+FILE_MAXFILE];

            get_proxy_filename(anim, proxy_sizes[i], fname, TRUE);
            BLI_make_existing_file(fname);

            proxy_ctx[i] = alloc_proxy_output_avi(
                               anim, fname,
                               anim->x * proxy_fac[i],
                               anim->y * proxy_fac[i],
                               quality);
        }
    }

    for (pos = 0; pos < cnt; pos++) {
        struct ImBuf * ibuf = IMB_anim_absolute(
                                  anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
        int next_progress = (int) ((double) pos / (double) cnt);

        if (*progress != next_progress) {
            *progress = next_progress;
            *do_update = 1;
        }

        if (*stop) {
            break;
        }

        IMB_flipy(ibuf);

        for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
            if (proxy_sizes_in_use & proxy_sizes[i]) {
                int x = anim->x * proxy_fac[i];
                int y = anim->y * proxy_fac[i];

                struct ImBuf * s_ibuf = IMB_scalefastImBuf(
                                            ibuf, x, y);

                IMB_convert_rgba_to_abgr(s_ibuf);

                AVI_write_frame (proxy_ctx[i], pos,
                                 AVI_FORMAT_RGB32,
                                 s_ibuf->rect, x * y * 4);

                /* note that libavi free's the buffer... */
                s_ibuf->rect = 0;

                IMB_freeImBuf(s_ibuf);
            }
        }
    }

    for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
        if (proxy_sizes_in_use & proxy_sizes[i]) {
            AVI_close_compress (proxy_ctx[i]);
            MEM_freeN (proxy_ctx[i]);

            get_proxy_filename(anim, proxy_sizes[i],
                               fname_tmp, TRUE);
            get_proxy_filename(anim, proxy_sizes[i],
                               fname, FALSE);

            if (*stop) {
                unlink(fname_tmp);
            } else {
                rename(fname_tmp, fname);
            }
        }
    }
}