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