Merged 15170:15635 from trunk (no conflicts or even merges)
[blender.git] / source / blender / imbuf / intern / anim.c
index 87d67f5263b898ada39e8a511bb86faad7c63c9b..720f5b0f7c8d0bc967424642274a1af88d33c5fd 100644 (file)
@@ -600,6 +600,7 @@ static int startffmpeg(struct anim * anim) {
        anim->videoStream = videoStream;
 
        anim->pFrame = avcodec_alloc_frame();
+       anim->pFrameDeinterlaced = avcodec_alloc_frame();
        anim->pFrameRGB = avcodec_alloc_frame();
 
        if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y)
@@ -609,10 +610,20 @@ static int startffmpeg(struct anim * anim) {
                avcodec_close(anim->pCodecCtx);
                av_close_input_file(anim->pFormatCtx);
                av_free(anim->pFrameRGB);
+               av_free(anim->pFrameDeinterlaced);
                av_free(anim->pFrame);
                return -1;
        }
 
+       if (anim->ib_flags & IB_animdeinterlace) {
+               avpicture_fill((AVPicture*) anim->pFrameDeinterlaced, 
+                              MEM_callocN(avpicture_get_size(
+                                                  anim->pCodecCtx->pix_fmt,
+                                                  anim->x, anim->y), 
+                                          "ffmpeg deinterlace"), 
+                              anim->pCodecCtx->pix_fmt, anim->x, anim->y);
+       }
+
        if (pCodecCtx->has_b_frames) {
                anim->preseek = 25; /* FIXME: detect gopsize ... */
        } else {
@@ -638,12 +649,13 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
        AVPacket packet;
        int64_t pts_to_search = 0;
        int pos_found = 1;
+       int filter_y = 0;
 
        if (anim == 0) return (0);
 
        ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0);
 
-       avpicture_fill((AVPicture *)anim->pFrameRGB, 
+       avpicture_fill((AVPicture*) anim->pFrameRGB, 
                       (unsigned char*) ibuf->rect, 
                       PIX_FMT_BGR32, anim->x, anim->y);
 
@@ -722,6 +734,32 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                        } 
 
                        if(frameFinished && pos_found == 1) {
+                               AVFrame * input = anim->pFrame;
+
+                               /* This means the data wasnt read properly, 
+                                  this check stops crashing */
+                               if (input->data[0]==0 && input->data[1]==0 
+                                   && input->data[2]==0 && input->data[3]==0){
+                                       av_free_packet(&packet);
+                                       break;
+                               }
+
+                               if (anim->ib_flags & IB_animdeinterlace) {
+                                       if (avpicture_deinterlace(
+                                                   (AVPicture*) 
+                                                   anim->pFrameDeinterlaced,
+                                                   (const AVPicture*)
+                                                   anim->pFrame,
+                                                   anim->pCodecCtx->pix_fmt,
+                                                   anim->pCodecCtx->width,
+                                                   anim->pCodecCtx->height)
+                                           < 0) {
+                                               filter_y = 1;
+                                       } else {
+                                               input = anim->pFrameDeinterlaced;
+                                       }
+                               }
+
                                if (G.order == B_ENDIAN) {
                                        int * dstStride 
                                                = anim->pFrameRGB->linesize;
@@ -735,8 +773,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                                        unsigned char* top;
 
                                        sws_scale(anim->img_convert_ctx,
-                                                 anim->pFrame->data,
-                                                 anim->pFrame->linesize,
+                                                 input->data,
+                                                 input->linesize,
                                                  0,
                                                  anim->pCodecCtx->height,
                                                  dst2,
@@ -793,27 +831,25 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                                        int i;
                                        unsigned char* r;
                                        
-                                       /* This means the data wasnt read properly, this check stops crashing */
-                                       if (anim->pFrame->data[0]!=0 || anim->pFrame->data[1]!=0 || anim->pFrame->data[2]!=0 || anim->pFrame->data[3]!=0) {
                                                
-                                               sws_scale(anim->img_convert_ctx,
-                                                         anim->pFrame->data,
-                                                         anim->pFrame->linesize,
-                                                         0,
-                                                         anim->pCodecCtx->height,
-                                                         dst2,
-                                                         dstStride2);
+                                       sws_scale(anim->img_convert_ctx,
+                                                 input->data,
+                                                 input->linesize,
+                                                 0,
+                                                 anim->pCodecCtx->height,
+                                                 dst2,
+                                                 dstStride2);
                                        
-                                               /* workaround: sws_scale 
-                                                  sets alpha = 0... */
+                                       /* workaround: sws_scale 
+                                          sets alpha = 0... */
                                        
-                                               r = (unsigned char*) ibuf->rect;
-       
-                                               for (i = 0; i < ibuf->x * ibuf->y;i++){
-                                                       r[3] = 0xff;
-                                                       r+=4;
-                                               }
+                                       r = (unsigned char*) ibuf->rect;
+                                       
+                                       for (i = 0; i < ibuf->x * ibuf->y;i++){
+                                               r[3] = 0xff;
+                                               r+=4;
                                        }
+                                       
                                        av_free_packet(&packet);
                                        break;
                                }
@@ -823,6 +859,10 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                av_free_packet(&packet);
        }
 
+       if (filter_y && ibuf) {
+               IMB_filtery(ibuf);
+       }
+
        return(ibuf);
 }
 
@@ -834,6 +874,11 @@ static void free_anim_ffmpeg(struct anim * anim) {
                av_close_input_file(anim->pFormatCtx);
                av_free(anim->pFrameRGB);
                av_free(anim->pFrame);
+
+               if (anim->ib_flags & IB_animdeinterlace) {
+                       MEM_freeN(anim->pFrameDeinterlaced->data[0]);
+               }
+               av_free(anim->pFrameDeinterlaced);
                sws_freeContext(anim->img_convert_ctx);
        }
        anim->duration = 0;
@@ -983,6 +1028,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
        char head[256], tail[256];
        unsigned short digits;
        int pic;
+       int filter_y = (anim->ib_flags & IB_animdeinterlace);
 
        if (anim == NULL) return(0);
 
@@ -1040,6 +1086,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
        case ANIM_FFMPEG:
                ibuf = ffmpeg_fetchibuf(anim, position);
                if (ibuf) anim->curposition = position;
+               filter_y = 0; /* done internally */
                break;
 #endif
 #ifdef WITH_REDCODE
@@ -1052,6 +1099,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
 
        if (ibuf) {
                if (anim->ib_flags & IB_ttob) IMB_flipy(ibuf);
+               if (filter_y) IMB_filtery(ibuf);
                sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1);
                
        }