You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
ffmpeg: use display matrix frame side data for autorotation
And give it priority over stream side data when present. Fixes part of ticket #6945. Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -2201,10 +2201,8 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_rotation(AVStream *st)
|
double get_rotation(int32_t *displaymatrix)
|
||||||
{
|
{
|
||||||
uint8_t* displaymatrix = av_stream_get_side_data(st,
|
|
||||||
AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
|
||||||
double theta = 0;
|
double theta = 0;
|
||||||
if (displaymatrix)
|
if (displaymatrix)
|
||||||
theta = -round(av_display_rotation_get((int32_t*) displaymatrix));
|
theta = -round(av_display_rotation_get((int32_t*) displaymatrix));
|
||||||
|
@@ -648,6 +648,6 @@ void *grow_array(void *array, int elem_size, int *size, int new_size);
|
|||||||
char name[128];\
|
char name[128];\
|
||||||
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
|
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
|
||||||
|
|
||||||
double get_rotation(AVStream *st);
|
double get_rotation(int32_t *displaymatrix);
|
||||||
|
|
||||||
#endif /* FFTOOLS_CMDUTILS_H */
|
#endif /* FFTOOLS_CMDUTILS_H */
|
||||||
|
@@ -535,6 +535,7 @@ static void ffmpeg_cleanup(int ret)
|
|||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
}
|
}
|
||||||
av_fifo_freep(&ifilter->frame_queue);
|
av_fifo_freep(&ifilter->frame_queue);
|
||||||
|
av_freep(&ifilter->displaymatrix);
|
||||||
if (ist->sub2video.sub_queue) {
|
if (ist->sub2video.sub_queue) {
|
||||||
while (av_fifo_size(ist->sub2video.sub_queue)) {
|
while (av_fifo_size(ist->sub2video.sub_queue)) {
|
||||||
AVSubtitle sub;
|
AVSubtitle sub;
|
||||||
@@ -2183,6 +2184,7 @@ static int ifilter_has_all_input_formats(FilterGraph *fg)
|
|||||||
static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
||||||
{
|
{
|
||||||
FilterGraph *fg = ifilter->graph;
|
FilterGraph *fg = ifilter->graph;
|
||||||
|
AVFrameSideData *sd;
|
||||||
int need_reinit, ret, i;
|
int need_reinit, ret, i;
|
||||||
|
|
||||||
/* determine if the parameters for this input changed */
|
/* determine if the parameters for this input changed */
|
||||||
@@ -2207,6 +2209,12 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
|
|||||||
(ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))
|
(ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))
|
||||||
need_reinit = 1;
|
need_reinit = 1;
|
||||||
|
|
||||||
|
if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) {
|
||||||
|
if (!ifilter->displaymatrix || memcmp(sd->data, ifilter->displaymatrix, sizeof(int32_t) * 9))
|
||||||
|
need_reinit = 1;
|
||||||
|
} else if (ifilter->displaymatrix)
|
||||||
|
need_reinit = 1;
|
||||||
|
|
||||||
if (need_reinit) {
|
if (need_reinit) {
|
||||||
ret = ifilter_parameters_from_frame(ifilter, frame);
|
ret = ifilter_parameters_from_frame(ifilter, frame);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@@ -258,6 +258,7 @@ typedef struct InputFilter {
|
|||||||
uint64_t channel_layout;
|
uint64_t channel_layout;
|
||||||
|
|
||||||
AVBufferRef *hw_frames_ctx;
|
AVBufferRef *hw_frames_ctx;
|
||||||
|
int32_t *displaymatrix;
|
||||||
|
|
||||||
int eof;
|
int eof;
|
||||||
} InputFilter;
|
} InputFilter;
|
||||||
|
@@ -757,7 +757,12 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
|||||||
last_filter = ifilter->filter;
|
last_filter = ifilter->filter;
|
||||||
|
|
||||||
if (ist->autorotate) {
|
if (ist->autorotate) {
|
||||||
double theta = get_rotation(ist->st);
|
int32_t *displaymatrix = ifilter->displaymatrix;
|
||||||
|
double theta;
|
||||||
|
|
||||||
|
if (!displaymatrix)
|
||||||
|
displaymatrix = (int32_t *)av_stream_get_side_data(ist->st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||||
|
theta = get_rotation(displaymatrix);
|
||||||
|
|
||||||
if (fabs(theta - 90) < 1.0) {
|
if (fabs(theta - 90) < 1.0) {
|
||||||
ret = insert_filter(&last_filter, &pad_idx, "transpose", "clock");
|
ret = insert_filter(&last_filter, &pad_idx, "transpose", "clock");
|
||||||
@@ -1127,6 +1132,8 @@ fail:
|
|||||||
|
|
||||||
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
|
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
|
||||||
{
|
{
|
||||||
|
AVFrameSideData *sd;
|
||||||
|
|
||||||
av_buffer_unref(&ifilter->hw_frames_ctx);
|
av_buffer_unref(&ifilter->hw_frames_ctx);
|
||||||
|
|
||||||
ifilter->format = frame->format;
|
ifilter->format = frame->format;
|
||||||
@@ -1139,6 +1146,11 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
|
|||||||
ifilter->channels = frame->channels;
|
ifilter->channels = frame->channels;
|
||||||
ifilter->channel_layout = frame->channel_layout;
|
ifilter->channel_layout = frame->channel_layout;
|
||||||
|
|
||||||
|
av_freep(&ifilter->displaymatrix);
|
||||||
|
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
|
||||||
|
if (sd)
|
||||||
|
ifilter->displaymatrix = av_memdup(sd->data, sizeof(int32_t) * 9);
|
||||||
|
|
||||||
if (frame->hw_frames_ctx) {
|
if (frame->hw_frames_ctx) {
|
||||||
ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
|
ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
|
||||||
if (!ifilter->hw_frames_ctx)
|
if (!ifilter->hw_frames_ctx)
|
||||||
|
@@ -1925,7 +1925,8 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
if (autorotate) {
|
if (autorotate) {
|
||||||
double theta = get_rotation(is->video_st);
|
int32_t *displaymatrix = (int32_t *)av_stream_get_side_data(is->video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||||
|
double theta = get_rotation(displaymatrix);
|
||||||
|
|
||||||
if (fabs(theta - 90) < 1.0) {
|
if (fabs(theta - 90) < 1.0) {
|
||||||
INSERT_FILT("transpose", "clock");
|
INSERT_FILT("transpose", "clock");
|
||||||
|
Reference in New Issue
Block a user