From 3646f8d39206cc8b72ca54cc841077b66bde8c5a Mon Sep 17 00:00:00 2001 From: Moonsik Park Date: Mon, 17 Jun 2024 18:03:22 +0900 Subject: [PATCH] Use `av_guess_sample_aspect_ratio` when reporting stream SAR, DAR --- av/video/stream.pyi | 4 ++-- av/video/stream.pyx | 29 +++++++++++++++++++++++++++++ include/libavformat/avformat.pxd | 6 ++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/av/video/stream.pyi b/av/video/stream.pyi index 4b78efd06..929847ed4 100644 --- a/av/video/stream.pyi +++ b/av/video/stream.pyi @@ -14,6 +14,8 @@ class VideoStream(Stream): bit_rate_tolerance: int thread_count: int thread_type: Any + sample_aspect_ratio: Fraction | None + display_aspect_ratio: Fraction | None codec_context: VideoCodecContext # from codec context format: VideoFormat @@ -24,8 +26,6 @@ class VideoStream(Stream): framerate: Fraction rate: Fraction gop_size: int - sample_aspect_ratio: Fraction | None - display_aspect_ratio: Fraction | None has_b_frames: bool coded_width: int coded_height: int diff --git a/av/video/stream.pyx b/av/video/stream.pyx index ae57ed136..6ab685167 100644 --- a/av/video/stream.pyx +++ b/av/video/stream.pyx @@ -86,3 +86,32 @@ cdef class VideoStream(Stream): # The two NULL arguments aren't used in FFmpeg >= 4.0 cdef lib.AVRational val = lib.av_guess_frame_rate(NULL, self.ptr, NULL) return avrational_to_fraction(&val) + + @property + def sample_aspect_ratio(self): + """The guessed sample aspect ratio (SAR) of this stream. + + This is a wrapper around :ffmpeg:`av_guess_sample_aspect_ratio`, and uses multiple + heuristics to decide what is "the" sample aspect ratio. + + :type: :class:`~fractions.Fraction` or ``None`` + """ + cdef lib.AVRational sar = lib.av_guess_sample_aspect_ratio(self.container.ptr, self.ptr, NULL) + return avrational_to_fraction(&sar) + + @property + def display_aspect_ratio(self): + """The guessed display aspect ratio (DAR) of this stream. + + This is calculated from :meth:`.VideoStream.guessed_sample_aspect_ratio`. + + :type: :class:`~fractions.Fraction` or ``None`` + """ + cdef lib.AVRational dar + + lib.av_reduce( + &dar.num, &dar.den, + self.format.width * self.sample_aspect_ratio.num, + self.format.height * self.sample_aspect_ratio.den, 1024*1024) + + return avrational_to_fraction(&dar) diff --git a/include/libavformat/avformat.pxd b/include/libavformat/avformat.pxd index 224e76b4e..9d9061cc2 100644 --- a/include/libavformat/avformat.pxd +++ b/include/libavformat/avformat.pxd @@ -325,6 +325,12 @@ cdef extern from "libavformat/avformat.h" nogil: AVFrame *frame ) + cdef AVRational av_guess_sample_aspect_ratio( + AVFormatContext *ctx, + AVStream *stream, + AVFrame *frame + ) + cdef const AVInputFormat* av_demuxer_iterate(void **opaque) cdef const AVOutputFormat* av_muxer_iterate(void **opaque)