Proxies: FFmpeg proxy builder wasn't taking image quality into account at all
[blender.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 #include "IMB_indexer.h"
26 #include "IMB_anim.h"
27 #include "AVI_avi.h"
28 #include "imbuf.h"
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_utildefines.h"
32 #include "BLI_blenlib.h"
33 #include "BLI_math_base.h"
34
35 #include "MEM_guardedalloc.h"
36 #include "DNA_userdef_types.h"
37 #include "BKE_global.h"
38 #include <stdlib.h>
39
40 #ifdef WITH_FFMPEG
41
42 #include "ffmpeg_compat.h"
43
44 #endif //WITH_FFMPEG
45
46
47 static char magic[] = "BlenMIdx";
48 static char temp_ext [] = "_part";
49
50 static int proxy_sizes[] = { IMB_PROXY_25, IMB_PROXY_50, IMB_PROXY_75,
51                              IMB_PROXY_100 };
52 static float proxy_fac[] = { 0.25, 0.50, 0.75, 1.00 };
53
54 #ifdef WITH_FFMPEG
55 static int tc_types[] = { IMB_TC_RECORD_RUN,
56                           IMB_TC_FREE_RUN,
57                           IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN,
58                           IMB_TC_RECORD_RUN_NO_GAPS,
59                         };
60 #endif
61
62 #define INDEX_FILE_VERSION 1
63
64 /* ---------------------------------------------------------------------- 
65    - special indexers
66    ---------------------------------------------------------------------- 
67  */
68
69 extern void IMB_indexer_dv_new(anim_index_builder * idx);
70
71
72 /* ----------------------------------------------------------------------
73    - time code index functions
74    ---------------------------------------------------------------------- */
75
76 anim_index_builder * IMB_index_builder_create(const char * name)
77 {
78
79         anim_index_builder * rv
80                 = MEM_callocN( sizeof(struct anim_index_builder),
81                                "index builder");
82
83         fprintf(stderr, "Starting work on index: %s\n", name);
84
85         BLI_strncpy(rv->name, name, sizeof(rv->name));
86         BLI_strncpy(rv->temp_name, name, sizeof(rv->temp_name));
87
88         strcat(rv->temp_name, temp_ext);
89
90         BLI_make_existing_file(rv->temp_name);
91
92         rv->fp = fopen(rv->temp_name, "wb");
93
94         if (!rv->fp) {
95                 fprintf(stderr, "Couldn't open index target: %s! "
96                         "Index build broken!\n", rv->temp_name);
97                 MEM_freeN(rv);
98                 return NULL;
99         }
100
101         fprintf(rv->fp, "%s%c%.3d", magic, (ENDIAN_ORDER==B_ENDIAN)?'V':'v',
102                 INDEX_FILE_VERSION);
103
104         return rv;
105 }
106
107 void IMB_index_builder_add_entry(anim_index_builder * fp, 
108                                  int frameno, unsigned long long seek_pos,
109                                  unsigned long long seek_pos_dts,
110                                  unsigned long long pts)
111 {
112         fwrite(&frameno, sizeof(int), 1, fp->fp);
113         fwrite(&seek_pos, sizeof(unsigned long long), 1, fp->fp);
114         fwrite(&seek_pos_dts, sizeof(unsigned long long), 1, fp->fp);
115         fwrite(&pts, sizeof(unsigned long long), 1, fp->fp);
116 }
117
118 void IMB_index_builder_proc_frame(anim_index_builder * fp, 
119                                   unsigned char * buffer,
120                                   int data_size,
121                                   int frameno, unsigned long long seek_pos,
122                                   unsigned long long seek_pos_dts,
123                                   unsigned long long pts)
124 {
125         if (fp->proc_frame) {
126                 anim_index_entry e;
127                 e.frameno = frameno;
128                 e.seek_pos = seek_pos;
129                 e.seek_pos_dts = seek_pos_dts;
130                 e.pts = pts;
131
132                 fp->proc_frame(fp, buffer, data_size, &e);
133         } else {
134                 IMB_index_builder_add_entry(fp, frameno, seek_pos,
135                                             seek_pos_dts, pts);
136         }
137 }
138
139 void IMB_index_builder_finish(anim_index_builder * fp, int rollback)
140 {
141         if (fp->delete_priv_data) {
142                 fp->delete_priv_data(fp);
143         }
144
145         fclose(fp->fp);
146         
147         if (rollback) {
148                 unlink(fp->temp_name);
149         } else {
150                 rename(fp->temp_name, fp->name);
151         }
152
153         MEM_freeN(fp);
154 }
155
156 struct anim_index * IMB_indexer_open(const char * name)
157 {
158         char header[13];
159         struct anim_index * idx;
160         FILE * fp = fopen(name, "rb");
161         int i;
162
163         if (!fp) {
164                 return NULL;
165         }
166
167         if (fread(header, 12, 1, fp) != 1) {
168                 fclose(fp);
169                 return NULL;
170         }
171
172         header[12] = 0;
173
174         if (memcmp(header, magic, 8) != 0) {
175                 fclose(fp);
176                 return NULL;
177         }
178
179         if (atoi(header+9) != INDEX_FILE_VERSION) {
180                 fclose(fp);
181                 return NULL;
182         }
183
184         idx = MEM_callocN( sizeof(struct anim_index), "anim_index");
185
186         BLI_strncpy(idx->name, name, sizeof(idx->name));
187         
188         fseek(fp, 0, SEEK_END);
189
190         idx->num_entries = (ftell(fp) - 12)
191                 / (sizeof(int) // framepos
192                    + sizeof(unsigned long long) // seek_pos
193                    + sizeof(unsigned long long) // seek_pos_dts
194                    + sizeof(unsigned long long) // pts
195                         );
196         
197         fseek(fp, 12, SEEK_SET);
198
199         idx->entries = MEM_callocN( sizeof(struct anim_index_entry) 
200                                     * idx->num_entries, "anim_index_entries");
201
202         for (i = 0; i < idx->num_entries; i++) {
203                 fread(&idx->entries[i].frameno,
204                       sizeof(int), 1, fp);
205                 fread(&idx->entries[i].seek_pos,
206                       sizeof(unsigned long long), 1, fp);
207                 fread(&idx->entries[i].seek_pos_dts,
208                       sizeof(unsigned long long), 1, fp);
209                 fread(&idx->entries[i].pts,
210                       sizeof(unsigned long long), 1, fp);
211         }
212
213         if (((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V'))) {
214                 for (i = 0; i < idx->num_entries; i++) {
215                         SWITCH_INT(idx->entries[i].frameno);
216                         SWITCH_INT64(idx->entries[i].seek_pos);
217                         SWITCH_INT64(idx->entries[i].seek_pos_dts);
218                         SWITCH_INT64(idx->entries[i].pts);
219                 }
220         }
221
222         fclose(fp);
223
224         return idx;
225 }
226
227 unsigned long long IMB_indexer_get_seek_pos(
228         struct anim_index * idx, int frame_index)
229 {
230         if (frame_index < 0) {
231                 frame_index = 0;
232         }
233         if (frame_index >= idx->num_entries) {
234                 frame_index = idx->num_entries - 1;
235         }
236         return idx->entries[frame_index].seek_pos;
237 }
238
239 unsigned long long IMB_indexer_get_seek_pos_dts(
240         struct anim_index * idx, int frame_index)
241 {
242         if (frame_index < 0) {
243                 frame_index = 0;
244         }
245         if (frame_index >= idx->num_entries) {
246                 frame_index = idx->num_entries - 1;
247         }
248         return idx->entries[frame_index].seek_pos_dts;
249 }
250
251 int IMB_indexer_get_frame_index(struct anim_index * idx, int frameno)
252 {
253         int len = idx->num_entries;
254         int half;
255         int middle;
256         int first = 0;
257
258         /* bsearch (lower bound) the right index */
259         
260         while (len > 0) {
261                 half = len >> 1;
262                 middle = first;
263
264                 middle += half;
265
266                 if (idx->entries[middle].frameno < frameno) {
267                         first = middle;
268                         ++first;
269                         len = len - half - 1;
270                 } else {
271                         len = half;
272                 }
273         }
274
275         if (first == idx->num_entries) {
276                 return idx->num_entries - 1;
277         } else {
278                 return first;
279         }
280 }
281
282 unsigned long long IMB_indexer_get_pts(struct anim_index * idx, 
283                                        int frame_index)
284 {
285         if (frame_index < 0) {
286                 frame_index = 0;
287         }
288         if (frame_index >= idx->num_entries) {
289                 frame_index = idx->num_entries - 1;
290         }
291         return idx->entries[frame_index].pts;
292 }
293
294 int IMB_indexer_get_duration(struct anim_index * idx)
295 {
296         if (idx->num_entries == 0) {
297                 return 0;
298         }
299         return idx->entries[idx->num_entries-1].frameno + 1;
300 }
301
302 int IMB_indexer_can_scan(struct anim_index * idx, 
303                          int old_frame_index, int new_frame_index)
304 {
305         /* makes only sense, if it is the same I-Frame and we are not
306            trying to run backwards in time... */
307         return (IMB_indexer_get_seek_pos(idx, old_frame_index)
308                 == IMB_indexer_get_seek_pos(idx, new_frame_index) && 
309                 old_frame_index < new_frame_index);
310 }
311
312 void IMB_indexer_close(struct anim_index * idx)
313 {
314         MEM_freeN(idx->entries);
315         MEM_freeN(idx);
316 }
317
318 int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size)
319 {
320         switch (pr_size) {
321         case IMB_PROXY_NONE: /* if we got here, something is broken anyways,
322                                 so sane defaults... */
323                 return 0;
324         case IMB_PROXY_25:
325                 return 0;
326         case IMB_PROXY_50:
327                 return 1;
328         case IMB_PROXY_75:
329                 return 2;
330         case IMB_PROXY_100:
331                 return 3;
332         default:
333                 return 0;
334         };
335         return 0;
336 }
337
338 int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
339 {
340         switch (tc) {
341         case IMB_TC_NONE: /* if we got here, something is broken anyways,
342                                 so sane defaults... */
343                 return 0;
344         case IMB_TC_RECORD_RUN:
345                 return 0;
346         case IMB_TC_FREE_RUN:
347                 return 1;
348         case IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN:
349                 return 2;
350         case IMB_TC_RECORD_RUN_NO_GAPS:
351                 return 3;
352         default:
353                 return 0;
354         };
355         return 0;
356 }
357
358
359 /* ----------------------------------------------------------------------
360    - rebuild helper functions
361    ---------------------------------------------------------------------- */
362
363 static void get_index_dir(struct anim * anim, char * index_dir)
364 {
365         if (!anim->index_dir[0]) {
366                 char fname[FILE_MAXFILE];
367                 BLI_strncpy(index_dir, anim->name, FILE_MAXDIR);
368                 BLI_splitdirstring(index_dir, fname);
369                 BLI_join_dirfile(index_dir, FILE_MAXDIR, index_dir, "BL_proxy");
370                 BLI_join_dirfile(index_dir, FILE_MAXDIR, index_dir, fname);
371         } else {
372                 BLI_strncpy(index_dir, anim->index_dir, FILE_MAXDIR);
373         }
374 }
375
376 static void get_proxy_filename(struct anim * anim, IMB_Proxy_Size preview_size,
377                                char * fname, int temp)
378 {
379         char index_dir[FILE_MAXDIR];
380         int i = IMB_proxy_size_to_array_index(preview_size);
381
382         char proxy_name[256];
383         char proxy_temp_name[256];
384         char stream_suffix[20];
385         
386         stream_suffix[0] = 0;
387
388         if (anim->streamindex > 0) {
389                 BLI_snprintf(stream_suffix, sizeof(stream_suffix), "_st%d", anim->streamindex);
390         }
391
392         BLI_snprintf(proxy_name, sizeof(proxy_name), "proxy_%d%s.avi",
393                      (int) (proxy_fac[i] * 100), stream_suffix);
394         BLI_snprintf(proxy_temp_name, sizeof(proxy_temp_name), "proxy_%d%s_part.avi",
395                      (int) (proxy_fac[i] * 100), stream_suffix);
396
397         get_index_dir(anim, index_dir);
398
399         BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir, 
400                          temp ? proxy_temp_name : proxy_name);
401 }
402
403 static void get_tc_filename(struct anim * anim, IMB_Timecode_Type tc,
404                             char * fname)
405 {
406         char index_dir[FILE_MAXDIR];
407         int i = IMB_timecode_to_array_index(tc);
408         const char * index_names[] = {
409                 "record_run%s.blen_tc",
410                 "free_run%s.blen_tc",
411                 "interp_free_run%s.blen_tc",
412                 "record_run_no_gaps%s.blen_tc"};
413
414         char stream_suffix[20];
415         char index_name[256];
416         
417         stream_suffix[0] = 0;
418
419         if (anim->streamindex > 0) {
420                 BLI_snprintf(stream_suffix, 20, "_st%d", anim->streamindex);
421         }
422         
423         BLI_snprintf(index_name, 256, index_names[i], stream_suffix);
424
425         get_index_dir(anim, index_dir);
426         
427         BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, 
428                          index_dir, index_name);
429 }
430
431 /* ----------------------------------------------------------------------
432    - ffmpeg rebuilder
433    ---------------------------------------------------------------------- */
434
435 #ifdef WITH_FFMPEG
436
437 struct proxy_output_ctx {
438         AVFormatContext* of;
439         AVStream* st;
440         AVCodecContext* c;
441         AVCodec* codec;
442         struct SwsContext * sws_ctx;
443         AVFrame* frame;
444         uint8_t* video_buffer;
445         int video_buffersize;
446         int cfra;
447         int proxy_size;
448         int orig_height;
449         struct anim * anim;
450 };
451
452 // work around stupid swscaler 16 bytes alignment bug...
453
454 static int round_up(int x, int mod)
455 {
456         return x + ((mod - (x % mod)) % mod);
457 }
458
459 static struct proxy_output_ctx * alloc_proxy_output_ffmpeg(
460         struct anim * anim,
461         AVStream * st, int proxy_size, int width, int height,
462         int quality)
463 {
464         struct proxy_output_ctx * rv = MEM_callocN(
465                 sizeof(struct proxy_output_ctx), "alloc_proxy_output");
466         
467         char fname[FILE_MAX];
468         int ffmpeg_quality;
469
470         // JPEG requires this
471         width = round_up(width, 8);
472         height = round_up(height, 8);
473
474         rv->proxy_size = proxy_size;
475         rv->anim = anim;
476
477         get_proxy_filename(rv->anim, rv->proxy_size, fname, TRUE);
478         BLI_make_existing_file(fname);
479
480         rv->of = avformat_alloc_context();
481         rv->of->oformat = av_guess_format("avi", NULL, NULL);
482         
483         BLI_snprintf(rv->of->filename, sizeof(rv->of->filename), "%s", fname);
484
485         fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
486
487         rv->st = av_new_stream(rv->of, 0);
488         rv->c = rv->st->codec;
489         rv->c->codec_type = AVMEDIA_TYPE_VIDEO;
490         rv->c->codec_id = 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, "No ffmpeg MJPEG encoder available? "
499                         "Proxy not built!\n");
500                 av_free(rv->of);
501                 return NULL;
502         }
503
504         if (rv->codec->pix_fmts) {
505                 rv->c->pix_fmt = rv->codec->pix_fmts[0];
506         } else {
507                 rv->c->pix_fmt = PIX_FMT_YUVJ420P;
508         }
509
510         rv->c->sample_aspect_ratio 
511                 = rv->st->sample_aspect_ratio 
512                 = 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_set_int(rv->c, "qmin", ffmpeg_quality);
522         av_set_int(rv->c, "qmax", ffmpeg_quality);
523
524         if (rv->of->flags & AVFMT_GLOBALHEADER) {
525                 rv->c->flags |= CODEC_FLAG_GLOBAL_HEADER;
526         }
527
528         if (av_set_parameters(rv->of, NULL) < 0) {
529                 fprintf(stderr, "Couldn't set output parameters? "
530                         "Proxy not built!\n");
531                 av_free(rv->of);
532                 return 0;
533         }
534
535         if (avio_open(&rv->of->pb, fname, AVIO_FLAG_WRITE) < 0) {
536                 fprintf(stderr, "Couldn't open outputfile! "
537                         "Proxy not built!\n");
538                 av_free(rv->of);
539                 return 0;
540         }
541
542         avcodec_open(rv->c, rv->codec);
543
544         rv->video_buffersize = 2000000;
545         rv->video_buffer = (uint8_t*)MEM_mallocN(
546                 rv->video_buffersize, "FFMPEG video buffer");
547
548         rv->orig_height = st->codec->height;
549
550         if (st->codec->width != width || st->codec->height != height ||
551                 st->codec->pix_fmt != rv->c->pix_fmt)
552         {
553                 rv->frame = avcodec_alloc_frame();
554                 avpicture_fill((AVPicture*) rv->frame,
555                                MEM_mallocN(avpicture_get_size(
556                                                rv->c->pix_fmt,
557                                                round_up(width, 16), height),
558                                            "alloc proxy output frame"),
559                                rv->c->pix_fmt, round_up(width, 16), height);
560
561                 rv->sws_ctx = sws_getContext(
562                         st->codec->width,
563                         st->codec->height,
564                         st->codec->pix_fmt,
565                         width, height,
566                         rv->c->pix_fmt,
567                         SWS_FAST_BILINEAR | SWS_PRINT_INFO,
568                         NULL, NULL, NULL);
569         }
570
571         av_write_header(rv->of);
572
573         return rv;
574 }
575
576 static int add_to_proxy_output_ffmpeg(
577         struct proxy_output_ctx * ctx, AVFrame * frame)
578 {
579         int outsize = 0;
580
581         if (!ctx) {
582                 return 0;
583         }
584
585         if (    ctx->sws_ctx && frame &&
586                 (frame->data[0] || frame->data[1] ||
587                  frame->data[2] || frame->data[3]))
588         {
589                 sws_scale(ctx->sws_ctx, (const uint8_t * const*) frame->data,
590                           frame->linesize, 0, ctx->orig_height,
591                           ctx->frame->data, ctx->frame->linesize);
592         }
593
594         frame = ctx->sws_ctx ? (frame ? ctx->frame : 0) : frame;
595
596         if (frame) {
597                 frame->pts = ctx->cfra++;
598         }
599
600         outsize = avcodec_encode_video(
601                 ctx->c, ctx->video_buffer, ctx->video_buffersize, 
602                 frame);
603
604         if (outsize < 0) {
605                 fprintf(stderr, "Error encoding proxy frame %d for '%s'\n", 
606                         ctx->cfra - 1, ctx->of->filename);
607                 return 0;
608         }
609
610         if (outsize != 0) {
611                 AVPacket packet;
612                 av_init_packet(&packet);
613
614                 if (ctx->c->coded_frame->pts != AV_NOPTS_VALUE) {
615                         packet.pts = av_rescale_q(ctx->c->coded_frame->pts,
616                                                   ctx->c->time_base,
617                                                   ctx->st->time_base);
618                 }
619                 if (ctx->c->coded_frame->key_frame)
620                         packet.flags |= AV_PKT_FLAG_KEY;
621
622                 packet.stream_index = ctx->st->index;
623                 packet.data = ctx->video_buffer;
624                 packet.size = outsize;
625
626                 if (av_interleaved_write_frame(ctx->of, &packet) != 0) {
627                         fprintf(stderr, "Error writing proxy frame %d "
628                                 "into '%s'\n", ctx->cfra - 1, 
629                                 ctx->of->filename);
630                         return 0;
631                 }
632
633                 return 1;
634         } else {
635                 return 0;
636         }
637 }
638
639 static void free_proxy_output_ffmpeg(struct proxy_output_ctx * ctx,
640                                      int rollback)
641 {
642         int i;
643         char fname[FILE_MAX];
644         char fname_tmp[FILE_MAX];
645
646         if (!ctx) {
647                 return;
648         }
649
650         if (!rollback) {
651                 while (add_to_proxy_output_ffmpeg(ctx, NULL)) ;
652         }
653
654         avcodec_flush_buffers(ctx->c);
655
656         av_write_trailer(ctx->of);
657         
658         avcodec_close(ctx->c);
659         
660         for (i = 0; i < ctx->of->nb_streams; i++) {
661                 if (&ctx->of->streams[i]) {
662                         av_freep(&ctx->of->streams[i]);
663                 }
664         }
665
666         if (ctx->of->oformat) {
667                 if (!(ctx->of->oformat->flags & AVFMT_NOFILE)) {
668                         avio_close(ctx->of->pb);
669                 }
670         }
671         av_free(ctx->of);
672
673         MEM_freeN(ctx->video_buffer);
674
675         if (ctx->sws_ctx) {
676                 sws_freeContext(ctx->sws_ctx);
677
678                 MEM_freeN(ctx->frame->data[0]);
679                 av_free(ctx->frame);
680         }
681
682         get_proxy_filename(ctx->anim, ctx->proxy_size, 
683                            fname_tmp, TRUE);
684
685         if (rollback) {
686                 unlink(fname_tmp);
687         } else {
688                 get_proxy_filename(ctx->anim, ctx->proxy_size, 
689                                    fname, FALSE);
690                 rename(fname_tmp, fname);
691         }
692         
693         MEM_freeN(ctx);
694 }
695
696
697 static int index_rebuild_ffmpeg(struct anim * anim, 
698                                 IMB_Timecode_Type tcs_in_use,
699                                 IMB_Proxy_Size proxy_sizes_in_use,
700                                 int quality,
701                                 short *stop, short *do_update, 
702                                 float *progress)
703 {
704         int i, videoStream;
705         unsigned long long seek_pos = 0;
706         unsigned long long last_seek_pos = 0;
707         unsigned long long seek_pos_dts = 0;
708         unsigned long long seek_pos_pts = 0;
709         unsigned long long last_seek_pos_dts = 0;
710         unsigned long long start_pts = 0;
711         double frame_rate;
712         double pts_time_base;
713         int frameno = 0, frameno_gapless = 0;
714         int start_pts_set = FALSE;
715
716         AVFormatContext *iFormatCtx;
717         AVCodecContext *iCodecCtx;
718         AVCodec *iCodec;
719         AVStream *iStream;
720         AVFrame* in_frame = 0;
721         AVPacket next_packet;
722         int streamcount;
723
724         struct proxy_output_ctx * proxy_ctx[IMB_PROXY_MAX_SLOT];
725         anim_index_builder * indexer [IMB_TC_MAX_SLOT];
726
727         int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
728         int num_indexers = IMB_TC_MAX_SLOT;
729         uint64_t stream_size;
730
731         memset(proxy_ctx, 0, sizeof(proxy_ctx));
732         memset(indexer, 0, sizeof(indexer));
733
734         if(av_open_input_file(&iFormatCtx, anim->name, NULL, 0, NULL) != 0) {
735                 return 0;
736         }
737
738         if (av_find_stream_info(iFormatCtx) < 0) {
739                 av_close_input_file(iFormatCtx);
740                 return 0;
741         }
742
743         streamcount = anim->streamindex;
744
745         /* Find the video stream */
746         videoStream = -1;
747         for (i = 0; i < iFormatCtx->nb_streams; i++)
748                 if(iFormatCtx->streams[i]->codec->codec_type
749                    == AVMEDIA_TYPE_VIDEO) {
750                         if (streamcount > 0) {
751                                 streamcount--;
752                                 continue;
753                         }
754                         videoStream = i;
755                         break;
756                 }
757
758         if (videoStream == -1) {
759                 av_close_input_file(iFormatCtx);
760                 return 0;
761         }
762
763         iStream = iFormatCtx->streams[videoStream];
764         iCodecCtx = iStream->codec;
765
766         iCodec = avcodec_find_decoder(iCodecCtx->codec_id);
767         
768         if (iCodec == NULL) {
769                 av_close_input_file(iFormatCtx);
770                 return 0;
771         }
772
773         iCodecCtx->workaround_bugs = 1;
774
775         if (avcodec_open(iCodecCtx, iCodec) < 0) {
776                 av_close_input_file(iFormatCtx);
777                 return 0;
778         }
779
780         in_frame = avcodec_alloc_frame();
781
782         stream_size = avio_size(iFormatCtx->pb);
783
784         for (i = 0; i < num_proxy_sizes; i++) {
785                 if (proxy_sizes_in_use & proxy_sizes[i]) {
786                         proxy_ctx[i] = alloc_proxy_output_ffmpeg(
787                                 anim, iStream, proxy_sizes[i],
788                                 iCodecCtx->width * proxy_fac[i],
789                                 iCodecCtx->height * proxy_fac[i],
790                                 quality);
791                         if (!proxy_ctx[i]) {
792                                 proxy_sizes_in_use &= ~proxy_sizes[i];
793                         }
794                 }
795         }
796
797         for (i = 0; i < num_indexers; i++) {
798                 if (tcs_in_use & tc_types[i]) {
799                         char fname[FILE_MAX];
800
801                         get_tc_filename(anim, tc_types[i], fname);
802
803                         indexer[i] = IMB_index_builder_create(fname);
804                         if (!indexer[i]) {
805                                 tcs_in_use &= ~tc_types[i];
806                         }
807                 }
808         }
809
810         frame_rate = av_q2d(iStream->r_frame_rate);
811         pts_time_base = av_q2d(iStream->time_base);
812
813         while(av_read_frame(iFormatCtx, &next_packet) >= 0) {
814                 int frame_finished = 0;
815                 float next_progress =  (float)((int)floor(((double) next_packet.pos) * 100 /
816                                                    ((double) stream_size)+0.5)) / 100;
817
818                 if (*progress != next_progress) {
819                         *progress = next_progress;
820                         *do_update = 1;
821                 }
822
823                 if (*stop) {
824                         av_free_packet(&next_packet);
825                         break;
826                 }
827
828                 if (next_packet.stream_index == videoStream) {
829                         if (next_packet.flags & AV_PKT_FLAG_KEY) {
830                                 last_seek_pos = seek_pos;
831                                 last_seek_pos_dts = seek_pos_dts;
832                                 seek_pos = next_packet.pos;
833                                 seek_pos_dts = next_packet.dts;
834                                 seek_pos_pts = next_packet.pts;
835                         }
836
837                         avcodec_decode_video2(
838                                 iCodecCtx, in_frame, &frame_finished, 
839                                 &next_packet);
840                 }
841
842                 if (frame_finished) {
843                         unsigned long long s_pos = seek_pos;
844                         unsigned long long s_dts = seek_pos_dts;
845                         unsigned long long pts 
846                                 = av_get_pts_from_frame(iFormatCtx, in_frame);
847
848                         for (i = 0; i < num_proxy_sizes; i++) {
849                                 add_to_proxy_output_ffmpeg(
850                                         proxy_ctx[i], in_frame);
851                         }
852
853                         if (!start_pts_set) {
854                                 start_pts = pts;
855                                 start_pts_set = TRUE;
856                         }
857
858                         frameno = floor((pts - start_pts)
859                                 * pts_time_base * frame_rate + 0.5f);
860
861                         /* decoding starts *always* on I-Frames,
862                            so: P-Frames won't work, even if all the
863                            information is in place, when we seek
864                            to the I-Frame presented *after* the P-Frame,
865                            but located before the P-Frame within
866                            the stream */
867
868                         if (pts < seek_pos_pts) {
869                                 s_pos = last_seek_pos;
870                                 s_dts = last_seek_pos_dts;
871                         }
872
873                         for (i = 0; i < num_indexers; i++) {
874                                 if (tcs_in_use & tc_types[i]) {
875                                         int tc_frameno = frameno;
876
877                                         if(tc_types[i] == IMB_TC_RECORD_RUN_NO_GAPS)
878                                                 tc_frameno = frameno_gapless;
879
880                                         IMB_index_builder_proc_frame(
881                                                 indexer[i], 
882                                                 next_packet.data, 
883                                                 next_packet.size,
884                                                 tc_frameno,
885                                                 s_pos, s_dts, pts);
886                                 }
887                         }
888
889                         frameno_gapless++;
890                 }
891                 av_free_packet(&next_packet);
892         }
893
894         for (i = 0; i < num_indexers; i++) {
895                 if (tcs_in_use & tc_types[i]) {
896                         IMB_index_builder_finish(indexer[i], *stop);
897                 }
898         }
899
900         for (i = 0; i < num_proxy_sizes; i++) {
901                 if (proxy_sizes_in_use & proxy_sizes[i]) {
902                         free_proxy_output_ffmpeg(proxy_ctx[i], *stop);
903                 }
904         }
905
906         av_free(in_frame);
907
908         return 1;
909 }
910
911 #endif
912
913 /* ----------------------------------------------------------------------
914    - internal AVI (fallback) rebuilder
915    ---------------------------------------------------------------------- */
916
917 static AviMovie * alloc_proxy_output_avi(
918         struct anim * anim, char * filename, int width, int height,
919         int quality)
920 {
921         int x, y;
922         AviFormat format;
923         double framerate;
924         AviMovie * avi;
925         short frs_sec = 25;      /* it doesn't really matter for proxies,
926                                     but sane defaults help anyways...*/
927         float frs_sec_base = 1.0;
928
929         IMB_anim_get_fps(anim, &frs_sec, &frs_sec_base);
930         
931         x = width;
932         y = height;
933
934         framerate= (double) frs_sec / (double) frs_sec_base;
935         
936         avi = MEM_mallocN (sizeof(AviMovie), "avimovie");
937
938         format = AVI_FORMAT_MJPEG;
939
940         if (AVI_open_compress (filename, avi, 1, format) != AVI_ERROR_NONE) {
941                 MEM_freeN(avi);
942                 return NULL;
943         }
944                         
945         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x);
946         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &y);
947         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &quality);           
948         AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &framerate);
949
950         avi->interlace= 0;
951         avi->odd_fields= 0;
952
953         return avi;
954 }
955
956 static void index_rebuild_fallback(struct anim * anim,
957                                    IMB_Timecode_Type UNUSED(tcs_in_use),
958                                    IMB_Proxy_Size proxy_sizes_in_use,
959                                    int quality,
960                                    short *stop, short *do_update, 
961                                    float *progress)
962 {
963         int cnt = IMB_anim_get_duration(anim, IMB_TC_NONE);
964         int i, pos;
965         AviMovie * proxy_ctx[IMB_PROXY_MAX_SLOT];
966         char fname[FILE_MAX];
967         char fname_tmp[FILE_MAX];
968         
969         memset(proxy_ctx, 0, sizeof(proxy_ctx));
970
971         /* since timecode indices only work with ffmpeg right now,
972            don't know a sensible fallback here...
973
974            so no proxies, no game to play...
975         */
976         if (proxy_sizes_in_use == IMB_PROXY_NONE) {
977                 return;
978         }
979
980         for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
981                 if (proxy_sizes_in_use & proxy_sizes[i]) {
982                         char fname[FILE_MAX];
983
984                         get_proxy_filename(anim, proxy_sizes[i], fname, TRUE);
985                         BLI_make_existing_file(fname);
986
987                         proxy_ctx[i] = alloc_proxy_output_avi(
988                                 anim, fname,
989                                 anim->x * proxy_fac[i],
990                                 anim->y * proxy_fac[i],
991                                 quality);
992                 }
993         }
994
995         for (pos = 0; pos < cnt; pos++) {
996                 struct ImBuf * ibuf = IMB_anim_absolute(
997                         anim, pos, IMB_TC_NONE, IMB_PROXY_NONE);
998                 int next_progress = (int) ((double) pos / (double) cnt);
999
1000                 if (*progress != next_progress) {
1001                         *progress = next_progress;
1002                         *do_update = 1;
1003                 }
1004                 
1005                 if (*stop) {
1006                         break;
1007                 }
1008
1009                 IMB_flipy(ibuf);
1010
1011                 for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
1012                         if (proxy_sizes_in_use & proxy_sizes[i]) {
1013                                 int x = anim->x * proxy_fac[i];
1014                                 int y = anim->y * proxy_fac[i];
1015
1016                                 struct ImBuf * s_ibuf = IMB_scalefastImBuf(
1017                                         ibuf, x, y);
1018
1019                                 IMB_convert_rgba_to_abgr(s_ibuf);
1020         
1021                                 AVI_write_frame (proxy_ctx[i], pos, 
1022                                                  AVI_FORMAT_RGB32, 
1023                                                  s_ibuf->rect, x * y * 4);
1024
1025                                 /* note that libavi free's the buffer... */
1026                                 s_ibuf->rect = NULL;
1027
1028                                 IMB_freeImBuf(s_ibuf);
1029                         }
1030                 }
1031         }
1032
1033         for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
1034                 if (proxy_sizes_in_use & proxy_sizes[i]) {
1035                         AVI_close_compress (proxy_ctx[i]);
1036                         MEM_freeN (proxy_ctx[i]);
1037
1038                         get_proxy_filename(anim, proxy_sizes[i], 
1039                                            fname_tmp, TRUE);
1040                         get_proxy_filename(anim, proxy_sizes[i], 
1041                                            fname, FALSE);
1042
1043                         if (*stop) {
1044                                 unlink(fname_tmp);
1045                         } else {
1046                                 rename(fname_tmp, fname);
1047                         }
1048                 }
1049         }
1050 }
1051
1052 /* ----------------------------------------------------------------------
1053    - public API
1054    ---------------------------------------------------------------------- */
1055
1056 void IMB_anim_index_rebuild(struct anim * anim, IMB_Timecode_Type tcs_in_use,
1057                             IMB_Proxy_Size proxy_sizes_in_use,
1058                             int quality,
1059                             short *stop, short *do_update, float *progress)
1060 {
1061         switch (anim->curtype) {
1062 #ifdef WITH_FFMPEG
1063         case ANIM_FFMPEG:
1064                 index_rebuild_ffmpeg(anim, tcs_in_use, proxy_sizes_in_use,
1065                                      quality, stop, do_update, progress);
1066                 break;
1067 #endif
1068         default:
1069                 index_rebuild_fallback(anim, tcs_in_use, proxy_sizes_in_use,
1070                                        quality, stop, do_update, progress);
1071                 break;
1072         }
1073 }
1074
1075 void IMB_free_indices(struct anim * anim)
1076 {
1077         int i;
1078
1079         for (i = 0; i < IMB_PROXY_MAX_SLOT; i++) {
1080                 if (anim->proxy_anim[i]) {
1081                         IMB_close_anim(anim->proxy_anim[i]);
1082                         anim->proxy_anim[i] = NULL;
1083                 }
1084         }
1085
1086         for (i = 0; i < IMB_TC_MAX_SLOT; i++) {
1087                 if (anim->curr_idx[i]) {
1088                         IMB_indexer_close(anim->curr_idx[i]);
1089                         anim->curr_idx[i] = NULL;
1090                 }
1091         }
1092
1093
1094         anim->proxies_tried = 0;
1095         anim->indices_tried = 0;
1096 }
1097
1098 void IMB_anim_set_index_dir(struct anim * anim, const char * dir)
1099 {
1100         if (strcmp(anim->index_dir, dir) == 0) {
1101                 return;
1102         }
1103         BLI_strncpy(anim->index_dir, dir, sizeof(anim->index_dir));
1104
1105         IMB_free_indices(anim);
1106 }
1107
1108 struct anim * IMB_anim_open_proxy(
1109         struct anim * anim, IMB_Proxy_Size preview_size)
1110 {
1111         char fname[FILE_MAX];
1112         int i = IMB_proxy_size_to_array_index(preview_size);
1113
1114         if (anim->proxy_anim[i]) {
1115                 return anim->proxy_anim[i];
1116         }
1117
1118         if (anim->proxies_tried & preview_size) {
1119                 return NULL;
1120         }
1121
1122         get_proxy_filename(anim, preview_size, fname, FALSE);
1123
1124         anim->proxy_anim[i] = IMB_open_anim(fname, 0, 0);
1125         
1126         anim->proxies_tried |= preview_size;
1127
1128         return anim->proxy_anim[i];
1129 }
1130
1131 struct anim_index * IMB_anim_open_index(
1132         struct anim * anim, IMB_Timecode_Type tc)
1133 {
1134         char fname[FILE_MAX];
1135         int i = IMB_timecode_to_array_index(tc);
1136
1137         if (anim->curr_idx[i]) {
1138                 return anim->curr_idx[i];
1139         }
1140
1141         if (anim->indices_tried & tc) {
1142                 return NULL;
1143         }
1144
1145         get_tc_filename(anim, tc, fname);
1146
1147         anim->curr_idx[i] = IMB_indexer_open(fname);
1148         
1149         anim->indices_tried |= tc;
1150
1151         return anim->curr_idx[i];
1152 }
1153
1154 int IMB_anim_index_get_frame_index(struct anim * anim, IMB_Timecode_Type tc,
1155                                    int position)
1156 {
1157         struct anim_index * idx = IMB_anim_open_index(anim, tc);
1158
1159         if (!idx) {
1160                 return position;
1161         }
1162
1163         return IMB_indexer_get_frame_index(idx, position);
1164 }
1165