ffmpeg: optimize ffmpeg_postprocess #116309
|
@ -842,26 +842,42 @@ static void ffmpeg_postprocess(anim *anim, AVFrame *input, ImBuf *ibuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sws_scale_frame_threaded(anim->img_convert_ctx, anim->pFrameRGB, input);
|
/* If final destination image layout matches that of decoded RGB frame (including
|
||||||
|
* any line padding done by ffmpeg for SIMD alignment), we can directly
|
||||||
|
* decode into that, doing the vertical flip in the same step. Otherwise have
|
||||||
|
* to do a separate flip. */
|
||||||
|
const int ibuf_linesize = ibuf->x * 4;
|
||||||
|
const int rgb_linesize = anim->pFrameRGB->linesize[0];
|
||||||
|
const bool scale_to_ibuf = (rgb_linesize == ibuf_linesize);
|
||||||
|
uint8_t *rgb_data = anim->pFrameRGB->data[0];
|
||||||
|
|
||||||
|
if (scale_to_ibuf) {
|
||||||
|
/* Decode RGB and do vertical flip directly into destination image, by using negative
|
||||||
|
* line size. */
|
||||||
|
anim->pFrameRGB->linesize[0] = -ibuf_linesize;
|
||||||
|
anim->pFrameRGB->data[0] = ibuf->byte_buffer.data + (ibuf->y - 1) * ibuf_linesize;
|
||||||
|
|
||||||
|
sws_scale_frame_threaded(anim->img_convert_ctx, anim->pFrameRGB, input);
|
||||||
|
|
||||||
|
anim->pFrameRGB->linesize[0] = rgb_linesize;
|
||||||
|
anim->pFrameRGB->data[0] = rgb_data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Decode, then do vertical flip into destination. */
|
||||||
|
sws_scale_frame_threaded(anim->img_convert_ctx, anim->pFrameRGB, input);
|
||||||
|
|
||||||
|
/* Use negative line size to do vertical image flip. */
|
||||||
|
const int src_linesize[4] = {-rgb_linesize, 0, 0, 0};
|
||||||
|
const uint8_t *const src[4] = {
|
||||||
|
rgb_data + (anim->y - 1) * rgb_linesize, nullptr, nullptr, nullptr};
|
||||||
|
int dst_size = av_image_get_buffer_size(AVPixelFormat(anim->pFrameRGB->format),
|
||||||
|
anim->pFrameRGB->width,
|
||||||
|
anim->pFrameRGB->height,
|
||||||
|
1);
|
||||||
|
av_image_copy_to_buffer(
|
||||||
|
ibuf->byte_buffer.data, dst_size, src, src_linesize, AV_PIX_FMT_RGBA, anim->x, anim->y, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the valid bytes from the aligned buffer vertically flipped into ImBuf */
|
|
||||||
int aligned_stride = anim->pFrameRGB->linesize[0];
|
|
||||||
const uint8_t *const src[4] = {
|
|
||||||
anim->pFrameRGB->data[0] + (anim->y - 1) * aligned_stride, nullptr, nullptr, nullptr};
|
|
||||||
/* NOTE: Negative linesize is used to copy and flip image at once with function
|
|
||||||
* `av_image_copy_to_buffer`. This could cause issues in future and image may need to be flipped
|
|
||||||
* explicitly. */
|
|
||||||
const int src_linesize[4] = {-anim->pFrameRGB->linesize[0], 0, 0, 0};
|
|
||||||
int dst_size = av_image_get_buffer_size(
|
|
||||||
AVPixelFormat(anim->pFrameRGB->format), anim->pFrameRGB->width, anim->pFrameRGB->height, 1);
|
|
||||||
av_image_copy_to_buffer((uint8_t *)ibuf->byte_buffer.data,
|
|
||||||
dst_size,
|
|
||||||
src,
|
|
||||||
src_linesize,
|
|
||||||
AV_PIX_FMT_RGBA,
|
|
||||||
anim->x,
|
|
||||||
anim->y,
|
|
||||||
1);
|
|
||||||
if (filter_y) {
|
if (filter_y) {
|
||||||
IMB_filtery(ibuf);
|
IMB_filtery(ibuf);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue