Merging r39199 through r39485 from trunk into vgroup_modifiers.
[blender-staging.git] / source / blender / imbuf / intern / anim_movie.c
1 /*
2  * anim.c
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 /** \file blender/imbuf/intern/anim_movie.c
33  *  \ingroup imbuf
34  */
35
36
37 #ifdef _WIN32
38 #define INC_OLE2
39 #include <windows.h>
40 #include <windowsx.h>
41 #include <mmsystem.h>
42 #include <memory.h>
43 #include <commdlg.h>
44
45 #ifndef FREE_WINDOWS
46 #include <vfw.h>
47 #endif
48
49 #undef AVIIF_KEYFRAME // redefined in AVI_avi.h
50 #undef AVIIF_LIST // redefined in AVI_avi.h
51
52 #define FIXCC(fcc)  if (fcc == 0)       fcc = mmioFOURCC('N', 'o', 'n', 'e'); \
53                 if (fcc == BI_RLE8) fcc = mmioFOURCC('R', 'l', 'e', '8');
54 #endif
55
56 #include <sys/types.h>
57 #include <ctype.h>
58 #include <stdlib.h>
59 #include <stdio.h>
60 #ifndef _WIN32
61 #include <dirent.h>
62 #else
63 #include <io.h>
64 #endif
65
66 #include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail
67                                                         BLI_countlist BLI_stringdec */
68 #include "BLI_utildefines.h"
69
70 #include "MEM_guardedalloc.h"
71
72 #include "DNA_userdef_types.h"
73
74
75 #include "BKE_global.h"
76 #include "BKE_depsgraph.h"
77
78 #include "imbuf.h"
79
80 #include "AVI_avi.h"
81
82 #ifdef WITH_QUICKTIME
83 #if defined(_WIN32) || defined(__APPLE__)
84 #include "quicktime_import.h"
85 #endif /* _WIN32 || __APPLE__ */
86 #endif /* WITH_QUICKTIME */
87
88 #include "IMB_imbuf_types.h"
89 #include "IMB_imbuf.h"
90
91 #include "IMB_allocimbuf.h"
92 #include "IMB_anim.h"
93
94 #ifdef WITH_FFMPEG
95 #include <libavformat/avformat.h>
96 #include <libavcodec/avcodec.h>
97 #include <libavutil/rational.h>
98 #include <libswscale/swscale.h>
99
100 #include "ffmpeg_compat.h"
101
102 #endif //WITH_FFMPEG
103
104 #ifdef WITH_REDCODE
105 #ifdef _WIN32 /* on windows we use the ones in extern instead */
106 #include "libredcode/format.h"
107 #include "libredcode/codec.h"
108 #else
109 #include "libredcode/format.h"
110 #include "libredcode/codec.h"
111 #endif
112 #endif
113
114 /****/
115
116 #ifdef __sgi
117
118 #include <dmedia/moviefile.h>
119
120 static void movie_printerror(char * str) {
121         const char * errstr = mvGetErrorStr(mvGetErrno());
122
123         if (str) {
124                 if (errstr) printf("%s: %s\n", str, errstr);
125                 else printf("%s: returned error\n", str);
126         } else printf("%s\n", errstr);
127 }
128
129 static int startmovie(struct anim * anim) {
130         if (anim == 0) return(-1);
131
132         if ( mvOpenFile (anim->name, O_BINARY|O_RDONLY, &anim->movie ) != DM_SUCCESS ) {
133                 printf("Can't open movie: %s\n", anim->name);
134                 return(-1);
135         }
136         if ( mvFindTrackByMedium (anim->movie, DM_IMAGE, &anim->track) != DM_SUCCESS ) {
137                 printf("No image track in movie: %s\n", anim->name);
138                 mvClose(anim->movie);
139                 return(-1);
140         }
141
142         anim->duration = mvGetTrackLength (anim->track);
143         anim->params = mvGetParams( anim->track );
144
145         anim->x = dmParamsGetInt( anim->params, DM_IMAGE_WIDTH);
146         anim->y = dmParamsGetInt( anim->params, DM_IMAGE_HEIGHT);
147         anim->interlacing = dmParamsGetEnum (anim->params, DM_IMAGE_INTERLACING);
148         anim->orientation = dmParamsGetEnum (anim->params, DM_IMAGE_ORIENTATION);
149         anim->framesize = dmImageFrameSize(anim->params);
150
151         anim->curposition = 0;
152         anim->preseek = 0;
153
154         /*printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
155         return (0);
156 }
157
158 static ImBuf * movie_fetchibuf(struct anim * anim, int position) {
159         ImBuf * ibuf;
160 /*      extern rectcpy(); */
161         int size;
162         unsigned int *rect1, *rect2;
163
164         if (anim == 0) return (0);
165
166         ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect);
167
168         if ( mvReadFrames(anim->track, position, 1, ibuf->x * ibuf->y * 
169                 sizeof(int), ibuf->rect ) != DM_SUCCESS ) {
170                 movie_printerror("mvReadFrames");
171                 IMB_freeImBuf(ibuf);
172                 return(0);
173         }
174
175 /*
176         if (anim->interlacing == DM_IMAGE_INTERLACED_EVEN) {
177                 rect1 = ibuf->rect + (ibuf->x * ibuf->y) - 1;
178                 rect2 = rect1 - ibuf->x;
179
180                 for (size = ibuf->x * (ibuf->y - 1); size > 0; size--){
181                         *rect1-- = *rect2--;
182                 }
183         }
184 */
185
186         if (anim->interlacing == DM_IMAGE_INTERLACED_EVEN)
187         {
188                 rect1 = ibuf->rect;
189                 rect2 = rect1 + ibuf->x;
190
191                 for (size = ibuf->x * (ibuf->y - 1); size > 0; size--){
192                         *rect1++ = *rect2++;
193                 }
194         }
195         /*if (anim->orientation == DM_TOP_TO_BOTTOM) IMB_flipy(ibuf);*/
196
197
198         return(ibuf);
199 }
200
201 static void free_anim_movie(struct anim * anim) {
202         if (anim == NULL) return;
203
204         if (anim->movie) {
205                 mvClose(anim->movie);
206                 anim->movie = NULL;
207         }
208         anim->duration = 0;
209 }
210
211 int ismovie(char *name) {
212         return (mvIsMovieFile(name) == DM_TRUE);
213 }
214
215 #else
216
217 int ismovie(const char *UNUSED(name)) {
218         return 0;
219 }
220
221         /* never called, just keep the linker happy */
222 static int startmovie(struct anim *UNUSED(anim)) { return 1; }
223 static ImBuf * movie_fetchibuf(struct anim *UNUSED(anim), int UNUSED(position)) { return NULL; }
224 static void free_anim_movie(struct anim *UNUSED(anim)) { ; }
225
226 #endif
227
228 #if defined(_WIN32)
229 # define PATHSEPERATOR '\\'
230 #else
231 # define PATHSEPERATOR '/'
232 #endif
233
234 static int an_stringdec(const char *string, char* head, char *tail, unsigned short *numlen) {
235         unsigned short len,nume,nums=0;
236         short i,found=FALSE;
237
238         len=strlen(string);
239         nume = len;
240
241         for(i=len-1;i>=0;i--){
242                 if (string[i]==PATHSEPERATOR) break;
243                 if (isdigit(string[i])) {
244                         if (found){
245                                 nums=i;
246                         } else{
247                                 nume=i;
248                                 nums=i;
249                                 found=TRUE;
250                         }
251                 } else{
252                         if (found) break;
253                 }
254         }
255         if (found){
256                 strcpy(tail ,&string[nume+1]);
257                 strcpy(head, string);
258                 head[nums]= '\0';
259                 *numlen=nume-nums+1;
260                 return ((int)atoi(&(string[nums])));
261         }
262         tail[0]= '\0';
263         strcpy(head, string);
264         *numlen=0;
265         return TRUE;
266 }
267
268
269 static void an_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic) {
270         BLI_stringenc(string, head, tail, numlen, pic);
271 }
272
273 static void free_anim_avi (struct anim *anim) {
274 #if defined(_WIN32) && !defined(FREE_WINDOWS)
275         int i;
276 #endif
277
278         if (anim == NULL) return;
279         if (anim->avi == NULL) return;
280
281         AVI_close (anim->avi);
282         MEM_freeN (anim->avi);
283         anim->avi = NULL;
284
285 #if defined(_WIN32) && !defined(FREE_WINDOWS)
286
287         if (anim->pgf) {
288                 AVIStreamGetFrameClose(anim->pgf);
289                 anim->pgf = NULL;
290         }
291
292         for (i = 0; i < anim->avistreams; i++){
293                 AVIStreamRelease(anim->pavi[i]);
294         }
295         anim->avistreams = 0;
296
297         if (anim->pfileopen) {
298                 AVIFileRelease(anim->pfile);
299                 anim->pfileopen = 0;
300                 AVIFileExit();
301         }
302 #endif
303
304         anim->duration = 0;
305 }
306
307 void IMB_free_anim_ibuf(struct anim * anim) {
308         if (anim == NULL) return;
309
310         if (anim->ibuf1) IMB_freeImBuf(anim->ibuf1);
311         if (anim->ibuf2) IMB_freeImBuf(anim->ibuf2);
312
313         anim->ibuf1 = anim->ibuf2 = NULL;
314 }
315
316 #ifdef WITH_FFMPEG
317 static void free_anim_ffmpeg(struct anim * anim);
318 #endif
319 #ifdef WITH_REDCODE
320 static void free_anim_redcode(struct anim * anim);
321 #endif
322
323 void IMB_free_anim(struct anim * anim) {
324         if (anim == NULL) {
325                 printf("free anim, anim == NULL\n");
326                 return;
327         }
328
329         IMB_free_anim_ibuf(anim);
330         free_anim_movie(anim);
331         free_anim_avi(anim);
332
333 #ifdef WITH_QUICKTIME
334         free_anim_quicktime(anim);
335 #endif
336 #ifdef WITH_FFMPEG
337         free_anim_ffmpeg(anim);
338 #endif
339 #ifdef WITH_REDCODE
340         free_anim_redcode(anim);
341 #endif
342
343         MEM_freeN(anim);
344 }
345
346 void IMB_close_anim(struct anim * anim) {
347         if (anim == NULL) return;
348
349         IMB_free_anim(anim);
350 }
351
352
353 struct anim * IMB_open_anim( const char * name, int ib_flags) {
354         struct anim * anim;
355
356         anim = (struct anim*)MEM_callocN(sizeof(struct anim), "anim struct");
357         if (anim != NULL) {
358                 BLI_strncpy(anim->name, name, sizeof(anim->name));
359                 anim->ib_flags = ib_flags;
360         }
361         return(anim);
362 }
363
364
365 static int startavi (struct anim *anim) {
366
367         AviError avierror;
368 #if defined(_WIN32) && !defined(FREE_WINDOWS)
369         HRESULT hr;
370         int i, firstvideo = -1;
371         BYTE abFormat[1024];
372         LONG l;
373         LPBITMAPINFOHEADER lpbi;
374         AVISTREAMINFO avis;
375 #endif
376
377         anim->avi = MEM_callocN (sizeof(AviMovie),"animavi");
378
379         if (anim->avi == NULL) {
380                 printf("Can't open avi: %s\n", anim->name);
381                 return -1;
382         }
383
384         avierror = AVI_open_movie (anim->name, anim->avi);
385
386 #if defined(_WIN32) && !defined(FREE_WINDOWS)
387         if (avierror == AVI_ERROR_COMPRESSION) {
388                 AVIFileInit();
389                 hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L);
390                 if (hr == 0) {
391                         anim->pfileopen = 1;
392                         for (i = 0; i < MAXNUMSTREAMS; i++) {
393                                 if (AVIFileGetStream(anim->pfile, &anim->pavi[i], 0L, i) != AVIERR_OK) {
394                                         break;
395                                 }
396                                 
397                                 AVIStreamInfo(anim->pavi[i], &avis, sizeof(avis));
398                                 if ((avis.fccType == streamtypeVIDEO) && (firstvideo == -1)) {
399                                         anim->pgf = AVIStreamGetFrameOpen(anim->pavi[i], NULL);
400                                         if (anim->pgf) {
401                                                 firstvideo = i;
402
403                                                 // get stream length
404                                                 anim->avi->header->TotalFrames = AVIStreamLength(anim->pavi[i]);
405                                                 
406                                                 // get information about images inside the stream
407                                                 l = sizeof(abFormat);
408                                                 AVIStreamReadFormat(anim->pavi[i], 0, &abFormat, &l);
409                                                 lpbi = (LPBITMAPINFOHEADER)abFormat;
410                                                 anim->avi->header->Height = lpbi->biHeight;
411                                                 anim->avi->header->Width = lpbi->biWidth;
412                                         } else {
413                                                 FIXCC(avis.fccHandler);
414                                                 FIXCC(avis.fccType);
415                                                 printf("Can't find AVI decoder for type : %4.4hs/%4.4hs\n",
416                                                         (LPSTR)&avis.fccType,
417                                                         (LPSTR)&avis.fccHandler);
418                                         }
419                                 }
420                         }
421
422                         // register number of opened avistreams
423                         anim->avistreams = i;
424
425                         //
426                         // Couldn't get any video streams out of this file
427                         //
428                         if ((anim->avistreams == 0) || (firstvideo == -1)) {
429                                 avierror = AVI_ERROR_FORMAT;
430                         } else {
431                                 avierror = AVI_ERROR_NONE;
432                                 anim->firstvideo = firstvideo;
433                         }
434                 } else {
435                         AVIFileExit();
436                 }
437         }
438 #endif
439
440         if (avierror != AVI_ERROR_NONE) {
441                 AVI_print_error(avierror);
442                 printf ("Error loading avi: %s\n", anim->name);         
443                 free_anim_avi(anim);
444                 return -1;
445         }
446         
447         anim->duration = anim->avi->header->TotalFrames;
448         anim->params = NULL;
449
450         anim->x = anim->avi->header->Width;
451         anim->y = anim->avi->header->Height;
452         anim->interlacing = 0;
453         anim->orientation = 0;
454         anim->framesize = anim->x * anim->y * 4;
455
456         anim->curposition = 0;
457         anim->preseek = 0;
458
459         /*  printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
460
461         return 0;
462 }
463
464 static ImBuf * avi_fetchibuf (struct anim *anim, int position) {
465         ImBuf *ibuf = NULL;
466         int *tmp;
467         int y;
468         
469         if (anim == NULL) return (NULL);
470
471 #if defined(_WIN32) && !defined(FREE_WINDOWS)
472         if (anim->avistreams) {
473                 LPBITMAPINFOHEADER lpbi;
474
475                 if (anim->pgf) {
476                         lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo]));
477                         if (lpbi) {
478                                 ibuf = IMB_ibImageFromMemory((unsigned char *) lpbi, 100, IB_rect);
479 //Oh brother...
480                         }
481                 }
482         } else {
483 #else
484         if (1) {
485 #endif
486                 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, IB_rect);
487
488                 tmp = AVI_read_frame (anim->avi, AVI_FORMAT_RGB32, position,
489                         AVI_get_stream(anim->avi, AVIST_VIDEO, 0));
490                 
491                 if (tmp == NULL) {
492                         printf ("Error reading frame from AVI");
493                         IMB_freeImBuf (ibuf);
494                         return NULL;
495                 }
496
497                 for (y=0; y < anim->y; y++) {
498                         memcpy (&(ibuf->rect)[((anim->y-y)-1)*anim->x],  &tmp[y*anim->x],  
499                                         anim->x * 4);
500                 }
501                 
502                 MEM_freeN (tmp);
503         }
504
505         ibuf->profile = IB_PROFILE_SRGB;
506                 
507         return ibuf;
508 }
509
510 #ifdef WITH_FFMPEG
511
512 extern void do_init_ffmpeg(void);
513
514 static int startffmpeg(struct anim * anim) {
515         int            i, videoStream;
516
517         AVCodec *pCodec;
518         AVFormatContext *pFormatCtx;
519         AVCodecContext *pCodecCtx;
520
521 #ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
522         /* The following for color space determination */
523         int srcRange, dstRange, brightness, contrast, saturation;
524         int *table;
525         const int *inv_table;
526 #endif
527
528         if (anim == 0) return(-1);
529
530         do_init_ffmpeg();
531
532         if(av_open_input_file(&pFormatCtx, anim->name, NULL, 0, NULL)!=0) {
533                 return -1;
534         }
535
536         if(av_find_stream_info(pFormatCtx)<0) {
537                 av_close_input_file(pFormatCtx);
538                 return -1;
539         }
540
541         av_dump_format(pFormatCtx, 0, anim->name, 0);
542
543
544                 /* Find the first video stream */
545         videoStream=-1;
546         for(i=0; i<pFormatCtx->nb_streams; i++)
547                 if(pFormatCtx->streams[i]->codec->codec_type
548                    == AVMEDIA_TYPE_VIDEO) {
549                         videoStream=i;
550                         break;
551                 }
552
553         if(videoStream==-1) {
554                 av_close_input_file(pFormatCtx);
555                 return -1;
556         }
557
558         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
559
560                 /* Find the decoder for the video stream */
561         pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
562         if(pCodec==NULL) {
563                 av_close_input_file(pFormatCtx);
564                 return -1;
565         }
566
567         pCodecCtx->workaround_bugs = 1;
568
569         if(avcodec_open(pCodecCtx, pCodec)<0) {
570                 av_close_input_file(pFormatCtx);
571                 return -1;
572         }
573
574         anim->duration = ceil(pFormatCtx->duration
575                 * av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate) 
576                 / AV_TIME_BASE);
577
578         anim->params = 0;
579
580         anim->x = pCodecCtx->width;
581         anim->y = pCodecCtx->height;
582         anim->interlacing = 0;
583         anim->orientation = 0;
584         anim->framesize = anim->x * anim->y * 4;
585
586         anim->curposition = -1;
587
588         anim->pFormatCtx = pFormatCtx;
589         anim->pCodecCtx = pCodecCtx;
590         anim->pCodec = pCodec;
591         anim->videoStream = videoStream;
592
593         anim->pFrame = avcodec_alloc_frame();
594         anim->pFrameDeinterlaced = avcodec_alloc_frame();
595         anim->pFrameRGB = avcodec_alloc_frame();
596
597         if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y)
598                 != anim->x * anim->y * 4) {
599                 fprintf (stderr,
600                          "ffmpeg has changed alloc scheme ... ARGHHH!\n");
601                 avcodec_close(anim->pCodecCtx);
602                 av_close_input_file(anim->pFormatCtx);
603                 av_free(anim->pFrameRGB);
604                 av_free(anim->pFrameDeinterlaced);
605                 av_free(anim->pFrame);
606                 anim->pCodecCtx = NULL;
607                 return -1;
608         }
609
610         if (anim->ib_flags & IB_animdeinterlace) {
611                 avpicture_fill((AVPicture*) anim->pFrameDeinterlaced, 
612                                    MEM_callocN(avpicture_get_size(
613                                                    anim->pCodecCtx->pix_fmt,
614                                                    anim->x, anim->y), 
615                                            "ffmpeg deinterlace"), 
616                                    anim->pCodecCtx->pix_fmt, anim->x, anim->y);
617         }
618
619         if (pCodecCtx->has_b_frames) {
620                 anim->preseek = 25; /* FIXME: detect gopsize ... */
621         } else {
622                 anim->preseek = 0;
623         }
624         
625         anim->img_convert_ctx = sws_getContext(
626                 anim->pCodecCtx->width,
627                 anim->pCodecCtx->height,
628                 anim->pCodecCtx->pix_fmt,
629                 anim->pCodecCtx->width,
630                 anim->pCodecCtx->height,
631                 PIX_FMT_RGBA,
632                 SWS_FAST_BILINEAR | SWS_PRINT_INFO,
633                 NULL, NULL, NULL);
634                 
635         if (!anim->img_convert_ctx) {
636                 fprintf (stderr,
637                          "Can't transform color space??? Bailing out...\n");
638                 avcodec_close(anim->pCodecCtx);
639                 av_close_input_file(anim->pFormatCtx);
640                 av_free(anim->pFrameRGB);
641                 av_free(anim->pFrameDeinterlaced);
642                 av_free(anim->pFrame);
643                 anim->pCodecCtx = NULL;
644                 return -1;
645         }
646
647 #ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
648         /* Try do detect if input has 0-255 YCbCR range (JFIF Jpeg MotionJpeg) */
649         if (!sws_getColorspaceDetails(anim->img_convert_ctx, (int**)&inv_table, &srcRange,
650                 &table, &dstRange, &brightness, &contrast, &saturation)) {
651
652                 srcRange = srcRange || anim->pCodecCtx->color_range == AVCOL_RANGE_JPEG;
653                 inv_table = sws_getCoefficients(anim->pCodecCtx->colorspace);
654
655                 if(sws_setColorspaceDetails(anim->img_convert_ctx, (int *)inv_table, srcRange,
656                         table, dstRange, brightness, contrast, saturation)) {
657
658                         printf("Warning: Could not set libswscale colorspace details.\n");
659                         }
660         }
661         else {
662                 printf("Warning: Could not set libswscale colorspace details.\n");
663         }
664 #endif
665                 
666         return (0);
667 }
668
669 static void ffmpeg_postprocess(struct anim * anim, ImBuf * ibuf,
670                                int * filter_y)
671 {
672         AVFrame * input = anim->pFrame;
673
674         /* This means the data wasnt read properly, 
675            this check stops crashing */
676         if (input->data[0]==0 && input->data[1]==0 
677             && input->data[2]==0 && input->data[3]==0){
678                 fprintf(stderr, "ffmpeg_fetchibuf: "
679                         "data not read properly...\n");
680                 return;
681         }
682
683         if (anim->ib_flags & IB_animdeinterlace) {
684                 if (avpicture_deinterlace(
685                             (AVPicture*) 
686                             anim->pFrameDeinterlaced,
687                             (const AVPicture*)
688                             anim->pFrame,
689                             anim->pCodecCtx->pix_fmt,
690                             anim->pCodecCtx->width,
691                             anim->pCodecCtx->height)
692                     < 0) {
693                         *filter_y = 1;
694                 } else {
695                         input = anim->pFrameDeinterlaced;
696                 }
697         }
698         
699         if (ENDIAN_ORDER == B_ENDIAN) {
700                 int * dstStride   = anim->pFrameRGB->linesize;
701                 uint8_t** dst     = anim->pFrameRGB->data;
702                 int dstStride2[4] = { dstStride[0], 0, 0, 0 };
703                 uint8_t* dst2[4]  = { dst[0], 0, 0, 0 };
704                 int x,y,h,w;
705                 unsigned char* bottom;
706                 unsigned char* top;
707                 
708                 sws_scale(anim->img_convert_ctx,
709                           (const uint8_t * const *)input->data,
710                           input->linesize,
711                           0,
712                           anim->pCodecCtx->height,
713                           dst2,
714                           dstStride2);
715                 
716                 /* workaround: sws_scale bug
717                    sets alpha = 0 and compensate
718                    for altivec-bugs and flipy... */
719                 
720                 bottom = (unsigned char*) ibuf->rect;
721                 top = bottom + ibuf->x * (ibuf->y-1) * 4;
722                 
723                 h = (ibuf->y + 1) / 2;
724                 w = ibuf->x;
725                 
726                 for (y = 0; y < h; y++) {
727                         unsigned char tmp[4];
728                         unsigned int * tmp_l =
729                                 (unsigned int*) tmp;
730                         tmp[3] = 0xff;
731                         
732                         for (x = 0; x < w; x++) {
733                                 tmp[0] = bottom[0];
734                                 tmp[1] = bottom[1];
735                                 tmp[2] = bottom[2];
736                                 
737                                 bottom[0] = top[0];
738                                 bottom[1] = top[1];
739                                 bottom[2] = top[2];
740                                 bottom[3] = 0xff;
741                                 
742                                 *(unsigned int*) top = *tmp_l;
743                                 
744                                 bottom +=4;
745                                 top += 4;
746                         }
747                         top -= 8 * w;
748                 }
749         } else {
750                 int * dstStride   = anim->pFrameRGB->linesize;
751                 uint8_t** dst     = anim->pFrameRGB->data;
752                 int dstStride2[4] = { -dstStride[0], 0, 0, 0 };
753                 uint8_t* dst2[4]  = { dst[0] + (anim->y - 1)*dstStride[0],
754                                       0, 0, 0 };
755                 int i;
756                 unsigned char* r;
757                 
758                 sws_scale(anim->img_convert_ctx,
759                           (const uint8_t * const *)input->data,
760                           input->linesize,
761                           0,
762                           anim->pCodecCtx->height,
763                           dst2,
764                           dstStride2);
765                 
766                 r = (unsigned char*) ibuf->rect;
767                 
768                 /* workaround sws_scale bug: older version of 
769                    sws_scale set alpha = 0... */
770                 if (r[3] == 0) {
771                         for (i = 0; i < ibuf->x * ibuf->y; i++) {
772                                 r[3] = 0xff;
773                                 r += 4;
774                         }
775                 }
776         }
777 }
778
779 static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
780         ImBuf * ibuf;
781         int frameFinished;
782         AVPacket packet;
783         int64_t pts_to_search = 0;
784         int pos_found = 1;
785         int filter_y = 0;
786         int seek_by_bytes= 0;
787         int preseek_count = 0;
788
789         if (anim == 0) return (0);
790
791         ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
792
793         avpicture_fill((AVPicture*) anim->pFrameRGB, 
794                            (unsigned char*) ibuf->rect, 
795                            PIX_FMT_RGBA, anim->x, anim->y);
796
797         if (position != anim->curposition + 1) { 
798                 if (position > anim->curposition + 1 
799                         && anim->preseek 
800                         && position - (anim->curposition + 1) < anim->preseek) {
801                         while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
802                                 if (packet.stream_index == anim->videoStream) {
803                                         avcodec_decode_video2(
804                                                 anim->pCodecCtx, 
805                                                 anim->pFrame, &frameFinished, 
806                                                 &packet);
807
808                                         if (frameFinished) {
809                                                 anim->curposition++;
810                                         }
811                                 }
812                                 av_free_packet(&packet);
813                                 if (position == anim->curposition+1) {
814                                         break;
815                                 }
816                         }
817                 }
818         }
819
820 /* disable seek_by_bytes for now, since bitrates are guessed wrong!
821    also: MPEG2TS-seeking was fixed in later versions of ffmpeg, so problem
822    is somewhat fixed by now (until we add correct timecode management code...)
823 */
824 #if 0
825         seek_by_bytes = !!(anim->pFormatCtx->iformat->flags & AVFMT_TS_DISCONT);
826 #else
827         seek_by_bytes = FALSE;
828 #endif
829
830         if (position != anim->curposition + 1) { 
831                 double frame_rate = 
832                         av_q2d(anim->pFormatCtx->streams[anim->videoStream]
833                                    ->r_frame_rate);
834                 double pts_time_base = av_q2d(anim->pFormatCtx->streams[anim->videoStream]->time_base);
835                 long long pos;
836                 long long st_time = anim->pFormatCtx->start_time;
837                 int ret;
838
839                 if (seek_by_bytes) {
840                         pos = position - anim->preseek;
841                         if (pos < 0) {
842                                 pos = 0;
843                         }
844                         preseek_count = position - pos;
845
846                         pos *= anim->pFormatCtx->bit_rate / frame_rate;
847                         pos /= 8;
848                 } else {
849                         pos = (long long) (position - anim->preseek) 
850                                 * AV_TIME_BASE / frame_rate;
851                         if (pos < 0) {
852                                 pos = 0;
853                         }
854
855                         if (st_time != AV_NOPTS_VALUE) {
856                                 pos += st_time;
857                         }
858                 }
859
860                 ret = av_seek_frame(anim->pFormatCtx, -1, 
861                                     pos, 
862                                     AVSEEK_FLAG_BACKWARD | (
863                                             seek_by_bytes 
864                                             ? AVSEEK_FLAG_ANY 
865                                             | AVSEEK_FLAG_BYTE : 0));
866                 if (ret < 0) {
867                         fprintf(stderr, "error while seeking: %d\n", ret);
868                 }
869
870                 pts_to_search = (long long) 
871                         (((double) position) / pts_time_base / frame_rate);
872                 if (st_time != AV_NOPTS_VALUE) {
873                         pts_to_search += st_time / pts_time_base/ AV_TIME_BASE;
874                 }
875
876                 pos_found = 0;
877                 avcodec_flush_buffers(anim->pCodecCtx);
878         }
879
880         while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
881                 if(packet.stream_index == anim->videoStream) {
882                         avcodec_decode_video2(anim->pCodecCtx, 
883                                               anim->pFrame, &frameFinished, 
884                                               &packet);
885
886                         if (seek_by_bytes && preseek_count > 0) {
887                                 preseek_count--;
888                         }
889
890                         if (frameFinished && !pos_found) {
891                                 if (seek_by_bytes) {
892                                         if (!preseek_count) {
893                                                 pos_found = 1;
894                                                 anim->curposition = position;
895                                         }
896                                 } else {
897                                         if (packet.dts >= pts_to_search) {
898                                                 pos_found = 1;
899                                                 anim->curposition = position;
900                                         }
901                                 }
902                         } 
903
904                         if(frameFinished && pos_found == 1) {
905                                 ffmpeg_postprocess(anim, ibuf, &filter_y);
906                                 av_free_packet(&packet);
907                                 break;
908                         }
909                 }
910
911                 av_free_packet(&packet);
912         }
913
914         if (filter_y && ibuf) {
915                 IMB_filtery(ibuf);
916         }
917
918         ibuf->profile = IB_PROFILE_SRGB;
919         
920         return(ibuf);
921 }
922
923 static void free_anim_ffmpeg(struct anim * anim) {
924         if (anim == NULL) return;
925
926         if (anim->pCodecCtx) {
927                 avcodec_close(anim->pCodecCtx);
928                 av_close_input_file(anim->pFormatCtx);
929                 av_free(anim->pFrameRGB);
930                 av_free(anim->pFrame);
931
932                 if (anim->ib_flags & IB_animdeinterlace) {
933                         MEM_freeN(anim->pFrameDeinterlaced->data[0]);
934                 }
935                 av_free(anim->pFrameDeinterlaced);
936                 sws_freeContext(anim->img_convert_ctx);
937         }
938         anim->duration = 0;
939 }
940
941 #endif
942
943 #ifdef WITH_REDCODE
944
945 static int startredcode(struct anim * anim) {
946         anim->redcodeCtx = redcode_open(anim->name);
947         if (!anim->redcodeCtx) {
948                 return -1;
949         }
950         anim->duration = redcode_get_length(anim->redcodeCtx);
951         
952         return 0;
953 }
954
955 static ImBuf * redcode_fetchibuf(struct anim * anim, int position) {
956         struct ImBuf * ibuf;
957         struct redcode_frame * frame;
958         struct redcode_frame_raw * raw_frame;
959
960         if (!anim->redcodeCtx) {
961                 return NULL;
962         }
963
964         frame = redcode_read_video_frame(anim->redcodeCtx, position);
965         
966         if (!frame) {
967                 return NULL;
968         }
969
970         raw_frame = redcode_decode_video_raw(frame, 1);
971
972         redcode_free_frame(frame);
973
974         if (!raw_frame) {
975                 return NULL;
976         }
977         
978                 ibuf = IMB_allocImBuf(raw_frame->width * 2, 
979                                   raw_frame->height * 2, 32, IB_rectfloat);
980
981         redcode_decode_video_float(raw_frame, ibuf->rect_float, 1);
982
983         return ibuf;
984 }
985
986 static void free_anim_redcode(struct anim * anim) {
987         if (anim->redcodeCtx) {
988                 redcode_close(anim->redcodeCtx);
989                 anim->redcodeCtx = 0;
990         }
991         anim->duration = 0;
992 }
993
994 #endif
995
996 /* probeer volgende plaatje te lezen */
997 /* Geen plaatje, probeer dan volgende animatie te openen */
998 /* gelukt, haal dan eerste plaatje van animatie */
999
1000 static struct ImBuf * anim_getnew(struct anim * anim) {
1001         struct ImBuf *ibuf = NULL;
1002
1003         if (anim == NULL) return(NULL);
1004
1005         free_anim_movie(anim);
1006         free_anim_avi(anim);
1007 #ifdef WITH_QUICKTIME
1008         free_anim_quicktime(anim);
1009 #endif
1010 #ifdef WITH_FFMPEG
1011         free_anim_ffmpeg(anim);
1012 #endif
1013 #ifdef WITH_REDCODE
1014         free_anim_redcode(anim);
1015 #endif
1016
1017
1018         if (anim->curtype != 0) return (NULL);
1019         anim->curtype = imb_get_anim_type(anim->name);  
1020
1021         switch (anim->curtype) {
1022         case ANIM_SEQUENCE:
1023                 ibuf = IMB_loadiffname(anim->name, anim->ib_flags);
1024                 if (ibuf) {
1025                         strcpy(anim->first, anim->name);
1026                         anim->duration = 1;
1027                 }
1028                 break;
1029         case ANIM_MOVIE:
1030                 if (startmovie(anim)) return (NULL);
1031                 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0); /* fake */
1032                 break;
1033         case ANIM_AVI:
1034                 if (startavi(anim)) {
1035                         printf("couldnt start avi\n"); 
1036                         return (NULL);
1037                 }
1038                 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0);
1039                 break;
1040 #ifdef WITH_QUICKTIME
1041         case ANIM_QTIME:
1042                 if (startquicktime(anim)) return (0);
1043                 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0);
1044                 break;
1045 #endif
1046 #ifdef WITH_FFMPEG
1047         case ANIM_FFMPEG:
1048                 if (startffmpeg(anim)) return (0);
1049                 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0);
1050                 break;
1051 #endif
1052 #ifdef WITH_REDCODE
1053         case ANIM_REDCODE:
1054                 if (startredcode(anim)) return (0);
1055                 ibuf = IMB_allocImBuf (8, 8, 32, 0);
1056                 break;
1057 #endif
1058         }
1059         return(ibuf);
1060 }
1061
1062 struct ImBuf * IMB_anim_previewframe(struct anim * anim) {
1063         struct ImBuf * ibuf = NULL;
1064         int position = 0;
1065         
1066         ibuf = IMB_anim_absolute(anim, 0);
1067         if (ibuf) {
1068                 IMB_freeImBuf(ibuf);
1069                 position = anim->duration / 2;
1070                 ibuf = IMB_anim_absolute(anim, position);
1071         }
1072         return ibuf;
1073 }
1074
1075 struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
1076         struct ImBuf * ibuf = NULL;
1077         char head[256], tail[256];
1078         unsigned short digits;
1079         int pic;
1080         int filter_y;
1081         if (anim == NULL) return(NULL);
1082
1083         filter_y = (anim->ib_flags & IB_animdeinterlace);
1084
1085         if (anim->curtype == 0) {
1086                 ibuf = anim_getnew(anim);
1087                 if (ibuf == NULL) {
1088                         return(NULL);
1089                 }
1090
1091                 IMB_freeImBuf(ibuf); /* ???? */
1092                 ibuf= NULL;
1093         }
1094
1095         if (position < 0) return(NULL);
1096         if (position >= anim->duration) return(NULL);
1097
1098         switch(anim->curtype) {
1099         case ANIM_SEQUENCE:
1100                 pic = an_stringdec(anim->first, head, tail, &digits);
1101                 pic += position;
1102                 an_stringenc(anim->name, head, tail, digits, pic);
1103                 ibuf = IMB_loadiffname(anim->name, IB_rect);
1104                 if (ibuf) {
1105                         anim->curposition = position;
1106                 }
1107                 break;
1108         case ANIM_MOVIE:
1109                 ibuf = movie_fetchibuf(anim, position);
1110                 if (ibuf) {
1111                         anim->curposition = position;
1112                         IMB_convert_rgba_to_abgr(ibuf);
1113                         ibuf->profile = IB_PROFILE_SRGB;
1114                 }
1115                 break;
1116         case ANIM_AVI:
1117                 ibuf = avi_fetchibuf(anim, position);
1118                 if (ibuf)
1119                         anim->curposition = position;
1120                 break;
1121 #ifdef WITH_QUICKTIME
1122         case ANIM_QTIME:
1123                 ibuf = qtime_fetchibuf(anim, position);
1124                 if (ibuf)
1125                         anim->curposition = position;
1126                 break;
1127 #endif
1128 #ifdef WITH_FFMPEG
1129         case ANIM_FFMPEG:
1130                 ibuf = ffmpeg_fetchibuf(anim, position);
1131                 if (ibuf)
1132                         anim->curposition = position;
1133                 filter_y = 0; /* done internally */
1134                 break;
1135 #endif
1136 #ifdef WITH_REDCODE
1137         case ANIM_REDCODE:
1138                 ibuf = redcode_fetchibuf(anim, position);
1139                 if (ibuf) anim->curposition = position;
1140                 break;
1141 #endif
1142         }
1143
1144         if (ibuf) {
1145                 if (filter_y) IMB_filtery(ibuf);
1146                 sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1);
1147                 
1148         }
1149         return(ibuf);
1150 }
1151
1152 /***/
1153
1154 int IMB_anim_get_duration(struct anim *anim) {
1155         return anim->duration;
1156 }
1157
1158 void IMB_anim_set_preseek(struct anim * anim, int preseek)
1159 {
1160         anim->preseek = preseek;
1161 }
1162
1163 int IMB_anim_get_preseek(struct anim * anim)
1164 {
1165         return anim->preseek;
1166 }