summaryrefslogtreecommitdiff
path: root/src/buffer
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer')
-rw-r--r--src/buffer/video.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/buffer/video.c b/src/buffer/video.c
index 0e9795f..f7d5e98 100644
--- a/src/buffer/video.c
+++ b/src/buffer/video.c
@@ -44,9 +44,22 @@ bool camu_video_buffer_init(struct camu_video_buffer *buf, struct camu_clock *cl
atomic_store(bool)(&buf->ref, false, AL_ATOMIC_RELAXED);
#endif
buf->view.mode = CAMU_VIEW_NONE;
+ // Rotation can be informed by the codec, we need to pass that information along.
+ buf->view.rotation = CAMU_VIEW_ROTATION_0;
return true;
}
+#ifdef CAMU_HAVE_FFMPEG
+static inline u8 rotation_from_displaymatrix(const s32 *matrix)
+{
+ f64 rotation = av_display_rotation_get(matrix);
+ if (!isnan(rotation) && rotation != 0.0) {
+ return camu_view_normalize_rotation((s32)(4.5 - rotation / 90.0));
+ }
+ return CAMU_VIEW_ROTATION_0;
+}
+#endif
+
bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_codec_stream *stream,
struct camu_renderer *renderer)
{
@@ -75,6 +88,11 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code
buf->weighted_first_read = true;
log_info("Stream: %s (%ux%u) VIDEO %.3ffps.", format_name, fmt->width, fmt->height, av_q2d(frame_rate));
}
+ // https://code.videolan.org/videolan/libplacebo/-/blob/a7a18af88ff0a17c04840dcb3246047bb6b46df3/src/include/libplacebo/utils/libav_internal.h#L870
+ const u8 *side_data = camu_ff_get_stream_side_data(stream->av.stream, AV_PKT_DATA_DISPLAYMATRIX);
+ if (side_data) {
+ buf->view.rotation = rotation_from_displaymatrix((const s32 *)side_data);
+ }
break;
}
#endif
@@ -132,12 +150,16 @@ static bool push_av_frame_internal(struct camu_video_buffer *buf, AVFrame *frame
AVStream *stream = buf->stream->av.stream;
f64 pts = frame->best_effort_timestamp * av_q2d(stream->time_base);
f64 base_pts = atomic_load(f64)(&buf->pts, AL_ATOMIC_ACQUIRE);
- f64 duration = camu_ff_frame_duration(frame) * av_q2d(stream->time_base);
+ f64 duration = camu_ff_get_frame_duration(frame) * av_q2d(stream->time_base);
if (!buf->is_static && frame_is_late(buf->clock, base_pts, pts, duration)) {
log_trace("Discarding late frame with PTS %f.", pts);
return false;
}
if (base_pts == -1.0) atomic_store(f64)(&buf->pts, pts, AL_ATOMIC_RELEASE);
+ const u8 *side_data = camu_ff_get_frame_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
+ if (side_data) {
+ buf->view.rotation = rotation_from_displaymatrix((const s32 *)side_data);
+ }
if (buf->fmt.scaler_needed) {
if (!buf->scaler->scale(buf->scaler, (const u8 **)frame->data, frame->linesize)) {
return false;