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