Fix T67008: Missing move handle and flickering in FileBrowser
[blender.git] / source / blender / imbuf / intern / indexer.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Peter Schlaile <peter [at] schlaile [dot] de> 2011
17  */
18
19 /** \file
20  * \ingroup imbuf
21  */
22
23 #include <stdlib.h>
24
25 #include "MEM_guardedalloc.h"
26
27 #include "BLI_utildefines.h"
28 #include "BLI_endian_switch.h"
29 #include "BLI_path_util.h"
30 #include "BLI_string.h"
31 #include "BLI_fileops.h"
32 #include "BLI_ghash.h"
33
34 #include "IMB_indexer.h"
35 #include "IMB_anim.h"
36 #include "imbuf.h"
37
38 #include "BKE_global.h"
39
40 #ifdef WITH_AVI
41 #  include "AVI_avi.h"
42 #endif
43
44 #ifdef WITH_FFMPEG
45 #  include "ffmpeg_compat.h"
46 #endif
47
48 static const char magic[] = "BlenMIdx";
49 static const char temp_ext[] = "_part";
50
51 static const int proxy_sizes[] = {IMB_PROXY_25, IMB_PROXY_50, IMB_PROXY_75, IMB_PROXY_100};
52 static const float proxy_fac[] = {0.25, 0.50, 0.75, 1.00};
53
54 #ifdef WITH_FFMPEG
55 static int tc_types[] = {
56     IMB_TC_RECORD_RUN,
57     IMB_TC_FREE_RUN,
58     IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN,
59     IMB_TC_RECORD_RUN_NO_GAPS,
60 };
61 #endif
62
63 #define INDEX_FILE_VERSION 1
64
65 /* ----------------------------------------------------------------------
66  * - time code index functions
67  * ---------------------------------------------------------------------- */
68
69 anim_index_builder *IMB_index_builder_create(const char *name)
70 {
71
72   anim_index_builder *rv = MEM_callocN(sizeof(struct anim_index_builder), "index builder");
73
74   fprintf(stderr, "Starting work on index: %s\n", name);
75
76   BLI_strncpy(rv->name, name, sizeof(rv->name));
77   BLI_strncpy(rv->temp_name, name, sizeof(rv->temp_name));
78
79   strcat(rv->temp_name, temp_ext);
80
81   BLI_make_existing_file(rv->temp_name);
82
83   rv->fp = BLI_fopen(rv->temp_name, "wb");
84
85   if (!rv->fp) {
86     fprintf(stderr,
87             "Couldn't open index target: %s! "
88             "Index build broken!\n",
89             rv->temp_name);
90     MEM_freeN(rv);
91     return NULL;
92   }
93
94   fprintf(rv->fp, "%s%c%.3d", magic, (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v', INDEX_FILE_VERSION);
95
96   return rv;
97 }
98
99 void IMB_index_builder_add_entry(anim_index_builder *fp,
100                                  int frameno,
101                                  unsigned long long seek_pos,
102                                  unsigned long long seek_pos_dts,
103                                  unsigned long long pts)
104 {
105   fwrite(&frameno, sizeof(int), 1, fp->fp);
106   fwrite(&seek_pos, sizeof(unsigned long long), 1, fp->fp);
107   fwrite(&seek_pos_dts, sizeof(unsigned long long), 1, fp->fp);
108   fwrite(&pts, sizeof(unsigned long long), 1, fp->fp);
109 }
110
111 void IMB_index_builder_proc_frame(anim_index_builder *fp,
112                                   unsigned char *buffer,
113                                   int data_size,
114                                   int frameno,
115                                   unsigned long long seek_pos,
116                                   unsigned long long seek_pos_dts,
117                                   unsigned long long pts)
118 {
119   if (fp->proc_frame) {
120     anim_index_entry e;
121     e.frameno = frameno;
122     e.seek_pos = seek_pos;
123     e.seek_pos_dts = seek_pos_dts;
124     e.pts = pts;
125
126     fp->proc_frame(fp, buffer, data_size, &e);
127   }
128   else {
129     IMB_index_builder_add_entry(fp, frameno, seek_pos, seek_pos_dts, pts);
130   }
131 }
132
133 void IMB_index_builder_finish(anim_index_builder *fp, int rollback)
134 {
135   if (fp->delete_priv_data) {
136     fp->delete_priv_data(fp);
137   }
138
139   fclose(fp->fp);
140
141   if (rollback) {
142     unlink(fp->temp_name);
143   }
144   else {
145     unlink(fp->name);
146     BLI_rename(fp->temp_name, fp->name);
147   }
148
149   MEM_freeN(fp);
150 }
151
152 struct anim_index *IMB_indexer_open(const char *name)
153 {
154   char header[13];
155   struct anim_index *idx;
156   FILE *fp = BLI_fopen(name, "rb");
157   int i;
158
159   if (!fp) {
160     return NULL;
161   }
162
163   if (fread(header, 12, 1, fp) != 1) {
164     fclose(fp);
165     return NULL;
166   }
167
168   header[12] = 0;
169
170   if (memcmp(header, magic, 8) != 0) {
171     fclose(fp);
172     return NULL;
173   }
174
175   if (atoi(header + 9) != INDEX_FILE_VERSION) {
176     fclose(fp);
177     return NULL;
178   }
179
180   idx = MEM_callocN(sizeof(struct anim_index), "anim_index");
181
182   BLI_strncpy(idx->name, name, sizeof(idx->name));
183
184   fseek(fp, 0, SEEK_END);
185
186   idx->num_entries = (ftell(fp) - 12) / (sizeof(int) +                /* framepos */
187                                          sizeof(unsigned long long) + /* seek_pos */
188                                          sizeof(unsigned long long) + /* seek_pos_dts */
189                                          sizeof(unsigned long long)   /* pts */
190                                         );
191
192   fseek(fp, 12, SEEK_SET);
193
194   idx->entries = MEM_callocN(sizeof(struct anim_index_entry) * idx->num_entries,
195                              "anim_index_entries");
196
197   for (i = 0; i < idx->num_entries; i++) {
198     fread(&idx->entries[i].frameno, sizeof(int), 1, fp);
199     fread(&idx->entries[i].seek_pos, sizeof(unsigned long long), 1, fp);
200     fread(&idx->entries[i].seek_pos_dts, sizeof(unsigned long long), 1, fp);
201     fread(&idx->entries[i].pts, sizeof(unsigned long long), 1, fp);
202   }
203
204   if (((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V'))) {
205     for (i = 0; i < idx->num_entries; i++) {
206       BLI_endian_switch_int32(&idx->entries[i].frameno);
207       BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos);
208       BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos_dts);
209       BLI_endian_switch_int64((int64_t *)&idx->entries[i].pts);
210     }
211   }
212
213   fclose(fp);
214
215   return idx;
216 }
217
218 unsigned long long IMB_indexer_get_seek_pos(struct anim_index *idx, int frame_index)
219 {
220   if (frame_index < 0) {
221     frame_index = 0;
222   }
223   if (frame_index >= idx->num_entries) {
224     frame_index = idx->num_entries - 1;
225   }
226   return idx->entries[frame_index].seek_pos;
227 }
228
229 unsigned long long IMB_indexer_get_seek_pos_dts(struct anim_index *idx, int frame_index)
230 {
231   if (frame_index < 0) {
232     frame_index = 0;
233   }
234   if (frame_index >= idx->num_entries) {
235     frame_index = idx->num_entries - 1;
236   }
237   return idx->entries[frame_index].seek_pos_dts;
238 }
239
240 int IMB_indexer_get_frame_index(struct anim_index *idx, int frameno)
241 {
242   int len = idx->num_entries;
243   int half;
244   int middle;
245   int first = 0;
246
247   /* bsearch (lower bound) the right index */
248
249   while (len > 0) {
250     half = len >> 1;
251     middle = first;
252
253     middle += half;
254
255     if (idx->entries[middle].frameno < frameno) {
256       first = middle;
257       first++;
258       len = len - half - 1;
259     }
260     else {
261       len = half;
262     }
263   }
264
265   if (first == idx->num_entries) {
266     return idx->num_entries - 1;
267   }
268   else {
269     return first;
270   }
271 }
272
273 unsigned long long IMB_indexer_get_pts(struct anim_index *idx, int frame_index)
274 {
275   if (frame_index < 0) {
276     frame_index = 0;
277   }
278   if (frame_index >= idx->num_entries) {
279     frame_index = idx->num_entries - 1;
280   }
281   return idx->entries[frame_index].pts;
282 }
283
284 int IMB_indexer_get_duration(struct anim_index *idx)
285 {
286   if (idx->num_entries == 0) {
287     return 0;
288   }
289   return idx->entries[idx->num_entries - 1].frameno + 1;
290 }
291
292 int IMB_indexer_can_scan(struct anim_index *idx, int old_frame_index, int new_frame_index)
293 {
294   /* makes only sense, if it is the same I-Frame and we are not
295    * trying to run backwards in time... */
296   return (IMB_indexer_get_seek_pos(idx, old_frame_index) ==
297               IMB_indexer_get_seek_pos(idx, new_frame_index) &&
298           old_frame_index < new_frame_index);
299 }
300
301 void IMB_indexer_close(struct anim_index *idx)
302 {
303   MEM_freeN(idx->entries);
304   MEM_freeN(idx);
305 }
306
307 int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size)
308 {
309   switch (pr_size) {
310     case IMB_PROXY_NONE:
311       /* if we got here, something is broken anyways, so sane defaults... */
312       return 0;
313     case IMB_PROXY_25:
314       return 0;
315     case IMB_PROXY_50:
316       return 1;
317     case IMB_PROXY_75:
318       return 2;
319     case IMB_PROXY_100:
320       return 3;
321     default:
322       return 0;
323   }
324 }
325
326 int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
327 {
328   switch (tc) {
329     case IMB_TC_NONE: /* if we got here, something is broken anyways,
330                        * so sane defaults... */
331       return 0;
332     case IMB_TC_RECORD_RUN:
333       return 0;
334     case IMB_TC_FREE_RUN:
335       return 1;
336     case IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN:
337       return 2;
338     case IMB_TC_RECORD_RUN_NO_GAPS:
339       return 3;
340     default:
341       return 0;
342   }
343 }
344
345 /* ----------------------------------------------------------------------
346  * - rebuild helper functions
347  * ---------------------------------------------------------------------- */
348
349 static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_len)
350 {
351   if (!anim->index_dir[0]) {
352     char fname[FILE_MAXFILE];
353     BLI_split_dirfile(anim->name, index_dir, fname, index_dir_len, sizeof(fname));
354     BLI_path_append(index_dir, index_dir_len, "BL_proxy");
355     BLI_path_append(index_dir, index_dir_len, fname);
356   }
357   else {
358     BLI_strncpy(index_dir, anim->index_dir, index_dir_len);
359   }
360 }
361
362 void IMB_anim_get_fname(struct anim *anim, char *file, int size)
363 {
364   char fname[FILE_MAXFILE];
365   BLI_split_dirfile(anim->name, file, fname, size, sizeof(fname));
366   BLI_strncpy(file, fname, size);
367 }
368
369 static void get_proxy_filename(struct anim *anim,
370                                IMB_Proxy_Size preview_size,
371                                char *fname,
372                                bool temp)
373 {
374   char index_dir[FILE_MAXDIR];
375   int i = IMB_proxy_size_to_array_index(preview_size);
376
377   char proxy_name[256];
378   char stream_suffix[20];
379   const char *name = (temp) ? "proxy_%d%s_part.avi" : "proxy_%d%s.avi";
380
381   stream_suffix[0] = 0;
382
383   if (anim->streamindex > 0) {
384     BLI_snprintf(stream_suffix, sizeof(stream_suffix), "_st%d", anim->streamindex);
385   }
386
387   BLI_snprintf(proxy_name,
388                sizeof(proxy_name),
389                name,
390                (int)(proxy_fac[i] * 100),
391                stream_suffix,
392                anim->suffix);
393
394   get_index_dir(anim, index_dir, sizeof(index_dir));
395
396   BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir, proxy_name);
397 }
398
399 static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc, char *fname)
400 {
401   char index_dir[FILE_MAXDIR];
402   int i = IMB_timecode_to_array_index(tc);
403   const char *index_names[] = {
404       "record_run%s%s.blen_tc",
405       "free_run%s%s.blen_tc",
406       "interp_free_run%s%s.blen_tc",
407       "record_run_no_gaps%s%s.blen_tc",
408   };
409
410   char stream_suffix[20];
411   char index_name[256];
412
413   stream_suffix[0] = 0;
414
415   if (anim->streamindex > 0) {
416     BLI_snprintf(stream_suffix, 20, "_st%d", anim->streamindex);
417   }
418
419   BLI_snprintf(index_name, 256, index_names[i], stream_suffix, anim->suffix);
420
421   get_index_dir(anim, index_dir, sizeof(index_dir));
422
423   BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir, index_name);
424 }
425
426 /* ----------------------------------------------------------------------
427  * - common rebuilder structures
428  * ---------------------------------------------------------------------- */
429
430 typedef struct IndexBuildContext {
431   int anim_type;
432 } IndexBuildContext;
433
434 /* ----------------------------------------------------------------------
435  * - ffmpeg rebuilder
436  * ---------------------------------------------------------------------- */
437
438 #ifdef WITH_FFMPEG
439
440 struct proxy_output_ctx {
441   AVFormatContext *of;
442   AVStream *st;
443   AVCodecContext *c;
444   AVCodec *codec;
445   struct SwsContext *sws_ctx;
446   AVFrame *frame;
447   int cfra;
448   int proxy_size;
449   int orig_height;
450   struct anim *anim;
451 };
452
453 // work around stupid swscaler 16 bytes alignment bug...
454
455 static int round_up(int x, int mod)
456 {
457   return x + ((mod - (x % mod)) % mod);
458 }
459
460 static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
461     struct anim *anim, AVStream *st, int proxy_size, int width, int height, int quality)
462 {
463   struct proxy_output_ctx *rv = MEM_callocN(sizeof(struct proxy_output_ctx), "alloc_proxy_output");
464
465   char fname[FILE_MAX];
466   int ffmpeg_quality;
467
468   /* JPEG requires this */
469   width = round_up(width, 8);
470   height = round_up(height, 8);
471
472   rv->proxy_size = proxy_size;
473   rv->anim = anim;
474
475   get_proxy_filename(rv->anim, rv->proxy_size, fname, true);
476   BLI_make_existing_file(fname);
477
478   rv->of = avformat_alloc_context();
479   rv->of->oformat = av_guess_format("avi", NULL, NULL);
480
481   BLI_strncpy(rv->of->filename, fname, sizeof(rv->of->filename));
482
483   fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
484
485   rv->st = avformat_new_stream(rv->of, NULL);
486   rv->st->id = 0;
487
488   rv->c = rv->st->codec;
489   rv->c->codec_type = AVMEDIA_TYPE_VIDEO;
490   rv->c->codec_id = AV_CODEC_ID_MJPEG;
491   rv->c->width = width;
492   rv->c->height = height;
493
494   rv->of->oformat->video_codec = rv->c->codec_id;
495   rv->codec = avcodec_find_encoder(rv->c->codec_id);
496
497   if (!rv->codec) {
498     fprintf(stderr,
499             "No ffmpeg MJPEG encoder available? "
500             "Proxy not built!\n");
501     av_free(rv->of);
502     return NULL;
503   }
504
505   if (rv->codec->pix_fmts) {
506     rv->c->pix_fmt = rv->codec->pix_fmts[0];
507   }
508   else {
509     rv->c->pix_fmt = AV_PIX_FMT_YUVJ420P;
510   }
511
512   rv->c->sample_aspect_ratio = rv->st->sample_aspect_ratio = st->codec->sample_aspect_ratio;
513
514   rv->c->time_base.den = 25;
515   rv->c->time_base.num = 1;
516   rv->st->time_base = rv->c->time_base;
517
518   /* there's no  way to set JPEG quality in the same way as in AVI JPEG and image sequence,
519    * but this seems to be giving expected quality result */
520   ffmpeg_quality = (int)(1.0f + 30.0f * (1.0f - (float)quality / 100.0f) + 0.5f);
521   av_opt_set_int(rv->c, "qmin", ffmpeg_quality, 0);
522   av_opt_set_int(rv->c, "qmax", ffmpeg_quality, 0);
523
524   if (rv->of->flags & AVFMT_GLOBALHEADER) {
525     rv->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
526   }
527
528   if (avio_open(&rv->of->pb, fname, AVIO_FLAG_WRITE) < 0) {
529     fprintf(stderr,
530             "Couldn't open outputfile! "
531             "Proxy not built!\n");
532     av_free(rv->of);
533     return 0;
534   }
535
536   avcodec_open2(rv->c, rv->codec, NULL);
537
538   rv->orig_height = av_get_cropped_height_from_codec(st->codec);
539
540   if (st->codec->width != width || st->codec->height != height ||
541       st->codec->pix_fmt != rv->c->pix_fmt) {
542     rv->frame = av_frame_alloc();
543     avpicture_fill((AVPicture *)rv->frame,
544                    MEM_mallocN(avpicture_get_size(rv->c->pix_fmt, round_up(width, 16), height),
545                                "alloc proxy output frame"),
546                    rv->c->pix_fmt,
547                    round_up(width, 16),
548                    height);
549
550     rv->sws_ctx = sws_getContext(st->codec->width,
551                                  rv->orig_height,
552                                  st->codec->pix_fmt,
553                                  width,
554                                  height,
555                                  rv->c->pix_fmt,
556                                  SWS_FAST_BILINEAR | SWS_PRINT_INFO,
557                                  NULL,
558                                  NULL,
559                                  NULL);
560   }
561
562   if (avformat_write_header(rv->of, NULL) < 0) {
563     fprintf(stderr,
564             "Couldn't set output parameters? "
565             "Proxy not built!\n");
566     av_free(rv->of);
567     return 0;
568   }
569
570   return rv;
571 }
572
573 static int add_to_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, AVFrame *frame)
574 {
575   AVPacket packet = {0};
576   int ret, got_output;
577
578   av_init_packet(&packet);
579
580   if (!ctx) {
581     return 0;
582   }
583
584   if (ctx->sws_ctx && frame &&
585       (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3])) {
586     sws_scale(ctx->sws_ctx,
587               (const uint8_t *const *)frame->data,
588               frame->linesize,
589               0,
590               ctx->orig_height,
591               ctx->frame->data,
592               ctx->frame->linesize);
593   }
594
595   frame = ctx->sws_ctx ? (frame ? ctx->frame : 0) : frame;
596
597   if (frame) {
598     frame->pts = ctx->cfra++;
599   }
600
601   ret = avcodec_encode_video2(ctx->c, &packet, frame, &got_output);
602   if (ret < 0) {
603     fprintf(stderr, "Error encoding proxy frame %d for '%s'\n", ctx->cfra - 1, ctx->of->filename);
604     return 0;
605   }
606
607   if (got_output) {
608     if (packet.pts != AV_NOPTS_VALUE) {
609       packet.pts = av_rescale_q(packet.pts, ctx->c->time_base, ctx->st->time_base);
610     }
611     if (packet.dts != AV_NOPTS_VALUE) {
612       packet.dts = av_rescale_q(packet.dts, ctx->c->time_base, ctx->st->time_base);
613     }
614
615     packet.stream_index = ctx->st->index;
616
617     if (av_interleaved_write_frame(ctx->of, &packet) != 0) {
618       fprintf(stderr,
619               "Error writing proxy frame %d "
620               "into '%s'\n",
621               ctx->cfra - 1,
622               ctx->of->filename);
623       return 0;
624     }
625
626     return 1;
627   }
628   else {
629     return 0;
630   }
631 }
632
633 static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, int rollback)
634 {
635   char fname[FILE_MAX];
636   char fname_tmp[FILE_MAX];
637
638   if (!ctx) {
639     return;
640   }
641
642   if (!rollback) {
643     while (add_to_proxy_output_ffmpeg(ctx, NULL)) {
644     }
645   }
646
647   avcodec_flush_buffers(ctx->c);
648
649   av_write_trailer(ctx->of);
650
651   avcodec_close(ctx->c);
652
653   if (ctx->of->oformat) {
654     if (!(ctx->of->oformat->flags & AVFMT_NOFILE)) {
655       avio_close(ctx->of->pb);
656     }
657   }
658   avformat_free_context(ctx->of);
659
660   if (ctx->sws_ctx) {
661     sws_freeContext(ctx->sws_ctx);
662
663     MEM_freeN(ctx->frame->data[0]);
664     av_free(ctx->frame);
665   }
666
667   get_proxy_filename(ctx->anim, ctx->proxy_size, fname_tmp, true);
668
669   if (rollback) {
670     unlink(fname_tmp);
671   }
672   else {
673     get_proxy_filename(ctx->anim, ctx->proxy_size, fname, false);
674     unlink(fname);
675     BLI_rename(fname_tmp, fname);
676   }
677
678   MEM_freeN(ctx);
679 }
680
681 typedef struct FFmpegIndexBuilderContext {
682   int anim_type;
683
684   AVFormatContext *iFormatCtx;
685   AVCodecContext *iCodecCtx;
686   AVCodec *iCodec;
687   AVStream *iStream;
688   int videoStream;
689
690   int num_proxy_sizes;
691   int num_indexers;
692
693   struct proxy_output_ctx *proxy_ctx[IMB_PROXY_MAX_SLOT];
694   anim_index_builder *indexer[IMB_TC_MAX_SLOT];
695
696   IMB_Timecode_Type tcs_in_use;
697   IMB_Proxy_Size proxy_sizes_in_use;
698
699   unsigned long long seek_pos;
700   unsigned long long last_seek_pos;
701   unsigned long long seek_pos_dts;
702   unsigned long long seek_pos_pts;
703   unsigned long long last_seek_pos_dts;
704   unsigned long long start_pts;
705   double frame_rate;
706   double pts_time_base;
707   int frameno, frameno_gapless;
708   int start_pts_set;
709 } FFmpegIndexBuilderContext;
710
711 static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim,
712                                                       IMB_Timecode_Type tcs_in_use,
713                                                       IMB_Proxy_Size proxy_sizes_in_use,
714                                                       int quality)
715 {
716   FFmpegIndexBuilderContext *context = MEM_callocN(sizeof(FFmpegIndexBuilderContext),
717                                                    "FFmpeg index builder context");
718   int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
719   int num_indexers = IMB_TC_MAX_SLOT;
720   int i, streamcount;
721
722   context->tcs_in_use = tcs_in_use;
723   context->proxy_sizes_in_use = proxy_sizes_in_use;
724   context->num_proxy_sizes = IMB_PROXY_MAX_SLOT;
725   context->num_indexers = IMB_TC_MAX_SLOT;
726
727   memset(context->proxy_ctx, 0, sizeof(context->proxy_ctx));
728   memset(context->indexer, 0, sizeof(context->indexer));
729
730   if (avformat_open_input(&context->iFormatCtx, anim->name, NULL, NULL) != 0) {
731     MEM_freeN(context);
732     return NULL;
733   }
734
735   if (avformat_find_stream_info(context->iFormatCtx, NULL) < 0) {
736     avformat_close_input(&context->iFormatCtx);
737     MEM_freeN(context);
738     return NULL;
739   }
740
741   streamcount = anim->streamindex;
742
743   /* Find the video stream */
744   context->videoStream = -1;
745   for (i = 0; i < context->iFormatCtx->nb_streams; i++) {
746     if (context->iFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
747       if (streamcount > 0) {
748         streamcount--;
749         continue;
750       }
751       context->videoStream = i;
752       break;
753     }
754   }
755
756   if (context->videoStream == -1) {
757     avformat_close_input(&context->iFormatCtx);
758     MEM_freeN(context);
759     return NULL;
760   }
761
762   context->iStream = context->iFormatCtx->streams[context->videoStream];
763   context->iCodecCtx = context->iStream->codec;
764
765   context->iCodec = avcodec_find_decoder(context->iCodecCtx->codec_id);
766
767   if (context->iCodec == NULL) {
768     avformat_close_input(&context->iFormatCtx);
769     MEM_freeN(context);
770     return NULL;
771   }
772
773   context->iCodecCtx->workaround_bugs = 1;
774
775   if (avcodec_open2(context->iCodecCtx, context->iCodec, NULL) < 0) {
776     avformat_close_input(&context->iFormatCtx);
777     MEM_freeN(context);
778     return NULL;
779   }
780
781   for (i = 0; i < num_proxy_sizes; i++) {
782     if (proxy_sizes_in_use & proxy_sizes[i]) {
783       context->proxy_ctx[i] = alloc_proxy_output_ffmpeg(
784           anim,
785           context->iStream,
786           proxy_sizes[i],
787           context->iCodecCtx->width * proxy_fac[i],
788           av_get_cropped_height_from_codec(context->iCodecCtx) * proxy_fac[i],
789           quality);
790       if (!context->proxy_ctx[i]) {
791         proxy_sizes_in_use &= ~proxy_sizes[i];
792       }
793     }
794   }
795
796   for (i = 0; i < num_indexers; i++) {
797     if (tcs_in_use & tc_types[i]) {
798       char fname[FILE_MAX];
799
800       get_tc_filename(anim, tc_types[i], fname);
801
802       context->indexer[i] = IMB_index_builder_create(fname);
803       if (!context->indexer[i]) {
804         tcs_in_use &= ~tc_types[i];
805       }
806     }
807   }
808
809   return (IndexBuildContext *)context;
810 }
811
812 static void index_rebuild_ffmpeg_finish(FFmpegIndexBuilderContext *context, int stop)
813 {
814   int i;
815
816   for (i = 0; i < context->num_indexers; i++) {
817     if (context->tcs_in_use & tc_types[i]) {
818       IMB_index_builder_finish(context->indexer[i], stop);
819     }
820   }
821
822   for (i = 0; i < context->num_proxy_sizes; i++) {
823     if (context->proxy_sizes_in_use & proxy_sizes[i]) {
824       free_proxy_output_ffmpeg(context->proxy_ctx[i], stop);
825     }
826   }
827
828   avcodec_close(context->iCodecCtx);
829   avformat_close_input(&context->iFormatCtx);
830
831   MEM_freeN(context);
832 }
833
834 static void index_rebuild_ffmpeg_proc_decoded_frame(FFmpegIndexBuilderContext *context,
835                                                     AVPacket *curr_packet,
836                                                     AVFrame *in_frame)
837 {
838   int i;
839   unsigned long long s_pos = context->seek_pos;
840   unsigned long long s_dts = context->seek_pos_dts;
841   unsigned long long pts = av_get_pts_from_frame(context->iFormatCtx, in_frame);
842
843   for (i = 0; i < context->num_proxy_sizes; i++) {
844     add_to_proxy_output_ffmpeg(context->proxy_ctx[i], in_frame);
845   }
846
847   if (!context->start_pts_set) {
848     context->start_pts = pts;
849     context->start_pts_set = true;
850   }
851
852   context->frameno = floor(
853       (pts - context->start_pts) * context->pts_time_base * context->frame_rate + 0.5);
854
855   /* decoding starts *always* on I-Frames,
856    * so: P-Frames won't work, even if all the
857    * information is in place, when we seek
858    * to the I-Frame presented *after* the P-Frame,
859    * but located before the P-Frame within
860    * the stream */
861
862   if (pts < context->seek_pos_pts) {
863     s_pos = context->last_seek_pos;
864     s_dts = context->last_seek_pos_dts;
865   }
866
867   for (i = 0; i < context->num_indexers; i++) {
868     if (context->tcs_in_use & tc_types[i]) {
869       int tc_frameno = context->frameno;
870
871       if (tc_types[i] == IMB_TC_RECORD_RUN_NO_GAPS) {
872         tc_frameno = context->frameno_gapless;
873       }
874
875       IMB_index_builder_proc_frame(context->indexer[i],
876                                    curr_packet->data,
877                                    curr_packet->size,
878                                    tc_frameno,
879                                    s_pos,
880                                    s_dts,
881                                    pts);
882     }
883   }
884
885   context->frameno_gapless++;
886 }
887
888 static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context,
889                                 short *stop,
890                                 short *do_update,
891                                 float *progress)
892 {
893   AVFrame *in_frame = 0;
894   AVPacket next_packet;
895   uint64_t stream_size;
896
897   memset(&next_packet, 0, sizeof(AVPacket));
898
899   in_frame = av_frame_alloc();
900
901   stream_size = avio_size(context->iFormatCtx->pb);
902
903   context->frame_rate = av_q2d(av_get_r_frame_rate_compat(context->iFormatCtx, context->iStream));
904   context->pts_time_base = av_q2d(context->iStream->time_base);
905
906   while (av_read_frame(context->iFormatCtx, &next_packet) >= 0) {
907     int frame_finished = 0;
908     float next_progress =
909         (float)((int)floor(((double)next_packet.pos) * 100 / ((double)stream_size) + 0.5)) / 100;
910
911     if (*progress != next_progress) {
912       *progress = next_progress;
913       *do_update = true;
914     }
915
916     if (*stop) {
917       av_free_packet(&next_packet);
918       break;
919     }
920
921     if (next_packet.stream_index == context->videoStream) {
922       if (next_packet.flags & AV_PKT_FLAG_KEY) {
923         context->last_seek_pos = context->seek_pos;
924         context->last_seek_pos_dts = context->seek_pos_dts;
925         context->seek_pos = next_packet.pos;
926         context->seek_pos_dts = next_packet.dts;
927         context->seek_pos_pts = next_packet.pts;
928       }
929
930       avcodec_decode_video2(context->iCodecCtx, in_frame, &frame_finished, &next_packet);
931     }
932
933     if (frame_finished) {
934       index_rebuild_ffmpeg_proc_decoded_frame(context, &next_packet, in_frame);
935     }
936     av_free_packet(&next_packet);
937   }
938
939   /* process pictures still stuck in decoder engine after EOF
940    * according to ffmpeg docs using 0-size packets.
941    *
942    * At least, if we haven't already stopped... */
943
944   /* this creates the 0-size packet and prevents a memory leak. */
945   av_free_packet(&next_packet);
946
947   if (!*stop) {
948     int frame_finished;
949
950     do {
951       frame_finished = 0;
952
953       avcodec_decode_video2(context->iCodecCtx, in_frame, &frame_finished, &next_packet);
954
955       if (frame_finished) {
956         index_rebuild_ffmpeg_proc_decoded_frame(context, &next_packet, in_frame);
957       }
958     } while (frame_finished);
959   }
960
961   av_free(in_frame);
962
963   return 1;
964 }
965
966 #endif
967
968 /* ----------------------------------------------------------------------
969  * - internal AVI (fallback) rebuilder
970  * ---------------------------------------------------------------------- */
971
972 #ifdef WITH_AVI
973 typedef struct FallbackIndexBuilderContext {
974   int anim_type;
975
976   struct anim *anim;
977   AviMovie *proxy_ctx[IMB_PROXY_MAX_SLOT];
978   IMB_Proxy_Size proxy_sizes_in_use;
979 } FallbackIndexBuilderContext;
980
981 static AviMovie *alloc_proxy_output_avi(
982     struct anim *anim, char *filename, int width, int height, int quality)
983 {
984   int x, y;
985   AviFormat format;
986   double framerate;
987   AviMovie *avi;
988   /* it doesn't really matter for proxies, but sane defaults help anyways...*/
989   short frs_sec = 25;
990   float frs_sec_base = 1.0;
991
992   IMB_anim_get_fps(anim, &frs_sec, &frs_sec_base, false);
993
994   x = width;
995   y = height;
996
997   framerate = (double)frs_sec / (double)frs_sec_base;
998
999   avi = MEM_mallocN(sizeof(AviMovie), "avimovie");
1000
1001   format = AVI_FORMAT_MJPEG;
1002
1003   if (AVI_open_compress(filename, avi, 1, format) != AVI_ERROR_NONE) {
1004     MEM_freeN(avi);
1005     return NULL;
1006   }
1007
1008   AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x);
1009   AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &y);
1010   AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &quality);
1011   AVI_set_compress_option(avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &framerate);
1012
1013   avi->interlace = 0;
1014   avi->odd_fields = 0;
1015
1016   return avi;
1017 }
1018
1019 static IndexBuildContext *index_fallback_create_context(struct anim *anim,
1020                                                         IMB_Timecode_Type UNUSED(tcs_in_use),
1021                                                         IMB_Proxy_Size proxy_sizes_in_use,
1022                                                         int quality)
1023 {
1024   FallbackIndexBuilderContext *context;
1025   int i;
1026
1027   /* since timecode indices only work with ffmpeg right now,
1028    * don't know a sensible fallback here...
1029    *
1030    * so no proxies...
1031    */
1032   if (proxy_sizes_in_use == IMB_PROXY_NONE) {
1033     return NULL;
1034   }
1035
1036   context = MEM_callocN(sizeof(FallbackIndexBuilderContext), "fallback index builder context");
1037
1038   context->anim = anim;
1039   context->proxy_sizes_in_use = proxy_sizes_in_use;
1040
1041   memset(context->proxy_ctx, 0, sizeof(context->proxy_ctx));
1042
1043   for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
1044     if (context->proxy_sizes_in_use & proxy_sizes[i]) {
1045       char fname[FILE_MAX];
1046
1047       get_proxy_filename(anim, proxy_sizes[i], fname, true);
1048       BLI_make_existing_file(fname);
1049
1050       context->proxy_ctx[i] = alloc_proxy_output_avi(
1051           anim, fname, anim->x * proxy_fac[i], anim->y * proxy_fac[i], quality);
1052     }
1053   }
1054
1055   return (IndexBuildContext *)context;
1056 }
1057
1058 static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *context, int stop)
1059 {
1060   struct anim *anim = context->anim;
1061   char fname[FILE_MAX];
1062   char fname_tmp[FILE_MAX];
1063   int i;
1064
1065   for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
1066     if (context->proxy_sizes_in_use & proxy_sizes[i]) {
1067       AVI_close_compress(context->proxy_ctx[i]);
1068       MEM_freeN(context->proxy_ctx[i]);
1069
1070       get_proxy_filename(anim, proxy_sizes[i], fname_tmp, true);
1071       get_proxy_filename(anim, proxy_sizes[i], fname, false);
1072
1073       if (stop) {
1074         unlink(fname_tmp);
1075       }
1076       else {
1077         unlink(fname);
1078         rename(fname_tmp, fname);
1079       }
1080     }
1081   }
1082 }
1083
1084 static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
1085                                    short *stop,
1086                                    short *do_update,
1087                                    float *progress)
1088 {
1089   int cnt = IMB_anim_get_duration(context->anim, IMB_TC_NONE);
1090   int i, pos;
1091   struct anim *anim = context->anim;
1092
1093   for (pos = 0; pos < cnt; pos++) {
1094     struct ImBuf *ibuf = IMB_anim_absolute(anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
1095     struct ImBuf *tmp_ibuf = IMB_dupImBuf(ibuf);
1096     float next_progress = (float)pos / (float)cnt;
1097
1098     if (*progress != next_progress) {
1099       *progress = next_progress;
1100       *do_update = true;
1101     }
1102
1103     if (*stop) {
1104       break;
1105     }
1106
1107     IMB_flipy(tmp_ibuf);
1108
1109     for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
1110       if (context->proxy_sizes_in_use & proxy_sizes[i]) {
1111         int x = anim->x * proxy_fac[i];
1112         int y = anim->y * proxy_fac[i];
1113
1114         struct ImBuf *s_ibuf = IMB_dupImBuf(tmp_ibuf);
1115
1116         IMB_scalefastImBuf(s_ibuf, x, y);
1117
1118         IMB_convert_rgba_to_abgr(s_ibuf);
1119
1120         AVI_write_frame(context->proxy_ctx[i], pos, AVI_FORMAT_RGB32, s_ibuf->rect, x * y * 4);
1121
1122         /* note that libavi free's the buffer... */
1123         s_ibuf->rect = NULL;
1124
1125         IMB_freeImBuf(s_ibuf);
1126       }
1127     }
1128
1129     IMB_freeImBuf(tmp_ibuf);
1130     IMB_freeImBuf(ibuf);
1131   }
1132 }
1133
1134 #endif /* WITH_AVI */
1135
1136 /* ----------------------------------------------------------------------
1137  * - public API
1138  * ---------------------------------------------------------------------- */
1139
1140 IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim,
1141                                                   IMB_Timecode_Type tcs_in_use,
1142                                                   IMB_Proxy_Size proxy_sizes_in_use,
1143                                                   int quality,
1144                                                   const bool overwrite,
1145                                                   GSet *file_list)
1146 {
1147   IndexBuildContext *context = NULL;
1148   IMB_Proxy_Size proxy_sizes_to_build = proxy_sizes_in_use;
1149   int i;
1150
1151   /* Don't generate the same file twice! */
1152   if (file_list) {
1153     for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
1154       IMB_Proxy_Size proxy_size = proxy_sizes[i];
1155       if (proxy_size & proxy_sizes_to_build) {
1156         char filename[FILE_MAX];
1157         get_proxy_filename(anim, proxy_size, filename, false);
1158
1159         void **filename_key_p;
1160         if (!BLI_gset_ensure_p_ex(file_list, filename, &filename_key_p)) {
1161           *filename_key_p = BLI_strdup(filename);
1162         }
1163         else {
1164           proxy_sizes_to_build &= ~proxy_size;
1165           printf("Proxy: %s already registered for generation, skipping\n", filename);
1166         }
1167       }
1168     }
1169   }
1170
1171   if (!overwrite) {
1172     IMB_Proxy_Size built_proxies = IMB_anim_proxy_get_existing(anim);
1173     if (built_proxies != 0) {
1174
1175       for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
1176         IMB_Proxy_Size proxy_size = proxy_sizes[i];
1177         if (proxy_size & built_proxies) {
1178           char filename[FILE_MAX];
1179           get_proxy_filename(anim, proxy_size, filename, false);
1180           printf("Skipping proxy: %s\n", filename);
1181         }
1182       }
1183     }
1184     proxy_sizes_to_build &= ~built_proxies;
1185   }
1186
1187   fflush(stdout);
1188
1189   if (proxy_sizes_to_build == 0) {
1190     return NULL;
1191   }
1192
1193   switch (anim->curtype) {
1194 #ifdef WITH_FFMPEG
1195     case ANIM_FFMPEG:
1196       context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
1197       break;
1198 #endif
1199 #ifdef WITH_AVI
1200     default:
1201       context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
1202       break;
1203 #endif
1204   }
1205
1206   if (context) {
1207     context->anim_type = anim->curtype;
1208   }
1209
1210   return context;
1211
1212   UNUSED_VARS(tcs_in_use, proxy_sizes_in_use, quality);
1213 }
1214
1215 void IMB_anim_index_rebuild(struct IndexBuildContext *context,
1216                             short *stop,
1217                             short *do_update,
1218                             float *progress)
1219 {
1220   switch (context->anim_type) {
1221 #ifdef WITH_FFMPEG
1222     case ANIM_FFMPEG:
1223       index_rebuild_ffmpeg((FFmpegIndexBuilderContext *)context, stop, do_update, progress);
1224       break;
1225 #endif
1226 #ifdef WITH_AVI
1227     default:
1228       index_rebuild_fallback((FallbackIndexBuilderContext *)context, stop, do_update, progress);
1229       break;
1230 #endif
1231   }
1232
1233   UNUSED_VARS(stop, do_update, progress);
1234 }
1235
1236 void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop)
1237 {
1238   switch (context->anim_type) {
1239 #ifdef WITH_FFMPEG
1240     case ANIM_FFMPEG:
1241       index_rebuild_ffmpeg_finish((FFmpegIndexBuilderContext *)context, stop);
1242       break;
1243 #endif
1244 #ifdef WITH_AVI
1245     default:
1246       index_rebuild_fallback_finish((FallbackIndexBuilderContext *)context, stop);
1247       break;
1248 #endif
1249   }
1250
1251   /* static defined at top of the file */
1252   UNUSED_VARS(stop, proxy_sizes);
1253 }
1254
1255 void IMB_free_indices(struct anim *anim)
1256 {
1257   int i;
1258
1259   for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
1260     if (anim->proxy_anim[i]) {
1261       IMB_close_anim(anim->proxy_anim[i]);
1262       anim->proxy_anim[i] = NULL;
1263     }
1264   }
1265
1266   for (i = 0; i < IMB_TC_MAX_SLOT; i++) {
1267     if (anim->curr_idx[i]) {
1268       IMB_indexer_close(anim->curr_idx[i]);
1269       anim->curr_idx[i] = NULL;
1270     }
1271   }
1272
1273   anim->proxies_tried = 0;
1274   anim->indices_tried = 0;
1275 }
1276
1277 void IMB_anim_set_index_dir(struct anim *anim, const char *dir)
1278 {
1279   if (STREQ(anim->index_dir, dir)) {
1280     return;
1281   }
1282   BLI_strncpy(anim->index_dir, dir, sizeof(anim->index_dir));
1283
1284   IMB_free_indices(anim);
1285 }
1286
1287 struct anim *IMB_anim_open_proxy(struct anim *anim, IMB_Proxy_Size preview_size)
1288 {
1289   char fname[FILE_MAX];
1290   int i = IMB_proxy_size_to_array_index(preview_size);
1291
1292   if (anim->proxy_anim[i]) {
1293     return anim->proxy_anim[i];
1294   }
1295
1296   if (anim->proxies_tried & preview_size) {
1297     return NULL;
1298   }
1299
1300   get_proxy_filename(anim, preview_size, fname, false);
1301
1302   /* proxies are generated in the same color space as animation itself */
1303   anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0, anim->colorspace);
1304
1305   anim->proxies_tried |= preview_size;
1306
1307   return anim->proxy_anim[i];
1308 }
1309
1310 struct anim_index *IMB_anim_open_index(struct anim *anim, IMB_Timecode_Type tc)
1311 {
1312   char fname[FILE_MAX];
1313   int i = IMB_timecode_to_array_index(tc);
1314
1315   if (anim->curr_idx[i]) {
1316     return anim->curr_idx[i];
1317   }
1318
1319   if (anim->indices_tried & tc) {
1320     return NULL;
1321   }
1322
1323   get_tc_filename(anim, tc, fname);
1324
1325   anim->curr_idx[i] = IMB_indexer_open(fname);
1326
1327   anim->indices_tried |= tc;
1328
1329   return anim->curr_idx[i];
1330 }
1331
1332 int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc, int position)
1333 {
1334   struct anim_index *idx = IMB_anim_open_index(anim, tc);
1335
1336   if (!idx) {
1337     return position;
1338   }
1339
1340   return IMB_indexer_get_frame_index(idx, position);
1341 }
1342
1343 IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim)
1344 {
1345   const int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
1346   IMB_Proxy_Size existing = 0;
1347   int i;
1348   for (i = 0; i < num_proxy_sizes; ++i) {
1349     IMB_Proxy_Size proxy_size = proxy_sizes[i];
1350     char filename[FILE_MAX];
1351     get_proxy_filename(anim, proxy_size, filename, false);
1352     if (BLI_exists(filename)) {
1353       existing |= proxy_size;
1354     }
1355   }
1356   return existing;
1357 }