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