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