Reduce amount of deprecated symbols used from FFmpeg
[blender.git] / source / blender / imbuf / intern / anim_movie.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/imbuf/intern/anim_movie.c
29  *  \ingroup imbuf
30  */
31
32
33 #ifdef _WIN32
34 #define INC_OLE2
35 #include <windows.h>
36 #include <windowsx.h>
37 #include <mmsystem.h>
38 #include <memory.h>
39 #include <commdlg.h>
40
41 #ifndef FREE_WINDOWS
42 #include <vfw.h>
43 #endif
44
45 #undef AVIIF_KEYFRAME // redefined in AVI_avi.h
46 #undef AVIIF_LIST // redefined in AVI_avi.h
47
48 #define FIXCC(fcc) \
49         { \
50                 if (fcc == 0)       { fcc = mmioFOURCC('N', 'o', 'n', 'e'); } \
51                 if (fcc == BI_RLE8) { fcc = mmioFOURCC('R', 'l', 'e', '8'); } \
52         } (void)0
53
54 #endif
55
56 #include <sys/types.h>
57 #include <ctype.h>
58 #include <stdlib.h>
59 #include <stdio.h>
60 #include <math.h>
61 #ifndef _WIN32
62 #include <dirent.h>
63 #else
64 #include <io.h>
65 #endif
66
67 #include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail
68                           * BLI_countlist BLI_stringdec */
69 #include "BLI_utildefines.h"
70 #include "BLI_math_base.h"
71
72 #include "MEM_guardedalloc.h"
73
74 #include "DNA_userdef_types.h"
75
76
77 #include "BKE_global.h"
78 #include "BKE_depsgraph.h"
79
80 #include "imbuf.h"
81
82 #include "AVI_avi.h"
83
84 #ifdef WITH_QUICKTIME
85 #if defined(_WIN32) || defined(__APPLE__)
86 #include "quicktime_import.h"
87 #endif /* _WIN32 || __APPLE__ */
88 #endif /* WITH_QUICKTIME */
89
90 #include "IMB_imbuf_types.h"
91 #include "IMB_imbuf.h"
92
93 #include "IMB_allocimbuf.h"
94 #include "IMB_anim.h"
95 #include "IMB_indexer.h"
96
97 #ifdef WITH_FFMPEG
98 #include <libavformat/avformat.h>
99 #include <libavcodec/avcodec.h>
100 #include <libavutil/rational.h>
101 #include <libswscale/swscale.h>
102
103 #include "ffmpeg_compat.h"
104
105 #endif //WITH_FFMPEG
106
107 #ifdef WITH_REDCODE
108 #ifdef _WIN32 /* on windows we use the ones in extern instead */
109 #include "libredcode/format.h"
110 #include "libredcode/codec.h"
111 #else
112 #include "libredcode/format.h"
113 #include "libredcode/codec.h"
114 #endif
115 #endif
116
117 int ismovie(const char *UNUSED(filepath))
118 {
119         return 0;
120 }
121
122 /* never called, just keep the linker happy */
123 static int startmovie(struct anim *UNUSED(anim))
124 {
125         return 1;
126 }
127 static ImBuf *movie_fetchibuf(struct anim *UNUSED(anim), int UNUSED(position))
128 {
129         return NULL;
130 }
131 static void free_anim_movie(struct anim *UNUSED(anim))
132 {
133         /* pass */
134 }
135
136
137 #if defined(_WIN32)
138 # define PATHSEPERATOR '\\'
139 #else
140 # define PATHSEPERATOR '/'
141 #endif
142
143 static int an_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
144 {
145         unsigned short len, nume, nums = 0;
146         short i, found = FALSE;
147
148         len = strlen(string);
149         nume = len;
150
151         for (i = len - 1; i >= 0; i--) {
152                 if (string[i] == PATHSEPERATOR) break;
153                 if (isdigit(string[i])) {
154                         if (found) {
155                                 nums = i;
156                         }
157                         else {
158                                 nume = i;
159                                 nums = i;
160                                 found = TRUE;
161                         }
162                 }
163                 else {
164                         if (found) break;
165                 }
166         }
167         if (found) {
168                 strcpy(tail, &string[nume + 1]);
169                 strcpy(head, string);
170                 head[nums] = '\0';
171                 *numlen = nume - nums + 1;
172                 return ((int)atoi(&(string[nums])));
173         }
174         tail[0] = '\0';
175         strcpy(head, string);
176         *numlen = 0;
177         return TRUE;
178 }
179
180
181 static void an_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
182 {
183         BLI_stringenc(string, head, tail, numlen, pic);
184 }
185
186 static void free_anim_avi(struct anim *anim)
187 {
188 #if defined(_WIN32) && !defined(FREE_WINDOWS)
189         int i;
190 #endif
191
192         if (anim == NULL) return;
193         if (anim->avi == NULL) return;
194
195         AVI_close(anim->avi);
196         MEM_freeN(anim->avi);
197         anim->avi = NULL;
198
199 #if defined(_WIN32) && !defined(FREE_WINDOWS)
200
201         if (anim->pgf) {
202                 AVIStreamGetFrameClose(anim->pgf);
203                 anim->pgf = NULL;
204         }
205
206         for (i = 0; i < anim->avistreams; i++) {
207                 AVIStreamRelease(anim->pavi[i]);
208         }
209         anim->avistreams = 0;
210
211         if (anim->pfileopen) {
212                 AVIFileRelease(anim->pfile);
213                 anim->pfileopen = 0;
214                 AVIFileExit();
215         }
216 #endif
217
218         anim->duration = 0;
219 }
220
221 #ifdef WITH_FFMPEG
222 static void free_anim_ffmpeg(struct anim *anim);
223 #endif
224 #ifdef WITH_REDCODE
225 static void free_anim_redcode(struct anim *anim);
226 #endif
227
228 void IMB_free_anim(struct anim *anim)
229 {
230         if (anim == NULL) {
231                 printf("free anim, anim == NULL\n");
232                 return;
233         }
234
235         free_anim_movie(anim);
236         free_anim_avi(anim);
237
238 #ifdef WITH_QUICKTIME
239         free_anim_quicktime(anim);
240 #endif
241 #ifdef WITH_FFMPEG
242         free_anim_ffmpeg(anim);
243 #endif
244 #ifdef WITH_REDCODE
245         free_anim_redcode(anim);
246 #endif
247         IMB_free_indices(anim);
248
249         MEM_freeN(anim);
250 }
251
252 void IMB_close_anim(struct anim *anim)
253 {
254         if (anim == NULL) return;
255
256         IMB_free_anim(anim);
257 }
258
259 void IMB_close_anim_proxies(struct anim *anim)
260 {
261         if (anim == NULL)
262                 return;
263
264         IMB_free_indices(anim);
265 }
266
267 struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex)
268 {
269         struct anim *anim;
270
271         anim = (struct anim *)MEM_callocN(sizeof(struct anim), "anim struct");
272         if (anim != NULL) {
273                 BLI_strncpy(anim->name, name, sizeof(anim->name));
274                 anim->ib_flags = ib_flags;
275                 anim->streamindex = streamindex;
276         }
277         return(anim);
278 }
279
280
281 static int startavi(struct anim *anim)
282 {
283
284         AviError avierror;
285 #if defined(_WIN32) && !defined(FREE_WINDOWS)
286         HRESULT hr;
287         int i, firstvideo = -1;
288         int streamcount;
289         BYTE abFormat[1024];
290         LONG l;
291         LPBITMAPINFOHEADER lpbi;
292         AVISTREAMINFO avis;
293
294         streamcount = anim->streamindex;
295 #endif
296
297         anim->avi = MEM_callocN(sizeof(AviMovie), "animavi");
298
299         if (anim->avi == NULL) {
300                 printf("Can't open avi: %s\n", anim->name);
301                 return -1;
302         }
303
304         avierror = AVI_open_movie(anim->name, anim->avi);
305
306 #if defined(_WIN32) && !defined(FREE_WINDOWS)
307         if (avierror == AVI_ERROR_COMPRESSION) {
308                 AVIFileInit();
309                 hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L);
310                 if (hr == 0) {
311                         anim->pfileopen = 1;
312                         for (i = 0; i < MAXNUMSTREAMS; i++) {
313                                 if (AVIFileGetStream(anim->pfile, &anim->pavi[i], 0L, i) != AVIERR_OK) {
314                                         break;
315                                 }
316                                 
317                                 AVIStreamInfo(anim->pavi[i], &avis, sizeof(avis));
318                                 if ((avis.fccType == streamtypeVIDEO) && (firstvideo == -1)) {
319                                         if (streamcount > 0) {
320                                                 streamcount--;
321                                                 continue;
322                                         }
323                                         anim->pgf = AVIStreamGetFrameOpen(anim->pavi[i], NULL);
324                                         if (anim->pgf) {
325                                                 firstvideo = i;
326
327                                                 // get stream length
328                                                 anim->avi->header->TotalFrames = AVIStreamLength(anim->pavi[i]);
329                                                 
330                                                 // get information about images inside the stream
331                                                 l = sizeof(abFormat);
332                                                 AVIStreamReadFormat(anim->pavi[i], 0, &abFormat, &l);
333                                                 lpbi = (LPBITMAPINFOHEADER)abFormat;
334                                                 anim->avi->header->Height = lpbi->biHeight;
335                                                 anim->avi->header->Width = lpbi->biWidth;
336                                         }
337                                         else {
338                                                 FIXCC(avis.fccHandler);
339                                                 FIXCC(avis.fccType);
340                                                 printf("Can't find AVI decoder for type : %4.4hs/%4.4hs\n",
341                                                        (LPSTR)&avis.fccType,
342                                                        (LPSTR)&avis.fccHandler);
343                                         }
344                                 }
345                         }
346
347                         // register number of opened avistreams
348                         anim->avistreams = i;
349
350                         //
351                         // Couldn't get any video streams out of this file
352                         //
353                         if ((anim->avistreams == 0) || (firstvideo == -1)) {
354                                 avierror = AVI_ERROR_FORMAT;
355                         }
356                         else {
357                                 avierror = AVI_ERROR_NONE;
358                                 anim->firstvideo = firstvideo;
359                         }
360                 }
361                 else {
362                         AVIFileExit();
363                 }
364         }
365 #endif
366
367         if (avierror != AVI_ERROR_NONE) {
368                 AVI_print_error(avierror);
369                 printf("Error loading avi: %s\n", anim->name);
370                 free_anim_avi(anim);
371                 return -1;
372         }
373         
374         anim->duration = anim->avi->header->TotalFrames;
375         anim->params = NULL;
376
377         anim->x = anim->avi->header->Width;
378         anim->y = anim->avi->header->Height;
379         anim->interlacing = 0;
380         anim->orientation = 0;
381         anim->framesize = anim->x * anim->y * 4;
382
383         anim->curposition = 0;
384         anim->preseek = 0;
385
386         /*  printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
387
388         return 0;
389 }
390
391 static ImBuf *avi_fetchibuf(struct anim *anim, int position)
392 {
393         ImBuf *ibuf = NULL;
394         int *tmp;
395         int y;
396         
397         if (anim == NULL) return (NULL);
398
399 #if defined(_WIN32) && !defined(FREE_WINDOWS)
400         if (anim->avistreams) {
401                 LPBITMAPINFOHEADER lpbi;
402
403                 if (anim->pgf) {
404                         lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo]));
405                         if (lpbi) {
406                                 ibuf = IMB_ibImageFromMemory((unsigned char *) lpbi, 100, IB_rect, "<avi_fetchibuf>");
407 //Oh brother...
408                         }
409                 }
410         }
411         else {
412 #else
413         if (1) {
414 #endif
415                 ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect);
416
417                 tmp = AVI_read_frame(anim->avi, AVI_FORMAT_RGB32, position,
418                                      AVI_get_stream(anim->avi, AVIST_VIDEO, 0));
419                 
420                 if (tmp == NULL) {
421                         printf("Error reading frame from AVI");
422                         IMB_freeImBuf(ibuf);
423                         return NULL;
424                 }
425
426                 for (y = 0; y < anim->y; y++) {
427                         memcpy(&(ibuf->rect)[((anim->y - y) - 1) * anim->x],  &tmp[y * anim->x],
428                                anim->x * 4);
429                 }
430                 
431                 MEM_freeN(tmp);
432         }
433         
434         ibuf->profile = IB_PROFILE_SRGB;
435         
436         return ibuf;
437 }
438
439 #ifdef WITH_FFMPEG
440
441 extern void do_init_ffmpeg(void);
442
443 static int startffmpeg(struct anim *anim)
444 {
445         int i, videoStream;
446
447         AVCodec *pCodec;
448         AVFormatContext *pFormatCtx = NULL;
449         AVCodecContext *pCodecCtx;
450         int frs_num;
451         double frs_den;
452         int streamcount;
453
454 #ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
455         /* The following for color space determination */
456         int srcRange, dstRange, brightness, contrast, saturation;
457         int *table;
458         const int *inv_table;
459 #endif
460
461         if (anim == 0) return(-1);
462
463         streamcount = anim->streamindex;
464
465         do_init_ffmpeg();
466
467         if (avformat_open_input(&pFormatCtx, anim->name, NULL, NULL) != 0) {
468                 return -1;
469         }
470
471         if (av_find_stream_info(pFormatCtx) < 0) {
472                 av_close_input_file(pFormatCtx);
473                 return -1;
474         }
475
476         av_dump_format(pFormatCtx, 0, anim->name, 0);
477
478
479         /* Find the video stream */
480         videoStream = -1;
481
482         for (i = 0; i < pFormatCtx->nb_streams; i++)
483                 if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
484                         if (streamcount > 0) {
485                                 streamcount--;
486                                 continue;
487                         }
488                         videoStream = i;
489                         break;
490                 }
491
492         if (videoStream == -1) {
493                 av_close_input_file(pFormatCtx);
494                 return -1;
495         }
496
497         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
498
499         /* Find the decoder for the video stream */
500         pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
501         if (pCodec == NULL) {
502                 av_close_input_file(pFormatCtx);
503                 return -1;
504         }
505
506         pCodecCtx->workaround_bugs = 1;
507
508         if (avcodec_open(pCodecCtx, pCodec) < 0) {
509                 av_close_input_file(pFormatCtx);
510                 return -1;
511         }
512
513         anim->duration = ceil(pFormatCtx->duration *
514                               av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate) /
515                               AV_TIME_BASE);
516
517         frs_num = pFormatCtx->streams[videoStream]->r_frame_rate.num;
518         frs_den = pFormatCtx->streams[videoStream]->r_frame_rate.den;
519
520         frs_den *= AV_TIME_BASE;
521
522         while (frs_num % 10 == 0 && frs_den >= 2.0 && frs_num > 10) {
523                 frs_num /= 10;
524                 frs_den /= 10;
525         }
526
527         anim->frs_sec = frs_num;
528         anim->frs_sec_base = frs_den;
529
530         anim->params = 0;
531
532         anim->x = pCodecCtx->width;
533         anim->y = pCodecCtx->height;
534         anim->interlacing = 0;
535         anim->orientation = 0;
536         anim->framesize = anim->x * anim->y * 4;
537
538         anim->curposition = -1;
539         anim->last_frame = 0;
540         anim->last_pts = -1;
541         anim->next_pts = -1;
542         anim->next_packet.stream_index = -1;
543
544         anim->pFormatCtx = pFormatCtx;
545         anim->pCodecCtx = pCodecCtx;
546         anim->pCodec = pCodec;
547         anim->videoStream = videoStream;
548
549         anim->pFrame = avcodec_alloc_frame();
550         anim->pFrameComplete = FALSE;
551         anim->pFrameDeinterlaced = avcodec_alloc_frame();
552         anim->pFrameRGB = avcodec_alloc_frame();
553
554         if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y)
555             != anim->x * anim->y * 4)
556         {
557                 fprintf(stderr,
558                         "ffmpeg has changed alloc scheme ... ARGHHH!\n");
559                 avcodec_close(anim->pCodecCtx);
560                 av_close_input_file(anim->pFormatCtx);
561                 av_free(anim->pFrameRGB);
562                 av_free(anim->pFrameDeinterlaced);
563                 av_free(anim->pFrame);
564                 anim->pCodecCtx = NULL;
565                 return -1;
566         }
567
568         if (anim->ib_flags & IB_animdeinterlace) {
569                 avpicture_fill((AVPicture *) anim->pFrameDeinterlaced,
570                                MEM_callocN(avpicture_get_size(
571                                                anim->pCodecCtx->pix_fmt,
572                                                anim->x, anim->y),
573                                            "ffmpeg deinterlace"),
574                                anim->pCodecCtx->pix_fmt, anim->x, anim->y);
575         }
576
577         if (pCodecCtx->has_b_frames) {
578                 anim->preseek = 25; /* FIXME: detect gopsize ... */
579         }
580         else {
581                 anim->preseek = 0;
582         }
583         
584         anim->img_convert_ctx = sws_getContext(
585                 anim->pCodecCtx->width,
586                 anim->pCodecCtx->height,
587                 anim->pCodecCtx->pix_fmt,
588                 anim->pCodecCtx->width,
589                 anim->pCodecCtx->height,
590                 PIX_FMT_RGBA,
591                 SWS_FAST_BILINEAR | SWS_PRINT_INFO,
592                 NULL, NULL, NULL);
593                 
594         if (!anim->img_convert_ctx) {
595                 fprintf(stderr,
596                         "Can't transform color space??? Bailing out...\n");
597                 avcodec_close(anim->pCodecCtx);
598                 av_close_input_file(anim->pFormatCtx);
599                 av_free(anim->pFrameRGB);
600                 av_free(anim->pFrameDeinterlaced);
601                 av_free(anim->pFrame);
602                 anim->pCodecCtx = NULL;
603                 return -1;
604         }
605
606 #ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
607         /* Try do detect if input has 0-255 YCbCR range (JFIF Jpeg MotionJpeg) */
608         if (!sws_getColorspaceDetails(anim->img_convert_ctx, (int **)&inv_table, &srcRange,
609                                       &table, &dstRange, &brightness, &contrast, &saturation))
610         {
611                 srcRange = srcRange || anim->pCodecCtx->color_range == AVCOL_RANGE_JPEG;
612                 inv_table = sws_getCoefficients(anim->pCodecCtx->colorspace);
613
614                 if (sws_setColorspaceDetails(anim->img_convert_ctx, (int *)inv_table, srcRange,
615                                              table, dstRange, brightness, contrast, saturation))
616                 {
617                         printf("Warning: Could not set libswscale colorspace details.\n");
618                 }
619         }
620         else {
621                 printf("Warning: Could not set libswscale colorspace details.\n");
622         }
623 #endif
624                 
625         return (0);
626 }
627
628 /* postprocess the image in anim->pFrame and do color conversion
629  * and deinterlacing stuff.
630  *
631  * Output is anim->last_frame
632  */
633
634 static void ffmpeg_postprocess(struct anim *anim)
635 {
636         AVFrame *input = anim->pFrame;
637         ImBuf *ibuf = anim->last_frame;
638         int filter_y = 0;
639
640         ibuf->profile = IB_PROFILE_SRGB;
641
642         if (!anim->pFrameComplete) {
643                 return;
644         }
645
646         /* This means the data wasnt read properly, 
647          * this check stops crashing */
648         if (input->data[0] == 0 && input->data[1] == 0 &&
649             input->data[2] == 0 && input->data[3] == 0)
650         {
651                 fprintf(stderr, "ffmpeg_fetchibuf: "
652                         "data not read properly...\n");
653                 return;
654         }
655
656         av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
657                "  POSTPROC: anim->pFrame planes: %p %p %p %p\n",
658                input->data[0], input->data[1], input->data[2],
659                input->data[3]);
660
661
662         if (anim->ib_flags & IB_animdeinterlace) {
663                 if (avpicture_deinterlace(
664                         (AVPicture *)
665                         anim->pFrameDeinterlaced,
666                         (const AVPicture *)
667                         anim->pFrame,
668                         anim->pCodecCtx->pix_fmt,
669                         anim->pCodecCtx->width,
670                         anim->pCodecCtx->height) < 0)
671                 {
672                         filter_y = TRUE;
673                 }
674                 else {
675                         input = anim->pFrameDeinterlaced;
676                 }
677         }
678         
679         avpicture_fill((AVPicture *) anim->pFrameRGB,
680                        (unsigned char *) ibuf->rect,
681                        PIX_FMT_RGBA, anim->x, anim->y);
682
683         if (ENDIAN_ORDER == B_ENDIAN) {
684                 int *dstStride   = anim->pFrameRGB->linesize;
685                 uint8_t **dst     = anim->pFrameRGB->data;
686                 int dstStride2[4] = { dstStride[0], 0, 0, 0 };
687                 uint8_t *dst2[4]  = { dst[0], 0, 0, 0 };
688                 int x, y, h, w;
689                 unsigned char *bottom;
690                 unsigned char *top;
691                 
692                 sws_scale(anim->img_convert_ctx,
693                           (const uint8_t *const *)input->data,
694                           input->linesize,
695                           0,
696                           anim->pCodecCtx->height,
697                           dst2,
698                           dstStride2);
699                 
700                 bottom = (unsigned char *) ibuf->rect;
701                 top = bottom + ibuf->x * (ibuf->y - 1) * 4;
702                 
703                 h = (ibuf->y + 1) / 2;
704                 w = ibuf->x;
705                 
706                 for (y = 0; y < h; y++) {
707                         unsigned char tmp[4];
708                         unsigned int *tmp_l =
709                             (unsigned int *) tmp;
710                         
711                         for (x = 0; x < w; x++) {
712                                 tmp[0] = bottom[0];
713                                 tmp[1] = bottom[1];
714                                 tmp[2] = bottom[2];
715                                 tmp[3] = bottom[3];
716                                 
717                                 bottom[0] = top[0];
718                                 bottom[1] = top[1];
719                                 bottom[2] = top[2];
720                                 bottom[3] = top[3];
721                                 
722                                 *(unsigned int *) top = *tmp_l;
723                                 
724                                 bottom += 4;
725                                 top += 4;
726                         }
727                         top -= 8 * w;
728                 }
729         }
730         else {
731                 int *dstStride   = anim->pFrameRGB->linesize;
732                 uint8_t **dst     = anim->pFrameRGB->data;
733                 int dstStride2[4] = { -dstStride[0], 0, 0, 0 };
734                 uint8_t *dst2[4]  = { dst[0] + (anim->y - 1) * dstStride[0],
735                                           0, 0, 0 };
736                 
737                 sws_scale(anim->img_convert_ctx,
738                           (const uint8_t *const *)input->data,
739                           input->linesize,
740                           0,
741                           anim->pCodecCtx->height,
742                           dst2,
743                           dstStride2);
744         }
745
746         if (filter_y) {
747                 IMB_filtery(ibuf);
748         }
749 }
750
751 /* decode one video frame also considering the packet read into next_packet */
752
753 static int ffmpeg_decode_video_frame(struct anim *anim)
754 {
755         int rval = 0;
756
757         av_log(anim->pFormatCtx, AV_LOG_DEBUG, "  DECODE VIDEO FRAME\n");
758
759         if (anim->next_packet.stream_index == anim->videoStream) {
760                 av_free_packet(&anim->next_packet);
761                 anim->next_packet.stream_index = -1;
762         }
763         
764         while ((rval = av_read_frame(anim->pFormatCtx, &anim->next_packet)) >= 0) {
765                 av_log(anim->pFormatCtx, 
766                        AV_LOG_DEBUG, 
767                        "%sREAD: strID=%d (VID: %d) dts=%lld pts=%lld "
768                        "%s\n",
769                        (anim->next_packet.stream_index == anim->videoStream)
770                        ? "->" : "  ",
771                        anim->next_packet.stream_index, 
772                        anim->videoStream,
773                        (anim->next_packet.dts == AV_NOPTS_VALUE) ? -1 :
774                        (long long int)anim->next_packet.dts,
775                        (anim->next_packet.pts == AV_NOPTS_VALUE) ? -1 :
776                        (long long int)anim->next_packet.pts,
777                        (anim->next_packet.flags & AV_PKT_FLAG_KEY) ? 
778                        " KEY" : "");
779                 if (anim->next_packet.stream_index == anim->videoStream) {
780                         anim->pFrameComplete = 0;
781
782                         avcodec_decode_video2(
783                             anim->pCodecCtx,
784                             anim->pFrame, &anim->pFrameComplete,
785                             &anim->next_packet);
786
787                         if (anim->pFrameComplete) {
788                                 anim->next_pts = av_get_pts_from_frame(
789                                         anim->pFormatCtx, anim->pFrame);
790
791                                 av_log(anim->pFormatCtx,
792                                        AV_LOG_DEBUG,
793                                        "  FRAME DONE: next_pts=%lld "
794                                        "pkt_pts=%lld, guessed_pts=%lld\n",
795                                        (anim->pFrame->pts == AV_NOPTS_VALUE) ?
796                                        -1 : (long long int)anim->pFrame->pts,
797                                        (anim->pFrame->pkt_pts == AV_NOPTS_VALUE) ?
798                                        -1 : (long long int)anim->pFrame->pkt_pts,
799                                        (long long int)anim->next_pts);
800                                 break;
801                         }
802                 }
803                 av_free_packet(&anim->next_packet);
804                 anim->next_packet.stream_index = -1;
805         }
806         
807         if (rval < 0) {
808                 anim->next_packet.stream_index = -1;
809
810                 av_log(anim->pFormatCtx,
811                        AV_LOG_ERROR, "  DECODE READ FAILED: av_read_frame() "
812                        "returned error: %d\n",  rval);
813         }
814
815         return (rval >= 0);
816 }
817
818 static void ffmpeg_decode_video_frame_scan(
819         struct anim *anim, int64_t pts_to_search)
820 {
821         /* there seem to exist *very* silly GOP lengths out in the wild... */
822         int count = 1000;
823
824         av_log(anim->pFormatCtx,
825                AV_LOG_DEBUG, 
826                "SCAN start: considering pts=%lld in search of %lld\n", 
827                (long long int)anim->next_pts, (long long int)pts_to_search);
828
829         while (count > 0 && anim->next_pts < pts_to_search) {
830                 av_log(anim->pFormatCtx,
831                        AV_LOG_DEBUG, 
832                        "  WHILE: pts=%lld in search of %lld\n", 
833                        (long long int)anim->next_pts, (long long int)pts_to_search);
834                 if (!ffmpeg_decode_video_frame(anim)) {
835                         break;
836                 }
837                 count--;
838         }
839         if (count == 0) {
840                 av_log(anim->pFormatCtx,
841                        AV_LOG_ERROR, 
842                        "SCAN failed: completely lost in stream, "
843                        "bailing out at PTS=%lld, searching for PTS=%lld\n", 
844                        (long long int)anim->next_pts, (long long int)pts_to_search);
845         }
846         if (anim->next_pts == pts_to_search) {
847                 av_log(anim->pFormatCtx,
848                        AV_LOG_DEBUG, "SCAN HAPPY: we found our PTS!\n");
849         }
850         else {
851                 av_log(anim->pFormatCtx,
852                        AV_LOG_ERROR, "SCAN UNHAPPY: PTS not matched!\n");
853         }
854 }
855
856 static int match_format(const char *name, AVFormatContext *pFormatCtx)
857 {
858         const char *p;
859         int len, namelen;
860
861         const char *names = pFormatCtx->iformat->name;
862
863         if (!name || !names)
864                 return 0;
865
866         namelen = strlen(name);
867         while ((p = strchr(names, ','))) {
868                 len = MAX2(p - names, namelen);
869                 if (!BLI_strncasecmp(name, names, len))
870                         return 1;
871                 names = p + 1;
872         }
873         return !BLI_strcasecmp(name, names);
874 }
875
876 static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx)
877 {
878         static const char *byte_seek_list[] = { "mpegts", 0 };
879         const char **p;
880
881         if (pFormatCtx->iformat->flags & AVFMT_TS_DISCONT) {
882                 return TRUE;
883         }
884
885         p = byte_seek_list;
886
887         while (*p) {
888                 if (match_format(*p++, pFormatCtx)) {
889                         return TRUE;
890                 }
891         }
892
893         return FALSE;
894 }
895
896 static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position,
897                                IMB_Timecode_Type tc) {
898         int64_t pts_to_search = 0;
899         double frame_rate;
900         double pts_time_base;
901         long long st_time; 
902         struct anim_index *tc_index = 0;
903         AVStream *v_st;
904         int new_frame_index = 0; /* To quite gcc barking... */
905         int old_frame_index = 0; /* To quite gcc barking... */
906
907         if (anim == 0) return (0);
908
909         av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: pos=%d\n", position);
910
911         if (tc != IMB_TC_NONE) {
912                 tc_index = IMB_anim_open_index(anim, tc);
913         }
914
915         v_st = anim->pFormatCtx->streams[anim->videoStream];
916
917         frame_rate = av_q2d(v_st->r_frame_rate);
918
919         st_time = anim->pFormatCtx->start_time;
920         pts_time_base = av_q2d(v_st->time_base);
921
922         if (tc_index) {
923                 new_frame_index = IMB_indexer_get_frame_index(
924                         tc_index, position);
925                 old_frame_index = IMB_indexer_get_frame_index(
926                         tc_index, anim->curposition);
927                 pts_to_search = IMB_indexer_get_pts(
928                         tc_index, new_frame_index);
929         }
930         else {
931                 pts_to_search = (long long) 
932                                 floor(((double) position) /
933                                       pts_time_base / frame_rate + 0.5);
934
935                 if (st_time != AV_NOPTS_VALUE) {
936                         pts_to_search += st_time / pts_time_base / AV_TIME_BASE;
937                 }
938         }
939
940         av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
941                "FETCH: looking for PTS=%lld "
942                "(pts_timebase=%g, frame_rate=%g, st_time=%lld)\n", 
943                (long long int)pts_to_search, pts_time_base, frame_rate, st_time);
944
945         if (anim->last_frame && 
946             anim->last_pts <= pts_to_search && anim->next_pts > pts_to_search)
947         {
948                 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
949                        "FETCH: frame repeat: last: %lld next: %lld\n",
950                        (long long int)anim->last_pts, 
951                        (long long int)anim->next_pts);
952                 IMB_refImBuf(anim->last_frame);
953                 anim->curposition = position;
954                 return anim->last_frame;
955         }
956          
957         if (position > anim->curposition + 1 &&
958             anim->preseek &&
959             !tc_index &&
960             position - (anim->curposition + 1) < anim->preseek)
961         {
962                 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
963                        "FETCH: within preseek interval (no index)\n");
964
965                 ffmpeg_decode_video_frame_scan(anim, pts_to_search);
966         }
967         else if (tc_index &&
968                  IMB_indexer_can_scan(tc_index, old_frame_index,
969                                       new_frame_index))
970         {
971                 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
972                        "FETCH: within preseek interval "
973                        "(index tells us)\n");
974
975                 ffmpeg_decode_video_frame_scan(anim, pts_to_search);
976         }
977         else if (position != anim->curposition + 1) {
978                 long long pos;
979                 int ret;
980
981                 if (tc_index) {
982                         unsigned long long dts;
983
984                         pos = IMB_indexer_get_seek_pos(
985                             tc_index, new_frame_index);
986                         dts = IMB_indexer_get_seek_pos_dts(
987                             tc_index, new_frame_index);
988
989                         av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
990                                "TC INDEX seek pos = %lld\n", pos);
991                         av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
992                                "TC INDEX seek dts = %lld\n", dts);
993
994                         if (ffmpeg_seek_by_byte(anim->pFormatCtx)) {
995                                 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
996                                        "... using BYTE pos\n");
997
998                                 ret = av_seek_frame(anim->pFormatCtx, 
999                                                     -1,
1000                                                     pos, AVSEEK_FLAG_BYTE);
1001                                 av_update_cur_dts(anim->pFormatCtx, v_st, dts);
1002                         }
1003                         else {
1004                                 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
1005                                        "... using DTS pos\n");
1006                                 ret = av_seek_frame(anim->pFormatCtx, 
1007                                                     anim->videoStream,
1008                                                     dts, AVSEEK_FLAG_BACKWARD);
1009                         }
1010                 }
1011                 else {
1012                         pos = (long long) (position - anim->preseek) *
1013                               AV_TIME_BASE / frame_rate;
1014
1015                         av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
1016                                "NO INDEX seek pos = %lld, st_time = %lld\n", 
1017                                pos, (st_time != AV_NOPTS_VALUE) ? st_time : 0);
1018
1019                         if (pos < 0) {
1020                                 pos = 0;
1021                         }
1022                 
1023                         if (st_time != AV_NOPTS_VALUE) {
1024                                 pos += st_time;
1025                         }
1026
1027                         av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
1028                                "NO INDEX final seek pos = %lld\n", pos);
1029
1030                         ret = av_seek_frame(anim->pFormatCtx, -1, 
1031                                             pos, AVSEEK_FLAG_BACKWARD);
1032                 }
1033
1034                 if (ret < 0) {
1035                         av_log(anim->pFormatCtx, AV_LOG_ERROR,
1036                                "FETCH: "
1037                                "error while seeking to DTS = %lld "
1038                                "(frameno = %d, PTS = %lld): errcode = %d\n",
1039                                pos, position, (long long int)pts_to_search, ret);
1040                 }
1041
1042                 avcodec_flush_buffers(anim->pCodecCtx);
1043
1044                 anim->next_pts = -1;
1045
1046                 if (anim->next_packet.stream_index == anim->videoStream) {
1047                         av_free_packet(&anim->next_packet);
1048                         anim->next_packet.stream_index = -1;
1049                 }
1050
1051                 /* memset(anim->pFrame, ...) ?? */
1052
1053                 if (ret >= 0) {
1054                         ffmpeg_decode_video_frame_scan(anim, pts_to_search);
1055                 }
1056         }
1057         else if (position == 0 && anim->curposition == -1) {
1058                 /* first frame without seeking special case... */
1059                 ffmpeg_decode_video_frame(anim);
1060         }
1061         else {
1062                 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
1063                        "FETCH: no seek necessary, just continue...\n");
1064         }
1065
1066         IMB_freeImBuf(anim->last_frame);
1067         anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
1068
1069         ffmpeg_postprocess(anim);
1070
1071         anim->last_pts = anim->next_pts;
1072         
1073         ffmpeg_decode_video_frame(anim);
1074         
1075         anim->curposition = position;
1076         
1077         IMB_refImBuf(anim->last_frame);
1078
1079         return anim->last_frame;
1080 }
1081
1082 static void free_anim_ffmpeg(struct anim *anim)
1083 {
1084         if (anim == NULL) return;
1085
1086         if (anim->pCodecCtx) {
1087                 avcodec_close(anim->pCodecCtx);
1088                 av_close_input_file(anim->pFormatCtx);
1089                 av_free(anim->pFrameRGB);
1090                 av_free(anim->pFrame);
1091
1092                 if (anim->ib_flags & IB_animdeinterlace) {
1093                         MEM_freeN(anim->pFrameDeinterlaced->data[0]);
1094                 }
1095                 av_free(anim->pFrameDeinterlaced);
1096                 sws_freeContext(anim->img_convert_ctx);
1097                 IMB_freeImBuf(anim->last_frame);
1098                 if (anim->next_packet.stream_index != -1) {
1099                         av_free_packet(&anim->next_packet);
1100                 }
1101         }
1102         anim->duration = 0;
1103 }
1104
1105 #endif
1106
1107 #ifdef WITH_REDCODE
1108
1109 static int startredcode(struct anim *anim)
1110 {
1111         anim->redcodeCtx = redcode_open(anim->name);
1112         if (!anim->redcodeCtx) {
1113                 return -1;
1114         }
1115         anim->duration = redcode_get_length(anim->redcodeCtx);
1116         
1117         return 0;
1118 }
1119
1120 static ImBuf *redcode_fetchibuf(struct anim *anim, int position)
1121 {
1122         struct ImBuf *ibuf;
1123         struct redcode_frame *frame;
1124         struct redcode_frame_raw *raw_frame;
1125
1126         if (!anim->redcodeCtx) {
1127                 return NULL;
1128         }
1129
1130         frame = redcode_read_video_frame(anim->redcodeCtx, position);
1131         
1132         if (!frame) {
1133                 return NULL;
1134         }
1135
1136         raw_frame = redcode_decode_video_raw(frame, 1);
1137
1138         redcode_free_frame(frame);
1139
1140         if (!raw_frame) {
1141                 return NULL;
1142         }
1143         
1144         ibuf = IMB_allocImBuf(raw_frame->width * 2,
1145                               raw_frame->height * 2, 32, IB_rectfloat);
1146
1147         redcode_decode_video_float(raw_frame, ibuf->rect_float, 1);
1148
1149         return ibuf;
1150 }
1151
1152 static void free_anim_redcode(struct anim *anim)
1153 {
1154         if (anim->redcodeCtx) {
1155                 redcode_close(anim->redcodeCtx);
1156                 anim->redcodeCtx = 0;
1157         }
1158         anim->duration = 0;
1159 }
1160
1161 #endif
1162
1163 /* Try next picture to read */
1164 /* No picture, try to open next animation */
1165 /* Succeed, remove first image from animation */
1166
1167 static ImBuf *anim_getnew(struct anim *anim)
1168 {
1169         struct ImBuf *ibuf = NULL;
1170
1171         if (anim == NULL) return(NULL);
1172
1173         free_anim_movie(anim);
1174         free_anim_avi(anim);
1175 #ifdef WITH_QUICKTIME
1176         free_anim_quicktime(anim);
1177 #endif
1178 #ifdef WITH_FFMPEG
1179         free_anim_ffmpeg(anim);
1180 #endif
1181 #ifdef WITH_REDCODE
1182         free_anim_redcode(anim);
1183 #endif
1184
1185
1186         if (anim->curtype != 0) return (NULL);
1187         anim->curtype = imb_get_anim_type(anim->name);  
1188
1189         switch (anim->curtype) {
1190                 case ANIM_SEQUENCE:
1191                         ibuf = IMB_loadiffname(anim->name, anim->ib_flags);
1192                         if (ibuf) {
1193                                 BLI_strncpy(anim->first, anim->name, sizeof(anim->first));
1194                                 anim->duration = 1;
1195                         }
1196                         break;
1197                 case ANIM_MOVIE:
1198                         if (startmovie(anim)) return (NULL);
1199                         ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); /* fake */
1200                         break;
1201                 case ANIM_AVI:
1202                         if (startavi(anim)) {
1203                                 printf("couldnt start avi\n");
1204                                 return (NULL);
1205                         }
1206                         ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0);
1207                         break;
1208 #ifdef WITH_QUICKTIME
1209                 case ANIM_QTIME:
1210                         if (startquicktime(anim)) return (0);
1211                         ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0);
1212                         break;
1213 #endif
1214 #ifdef WITH_FFMPEG
1215                 case ANIM_FFMPEG:
1216                         if (startffmpeg(anim)) return (0);
1217                         ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0);
1218                         break;
1219 #endif
1220 #ifdef WITH_REDCODE
1221                 case ANIM_REDCODE:
1222                         if (startredcode(anim)) return (0);
1223                         ibuf = IMB_allocImBuf(8, 8, 32, 0);
1224                         break;
1225 #endif
1226         }
1227         return(ibuf);
1228 }
1229
1230 struct ImBuf *IMB_anim_previewframe(struct anim *anim)
1231 {
1232         struct ImBuf *ibuf = NULL;
1233         int position = 0;
1234         
1235         ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
1236         if (ibuf) {
1237                 IMB_freeImBuf(ibuf);
1238                 position = anim->duration / 2;
1239                 ibuf = IMB_anim_absolute(anim, position, IMB_TC_NONE,
1240                                          IMB_PROXY_NONE);
1241         }
1242         return ibuf;
1243 }
1244
1245 struct ImBuf *IMB_anim_absolute(struct anim *anim, int position,
1246                                 IMB_Timecode_Type tc,
1247                                 IMB_Proxy_Size preview_size) {
1248         struct ImBuf *ibuf = NULL;
1249         char head[256], tail[256];
1250         unsigned short digits;
1251         int pic;
1252         int filter_y;
1253         if (anim == NULL) return(NULL);
1254
1255         filter_y = (anim->ib_flags & IB_animdeinterlace);
1256
1257         if (anim->curtype == 0) {
1258                 ibuf = anim_getnew(anim);
1259                 if (ibuf == NULL) {
1260                         return(NULL);
1261                 }
1262
1263                 IMB_freeImBuf(ibuf); /* ???? */
1264                 ibuf = NULL;
1265         }
1266
1267         if (position < 0) return(NULL);
1268         if (position >= anim->duration) return(NULL);
1269
1270         if (preview_size != IMB_PROXY_NONE) {
1271                 struct anim *proxy = IMB_anim_open_proxy(anim, preview_size);
1272
1273                 if (proxy) {
1274                         position = IMB_anim_index_get_frame_index(
1275                             anim, tc, position);
1276                         return IMB_anim_absolute(
1277                                    proxy, position,
1278                                    IMB_TC_NONE, IMB_PROXY_NONE);
1279                 }
1280         }
1281
1282         switch (anim->curtype) {
1283                 case ANIM_SEQUENCE:
1284                         pic = an_stringdec(anim->first, head, tail, &digits);
1285                         pic += position;
1286                         an_stringenc(anim->name, head, tail, digits, pic);
1287                         ibuf = IMB_loadiffname(anim->name, IB_rect);
1288                         if (ibuf) {
1289                                 anim->curposition = position;
1290                         }
1291                         break;
1292                 case ANIM_MOVIE:
1293                         ibuf = movie_fetchibuf(anim, position);
1294                         if (ibuf) {
1295                                 anim->curposition = position;
1296                                 IMB_convert_rgba_to_abgr(ibuf);
1297                                 ibuf->profile = IB_PROFILE_SRGB;
1298                         }
1299                         break;
1300                 case ANIM_AVI:
1301                         ibuf = avi_fetchibuf(anim, position);
1302                         if (ibuf)
1303                                 anim->curposition = position;
1304                         break;
1305 #ifdef WITH_QUICKTIME
1306                 case ANIM_QTIME:
1307                         ibuf = qtime_fetchibuf(anim, position);
1308                         if (ibuf)
1309                                 anim->curposition = position;
1310                         break;
1311 #endif
1312 #ifdef WITH_FFMPEG
1313                 case ANIM_FFMPEG:
1314                         ibuf = ffmpeg_fetchibuf(anim, position, tc);
1315                         if (ibuf)
1316                                 anim->curposition = position;
1317                         filter_y = 0; /* done internally */
1318                         break;
1319 #endif
1320 #ifdef WITH_REDCODE
1321                 case ANIM_REDCODE:
1322                         ibuf = redcode_fetchibuf(anim, position);
1323                         if (ibuf) anim->curposition = position;
1324                         break;
1325 #endif
1326         }
1327
1328         if (ibuf) {
1329                 if (filter_y) IMB_filtery(ibuf);
1330                 BLI_snprintf(ibuf->name, sizeof(ibuf->name), "%s.%04d", anim->name, anim->curposition + 1);
1331                 
1332         }
1333         return(ibuf);
1334 }
1335
1336 /***/
1337
1338 int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc)
1339 {
1340         struct anim_index *idx;
1341         if (tc == IMB_TC_NONE) {
1342                 return anim->duration;
1343         }
1344         
1345         idx = IMB_anim_open_index(anim, tc);
1346         if (!idx) {
1347                 return anim->duration;
1348         }
1349
1350         return IMB_indexer_get_duration(idx);
1351 }
1352
1353 int IMB_anim_get_fps(struct anim *anim,
1354                      short *frs_sec, float *frs_sec_base)
1355 {
1356         if (anim->frs_sec) {
1357                 *frs_sec = anim->frs_sec;
1358                 *frs_sec_base = anim->frs_sec_base;
1359                 return TRUE;
1360         }
1361         return FALSE;
1362 }
1363
1364 void IMB_anim_set_preseek(struct anim *anim, int preseek)
1365 {
1366         anim->preseek = preseek;
1367 }
1368
1369 int IMB_anim_get_preseek(struct anim *anim)
1370 {
1371         return anim->preseek;
1372 }