Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #ifdef _WIN32 00034 #define INC_OLE2 00035 #include <windows.h> 00036 #include <windowsx.h> 00037 #include <mmsystem.h> 00038 #include <memory.h> 00039 #include <commdlg.h> 00040 00041 #ifndef FREE_WINDOWS 00042 #include <vfw.h> 00043 #endif 00044 00045 #undef AVIIF_KEYFRAME // redefined in AVI_avi.h 00046 #undef AVIIF_LIST // redefined in AVI_avi.h 00047 00048 #define FIXCC(fcc) if (fcc == 0) fcc = mmioFOURCC('N', 'o', 'n', 'e'); \ 00049 if (fcc == BI_RLE8) fcc = mmioFOURCC('R', 'l', 'e', '8'); 00050 #endif 00051 00052 #include <sys/types.h> 00053 #include <ctype.h> 00054 #include <stdlib.h> 00055 #include <stdio.h> 00056 #include <math.h> 00057 #ifndef _WIN32 00058 #include <dirent.h> 00059 #else 00060 #include <io.h> 00061 #endif 00062 00063 #include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail 00064 BLI_countlist BLI_stringdec */ 00065 #include "BLI_utildefines.h" 00066 #include "BLI_math_base.h" 00067 00068 #include "MEM_guardedalloc.h" 00069 00070 #include "DNA_userdef_types.h" 00071 00072 00073 #include "BKE_global.h" 00074 #include "BKE_depsgraph.h" 00075 00076 #include "imbuf.h" 00077 00078 #include "AVI_avi.h" 00079 00080 #ifdef WITH_QUICKTIME 00081 #if defined(_WIN32) || defined(__APPLE__) 00082 #include "quicktime_import.h" 00083 #endif /* _WIN32 || __APPLE__ */ 00084 #endif /* WITH_QUICKTIME */ 00085 00086 #include "IMB_imbuf_types.h" 00087 #include "IMB_imbuf.h" 00088 00089 #include "IMB_allocimbuf.h" 00090 #include "IMB_anim.h" 00091 #include "IMB_indexer.h" 00092 00093 #ifdef WITH_FFMPEG 00094 #include <libavformat/avformat.h> 00095 #include <libavcodec/avcodec.h> 00096 #include <libavutil/rational.h> 00097 #include <libswscale/swscale.h> 00098 00099 #include "ffmpeg_compat.h" 00100 00101 #endif //WITH_FFMPEG 00102 00103 #ifdef WITH_REDCODE 00104 #ifdef _WIN32 /* on windows we use the ones in extern instead */ 00105 #include "libredcode/format.h" 00106 #include "libredcode/codec.h" 00107 #else 00108 #include "libredcode/format.h" 00109 #include "libredcode/codec.h" 00110 #endif 00111 #endif 00112 00113 int ismovie(const char *UNUSED(filepath)) 00114 { 00115 return 0; 00116 } 00117 00118 /* never called, just keep the linker happy */ 00119 static int startmovie(struct anim *UNUSED(anim)) { return 1; } 00120 static ImBuf * movie_fetchibuf(struct anim *UNUSED(anim), int UNUSED(position)) { return NULL; } 00121 static void free_anim_movie(struct anim *UNUSED(anim)) { ; } 00122 00123 00124 #if defined(_WIN32) 00125 # define PATHSEPERATOR '\\' 00126 #else 00127 # define PATHSEPERATOR '/' 00128 #endif 00129 00130 static int an_stringdec(const char *string, char* head, char *tail, unsigned short *numlen) 00131 { 00132 unsigned short len,nume,nums=0; 00133 short i,found=FALSE; 00134 00135 len=strlen(string); 00136 nume = len; 00137 00138 for(i=len-1;i>=0;i--){ 00139 if (string[i]==PATHSEPERATOR) break; 00140 if (isdigit(string[i])) { 00141 if (found){ 00142 nums=i; 00143 } else{ 00144 nume=i; 00145 nums=i; 00146 found=TRUE; 00147 } 00148 } else{ 00149 if (found) break; 00150 } 00151 } 00152 if (found){ 00153 strcpy(tail ,&string[nume+1]); 00154 strcpy(head, string); 00155 head[nums]= '\0'; 00156 *numlen=nume-nums+1; 00157 return ((int)atoi(&(string[nums]))); 00158 } 00159 tail[0]= '\0'; 00160 strcpy(head, string); 00161 *numlen=0; 00162 return TRUE; 00163 } 00164 00165 00166 static void an_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic) 00167 { 00168 BLI_stringenc(string, head, tail, numlen, pic); 00169 } 00170 00171 static void free_anim_avi (struct anim *anim) 00172 { 00173 #if defined(_WIN32) && !defined(FREE_WINDOWS) 00174 int i; 00175 #endif 00176 00177 if (anim == NULL) return; 00178 if (anim->avi == NULL) return; 00179 00180 AVI_close (anim->avi); 00181 MEM_freeN (anim->avi); 00182 anim->avi = NULL; 00183 00184 #if defined(_WIN32) && !defined(FREE_WINDOWS) 00185 00186 if (anim->pgf) { 00187 AVIStreamGetFrameClose(anim->pgf); 00188 anim->pgf = NULL; 00189 } 00190 00191 for (i = 0; i < anim->avistreams; i++){ 00192 AVIStreamRelease(anim->pavi[i]); 00193 } 00194 anim->avistreams = 0; 00195 00196 if (anim->pfileopen) { 00197 AVIFileRelease(anim->pfile); 00198 anim->pfileopen = 0; 00199 AVIFileExit(); 00200 } 00201 #endif 00202 00203 anim->duration = 0; 00204 } 00205 00206 #ifdef WITH_FFMPEG 00207 static void free_anim_ffmpeg(struct anim * anim); 00208 #endif 00209 #ifdef WITH_REDCODE 00210 static void free_anim_redcode(struct anim * anim); 00211 #endif 00212 00213 void IMB_free_anim(struct anim * anim) 00214 { 00215 if (anim == NULL) { 00216 printf("free anim, anim == NULL\n"); 00217 return; 00218 } 00219 00220 free_anim_movie(anim); 00221 free_anim_avi(anim); 00222 00223 #ifdef WITH_QUICKTIME 00224 free_anim_quicktime(anim); 00225 #endif 00226 #ifdef WITH_FFMPEG 00227 free_anim_ffmpeg(anim); 00228 #endif 00229 #ifdef WITH_REDCODE 00230 free_anim_redcode(anim); 00231 #endif 00232 IMB_free_indices(anim); 00233 00234 MEM_freeN(anim); 00235 } 00236 00237 void IMB_close_anim(struct anim * anim) 00238 { 00239 if (anim == NULL) return; 00240 00241 IMB_free_anim(anim); 00242 } 00243 00244 00245 struct anim * IMB_open_anim( const char * name, int ib_flags, int streamindex) 00246 { 00247 struct anim * anim; 00248 00249 anim = (struct anim*)MEM_callocN(sizeof(struct anim), "anim struct"); 00250 if (anim != NULL) { 00251 BLI_strncpy(anim->name, name, sizeof(anim->name)); 00252 anim->ib_flags = ib_flags; 00253 anim->streamindex = streamindex; 00254 } 00255 return(anim); 00256 } 00257 00258 00259 static int startavi (struct anim *anim) 00260 { 00261 00262 AviError avierror; 00263 #if defined(_WIN32) && !defined(FREE_WINDOWS) 00264 HRESULT hr; 00265 int i, firstvideo = -1; 00266 int streamcount; 00267 BYTE abFormat[1024]; 00268 LONG l; 00269 LPBITMAPINFOHEADER lpbi; 00270 AVISTREAMINFO avis; 00271 00272 streamcount = anim->streamindex; 00273 #endif 00274 00275 anim->avi = MEM_callocN (sizeof(AviMovie),"animavi"); 00276 00277 if (anim->avi == NULL) { 00278 printf("Can't open avi: %s\n", anim->name); 00279 return -1; 00280 } 00281 00282 avierror = AVI_open_movie (anim->name, anim->avi); 00283 00284 #if defined(_WIN32) && !defined(FREE_WINDOWS) 00285 if (avierror == AVI_ERROR_COMPRESSION) { 00286 AVIFileInit(); 00287 hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L); 00288 if (hr == 0) { 00289 anim->pfileopen = 1; 00290 for (i = 0; i < MAXNUMSTREAMS; i++) { 00291 if (AVIFileGetStream(anim->pfile, &anim->pavi[i], 0L, i) != AVIERR_OK) { 00292 break; 00293 } 00294 00295 AVIStreamInfo(anim->pavi[i], &avis, sizeof(avis)); 00296 if ((avis.fccType == streamtypeVIDEO) && (firstvideo == -1)) { 00297 if (streamcount > 0) { 00298 streamcount--; 00299 continue; 00300 } 00301 anim->pgf = AVIStreamGetFrameOpen(anim->pavi[i], NULL); 00302 if (anim->pgf) { 00303 firstvideo = i; 00304 00305 // get stream length 00306 anim->avi->header->TotalFrames = AVIStreamLength(anim->pavi[i]); 00307 00308 // get information about images inside the stream 00309 l = sizeof(abFormat); 00310 AVIStreamReadFormat(anim->pavi[i], 0, &abFormat, &l); 00311 lpbi = (LPBITMAPINFOHEADER)abFormat; 00312 anim->avi->header->Height = lpbi->biHeight; 00313 anim->avi->header->Width = lpbi->biWidth; 00314 } else { 00315 FIXCC(avis.fccHandler); 00316 FIXCC(avis.fccType); 00317 printf("Can't find AVI decoder for type : %4.4hs/%4.4hs\n", 00318 (LPSTR)&avis.fccType, 00319 (LPSTR)&avis.fccHandler); 00320 } 00321 } 00322 } 00323 00324 // register number of opened avistreams 00325 anim->avistreams = i; 00326 00327 // 00328 // Couldn't get any video streams out of this file 00329 // 00330 if ((anim->avistreams == 0) || (firstvideo == -1)) { 00331 avierror = AVI_ERROR_FORMAT; 00332 } else { 00333 avierror = AVI_ERROR_NONE; 00334 anim->firstvideo = firstvideo; 00335 } 00336 } else { 00337 AVIFileExit(); 00338 } 00339 } 00340 #endif 00341 00342 if (avierror != AVI_ERROR_NONE) { 00343 AVI_print_error(avierror); 00344 printf ("Error loading avi: %s\n", anim->name); 00345 free_anim_avi(anim); 00346 return -1; 00347 } 00348 00349 anim->duration = anim->avi->header->TotalFrames; 00350 anim->params = NULL; 00351 00352 anim->x = anim->avi->header->Width; 00353 anim->y = anim->avi->header->Height; 00354 anim->interlacing = 0; 00355 anim->orientation = 0; 00356 anim->framesize = anim->x * anim->y * 4; 00357 00358 anim->curposition = 0; 00359 anim->preseek = 0; 00360 00361 /* printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/ 00362 00363 return 0; 00364 } 00365 00366 static ImBuf * avi_fetchibuf (struct anim *anim, int position) 00367 { 00368 ImBuf *ibuf = NULL; 00369 int *tmp; 00370 int y; 00371 00372 if (anim == NULL) return (NULL); 00373 00374 #if defined(_WIN32) && !defined(FREE_WINDOWS) 00375 if (anim->avistreams) { 00376 LPBITMAPINFOHEADER lpbi; 00377 00378 if (anim->pgf) { 00379 lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo])); 00380 if (lpbi) { 00381 ibuf = IMB_ibImageFromMemory((unsigned char *) lpbi, 100, IB_rect, "<avi_fetchibuf>"); 00382 //Oh brother... 00383 } 00384 } 00385 } else { 00386 #else 00387 if (1) { 00388 #endif 00389 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, IB_rect); 00390 00391 tmp = AVI_read_frame (anim->avi, AVI_FORMAT_RGB32, position, 00392 AVI_get_stream(anim->avi, AVIST_VIDEO, 0)); 00393 00394 if (tmp == NULL) { 00395 printf ("Error reading frame from AVI"); 00396 IMB_freeImBuf (ibuf); 00397 return NULL; 00398 } 00399 00400 for (y=0; y < anim->y; y++) { 00401 memcpy (&(ibuf->rect)[((anim->y-y)-1)*anim->x], &tmp[y*anim->x], 00402 anim->x * 4); 00403 } 00404 00405 MEM_freeN (tmp); 00406 } 00407 00408 ibuf->profile = IB_PROFILE_SRGB; 00409 00410 return ibuf; 00411 } 00412 00413 #ifdef WITH_FFMPEG 00414 00415 extern void do_init_ffmpeg(void); 00416 00417 static int startffmpeg(struct anim * anim) 00418 { 00419 int i, videoStream; 00420 00421 AVCodec *pCodec; 00422 AVFormatContext *pFormatCtx; 00423 AVCodecContext *pCodecCtx; 00424 int frs_num; 00425 double frs_den; 00426 int streamcount; 00427 00428 #ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT 00429 /* The following for color space determination */ 00430 int srcRange, dstRange, brightness, contrast, saturation; 00431 int *table; 00432 const int *inv_table; 00433 #endif 00434 00435 if (anim == 0) return(-1); 00436 00437 streamcount = anim->streamindex; 00438 00439 do_init_ffmpeg(); 00440 00441 if(av_open_input_file(&pFormatCtx, anim->name, NULL, 0, NULL)!=0) { 00442 return -1; 00443 } 00444 00445 if(av_find_stream_info(pFormatCtx)<0) { 00446 av_close_input_file(pFormatCtx); 00447 return -1; 00448 } 00449 00450 av_dump_format(pFormatCtx, 0, anim->name, 0); 00451 00452 00453 /* Find the video stream */ 00454 videoStream = -1; 00455 00456 for(i = 0; i < pFormatCtx->nb_streams; i++) 00457 if (pFormatCtx->streams[i]->codec->codec_type 00458 == AVMEDIA_TYPE_VIDEO) { 00459 if (streamcount > 0) { 00460 streamcount--; 00461 continue; 00462 } 00463 videoStream = i; 00464 break; 00465 } 00466 00467 if(videoStream==-1) { 00468 av_close_input_file(pFormatCtx); 00469 return -1; 00470 } 00471 00472 pCodecCtx = pFormatCtx->streams[videoStream]->codec; 00473 00474 /* Find the decoder for the video stream */ 00475 pCodec = avcodec_find_decoder(pCodecCtx->codec_id); 00476 if(pCodec == NULL) { 00477 av_close_input_file(pFormatCtx); 00478 return -1; 00479 } 00480 00481 pCodecCtx->workaround_bugs = 1; 00482 00483 if(avcodec_open(pCodecCtx, pCodec) < 0) { 00484 av_close_input_file(pFormatCtx); 00485 return -1; 00486 } 00487 00488 anim->duration = ceil(pFormatCtx->duration 00489 * av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate) 00490 / AV_TIME_BASE); 00491 00492 frs_num = pFormatCtx->streams[videoStream]->r_frame_rate.num; 00493 frs_den = pFormatCtx->streams[videoStream]->r_frame_rate.den; 00494 00495 frs_den *= AV_TIME_BASE; 00496 00497 while (frs_num % 10 == 0 && frs_den >= 2.0 && frs_num > 10) { 00498 frs_num /= 10; 00499 frs_den /= 10; 00500 } 00501 00502 anim->frs_sec = frs_num; 00503 anim->frs_sec_base = frs_den; 00504 00505 anim->params = 0; 00506 00507 anim->x = pCodecCtx->width; 00508 anim->y = pCodecCtx->height; 00509 anim->interlacing = 0; 00510 anim->orientation = 0; 00511 anim->framesize = anim->x * anim->y * 4; 00512 00513 anim->curposition = -1; 00514 anim->last_frame = 0; 00515 anim->last_pts = -1; 00516 anim->next_pts = -1; 00517 anim->next_packet.stream_index = -1; 00518 00519 anim->pFormatCtx = pFormatCtx; 00520 anim->pCodecCtx = pCodecCtx; 00521 anim->pCodec = pCodec; 00522 anim->videoStream = videoStream; 00523 00524 anim->pFrame = avcodec_alloc_frame(); 00525 anim->pFrameComplete = FALSE; 00526 anim->pFrameDeinterlaced = avcodec_alloc_frame(); 00527 anim->pFrameRGB = avcodec_alloc_frame(); 00528 00529 if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y) 00530 != anim->x * anim->y * 4) { 00531 fprintf (stderr, 00532 "ffmpeg has changed alloc scheme ... ARGHHH!\n"); 00533 avcodec_close(anim->pCodecCtx); 00534 av_close_input_file(anim->pFormatCtx); 00535 av_free(anim->pFrameRGB); 00536 av_free(anim->pFrameDeinterlaced); 00537 av_free(anim->pFrame); 00538 anim->pCodecCtx = NULL; 00539 return -1; 00540 } 00541 00542 if (anim->ib_flags & IB_animdeinterlace) { 00543 avpicture_fill((AVPicture*) anim->pFrameDeinterlaced, 00544 MEM_callocN(avpicture_get_size( 00545 anim->pCodecCtx->pix_fmt, 00546 anim->x, anim->y), 00547 "ffmpeg deinterlace"), 00548 anim->pCodecCtx->pix_fmt, anim->x, anim->y); 00549 } 00550 00551 if (pCodecCtx->has_b_frames) { 00552 anim->preseek = 25; /* FIXME: detect gopsize ... */ 00553 } else { 00554 anim->preseek = 0; 00555 } 00556 00557 anim->img_convert_ctx = sws_getContext( 00558 anim->pCodecCtx->width, 00559 anim->pCodecCtx->height, 00560 anim->pCodecCtx->pix_fmt, 00561 anim->pCodecCtx->width, 00562 anim->pCodecCtx->height, 00563 PIX_FMT_RGBA, 00564 SWS_FAST_BILINEAR | SWS_PRINT_INFO, 00565 NULL, NULL, NULL); 00566 00567 if (!anim->img_convert_ctx) { 00568 fprintf (stderr, 00569 "Can't transform color space??? Bailing out...\n"); 00570 avcodec_close(anim->pCodecCtx); 00571 av_close_input_file(anim->pFormatCtx); 00572 av_free(anim->pFrameRGB); 00573 av_free(anim->pFrameDeinterlaced); 00574 av_free(anim->pFrame); 00575 anim->pCodecCtx = NULL; 00576 return -1; 00577 } 00578 00579 #ifdef FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT 00580 /* Try do detect if input has 0-255 YCbCR range (JFIF Jpeg MotionJpeg) */ 00581 if (!sws_getColorspaceDetails(anim->img_convert_ctx, (int**)&inv_table, &srcRange, 00582 &table, &dstRange, &brightness, &contrast, &saturation)) { 00583 00584 srcRange = srcRange || anim->pCodecCtx->color_range == AVCOL_RANGE_JPEG; 00585 inv_table = sws_getCoefficients(anim->pCodecCtx->colorspace); 00586 00587 if(sws_setColorspaceDetails(anim->img_convert_ctx, (int *)inv_table, srcRange, 00588 table, dstRange, brightness, contrast, saturation)) { 00589 00590 printf("Warning: Could not set libswscale colorspace details.\n"); 00591 } 00592 } 00593 else { 00594 printf("Warning: Could not set libswscale colorspace details.\n"); 00595 } 00596 #endif 00597 00598 return (0); 00599 } 00600 00601 /* postprocess the image in anim->pFrame and do color conversion 00602 and deinterlacing stuff. 00603 00604 Output is anim->last_frame 00605 */ 00606 00607 static void ffmpeg_postprocess(struct anim * anim) 00608 { 00609 AVFrame * input = anim->pFrame; 00610 ImBuf * ibuf = anim->last_frame; 00611 int filter_y = 0; 00612 00613 ibuf->profile = IB_PROFILE_SRGB; 00614 00615 if (!anim->pFrameComplete) { 00616 return; 00617 } 00618 00619 /* This means the data wasnt read properly, 00620 this check stops crashing */ 00621 if (input->data[0]==0 && input->data[1]==0 00622 && input->data[2]==0 && input->data[3]==0){ 00623 fprintf(stderr, "ffmpeg_fetchibuf: " 00624 "data not read properly...\n"); 00625 return; 00626 } 00627 00628 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00629 " POSTPROC: anim->pFrame planes: %p %p %p %p\n", 00630 input->data[0], input->data[1], input->data[2], 00631 input->data[3]); 00632 00633 00634 if (anim->ib_flags & IB_animdeinterlace) { 00635 if (avpicture_deinterlace( 00636 (AVPicture*) 00637 anim->pFrameDeinterlaced, 00638 (const AVPicture*) 00639 anim->pFrame, 00640 anim->pCodecCtx->pix_fmt, 00641 anim->pCodecCtx->width, 00642 anim->pCodecCtx->height) 00643 < 0) { 00644 filter_y = TRUE; 00645 } else { 00646 input = anim->pFrameDeinterlaced; 00647 } 00648 } 00649 00650 avpicture_fill((AVPicture*) anim->pFrameRGB, 00651 (unsigned char*) ibuf->rect, 00652 PIX_FMT_RGBA, anim->x, anim->y); 00653 00654 if (ENDIAN_ORDER == B_ENDIAN) { 00655 int * dstStride = anim->pFrameRGB->linesize; 00656 uint8_t** dst = anim->pFrameRGB->data; 00657 int dstStride2[4] = { dstStride[0], 0, 0, 0 }; 00658 uint8_t* dst2[4] = { dst[0], 0, 0, 0 }; 00659 int x,y,h,w; 00660 unsigned char* bottom; 00661 unsigned char* top; 00662 00663 sws_scale(anim->img_convert_ctx, 00664 (const uint8_t * const *)input->data, 00665 input->linesize, 00666 0, 00667 anim->pCodecCtx->height, 00668 dst2, 00669 dstStride2); 00670 00671 bottom = (unsigned char*) ibuf->rect; 00672 top = bottom + ibuf->x * (ibuf->y-1) * 4; 00673 00674 h = (ibuf->y + 1) / 2; 00675 w = ibuf->x; 00676 00677 for (y = 0; y < h; y++) { 00678 unsigned char tmp[4]; 00679 unsigned int * tmp_l = 00680 (unsigned int*) tmp; 00681 00682 for (x = 0; x < w; x++) { 00683 tmp[0] = bottom[0]; 00684 tmp[1] = bottom[1]; 00685 tmp[2] = bottom[2]; 00686 tmp[3] = bottom[3]; 00687 00688 bottom[0] = top[0]; 00689 bottom[1] = top[1]; 00690 bottom[2] = top[2]; 00691 bottom[3] = top[3]; 00692 00693 *(unsigned int*) top = *tmp_l; 00694 00695 bottom +=4; 00696 top += 4; 00697 } 00698 top -= 8 * w; 00699 } 00700 } else { 00701 int * dstStride = anim->pFrameRGB->linesize; 00702 uint8_t** dst = anim->pFrameRGB->data; 00703 int dstStride2[4] = { -dstStride[0], 0, 0, 0 }; 00704 uint8_t* dst2[4] = { dst[0] + (anim->y - 1)*dstStride[0], 00705 0, 0, 0 }; 00706 00707 sws_scale(anim->img_convert_ctx, 00708 (const uint8_t * const *)input->data, 00709 input->linesize, 00710 0, 00711 anim->pCodecCtx->height, 00712 dst2, 00713 dstStride2); 00714 } 00715 00716 if (filter_y) { 00717 IMB_filtery(ibuf); 00718 } 00719 } 00720 00721 /* decode one video frame also considering the packet read into next_packet */ 00722 00723 static int ffmpeg_decode_video_frame(struct anim * anim) 00724 { 00725 int rval = 0; 00726 00727 av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n"); 00728 00729 if (anim->next_packet.stream_index == anim->videoStream) { 00730 av_free_packet(&anim->next_packet); 00731 anim->next_packet.stream_index = -1; 00732 } 00733 00734 while((rval = av_read_frame(anim->pFormatCtx, &anim->next_packet)) >= 0) { 00735 av_log(anim->pFormatCtx, 00736 AV_LOG_DEBUG, 00737 "%sREAD: strID=%d (VID: %d) dts=%lld pts=%lld " 00738 "%s\n", 00739 (anim->next_packet.stream_index == anim->videoStream) 00740 ? "->" : " ", 00741 anim->next_packet.stream_index, 00742 anim->videoStream, 00743 (anim->next_packet.dts == AV_NOPTS_VALUE) ? -1: 00744 (long long int)anim->next_packet.dts, 00745 (anim->next_packet.pts == AV_NOPTS_VALUE) ? -1: 00746 (long long int)anim->next_packet.pts, 00747 (anim->next_packet.flags & AV_PKT_FLAG_KEY) ? 00748 " KEY" : ""); 00749 if (anim->next_packet.stream_index == anim->videoStream) { 00750 anim->pFrameComplete = 0; 00751 00752 avcodec_decode_video2( 00753 anim->pCodecCtx, 00754 anim->pFrame, &anim->pFrameComplete, 00755 &anim->next_packet); 00756 00757 if (anim->pFrameComplete) { 00758 anim->next_pts = av_get_pts_from_frame( 00759 anim->pFormatCtx, anim->pFrame); 00760 00761 av_log(anim->pFormatCtx, 00762 AV_LOG_DEBUG, 00763 " FRAME DONE: next_pts=%lld " 00764 "pkt_pts=%lld, guessed_pts=%lld\n", 00765 (anim->pFrame->pts == AV_NOPTS_VALUE) ? 00766 -1 : (long long int)anim->pFrame->pts, 00767 (anim->pFrame->pkt_pts 00768 == AV_NOPTS_VALUE) ? 00769 -1 : (long long int)anim->pFrame->pkt_pts, 00770 (long long int)anim->next_pts); 00771 break; 00772 } 00773 } 00774 av_free_packet(&anim->next_packet); 00775 anim->next_packet.stream_index = -1; 00776 } 00777 00778 if (rval < 0) { 00779 anim->next_packet.stream_index = -1; 00780 00781 av_log(anim->pFormatCtx, 00782 AV_LOG_ERROR, " DECODE READ FAILED: av_read_frame() " 00783 "returned error: %d\n", rval); 00784 } 00785 00786 return (rval >= 0); 00787 } 00788 00789 static void ffmpeg_decode_video_frame_scan( 00790 struct anim * anim, int64_t pts_to_search) 00791 { 00792 /* there seem to exist *very* silly GOP lengths out in the wild... */ 00793 int count = 1000; 00794 00795 av_log(anim->pFormatCtx, 00796 AV_LOG_DEBUG, 00797 "SCAN start: considering pts=%lld in search of %lld\n", 00798 (long long int)anim->next_pts, (long long int)pts_to_search); 00799 00800 while (count > 0 && anim->next_pts < pts_to_search) { 00801 av_log(anim->pFormatCtx, 00802 AV_LOG_DEBUG, 00803 " WHILE: pts=%lld in search of %lld\n", 00804 (long long int)anim->next_pts, (long long int)pts_to_search); 00805 if (!ffmpeg_decode_video_frame(anim)) { 00806 break; 00807 } 00808 count--; 00809 } 00810 if (count == 0) { 00811 av_log(anim->pFormatCtx, 00812 AV_LOG_ERROR, 00813 "SCAN failed: completely lost in stream, " 00814 "bailing out at PTS=%lld, searching for PTS=%lld\n", 00815 (long long int)anim->next_pts, (long long int)pts_to_search); 00816 } 00817 if (anim->next_pts == pts_to_search) { 00818 av_log(anim->pFormatCtx, 00819 AV_LOG_DEBUG, "SCAN HAPPY: we found our PTS!\n"); 00820 } else { 00821 av_log(anim->pFormatCtx, 00822 AV_LOG_ERROR, "SCAN UNHAPPY: PTS not matched!\n"); 00823 } 00824 } 00825 00826 static int match_format(const char *name, AVFormatContext * pFormatCtx) 00827 { 00828 const char *p; 00829 int len, namelen; 00830 00831 const char *names = pFormatCtx->iformat->name; 00832 00833 if (!name || !names) 00834 return 0; 00835 00836 namelen = strlen(name); 00837 while ((p = strchr(names, ','))) { 00838 len = MAX2(p - names, namelen); 00839 if (!BLI_strncasecmp(name, names, len)) 00840 return 1; 00841 names = p+1; 00842 } 00843 return !BLI_strcasecmp(name, names); 00844 } 00845 00846 static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx) 00847 { 00848 static const char * byte_seek_list [] = { "mpegts", 0 }; 00849 const char ** p; 00850 00851 if (pFormatCtx->iformat->flags & AVFMT_TS_DISCONT) { 00852 return TRUE; 00853 } 00854 00855 p = byte_seek_list; 00856 00857 while (*p) { 00858 if (match_format(*p++, pFormatCtx)) { 00859 return TRUE; 00860 } 00861 } 00862 00863 return FALSE; 00864 } 00865 00866 static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position, 00867 IMB_Timecode_Type tc) { 00868 int64_t pts_to_search = 0; 00869 double frame_rate; 00870 double pts_time_base; 00871 long long st_time; 00872 struct anim_index * tc_index = 0; 00873 AVStream * v_st; 00874 int new_frame_index = 0; /* To quite gcc barking... */ 00875 int old_frame_index = 0; /* To quite gcc barking... */ 00876 00877 if (anim == 0) return (0); 00878 00879 av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: pos=%d\n", position); 00880 00881 if (tc != IMB_TC_NONE) { 00882 tc_index = IMB_anim_open_index(anim, tc); 00883 } 00884 00885 v_st = anim->pFormatCtx->streams[anim->videoStream]; 00886 00887 frame_rate = av_q2d(v_st->r_frame_rate); 00888 00889 st_time = anim->pFormatCtx->start_time; 00890 pts_time_base = av_q2d(v_st->time_base); 00891 00892 if (tc_index) { 00893 new_frame_index = IMB_indexer_get_frame_index( 00894 tc_index, position); 00895 old_frame_index = IMB_indexer_get_frame_index( 00896 tc_index, anim->curposition); 00897 pts_to_search = IMB_indexer_get_pts( 00898 tc_index, new_frame_index); 00899 } else { 00900 pts_to_search = (long long) 00901 floor(((double) position) 00902 / pts_time_base / frame_rate + 0.5); 00903 00904 if (st_time != AV_NOPTS_VALUE) { 00905 pts_to_search += st_time / pts_time_base 00906 / AV_TIME_BASE; 00907 } 00908 } 00909 00910 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00911 "FETCH: looking for PTS=%lld " 00912 "(pts_timebase=%g, frame_rate=%g, st_time=%lld)\n", 00913 (long long int)pts_to_search,pts_time_base, frame_rate, st_time); 00914 00915 if (anim->last_frame && 00916 anim->last_pts <= pts_to_search && anim->next_pts > pts_to_search){ 00917 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00918 "FETCH: frame repeat: last: %lld next: %lld\n", 00919 (long long int)anim->last_pts, 00920 (long long int)anim->next_pts); 00921 IMB_refImBuf(anim->last_frame); 00922 anim->curposition = position; 00923 return anim->last_frame; 00924 } 00925 00926 if (position > anim->curposition + 1 00927 && anim->preseek 00928 && !tc_index 00929 && position - (anim->curposition + 1) < anim->preseek) { 00930 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00931 "FETCH: within preseek interval (no index)\n"); 00932 00933 ffmpeg_decode_video_frame_scan(anim, pts_to_search); 00934 } else if (tc_index && 00935 IMB_indexer_can_scan(tc_index, old_frame_index, 00936 new_frame_index)) { 00937 00938 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00939 "FETCH: within preseek interval " 00940 "(index tells us)\n"); 00941 00942 ffmpeg_decode_video_frame_scan(anim, pts_to_search); 00943 } else if (position != anim->curposition + 1) { 00944 long long pos; 00945 int ret; 00946 00947 if (tc_index) { 00948 unsigned long long dts; 00949 00950 pos = IMB_indexer_get_seek_pos( 00951 tc_index, new_frame_index); 00952 dts = IMB_indexer_get_seek_pos_dts( 00953 tc_index, new_frame_index); 00954 00955 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00956 "TC INDEX seek pos = %lld\n", pos); 00957 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00958 "TC INDEX seek dts = %lld\n", dts); 00959 00960 if (ffmpeg_seek_by_byte(anim->pFormatCtx)) { 00961 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00962 "... using BYTE pos\n"); 00963 00964 ret = av_seek_frame(anim->pFormatCtx, 00965 -1, 00966 pos, AVSEEK_FLAG_BYTE); 00967 av_update_cur_dts(anim->pFormatCtx, v_st, dts); 00968 } else { 00969 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00970 "... using DTS pos\n"); 00971 ret = av_seek_frame(anim->pFormatCtx, 00972 anim->videoStream, 00973 dts, AVSEEK_FLAG_BACKWARD); 00974 } 00975 } else { 00976 pos = (long long) (position - anim->preseek) 00977 * AV_TIME_BASE / frame_rate; 00978 00979 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00980 "NO INDEX seek pos = %lld, st_time = %lld\n", 00981 pos, (st_time != AV_NOPTS_VALUE) ? st_time : 0); 00982 00983 if (pos < 0) { 00984 pos = 0; 00985 } 00986 00987 if (st_time != AV_NOPTS_VALUE) { 00988 pos += st_time; 00989 } 00990 00991 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 00992 "NO INDEX final seek pos = %lld\n", pos); 00993 00994 ret = av_seek_frame(anim->pFormatCtx, -1, 00995 pos, AVSEEK_FLAG_BACKWARD); 00996 } 00997 00998 if (ret < 0) { 00999 av_log(anim->pFormatCtx, AV_LOG_ERROR, 01000 "FETCH: " 01001 "error while seeking to DTS = %lld " 01002 "(frameno = %d, PTS = %lld): errcode = %d\n", 01003 pos, position, (long long int)pts_to_search, ret); 01004 } 01005 01006 avcodec_flush_buffers(anim->pCodecCtx); 01007 01008 anim->next_pts = -1; 01009 01010 if (anim->next_packet.stream_index == anim->videoStream) { 01011 av_free_packet(&anim->next_packet); 01012 anim->next_packet.stream_index = -1; 01013 } 01014 01015 /* memset(anim->pFrame,...) ?? */ 01016 01017 if (ret >= 0) { 01018 ffmpeg_decode_video_frame_scan(anim, pts_to_search); 01019 } 01020 } else if (position == 0 && anim->curposition == -1) { 01021 /* first frame without seeking special case... */ 01022 ffmpeg_decode_video_frame(anim); 01023 } else { 01024 av_log(anim->pFormatCtx, AV_LOG_DEBUG, 01025 "FETCH: no seek necessary, just continue...\n"); 01026 } 01027 01028 IMB_freeImBuf(anim->last_frame); 01029 anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect); 01030 01031 ffmpeg_postprocess(anim); 01032 01033 anim->last_pts = anim->next_pts; 01034 01035 ffmpeg_decode_video_frame(anim); 01036 01037 anim->curposition = position; 01038 01039 IMB_refImBuf(anim->last_frame); 01040 01041 return anim->last_frame; 01042 } 01043 01044 static void free_anim_ffmpeg(struct anim * anim) 01045 { 01046 if (anim == NULL) return; 01047 01048 if (anim->pCodecCtx) { 01049 avcodec_close(anim->pCodecCtx); 01050 av_close_input_file(anim->pFormatCtx); 01051 av_free(anim->pFrameRGB); 01052 av_free(anim->pFrame); 01053 01054 if (anim->ib_flags & IB_animdeinterlace) { 01055 MEM_freeN(anim->pFrameDeinterlaced->data[0]); 01056 } 01057 av_free(anim->pFrameDeinterlaced); 01058 sws_freeContext(anim->img_convert_ctx); 01059 IMB_freeImBuf(anim->last_frame); 01060 if (anim->next_packet.stream_index != -1) { 01061 av_free_packet(&anim->next_packet); 01062 } 01063 } 01064 anim->duration = 0; 01065 } 01066 01067 #endif 01068 01069 #ifdef WITH_REDCODE 01070 01071 static int startredcode(struct anim * anim) 01072 { 01073 anim->redcodeCtx = redcode_open(anim->name); 01074 if (!anim->redcodeCtx) { 01075 return -1; 01076 } 01077 anim->duration = redcode_get_length(anim->redcodeCtx); 01078 01079 return 0; 01080 } 01081 01082 static ImBuf * redcode_fetchibuf(struct anim * anim, int position) 01083 { 01084 struct ImBuf * ibuf; 01085 struct redcode_frame * frame; 01086 struct redcode_frame_raw * raw_frame; 01087 01088 if (!anim->redcodeCtx) { 01089 return NULL; 01090 } 01091 01092 frame = redcode_read_video_frame(anim->redcodeCtx, position); 01093 01094 if (!frame) { 01095 return NULL; 01096 } 01097 01098 raw_frame = redcode_decode_video_raw(frame, 1); 01099 01100 redcode_free_frame(frame); 01101 01102 if (!raw_frame) { 01103 return NULL; 01104 } 01105 01106 ibuf = IMB_allocImBuf(raw_frame->width * 2, 01107 raw_frame->height * 2, 32, IB_rectfloat); 01108 01109 redcode_decode_video_float(raw_frame, ibuf->rect_float, 1); 01110 01111 return ibuf; 01112 } 01113 01114 static void free_anim_redcode(struct anim * anim) 01115 { 01116 if (anim->redcodeCtx) { 01117 redcode_close(anim->redcodeCtx); 01118 anim->redcodeCtx = 0; 01119 } 01120 anim->duration = 0; 01121 } 01122 01123 #endif 01124 01125 /* probeer volgende plaatje te lezen */ 01126 /* Geen plaatje, probeer dan volgende animatie te openen */ 01127 /* gelukt, haal dan eerste plaatje van animatie */ 01128 01129 static struct ImBuf * anim_getnew(struct anim * anim) 01130 { 01131 struct ImBuf *ibuf = NULL; 01132 01133 if (anim == NULL) return(NULL); 01134 01135 free_anim_movie(anim); 01136 free_anim_avi(anim); 01137 #ifdef WITH_QUICKTIME 01138 free_anim_quicktime(anim); 01139 #endif 01140 #ifdef WITH_FFMPEG 01141 free_anim_ffmpeg(anim); 01142 #endif 01143 #ifdef WITH_REDCODE 01144 free_anim_redcode(anim); 01145 #endif 01146 01147 01148 if (anim->curtype != 0) return (NULL); 01149 anim->curtype = imb_get_anim_type(anim->name); 01150 01151 switch (anim->curtype) { 01152 case ANIM_SEQUENCE: 01153 ibuf = IMB_loadiffname(anim->name, anim->ib_flags); 01154 if (ibuf) { 01155 BLI_strncpy(anim->first, anim->name, sizeof(anim->first)); 01156 anim->duration = 1; 01157 } 01158 break; 01159 case ANIM_MOVIE: 01160 if (startmovie(anim)) return (NULL); 01161 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0); /* fake */ 01162 break; 01163 case ANIM_AVI: 01164 if (startavi(anim)) { 01165 printf("couldnt start avi\n"); 01166 return (NULL); 01167 } 01168 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0); 01169 break; 01170 #ifdef WITH_QUICKTIME 01171 case ANIM_QTIME: 01172 if (startquicktime(anim)) return (0); 01173 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0); 01174 break; 01175 #endif 01176 #ifdef WITH_FFMPEG 01177 case ANIM_FFMPEG: 01178 if (startffmpeg(anim)) return (0); 01179 ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0); 01180 break; 01181 #endif 01182 #ifdef WITH_REDCODE 01183 case ANIM_REDCODE: 01184 if (startredcode(anim)) return (0); 01185 ibuf = IMB_allocImBuf (8, 8, 32, 0); 01186 break; 01187 #endif 01188 } 01189 return(ibuf); 01190 } 01191 01192 struct ImBuf * IMB_anim_previewframe(struct anim * anim) 01193 { 01194 struct ImBuf * ibuf = NULL; 01195 int position = 0; 01196 01197 ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); 01198 if (ibuf) { 01199 IMB_freeImBuf(ibuf); 01200 position = anim->duration / 2; 01201 ibuf = IMB_anim_absolute(anim, position, IMB_TC_NONE, 01202 IMB_PROXY_NONE); 01203 } 01204 return ibuf; 01205 } 01206 01207 struct ImBuf * IMB_anim_absolute(struct anim * anim, int position, 01208 IMB_Timecode_Type tc, 01209 IMB_Proxy_Size preview_size) { 01210 struct ImBuf * ibuf = NULL; 01211 char head[256], tail[256]; 01212 unsigned short digits; 01213 int pic; 01214 int filter_y; 01215 if (anim == NULL) return(NULL); 01216 01217 filter_y = (anim->ib_flags & IB_animdeinterlace); 01218 01219 if (anim->curtype == 0) { 01220 ibuf = anim_getnew(anim); 01221 if (ibuf == NULL) { 01222 return(NULL); 01223 } 01224 01225 IMB_freeImBuf(ibuf); /* ???? */ 01226 ibuf= NULL; 01227 } 01228 01229 if (position < 0) return(NULL); 01230 if (position >= anim->duration) return(NULL); 01231 01232 if (preview_size != IMB_PROXY_NONE) { 01233 struct anim * proxy = IMB_anim_open_proxy(anim, preview_size); 01234 01235 if (proxy) { 01236 position = IMB_anim_index_get_frame_index( 01237 anim, tc, position); 01238 return IMB_anim_absolute( 01239 proxy, position, 01240 IMB_TC_NONE, IMB_PROXY_NONE); 01241 } 01242 } 01243 01244 switch(anim->curtype) { 01245 case ANIM_SEQUENCE: 01246 pic = an_stringdec(anim->first, head, tail, &digits); 01247 pic += position; 01248 an_stringenc(anim->name, head, tail, digits, pic); 01249 ibuf = IMB_loadiffname(anim->name, IB_rect); 01250 if (ibuf) { 01251 anim->curposition = position; 01252 } 01253 break; 01254 case ANIM_MOVIE: 01255 ibuf = movie_fetchibuf(anim, position); 01256 if (ibuf) { 01257 anim->curposition = position; 01258 IMB_convert_rgba_to_abgr(ibuf); 01259 ibuf->profile = IB_PROFILE_SRGB; 01260 } 01261 break; 01262 case ANIM_AVI: 01263 ibuf = avi_fetchibuf(anim, position); 01264 if (ibuf) 01265 anim->curposition = position; 01266 break; 01267 #ifdef WITH_QUICKTIME 01268 case ANIM_QTIME: 01269 ibuf = qtime_fetchibuf(anim, position); 01270 if (ibuf) 01271 anim->curposition = position; 01272 break; 01273 #endif 01274 #ifdef WITH_FFMPEG 01275 case ANIM_FFMPEG: 01276 ibuf = ffmpeg_fetchibuf(anim, position, tc); 01277 if (ibuf) 01278 anim->curposition = position; 01279 filter_y = 0; /* done internally */ 01280 break; 01281 #endif 01282 #ifdef WITH_REDCODE 01283 case ANIM_REDCODE: 01284 ibuf = redcode_fetchibuf(anim, position); 01285 if (ibuf) anim->curposition = position; 01286 break; 01287 #endif 01288 } 01289 01290 if (ibuf) { 01291 if (filter_y) IMB_filtery(ibuf); 01292 BLI_snprintf(ibuf->name, sizeof(ibuf->name), "%s.%04d", anim->name, anim->curposition + 1); 01293 01294 } 01295 return(ibuf); 01296 } 01297 01298 /***/ 01299 01300 int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc) 01301 { 01302 struct anim_index * idx; 01303 if (tc == IMB_TC_NONE) { 01304 return anim->duration; 01305 } 01306 01307 idx = IMB_anim_open_index(anim, tc); 01308 if (!idx) { 01309 return anim->duration; 01310 } 01311 01312 return IMB_indexer_get_duration(idx); 01313 } 01314 01315 int IMB_anim_get_fps(struct anim * anim, 01316 short * frs_sec, float * frs_sec_base) 01317 { 01318 if (anim->frs_sec) { 01319 *frs_sec = anim->frs_sec; 01320 *frs_sec_base = anim->frs_sec_base; 01321 return TRUE; 01322 } 01323 return FALSE; 01324 } 01325 01326 void IMB_anim_set_preseek(struct anim * anim, int preseek) 01327 { 01328 anim->preseek = preseek; 01329 } 01330 01331 int IMB_anim_get_preseek(struct anim * anim) 01332 { 01333 return anim->preseek; 01334 }