37 # include <libavutil/imgutils.h>
44 static const float proxy_fac[] = {0.25, 0.50, 0.75, 1.00};
47 static int tc_types[] = {
55 #define INDEX_FILE_VERSION 2
66 fprintf(stderr,
"Starting work on index: %s\n", name);
79 "Couldn't open index target: %s! "
80 "Index build broken!\n",
102 fwrite(&frameno,
sizeof(
int), 1, fp->
fp);
103 fwrite(&seek_pos,
sizeof(
uint64_t), 1, fp->
fp);
104 fwrite(&seek_pos_pts,
sizeof(
uint64_t), 1, fp->
fp);
105 fwrite(&seek_pos_dts,
sizeof(
uint64_t), 1, fp->
fp);
121 e.seek_pos = seek_pos;
122 e.seek_pos_pts = seek_pos_pts;
123 e.seek_pos_dts = seek_pos_dts;
163 if (fread(header, 12, 1, fp) != 1) {
164 fprintf(stderr,
"Couldn't read indexer file: %s\n",
name);
172 fprintf(stderr,
"Error reading %s: Binary file type string mismatch\n",
name);
178 fprintf(stderr,
"Error reading %s: File version mismatch\n",
name);
187 fseek(fp, 0, SEEK_END);
189 idx->
num_entries = (ftell(fp) - 12) / (
sizeof(
int) +
196 fseek(fp, 12, SEEK_SET);
199 "anim_index_entries");
201 size_t items_read = 0;
203 items_read += fread(&idx->
entries[i].
frameno,
sizeof(
int), 1, fp);
211 fprintf(stderr,
"Error: Element data size mismatch in: %s\n",
name);
237 if (frame_index <= 0) {
248 if (frame_index < 0) {
259 if (frame_index < 0) {
302 if (frame_index < 0) {
325 old_frame_index < new_frame_index);
406 char proxy_name[256];
407 char stream_suffix[20];
408 const char *
name = (temp) ?
"proxy_%d%s_part.avi" :
"proxy_%d%s.avi";
410 stream_suffix[0] = 0;
440 const char *index_names[] = {
441 "record_run%s%s.blen_tc",
442 "free_run%s%s.blen_tc",
443 "interp_free_run%s%s.blen_tc",
444 "record_run_no_gaps%s%s.blen_tc",
447 char stream_suffix[20];
448 char index_name[256];
450 stream_suffix[0] = 0;
477 struct proxy_output_ctx {
481 const AVCodec *codec;
482 struct SwsContext *sws_ctx;
490 static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
493 struct proxy_output_ctx *rv =
MEM_callocN(
sizeof(
struct proxy_output_ctx),
"alloc_proxy_output");
497 rv->proxy_size = proxy_size;
503 rv->of = avformat_alloc_context();
504 rv->of->oformat = av_guess_format(
"avi",
NULL,
NULL);
506 rv->of->url = av_strdup(filepath);
508 fprintf(stderr,
"Starting work on proxy: %s\n", rv->of->url);
510 rv->st = avformat_new_stream(rv->of,
NULL);
513 rv->codec = avcodec_find_encoder(AV_CODEC_ID_H264);
515 rv->c = avcodec_alloc_context3(rv->codec);
519 "No ffmpeg encoder available? "
520 "Proxy not built!\n");
521 avcodec_free_context(&rv->c);
522 avformat_free_context(rv->of);
527 rv->c->width =
width;
529 rv->c->gop_size = 10;
530 rv->c->max_b_frames = 0;
532 if (rv->codec->pix_fmts) {
533 rv->c->pix_fmt = rv->codec->pix_fmts[0];
536 rv->c->pix_fmt = AV_PIX_FMT_YUVJ420P;
539 rv->c->sample_aspect_ratio = rv->st->sample_aspect_ratio =
st->sample_aspect_ratio;
541 rv->c->time_base.den = 25;
542 rv->c->time_base.num = 1;
543 rv->st->time_base = rv->c->time_base;
547 const int crf_range_min = 32;
548 const int crf_range_max = 17;
549 int crf =
round_fl_to_int((quality / 100.0f) * (crf_range_max - crf_range_min) + crf_range_min);
551 AVDictionary *codec_opts =
NULL;
553 av_dict_set_int(&codec_opts,
"crf", crf, 0);
557 av_dict_set(&codec_opts,
"preset",
"veryfast", 0);
558 av_dict_set(&codec_opts,
"tune",
"fastdecode", 0);
560 if (rv->codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
561 rv->c->thread_count = 0;
567 if (rv->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
568 rv->c->thread_type = FF_THREAD_FRAME;
570 else if (rv->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
571 rv->c->thread_type = FF_THREAD_SLICE;
574 if (rv->of->flags & AVFMT_GLOBALHEADER) {
575 rv->c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
578 avcodec_parameters_from_context(rv->st->codecpar, rv->c);
580 int ret = avio_open(&rv->of->pb, filepath, AVIO_FLAG_WRITE);
584 "Couldn't open IO: %s\n"
585 "Proxy not built!\n",
587 avcodec_free_context(&rv->c);
588 avformat_free_context(rv->of);
593 ret = avcodec_open2(rv->c, rv->codec, &codec_opts);
596 "Couldn't open codec: %s\n"
597 "Proxy not built!\n",
599 avcodec_free_context(&rv->c);
600 avformat_free_context(rv->of);
605 rv->orig_height =
st->codecpar->height;
608 st->codecpar->format != rv->c->pix_fmt) {
609 rv->frame = av_frame_alloc();
611 av_image_fill_arrays(rv->frame->data,
614 "alloc proxy output frame"),
620 rv->frame->format = rv->c->pix_fmt;
621 rv->frame->width =
width;
622 rv->frame->height =
height;
624 rv->sws_ctx = sws_getContext(
st->codecpar->width,
626 st->codecpar->format,
630 SWS_FAST_BILINEAR | SWS_PRINT_INFO,
636 ret = avformat_write_header(rv->of,
NULL);
639 "Couldn't write header: %s\n"
640 "Proxy not built!\n",
644 av_frame_free(&rv->frame);
647 avcodec_free_context(&rv->c);
648 avformat_free_context(rv->of);
656 static void add_to_proxy_output_ffmpeg(
struct proxy_output_ctx *ctx, AVFrame *frame)
662 if (ctx->sws_ctx && frame &&
663 (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3])) {
664 sws_scale(ctx->sws_ctx,
665 (
const uint8_t *
const *)frame->data,
670 ctx->frame->linesize);
673 frame = ctx->sws_ctx ? (frame ? ctx->frame : 0) : frame;
676 frame->pts = ctx->cfra++;
679 int ret = avcodec_send_frame(ctx->c, frame);
682 fprintf(stderr,
"Can't send video frame: %s\n", av_err2str(
ret));
685 AVPacket *packet = av_packet_alloc();
688 ret = avcodec_receive_packet(ctx->c, packet);
690 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
696 "Error encoding proxy frame %d for '%s': %s\n",
703 packet->stream_index = ctx->st->index;
704 av_packet_rescale_ts(packet, ctx->c->time_base, ctx->st->time_base);
705 # ifdef FFMPEG_USE_DURATION_WORKAROUND
709 int write_ret = av_interleaved_write_frame(ctx->of, packet);
710 if (write_ret != 0) {
712 "Error writing proxy frame %d "
716 av_err2str(write_ret));
721 av_packet_free(&packet);
724 static void free_proxy_output_ffmpeg(
struct proxy_output_ctx *ctx,
int rollback)
735 add_to_proxy_output_ffmpeg(ctx,
NULL);
738 avcodec_flush_buffers(ctx->c);
740 av_write_trailer(ctx->of);
742 avcodec_free_context(&ctx->c);
744 if (ctx->of->oformat) {
745 if (!(ctx->of->oformat->flags & AVFMT_NOFILE)) {
746 avio_close(ctx->of->pb);
749 avformat_free_context(ctx->of);
752 sws_freeContext(ctx->sws_ctx);
761 unlink(filepath_tmp);
772 typedef struct FFmpegIndexBuilderContext {
775 AVFormatContext *iFormatCtx;
776 AVCodecContext *iCodecCtx;
777 const AVCodec *iCodec;
798 double pts_time_base;
799 int frameno, frameno_gapless;
802 bool build_only_on_bad_performance;
803 bool building_cancelled;
804 } FFmpegIndexBuilderContext;
810 bool build_only_on_bad_performance)
813 "FFmpeg index builder context");
818 context->tcs_in_use = tcs_in_use;
819 context->proxy_sizes_in_use = proxy_sizes_in_use;
822 context->build_only_on_bad_performance = build_only_on_bad_performance;
832 if (avformat_find_stream_info(
context->iFormatCtx,
NULL) < 0) {
833 avformat_close_input(&
context->iFormatCtx);
842 for (i = 0; i <
context->iFormatCtx->nb_streams; i++) {
843 if (
context->iFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
844 if (streamcount > 0) {
853 if (
context->videoStream == -1) {
854 avformat_close_input(&
context->iFormatCtx);
861 context->iCodec = avcodec_find_decoder(
context->iStream->codecpar->codec_id);
864 avformat_close_input(&
context->iFormatCtx);
870 avcodec_parameters_to_context(
context->iCodecCtx,
context->iStream->codecpar);
871 context->iCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
873 if (
context->iCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
874 context->iCodecCtx->thread_count = 0;
880 if (
context->iCodec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
881 context->iCodecCtx->thread_type = FF_THREAD_FRAME;
883 else if (
context->iCodec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
884 context->iCodecCtx->thread_type = FF_THREAD_SLICE;
888 avformat_close_input(&
context->iFormatCtx);
889 avcodec_free_context(&
context->iCodecCtx);
894 for (i = 0; i < num_proxy_sizes; i++) {
896 context->proxy_ctx[i] = alloc_proxy_output_ffmpeg(
anim,
908 for (i = 0; i < num_indexers; i++) {
909 if (tcs_in_use & tc_types[i]) {
916 tcs_in_use &= ~tc_types[i];
924 static void index_rebuild_ffmpeg_finish(FFmpegIndexBuilderContext *
context,
int stop)
928 const bool do_rollback = stop ||
context->building_cancelled;
930 for (i = 0; i <
context->num_indexers; i++) {
931 if (
context->tcs_in_use & tc_types[i]) {
936 for (i = 0; i <
context->num_proxy_sizes; i++) {
938 free_proxy_output_ffmpeg(
context->proxy_ctx[i], do_rollback);
942 avcodec_free_context(&
context->iCodecCtx);
943 avformat_close_input(&
context->iFormatCtx);
948 static void index_rebuild_ffmpeg_proc_decoded_frame(FFmpegIndexBuilderContext *
context,
949 AVPacket *curr_packet,
958 for (i = 0; i <
context->num_proxy_sizes; i++) {
959 add_to_proxy_output_ffmpeg(
context->proxy_ctx[i], in_frame);
972 if (pts < seek_pos_pts) {
977 s_pos =
context->last_seek_pos;
978 s_pts =
context->last_seek_pos_pts;
979 s_dts =
context->last_seek_pos_dts;
982 for (i = 0; i <
context->num_indexers; i++) {
983 if (
context->tcs_in_use & tc_types[i]) {
984 int tc_frameno =
context->frameno;
987 tc_frameno =
context->frameno_gapless;
1004 static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *
context,
1009 AVFrame *in_frame = av_frame_alloc();
1010 AVPacket *next_packet = av_packet_alloc();
1013 stream_size = avio_size(
context->iFormatCtx->pb);
1018 while (av_read_frame(
context->iFormatCtx, next_packet) >= 0) {
1019 float next_progress =
1020 (
float)((
int)
floor(((
double)next_packet->pos) * 100 / ((
double)stream_size) + 0.5)) / 100;
1022 if (*progress != next_progress) {
1023 *progress = next_progress;
1031 if (next_packet->stream_index ==
context->videoStream) {
1032 if (next_packet->flags & AV_PKT_FLAG_KEY) {
1037 context->seek_pos = next_packet->pos;
1038 context->seek_pos_pts = next_packet->pts;
1039 context->seek_pos_dts = next_packet->dts;
1042 int ret = avcodec_send_packet(
context->iCodecCtx, next_packet);
1044 ret = avcodec_receive_frame(
context->iCodecCtx, in_frame);
1046 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
1051 fprintf(stderr,
"Error decoding proxy frame: %s\n", av_err2str(
ret));
1054 index_rebuild_ffmpeg_proc_decoded_frame(
context, next_packet, in_frame);
1057 av_packet_unref(next_packet);
1069 ret = avcodec_receive_frame(
context->iCodecCtx, in_frame);
1071 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
1076 fprintf(stderr,
"Error flushing proxy frame: %s\n", av_err2str(
ret));
1079 index_rebuild_ffmpeg_proc_decoded_frame(
context, next_packet, in_frame);
1083 av_packet_free(&next_packet);
1090 static int indexer_performance_get_decode_rate(FFmpegIndexBuilderContext *
context,
1091 const double time_period)
1093 AVFrame *in_frame = av_frame_alloc();
1094 AVPacket *packet = av_packet_alloc();
1097 int frames_decoded = 0;
1099 while (av_read_frame(
context->iFormatCtx, packet) >= 0) {
1100 if (packet->stream_index !=
context->videoStream) {
1101 av_packet_unref(packet);
1105 int ret = avcodec_send_packet(
context->iCodecCtx, packet);
1107 ret = avcodec_receive_frame(
context->iCodecCtx, in_frame);
1109 if (
ret == AVERROR(EAGAIN) ||
ret == AVERROR_EOF) {
1114 fprintf(stderr,
"Error decoding proxy frame: %s\n", av_err2str(
ret));
1122 if (end > start + time_period) {
1125 av_packet_unref(packet);
1128 av_packet_free(&packet);
1129 av_frame_free(&in_frame);
1131 avcodec_flush_buffers(
context->iCodecCtx);
1132 av_seek_frame(
context->iFormatCtx, -1, 0, AVSEEK_FLAG_BACKWARD);
1133 return frames_decoded;
1139 static int indexer_performance_get_max_gop_size(FFmpegIndexBuilderContext *
context)
1141 AVPacket *packet = av_packet_alloc();
1143 const int packets_max = 10000;
1144 int packet_index = 0;
1148 while (av_read_frame(
context->iFormatCtx, packet) >= 0) {
1149 if (packet->stream_index !=
context->videoStream) {
1150 av_packet_unref(packet);
1156 if (packet->flags & AV_PKT_FLAG_KEY) {
1157 max_gop =
max_ii(max_gop, cur_gop);
1161 if (packet_index > packets_max) {
1164 av_packet_unref(packet);
1167 av_packet_free(&packet);
1169 av_seek_frame(
context->iFormatCtx, -1, 0, AVSEEK_FLAG_BACKWARD);
1180 static bool indexer_need_to_build_proxy(FFmpegIndexBuilderContext *
context)
1182 if (!
context->build_only_on_bad_performance) {
1187 indexer_performance_get_decode_rate(
context, 0.1);
1190 const int decode_rate = indexer_performance_get_decode_rate(
context, 0.1);
1191 const int max_gop_size = indexer_performance_get_max_gop_size(
context);
1193 if (max_gop_size <= 10 || max_gop_size < decode_rate) {
1194 printf(
"Skipping proxy building for %s: Decoding performance is already good.\n",
1196 context->building_cancelled =
true;
1210 typedef struct FallbackIndexBuilderContext {
1216 } FallbackIndexBuilderContext;
1218 static AviMovie *alloc_proxy_output_avi(
1261 FallbackIndexBuilderContext *
context;
1273 context =
MEM_callocN(
sizeof(FallbackIndexBuilderContext),
"fallback index builder context");
1276 context->proxy_sizes_in_use = proxy_sizes_in_use;
1287 context->proxy_ctx[i] = alloc_proxy_output_avi(
1295 static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *
context,
int stop)
1311 unlink(filepath_tmp);
1315 rename(filepath_tmp, filepath);
1321 static void index_rebuild_fallback(FallbackIndexBuilderContext *
context,
1335 if (*progress != next_progress) {
1336 *progress = next_progress;
1381 const bool overwrite,
1383 bool build_only_on_bad_performance)
1393 if (proxy_size & proxy_sizes_to_build) {
1398 void **filename_key_p;
1403 proxy_sizes_to_build &= ~proxy_size;
1404 printf(
"Proxy: %s already registered for generation, skipping\n", filename);
1412 if (built_proxies != 0) {
1416 if (proxy_size & built_proxies) {
1421 printf(
"Skipping proxy: %s\n", filename);
1425 proxy_sizes_to_build &= ~built_proxies;
1430 if (proxy_sizes_to_build == 0) {
1437 context = index_ffmpeg_create_context(
1438 anim, tcs_in_use, proxy_sizes_to_build, quality, build_only_on_bad_performance);
1446 context = index_fallback_create_context(
anim, tcs_in_use, proxy_sizes_to_build, quality);
1457 UNUSED_VARS(tcs_in_use, proxy_sizes_in_use, quality);
1471 if (indexer_need_to_build_proxy((FFmpegIndexBuilderContext *)
context)) {
1472 index_rebuild_ffmpeg((FFmpegIndexBuilderContext *)
context, stop, do_update, progress);
1478 index_rebuild_fallback((FallbackIndexBuilderContext *)
context, stop, do_update, progress);
1491 index_rebuild_ffmpeg_finish((FFmpegIndexBuilderContext *)
context, stop);
1496 index_rebuild_fallback_finish((FallbackIndexBuilderContext *)
context, stop);
1606 for (i = 0; i < num_proxy_sizes; i++) {
1611 existing |= proxy_size;
AviError AVI_open_compress(char *name, AviMovie *movie, int streams,...)
AviError AVI_close_compress(AviMovie *movie)
#define AVI_OPTION_TYPE_MAIN
AviError AVI_write_frame(AviMovie *movie, int frame_num,...)
AviError AVI_set_compress_option(AviMovie *movie, int option_type, int stream, AviOption option, void *opt_data)
typedef float(TangentPoint)[2]
#define BLI_assert_msg(a, msg)
BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) ATTR_NONNULL(1)
BLI_INLINE void BLI_endian_switch_int32(int *val) ATTR_NONNULL(1)
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_rename(const char *from, const char *to) ATTR_NONNULL()
bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key)
MINLINE int round_fl_to_int(float a)
MINLINE int max_ii(int a, int b)
bool BLI_make_existing_file(const char *name)
void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen)
void BLI_path_append(char *__restrict dst, size_t maxlen, const char *__restrict file) ATTR_NONNULL()
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
int BLI_system_thread_count(void)
Compatibility-like things for windows.
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base)
struct ImBuf * IMB_dupImBuf(const struct ImBuf *ibuf1)
void IMB_close_anim(struct anim *anim)
struct anim * IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE])
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
struct ImBuf * IMB_anim_absolute(struct anim *anim, int position, IMB_Timecode_Type tc, IMB_Proxy_Size preview_size)
bool IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc)
void IMB_flipy(struct ImBuf *ibuf)
@ IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN
@ IMB_TC_RECORD_RUN_NO_GAPS
Read Guarded memory(de)allocation.
Platform independent time functions.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
FFMPEG_INLINE int64_t timestamp_from_pts_or_dts(int64_t pts, int64_t dts)
FFMPEG_INLINE int64_t av_get_pts_from_frame(AVFrame *picture)
FFMPEG_INLINE void my_guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
anim_index_builder * IMB_index_builder_create(const char *name)
void IMB_index_builder_proc_frame(anim_index_builder *fp, uchar *buffer, int data_size, int frameno, uint64_t seek_pos, uint64_t seek_pos_pts, uint64_t seek_pos_dts, uint64_t pts)
void IMB_anim_index_rebuild(struct IndexBuildContext *context, short *stop, short *do_update, float *progress)
static const char temp_ext[]
uint64_t IMB_indexer_get_seek_pos(struct anim_index *idx, int frame_index)
#define INDEX_FILE_VERSION
void IMB_anim_set_index_dir(struct anim *anim, const char *dir)
uint64_t IMB_indexer_get_seek_pos_pts(struct anim_index *idx, int frame_index)
int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc, int position)
int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
IndexBuildContext * IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecode_Type tcs_in_use, IMB_Proxy_Size proxy_sizes_in_use, int quality, const bool overwrite, GSet *file_list, bool build_only_on_bad_performance)
static const char binary_header_str[]
static bool get_proxy_filepath(struct anim *anim, IMB_Proxy_Size preview_size, char *filepath, bool temp)
struct anim_index * IMB_anim_open_index(struct anim *anim, IMB_Timecode_Type tc)
void IMB_index_builder_finish(anim_index_builder *fp, int rollback)
void IMB_indexer_close(struct anim_index *idx)
void IMB_index_builder_add_entry(anim_index_builder *fp, int frameno, uint64_t seek_pos, uint64_t seek_pos_pts, uint64_t seek_pos_dts, uint64_t pts)
uint64_t IMB_indexer_get_seek_pos_dts(struct anim_index *idx, int frame_index)
static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_len)
IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim)
void IMB_free_indices(struct anim *anim)
static const float proxy_fac[]
static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc, char *filepath)
int IMB_indexer_get_duration(struct anim_index *idx)
struct anim * IMB_anim_open_proxy(struct anim *anim, IMB_Proxy_Size preview_size)
int IMB_indexer_can_scan(struct anim_index *idx, int old_frame_index, int new_frame_index)
uint64_t IMB_indexer_get_pts(struct anim_index *idx, int frame_index)
static const int proxy_sizes[]
struct anim_index * IMB_indexer_open(const char *name)
int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size)
int IMB_indexer_get_frame_index(struct anim_index *idx, int frameno)
struct IndexBuildContext IndexBuildContext
void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop)
void IMB_anim_get_fname(struct anim *anim, char *file, int size)
ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
unsigned __int64 uint64_t
void(* proc_frame)(struct anim_index_builder *idx, unsigned char *buffer, int data_size, struct anim_index_entry *entry)
void(* delete_priv_data)(struct anim_index_builder *idx)
struct anim_index_entry * entries
struct anim_index * curr_idx[IMB_TC_MAX_SLOT]
struct anim * proxy_anim[IMB_PROXY_MAX_SLOT]
double PIL_check_seconds_timer(void)