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