Hi everyone, I could use some help regarding trimming the padding from a video's frames. I've created an issue here with more details: PyAV-Org/PyAV#802. But basically, if I reshape numpy array of a frame's plane along line size and then slice along frame width to get a frame without padding, I'm not getting a properly aligned frame. However, when I try accounting for memory alignment, results are better which leads me to suspect it might be something to do with PyAv ignoring memory alignment issues in its frame width property.
def _remove_padding(self, plane):
"""Remove padding from a video plane.
Args:
plane (av.video.plane.VideoPlane): the plane to remove padding from
Returns:
numpy.array: an array with proper memory aligned width
"""
buf_width = plane.line_size
bytes_per_pixel = 1
frame_width = plane.width * bytes_per_pixel
arr = np.frombuffer(plane, np.uint8)
if buf_width != frame_width:
align_to = 16
# Frame width that is aligned up with a 16 bit boundary
frame_width = (frame_width + align_to - 1) & ~(align_to - 1)
# Slice (create a view) at the aligned boundary
arr = arr.reshape(-1, buf_width)[:, :frame_width]
return arr.reshape(-1, frame_width)
Although the above manual alignment kind of works, it's not correct for every format. In my case, the above works correctly for luma plane but not chroma planes. I'm not sure how to proceed so any advice would be really helpful. Thanks.
output = av.open(output_name, 'w')
stream = output.add_stream('h264', fps)
... #later in a loop
frame = av.VideoFrame.from_ndarray(frame, format='bgr24')
print(frame)
packet = stream.encode(frame)
output.mux(packet)
Python 3.9.5 (default, May 4 2021, 03:33:11)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import av
>>> c = av.open(':0', mode='r', format='avfoundation')
>>> c.non_block
False
>>> stream = c.streams[0]
>>> stream
<av.AudioStream #0 pcm_f32le at 44100Hz, stereo, flt at 0x10b5195e0>
>>> for packet in c.demux(stream):
... print(packet)
...
<av.Packet of #0, dts=5346293809909, pts=5346293809909; 4096 bytes at 0x10b320220>
<av.Packet of #0, dts=5346324390590, pts=5346324390590; 4096 bytes at 0x10b320360>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "av/container/input.pyx", line 142, in demux
File "av/container/core.pyx", line 258, in av.container.core.Container.err_check
File "av/error.pyx", line 336, in av.error.err_check
av.error.BlockingIOError: [Errno 35] Resource temporarily unavailable: ':0'
Anyone know how to get avfoundation to run in blocking mode, or how to poll for packets on an audiostream? If I catch BlockingIOError it "works", but it will eat all the cpu
hevc
to mpeg4
. When I try decode the just-encoded Packet, by using decode_context.decode(new_packets[0])
, the error says Operation not permitted;
. Is it because the Packet is generated from encoding operation? or there is something wrong with the decode context set up
I'm trying to set the metadata fields on an MPEG-TS clip. I can set service_type
using the container_options
but can't figure out how to set the metadata
since there's a space for the field name and there's two of them (python dictionary)
example from ffmpeg docs,
ffmpeg -i file.mpg -c copy \
-mpegts_original_network_id 0x1122 \
-mpegts_transport_stream_id 0x3344 \
-mpegts_service_id 0x5566 \
-mpegts_pmt_start_pid 0x1500 \
-mpegts_start_pid 0x150 \
-metadata service_provider="Some provider" \ <--- these
-metadata service_name="Some Channel" \
out.ts
code,
out = av.open(
out_name,
'w',
format='mpegts',
container_options={
'mpegts_copyts': '1',
'mpegts_service_type': 'mpeg2_digital_hdtv',
},
)
out.flags |= 'DISCARD_CORRUPT'
av.FilterContext
object. The initial volume is set on init (filter_graph.add("volume", "volume=1.0:precision=float")
). I would like to change the volume on demand without reinitializing the whole graph. From what I understand, I would need to send a command to the filter (I checked that av.filter.filter.Filter.command_support
is true) but it does not look like there is an API to send commands to the filter object. Am I overlooking something?
Hello All!
I have quite a far fetched question :)
I've tried to compile a large python project using Nuitka.
The project use PyAV for everything video related.
There seems to be an incompatibility between Nuitka and PyAv, at runtime I got a
Traceback (most recent call last):
File "...\test.py", line 1, in <module>
import av
File "...\av\__init__.py", line 15, in <module av>
File "...\av\audio\__init__.py", line 1, in <module av.audio>
File "av\audio\frame.pyx", line 1, in init av.audio.frame
ModuleNotFoundError: No module named 'av.frame'
Have anyone encountered this issue?
Can this come from the fact that there is a frame.pyd in 'av\' in 'av\audio\' and in 'av\video\' ?
Any help would be greatly appreciated.
import av
container = av.open(path_to_video)
for frame in container.decode(video=0):
frame.to_image().save('frame-%04d.jpg' % frame.index)