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