Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/imbuf/intern/anim_movie.c144
1 files changed, 28 insertions, 116 deletions
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 6a05b681c88..17e82fc79c9 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -504,11 +504,6 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position)
#ifdef WITH_FFMPEG
-BLI_INLINE bool need_aligned_ffmpeg_buffer(struct anim *anim)
-{
- return (anim->x & 31) != 0;
-}
-
static int startffmpeg(struct anim *anim)
{
int i, video_stream_index;
@@ -707,23 +702,20 @@ static int startffmpeg(struct anim *anim)
anim->pFrameComplete = false;
anim->pFrameDeinterlaced = av_frame_alloc();
anim->pFrameRGB = av_frame_alloc();
+ anim->pFrameRGB->format = AV_PIX_FMT_RGBA;
+ anim->pFrameRGB->width = anim->x;
+ anim->pFrameRGB->height = anim->y;
- if (need_aligned_ffmpeg_buffer(anim)) {
- anim->pFrameRGB->format = AV_PIX_FMT_RGBA;
- anim->pFrameRGB->width = anim->x;
- anim->pFrameRGB->height = anim->y;
-
- if (av_frame_get_buffer(anim->pFrameRGB, 32) < 0) {
- fprintf(stderr, "Could not allocate frame data.\n");
- avcodec_free_context(&anim->pCodecCtx);
- avformat_close_input(&anim->pFormatCtx);
- av_packet_free(&anim->cur_packet);
- av_frame_free(&anim->pFrameRGB);
- av_frame_free(&anim->pFrameDeinterlaced);
- av_frame_free(&anim->pFrame);
- anim->pCodecCtx = NULL;
- return -1;
- }
+ if (av_frame_get_buffer(anim->pFrameRGB, 0) < 0) {
+ fprintf(stderr, "Could not allocate frame data.\n");
+ avcodec_free_context(&anim->pCodecCtx);
+ avformat_close_input(&anim->pFormatCtx);
+ av_packet_free(&anim->cur_packet);
+ av_frame_free(&anim->pFrameRGB);
+ av_frame_free(&anim->pFrameDeinterlaced);
+ av_frame_free(&anim->pFrame);
+ anim->pCodecCtx = NULL;
+ return -1;
}
if (av_image_get_buffer_size(AV_PIX_FMT_RGBA, anim->x, anim->y, 1) != anim->x * anim->y * 4) {
@@ -851,92 +843,26 @@ static void ffmpeg_postprocess(struct anim *anim)
}
}
- if (!need_aligned_ffmpeg_buffer(anim)) {
- av_image_fill_arrays(anim->pFrameRGB->data,
- anim->pFrameRGB->linesize,
- (unsigned char *)ibuf->rect,
- AV_PIX_FMT_RGBA,
- anim->x,
- anim->y,
- 1);
- }
-
-# if defined(__x86_64__) || defined(_M_X64)
- /* Scale and flip image over Y axis in one go, using negative strides.
- * This doesn't work with ARM/PowerPC though and may be misusing the API.
- * Limit it x86_64 where it appears to work.
- * http://trac.ffmpeg.org/ticket/9060 */
- int *dstStride = anim->pFrameRGB->linesize;
- uint8_t **dst = anim->pFrameRGB->data;
- const 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);
-# else
- /* Scale with swscale. */
- int *dstStride = anim->pFrameRGB->linesize;
- uint8_t **dst = anim->pFrameRGB->data;
- const 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);
-
- /* Flip destination image buffer over Y axis. */
- bottom = (unsigned char *)dst[0];
- top = bottom + anim->x * (anim->y - 1) * 4;
-
- h = (anim->y + 1) / 2;
- w = anim->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;
- }
-# endif
-
- if (need_aligned_ffmpeg_buffer(anim)) {
- uint8_t *buf_src = anim->pFrameRGB->data[0];
- uint8_t *buf_dst = (uint8_t *)ibuf->rect;
- for (int y = 0; y < anim->y; y++) {
- memcpy(buf_dst, buf_src, anim->x * 4);
- buf_dst += anim->x * 4;
- buf_src += anim->pFrameRGB->linesize[0];
- }
- }
-
+ anim->pFrameRGB->data,
+ anim->pFrameRGB->linesize);
+
+ /* 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, 0, 0, 0};
+ /* 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(
+ anim->pFrameRGB->format, anim->pFrameRGB->width, anim->pFrameRGB->height, 1);
+ av_image_copy_to_buffer(
+ (uint8_t *)ibuf->rect, dst_size, src, src_linesize, AV_PIX_FMT_RGBA, anim->x, anim->y, 1);
if (filter_y) {
IMB_filtery(ibuf);
}
@@ -1482,20 +1408,6 @@ static void free_anim_ffmpeg(struct anim *anim)
av_packet_free(&anim->cur_packet);
av_frame_free(&anim->pFrame);
-
- if (!need_aligned_ffmpeg_buffer(anim)) {
- /* If there's no need for own aligned buffer it means that FFmpeg's
- * frame shares the same buffer as temporary ImBuf. In this case we
- * should not free the buffer when freeing the FFmpeg buffer.
- */
- av_image_fill_arrays(anim->pFrameRGB->data,
- anim->pFrameRGB->linesize,
- NULL,
- AV_PIX_FMT_RGBA,
- anim->x,
- anim->y,
- 1);
- }
av_frame_free(&anim->pFrameRGB);
av_frame_free(&anim->pFrameDeinterlaced);