Fix #107493: Auto rotate videos fix #115661
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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);
|
||||
ErikHK marked this conversation as resolved
Outdated
|
||||
|
||||
/* 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;
|
||||
|
||||
|
|
|
@ -108,3 +108,32 @@ void IMB_flipx(ImBuf *ibuf)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IMB_rotate90(ImBuf *ibuf)
|
||||
{
|
||||
if (ibuf == nullptr)
|
||||
return;
|
||||
ErikHK marked this conversation as resolved
Sergey Sharybin
commented
Reduce the scope of variables. So instead of defining them in the beginning of the function define close to where you use htem. Examples:
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;
|
||||
ErikHK marked this conversation as resolved
Outdated
Sergey Sharybin
commented
`nullptr` instead of `0`.
|
||||
uint *ibufrect = (uint *)ibuf->byte_buffer.data;
|
||||
int skip = ibuf->x;
|
||||
|
||||
uint *rect;
|
||||
for (int y = ibuf->x - 1; y >= 0; y--) {
|
||||
Sergey Sharybin
commented
You can duplicate just the data, and use that as a const-source , and write the rotated result directly to the You can duplicate just the data, and use that as a const-source , and write the rotated result directly to the `ibuf->byte_buffer`. This way you wouldn't need the extra `memcpy` after the loop.
ErikHK
commented
Thanks for the tip! I think I solved it in the way you suggested, but since I'm not great at memory handling and stuff in C it would be nice if you could take a look at it :) Thanks for the tip! I think I solved it in the way you suggested, but since I'm not great at memory handling and stuff in C it would be nice if you could take a look at it :)
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
const double theta = av_display_rotation_get((int32_t *)displaymatrix);