Beispiel #1
0
static void ffmpeg_postprocess(struct anim *anim)
{
	AVFrame *input = anim->pFrame;
	ImBuf *ibuf = anim->last_frame;
	int filter_y = 0;

	if (!anim->pFrameComplete) {
		return;
	}

	/* 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)
	{
		fprintf(stderr, "ffmpeg_fetchibuf: "
		        "data not read properly...\n");
		return;
	}

	av_log(anim->pFormatCtx, AV_LOG_DEBUG, 
	       "  POSTPROC: anim->pFrame planes: %p %p %p %p\n",
	       input->data[0], input->data[1], input->data[2],
	       input->data[3]);


	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 = TRUE;
		}
		else {
			input = anim->pFrameDeinterlaced;
		}
	}
	
	avpicture_fill((AVPicture *) anim->pFrameRGB,
	               (unsigned char *) ibuf->rect,
	               PIX_FMT_RGBA, anim->x, anim->y);

	if (ENDIAN_ORDER == B_ENDIAN) {
		int *dstStride   = anim->pFrameRGB->linesize;
		uint8_t **dst     = anim->pFrameRGB->data;
		int dstStride2[4] = { dstStride[0], 0, 0, 0 };
		uint8_t *dst2[4]  = { dst[0], 0, 0, 0 };
		int x, y, h, w;
		unsigned char *bottom;
		unsigned char *top;
		
		sws_scale(anim->img_convert_ctx,
		          (const uint8_t *const *)input->data,
		          input->linesize,
		          0,
		          anim->y,
		          dst2,
		          dstStride2);
		
		bottom = (unsigned char *) ibuf->rect;
		top = bottom + ibuf->x * (ibuf->y - 1) * 4;
		
		h = (ibuf->y + 1) / 2;
		w = ibuf->x;
		
		for (y = 0; y < h; y++) {
			unsigned char tmp[4];
			unsigned int *tmp_l =
			    (unsigned int *) tmp;
			
			for (x = 0; x < w; x++) {
				tmp[0] = bottom[0];
				tmp[1] = bottom[1];
				tmp[2] = bottom[2];
				tmp[3] = bottom[3];
				
				bottom[0] = top[0];
				bottom[1] = top[1];
				bottom[2] = top[2];
				bottom[3] = top[3];
				
				*(unsigned int *) top = *tmp_l;
				
				bottom += 4;
				top += 4;
			}
			top -= 8 * w;
		}
	}
	else {
		int *dstStride   = anim->pFrameRGB->linesize;
		uint8_t **dst     = anim->pFrameRGB->data;
		int dstStride2[4] = { -dstStride[0], 0, 0, 0 };
		uint8_t *dst2[4]  = { dst[0] + (anim->y - 1) * dstStride[0],
			                  0, 0, 0 };
		
		sws_scale(anim->img_convert_ctx,
		          (const uint8_t *const *)input->data,
		          input->linesize,
		          0,
		          anim->y,
		          dst2,
		          dstStride2);
	}

	if (filter_y) {
		IMB_filtery(ibuf);
	}
}
Beispiel #2
0
struct ImBuf *IMB_anim_absolute(struct anim *anim, int position,
                                IMB_Timecode_Type tc,
                                IMB_Proxy_Size preview_size)
{
	struct ImBuf *ibuf = NULL;
	char head[256], tail[256];
	unsigned short digits;
	int pic;
	int filter_y;
	if (anim == NULL) return(NULL);

	filter_y = (anim->ib_flags & IB_animdeinterlace);

	if (anim->curtype == 0) {
		ibuf = anim_getnew(anim);
		if (ibuf == NULL) {
			return(NULL);
		}

		IMB_freeImBuf(ibuf); /* ???? */
		ibuf = NULL;
	}

	if (position < 0) return(NULL);
	if (position >= anim->duration) return(NULL);

	if (preview_size != IMB_PROXY_NONE) {
		struct anim *proxy = IMB_anim_open_proxy(anim, preview_size);

		if (proxy) {
			position = IMB_anim_index_get_frame_index(
			    anim, tc, position);
			return IMB_anim_absolute(
			           proxy, position,
			           IMB_TC_NONE, IMB_PROXY_NONE);
		}
	}

	switch (anim->curtype) {
		case ANIM_SEQUENCE:
			pic = an_stringdec(anim->first, head, tail, &digits);
			pic += position;
			an_stringenc(anim->name, head, tail, digits, pic);
			ibuf = IMB_loadiffname(anim->name, IB_rect, anim->colorspace);
			if (ibuf) {
				anim->curposition = position;
			}
			break;
		case ANIM_MOVIE:
			ibuf = movie_fetchibuf(anim, position);
			if (ibuf) {
				anim->curposition = position;
				IMB_convert_rgba_to_abgr(ibuf);
			}
			break;
#ifdef WITH_AVI
		case ANIM_AVI:
			ibuf = avi_fetchibuf(anim, position);
			if (ibuf)
				anim->curposition = position;
			break;
#endif
#ifdef WITH_QUICKTIME
		case ANIM_QTIME:
			ibuf = qtime_fetchibuf(anim, position);
			if (ibuf) {
				if (ibuf->rect) {
					/* OCIO_TODO: should happen in quicktime module, but it currently doesn't have access
					 *            to color management's internals
					 */
					ibuf->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
				}

				anim->curposition = position;
			}
			break;
#endif
#ifdef WITH_FFMPEG
		case ANIM_FFMPEG:
			ibuf = ffmpeg_fetchibuf(anim, position, tc);
			if (ibuf)
				anim->curposition = position;
			filter_y = 0; /* done internally */
			break;
#endif
#ifdef WITH_REDCODE
		case ANIM_REDCODE:
			ibuf = redcode_fetchibuf(anim, position);
			if (ibuf) anim->curposition = position;
			break;
#endif
	}

	if (ibuf) {
		if (filter_y) IMB_filtery(ibuf);
		BLI_snprintf(ibuf->name, sizeof(ibuf->name), "%s.%04d", anim->name, anim->curposition + 1);
		
	}
	return(ibuf);
}
Beispiel #3
0
static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
	ImBuf * ibuf;
	int frameFinished;
	AVPacket packet;
	int64_t pts_to_search = 0;
	int pos_found = 1;
	int filter_y = 0;
	int seek_by_bytes= 0;
	int preseek_count = 0;

	if (anim == 0) return (0);

	ibuf = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);

	avpicture_fill((AVPicture*) anim->pFrameRGB, 
			   (unsigned char*) ibuf->rect, 
			   PIX_FMT_RGBA, anim->x, anim->y);

	if (position != anim->curposition + 1) { 
		if (position > anim->curposition + 1 
			&& anim->preseek 
			&& position - (anim->curposition + 1) < anim->preseek) {
			while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
				if (packet.stream_index == anim->videoStream) {
					avcodec_decode_video2(
						anim->pCodecCtx, 
						anim->pFrame, &frameFinished, 
						&packet);

					if (frameFinished) {
						anim->curposition++;
					}
				}
				av_free_packet(&packet);
				if (position == anim->curposition+1) {
					break;
				}
			}
		}
	}

/* disable seek_by_bytes for now, since bitrates are guessed wrong!
   also: MPEG2TS-seeking was fixed in later versions of ffmpeg, so problem
   is somewhat fixed by now (until we add correct timecode management code...)
*/
#if 0
	seek_by_bytes = !!(anim->pFormatCtx->iformat->flags & AVFMT_TS_DISCONT);
#else
	seek_by_bytes = FALSE;
#endif

	if (position != anim->curposition + 1) { 
		double frame_rate = 
			av_q2d(anim->pFormatCtx->streams[anim->videoStream]
				   ->r_frame_rate);
		double pts_time_base = av_q2d(anim->pFormatCtx->streams[anim->videoStream]->time_base);
		long long pos;
		long long st_time = anim->pFormatCtx->start_time;
		int ret;

		if (seek_by_bytes) {
			pos = position - anim->preseek;
			if (pos < 0) {
				pos = 0;
			}
			preseek_count = position - pos;

			pos *= anim->pFormatCtx->bit_rate / frame_rate;
			pos /= 8;
		} else {
			pos = (long long) (position - anim->preseek) 
				* AV_TIME_BASE / frame_rate;
			if (pos < 0) {
				pos = 0;
			}

			if (st_time != AV_NOPTS_VALUE) {
				pos += st_time;
			}
		}

		ret = av_seek_frame(anim->pFormatCtx, -1, 
				    pos, 
				    AVSEEK_FLAG_BACKWARD | (
					    seek_by_bytes 
					    ? AVSEEK_FLAG_ANY 
					    | AVSEEK_FLAG_BYTE : 0));
		if (ret < 0) {
			fprintf(stderr, "error while seeking: %d\n", ret);
		}

		pts_to_search = (long long) 
			(((double) position) / pts_time_base / frame_rate);
		if (st_time != AV_NOPTS_VALUE) {
			pts_to_search += st_time / pts_time_base/ AV_TIME_BASE;
		}

		pos_found = 0;
		avcodec_flush_buffers(anim->pCodecCtx);
	}

	while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
		if(packet.stream_index == anim->videoStream) {
			avcodec_decode_video2(anim->pCodecCtx, 
					      anim->pFrame, &frameFinished, 
					      &packet);

			if (seek_by_bytes && preseek_count > 0) {
				preseek_count--;
			}

			if (frameFinished && !pos_found) {
				if (seek_by_bytes) {
					if (!preseek_count) {
						pos_found = 1;
						anim->curposition = position;
					}
				} else {
					if (packet.dts >= pts_to_search) {
						pos_found = 1;
						anim->curposition = position;
					}
				}
			} 

			if(frameFinished && pos_found == 1) {
				ffmpeg_postprocess(anim, ibuf, &filter_y);
				av_free_packet(&packet);
				break;
			}
		}

		av_free_packet(&packet);
	}

	if (filter_y && ibuf) {
		IMB_filtery(ibuf);
	}

	ibuf->profile = IB_PROFILE_SRGB;
	
	return(ibuf);
}
Beispiel #4
0
static void ffmpeg_postprocess(struct anim * anim)
{
	AVFrame * input = anim->pFrame;
	ImBuf * ibuf = anim->last_frame;
	int filter_y = 0;

	ibuf->profile = IB_PROFILE_SRGB;

	/* 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){
		fprintf(stderr, "ffmpeg_fetchibuf: "
			"data not read properly...\n");
		return;
	}

	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 = TRUE;
		} else {
			input = anim->pFrameDeinterlaced;
		}
	}
	
	avpicture_fill((AVPicture*) anim->pFrameRGB, 
		       (unsigned char*) ibuf->rect, 
		       PIX_FMT_RGBA, anim->x, anim->y);

	if (ENDIAN_ORDER == B_ENDIAN) {
		int * dstStride   = anim->pFrameRGB->linesize;
		uint8_t** dst     = anim->pFrameRGB->data;
		int dstStride2[4] = { dstStride[0], 0, 0, 0 };
		uint8_t* dst2[4]  = { dst[0], 0, 0, 0 };
		int x,y,h,w;
		unsigned char* bottom;
		unsigned char* top;
		
		sws_scale(anim->img_convert_ctx,
			  (const uint8_t * const *)input->data,
			  input->linesize,
			  0,
			  anim->pCodecCtx->height,
			  dst2,
			  dstStride2);
		
		/* workaround: sws_scale bug
		   sets alpha = 0 and compensate
		   for altivec-bugs and flipy... */
		
		bottom = (unsigned char*) ibuf->rect;
		top = bottom + ibuf->x * (ibuf->y-1) * 4;
		
		h = (ibuf->y + 1) / 2;
		w = ibuf->x;
		
		for (y = 0; y < h; y++) {
			unsigned char tmp[4];
			unsigned int * tmp_l =
				(unsigned int*) tmp;
			tmp[3] = 0xff;
			
			for (x = 0; x < w; x++) {
				tmp[0] = bottom[0];
				tmp[1] = bottom[1];
				tmp[2] = bottom[2];
				
				bottom[0] = top[0];
				bottom[1] = top[1];
				bottom[2] = top[2];
				bottom[3] = 0xff;
				
				*(unsigned int*) top = *tmp_l;
				
				bottom +=4;
				top += 4;
			}
			top -= 8 * w;
		}
	} else {
		int * dstStride   = anim->pFrameRGB->linesize;
		uint8_t** dst     = anim->pFrameRGB->data;
		int dstStride2[4] = { -dstStride[0], 0, 0, 0 };
		uint8_t* dst2[4]  = { dst[0] + (anim->y - 1)*dstStride[0],
				      0, 0, 0 };
		int i;
		unsigned char* r;
		
		sws_scale(anim->img_convert_ctx,
			  (const uint8_t * const *)input->data,
			  input->linesize,
			  0,
			  anim->pCodecCtx->height,
			  dst2,
			  dstStride2);
		
		r = (unsigned char*) ibuf->rect;
		
		/* workaround sws_scale bug: older version of 
		   sws_scale set alpha = 0... */
		if (r[3] == 0) {
			for (i = 0; i < ibuf->x * ibuf->y; i++) {
				r[3] = 0xff;
				r += 4;
			}
		}
	}

	if (filter_y) {
		IMB_filtery(ibuf);
	}
}
Beispiel #5
0
struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
	struct ImBuf * ibuf = NULL;
	char head[256], tail[256];
	unsigned short digits;
	int pic;
	int filter_y;
	if (anim == NULL) return(NULL);

	filter_y = (anim->ib_flags & IB_animdeinterlace);

	if (anim->curtype == 0)	{
		ibuf = anim_getnew(anim);
		if (ibuf == NULL) {
			return(NULL);
		}

		IMB_freeImBuf(ibuf); /* ???? */
		ibuf= NULL;
	}

	if (position < 0) return(NULL);
	if (position >= anim->duration) return(NULL);

	switch(anim->curtype) {
	case ANIM_SEQUENCE:
		pic = an_stringdec(anim->first, head, tail, &digits);
		pic += position;
		an_stringenc(anim->name, head, tail, digits, pic);
		ibuf = IMB_loadiffname(anim->name, IB_rect);
		if (ibuf) {
			anim->curposition = position;
		}
		break;
	case ANIM_MOVIE:
		ibuf = movie_fetchibuf(anim, position);
		if (ibuf) {
			anim->curposition = position;
			IMB_convert_rgba_to_abgr(ibuf);
			ibuf->profile = IB_PROFILE_SRGB;
		}
		break;
	case ANIM_AVI:
		ibuf = avi_fetchibuf(anim, position);
		if (ibuf)
			anim->curposition = position;
		break;
#ifdef WITH_QUICKTIME
	case ANIM_QTIME:
		ibuf = qtime_fetchibuf(anim, position);
		if (ibuf)
			anim->curposition = position;
		break;
#endif
#ifdef WITH_FFMPEG
	case ANIM_FFMPEG:
		ibuf = ffmpeg_fetchibuf(anim, position);
		if (ibuf)
			anim->curposition = position;
		filter_y = 0; /* done internally */
		break;
#endif
#ifdef WITH_REDCODE
	case ANIM_REDCODE:
		ibuf = redcode_fetchibuf(anim, position);
		if (ibuf) anim->curposition = position;
		break;
#endif
	}

	if (ibuf) {
		if (filter_y) IMB_filtery(ibuf);
		sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1);
		
	}
	return(ibuf);
}