diff options
| author | 2026-07-10 15:17:41 -0400 | |
|---|---|---|
| committer | 2026-07-10 15:17:41 -0400 | |
| commit | da9bddc70ff8544f3294b880d719c4605e87ad97 (patch) | |
| tree | 578f1554d992840aad4618ad0ce657868fcadc16 /src/buffer/video.c | |
| parent | 566c022572bbff8bb7ff105b9adbe74500b2c716 (diff) | |
| download | camu-da9bddc70ff8544f3294b880d719c4605e87ad97.tar.gz camu-da9bddc70ff8544f3294b880d719c4605e87ad97.tar.bz2 camu-da9bddc70ff8544f3294b880d719c4605e87ad97.zip | |
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/buffer/video.c')
| -rw-r--r-- | src/buffer/video.c | 24 |
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; |