106 lines
2.9 KiB
Python
106 lines
2.9 KiB
Python
import cython
|
|
from cython.cimports import libav as lib
|
|
from cython.cimports.av.audio.format import AudioFormat, get_audio_format
|
|
from cython.cimports.av.audio.frame import AudioFrame, alloc_audio_frame
|
|
from cython.cimports.av.audio.layout import AudioLayout, get_audio_layout
|
|
from cython.cimports.av.frame import Frame
|
|
from cython.cimports.av.packet import Packet
|
|
|
|
|
|
@cython.cclass
|
|
class AudioCodecContext(CodecContext):
|
|
@cython.cfunc
|
|
def _prepare_frames_for_encode(self, input_frame: Frame | None):
|
|
frame: AudioFrame | None = input_frame
|
|
allow_var_frame_size: cython.bint = (
|
|
self.ptr.codec.capabilities & lib.AV_CODEC_CAP_VARIABLE_FRAME_SIZE
|
|
)
|
|
|
|
# Note that the resampler will simply return an input frame if there is
|
|
# no resampling to be done. The control flow was just a little easier this way.
|
|
if not self.resampler:
|
|
self.resampler = AudioResampler(
|
|
format=self.format,
|
|
layout=self.layout,
|
|
rate=self.ptr.sample_rate,
|
|
frame_size=None if allow_var_frame_size else self.ptr.frame_size,
|
|
)
|
|
frames = self.resampler.resample(frame)
|
|
if input_frame is None:
|
|
frames.append(None) # flush if input frame is None
|
|
|
|
return frames
|
|
|
|
@cython.cfunc
|
|
def _alloc_next_frame(self) -> Frame:
|
|
return alloc_audio_frame()
|
|
|
|
@cython.cfunc
|
|
def _setup_decoded_frame(self, frame: Frame, packet: Packet):
|
|
CodecContext._setup_decoded_frame(self, frame, packet)
|
|
aframe: AudioFrame = frame
|
|
aframe._init_user_attributes()
|
|
|
|
@property
|
|
def frame_size(self):
|
|
"""
|
|
Number of samples per channel in an audio frame.
|
|
|
|
:type: int
|
|
"""
|
|
return self.ptr.frame_size
|
|
|
|
@property
|
|
def sample_rate(self):
|
|
"""
|
|
Sample rate of the audio data, in samples per second.
|
|
|
|
:type: int
|
|
"""
|
|
return self.ptr.sample_rate
|
|
|
|
@sample_rate.setter
|
|
def sample_rate(self, value: cython.int):
|
|
self.ptr.sample_rate = value
|
|
|
|
@property
|
|
def rate(self):
|
|
"""Another name for :attr:`sample_rate`."""
|
|
return self.sample_rate
|
|
|
|
@rate.setter
|
|
def rate(self, value):
|
|
self.sample_rate = value
|
|
|
|
@property
|
|
def channels(self):
|
|
return self.layout.nb_channels
|
|
|
|
@property
|
|
def layout(self):
|
|
"""
|
|
The audio channel layout.
|
|
|
|
:type: AudioLayout
|
|
"""
|
|
return get_audio_layout(self.ptr.ch_layout)
|
|
|
|
@layout.setter
|
|
def layout(self, value):
|
|
layout: AudioLayout = AudioLayout(value)
|
|
self.ptr.ch_layout = layout.layout
|
|
|
|
@property
|
|
def format(self):
|
|
"""
|
|
The audio sample format.
|
|
|
|
:type: AudioFormat
|
|
"""
|
|
return get_audio_format(self.ptr.sample_fmt)
|
|
|
|
@format.setter
|
|
def format(self, value):
|
|
format: AudioFormat = AudioFormat(value)
|
|
self.ptr.sample_fmt = format.sample_fmt
|