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