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; }
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; } } } }
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; }
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); } }
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; }
/* 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; }
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); } }
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); } }
/* 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; }
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; }
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; }
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); } } } }