File: stream.py

package info (click to toggle)
python-av 16.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,684 kB
  • sloc: python: 7,607; sh: 182; ansic: 174; makefile: 135
file content (123 lines) | stat: -rw-r--r-- 3,972 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import cython
from cython.cimports import libav as lib
from cython.cimports.av.packet import Packet
from cython.cimports.av.utils import avrational_to_fraction, to_avrational
from cython.cimports.av.video.frame import VideoFrame


@cython.cclass
class VideoStream(Stream):
    def __repr__(self):
        return (
            f"<av.VideoStream #{self.index} {self.name}, "
            f"{self.format.name if self.format else None} {self.codec_context.width}x"
            f"{self.codec_context.height} at 0x{id(self):x}>"
        )

    def __getattr__(self, name):
        if name in ("framerate", "rate"):
            raise AttributeError(
                f"'{type(self).__name__}' object has no attribute '{name}'"
            )

        return getattr(self.codec_context, name)

    @cython.ccall
    def encode(self, frame: VideoFrame | None = None):
        """
        Encode an :class:`.VideoFrame` and return a list of :class:`.Packet`.

        :rtype: list[Packet]

        .. seealso:: This is mostly a passthrough to :meth:`.CodecContext.encode`.
        """

        packets = self.codec_context.encode(frame)
        packet: Packet
        for packet in packets:
            packet._stream = self
            packet.ptr.stream_index = self.ptr.index
        return packets

    @cython.ccall
    def decode(self, packet: Packet | None = None):
        """
        Decode a :class:`.Packet` and return a list of :class:`.VideoFrame`.

        :rtype: list[VideoFrame]

        .. seealso:: This is a passthrough to :meth:`.CodecContext.decode`.
        """
        return self.codec_context.decode(packet)

    @property
    def average_rate(self):
        """
        The average frame rate of this video stream.

        This is calculated when the file is opened by looking at the first
        few frames and averaging their rate.

        :type: fractions.Fraction | None
        """
        return avrational_to_fraction(cython.address(self.ptr.avg_frame_rate))

    @property
    def base_rate(self):
        """
        The base frame rate of this stream.

        This is calculated as the lowest framerate at which the timestamps of
        frames can be represented accurately. See :ffmpeg:`AVStream.r_frame_rate`
        for more.

        :type: fractions.Fraction | None
        """
        return avrational_to_fraction(cython.address(self.ptr.r_frame_rate))

    @property
    def guessed_rate(self):
        """The guessed frame rate of this stream.

        This is a wrapper around :ffmpeg:`av_guess_frame_rate`, and uses multiple
        heuristics to decide what is "the" frame rate.

        :type: fractions.Fraction | None
        """
        val: lib.AVRational = lib.av_guess_frame_rate(
            cython.NULL, self.ptr, cython.NULL
        )
        return avrational_to_fraction(cython.address(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: fractions.Fraction | None
        """
        sar: lib.AVRational = lib.av_guess_sample_aspect_ratio(
            self.container.ptr, self.ptr, cython.NULL
        )
        return avrational_to_fraction(cython.address(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: fractions.Fraction | None
        """
        dar = cython.declare(lib.AVRational)
        lib.av_reduce(
            cython.address(dar.num),
            cython.address(dar.den),
            self.format.width * self.sample_aspect_ratio.num,
            self.format.height * self.sample_aspect_ratio.den,
            1024 * 1024,
        )

        return avrational_to_fraction(cython.address(dar))