Fix #107493: Auto rotate videos fix #115661

Open
ErikHK wants to merge 7 commits from ErikHK/blender:auto_rotate_video into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 52 additions and 0 deletions

View File

@ -749,6 +749,7 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1);
*/
void IMB_flipx(struct ImBuf *ibuf);
void IMB_flipy(struct ImBuf *ibuf);
void IMB_rotate90(struct ImBuf *ibuf);
/* Pre-multiply alpha. */

View File

@ -71,6 +71,8 @@ extern "C" {
# include <libavutil/rational.h>
# include <libswscale/swscale.h>
# include <libavutil/display.h>
# include "ffmpeg_compat.h"
}
@ -875,6 +877,25 @@ static void ffmpeg_postprocess(anim *anim, AVFrame *input, ImBuf *ibuf)
if (filter_y) {
IMB_filtery(ibuf);
}
/* auto rotate video */
/* get display matrix rotation to see if a rotation is in order: */
uint8_t *displaymatrix = av_stream_get_side_data(
anim->pFormatCtx->streams[anim->videoStream], AV_PKT_DATA_DISPLAYMATRIX, NULL);
if (displaymatrix == nullptr)
return;
const double theta = av_display_rotation_get((int32_t *)displaymatrix);
/* perform rotation */
if (theta == -90) {
IMB_rotate90(ibuf);
}
else if (theta == 180 || theta == -180) {
IMB_flipx(ibuf);
IMB_flipy(ibuf);
}
}
static void final_frame_log(anim *anim,
@ -1386,6 +1407,7 @@ static ImBuf *ffmpeg_fetchibuf(anim *anim, int position, IMB_Timecode_Type tc)
ffmpeg_decode_video_frame_scan(anim, pts_to_search);
/* Update resolution as it can change per-frame with WebM. See #100741 & #100081. */
anim->x = anim->pCodecCtx->width;
anim->y = anim->pCodecCtx->height;

View File

@ -108,3 +108,32 @@ void IMB_flipx(ImBuf *ibuf)
}
}
}
void IMB_rotate90(ImBuf *ibuf)
{
if (ibuf == nullptr)
return;
ErikHK marked this conversation as resolved
Review

Reduce the scope of variables. So instead of defining them in the beginning of the function define close to where you use htem. Examples:

  • ImBuf *tbuf = IMB_allocImBuf(ibuf->y, ibuf->x, 32, IB_rect);
  • for (int y = tbuf->y - 1; y >= 0; y--) {
Reduce the scope of variables. So instead of defining them in the beginning of the function define close to where you use htem. Examples: - `ImBuf *tbuf = IMB_allocImBuf(ibuf->y, ibuf->x, 32, IB_rect);` - `for (int y = tbuf->y - 1; y >= 0; y--) {`
/* create a temporary copy of the image */
uint8_t *imgdata = (uint8_t *)malloc(ibuf->x * ibuf->y * sizeof(uint));
memcpy(imgdata, ibuf->byte_buffer.data, ibuf->x * ibuf->y * sizeof(uint));
uint *imgdatarect = (uint *)imgdata;
uint *ibufrect = (uint *)ibuf->byte_buffer.data;
int skip = ibuf->x;
uint *rect;
for (int y = ibuf->x - 1; y >= 0; y--) {
rect = imgdatarect + y;
for (int x = ibuf->y; x > 0; x--) {
*ibufrect++ = *rect;
rect += skip;
}
}
/* swap width and height of ibuf */
SWAP(int, ibuf->x, ibuf->y);
/* free temporary copy of image */
free(imgdata);
}