Repository navigation
AVError: [Errno 22] Invalid argument: 'xxxxxxxxxx.mp4' (16: mp4) #334
Copy link
Copy link
Closed
Description
I am using the latest git repo code (cloned from this repo 2 weeks ago) on Ubuntu 16.04.
I am doing the demux and remux with the following code(no decode and encode at all):
output_file = av.open(mux_file, mode='w')
output_video_stream = output_file.add_stream(template=input_video_stream)
output_audio_stream = output_file.add_stream(template=input_audio_stream)
for packet_data in mux_tmp_buffer:
#print('before', packet_data.stream.type, packet_data.dts, packet_data.pts)
if packet_data.stream.type == b'video':
if packet_data.dts:
packet_data.dts = packet_data.dts - video_dts_start
packet_data.pts = packet_data.pts - video_dts_start
packet_data.stream = output_video_stream
mux_vpacket_c += 1
else:
if packet_data.dts:
packet_data.dts = packet_data.dts - audio_dts_start
packet_data.pts = packet_data.pts - audio_dts_start
packet_data.stream = output_audio_stream
#print('after', packet_data.stream.type, packet_data.dts, packet_data.pts)
output_file.mux(packet_data)
output_file.close()the mux_tmp_buffer is a packet list demuxed from input container.
But I got the following exceptions after run multiple times of above code.
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "remux.py", line 482, in mux
mux_packet_c += muxer.extendRedisResult()
File "remux.py", line 399, in extendRedisResult
mux_packet_c += self.muxClip(self.ins[scene].name, l[0], l[-1], self.ins[scene].img_list)
File "remux.py", line 462, in muxClip
output_file.mux(packet_data)
File "av/container/output.pyx", line 199, in av.container.output.OutputContainer.mux
self.mux_one(packets)
File "av/container/output.pyx", line 213, in av.container.output.OutputContainer.mux_one
self.proxy.err_check(lib.av_interleaved_write_frame(self.proxy.ptr, &packet.struct))
File "av/container/core.pyx", line 183, in av.container.core.ContainerProxy.err_check
return err_check(value, filename=self.name)
File "av/utils.pyx", line 105, in av.utils.err_check
raise AVError(-res, message, filename, log)
AVError: [Errno 22] Invalid argument: '/home/gemfield/web/static/videos/xxxxxxxxxx.mp4' (16: mp4)
And another quesions, how to deal with the packet.dts value when doing the mux (what I am doing now is packet_data.pts = packet_data.pts - video_dts_start, which seems ugly...)?
Thanks very much.
Metadata
Metadata
Assignees
Labels
No labels
Activity
notedit commentedon Jun 6, 2018
#333
Maybe we have the similar problem
gemfield commentedon Jun 6, 2018
I think I have found the root cause. This is due to I muxed a packet (av.packet.Packet) twice (in other places).
So is there a way that I can do a deep copy of a packet?
mikeboers commentedon Jun 7, 2018
I've not dug deep into that part for a while, and my memory of it is quite bad, but I'm surprised that muxing the same packet twice would be problematic in general. I can see having shallow and deep copies on packets being useful (the difference being if it copies the underlying buffer).
I agree that the PTS handling is not ideal. The FFmpeg binary has a few different modes for automatically dealing with PTSes, but it is in the binary, not the library. If (and only if) your streams are completely consistent you can set the PTS to
Noneand PyAV will generate reasonable ones.gemfield commentedon Jun 7, 2018
Now I solved this issue by doing deep copy of a packet through the update_buffer API. Thanks very much.
notedit commentedon Jun 9, 2018
Yes, I came into this issue too. It seems it will recycle the packet after mux.
notedit commentedon Jun 9, 2018
@gemfield How can i deepcopy Packet? I did not get how to deepcopy with update_buffer.
Can you give some sample code?
mikeboers commentedon Jun 9, 2018
Huh. I can see how it might claim ownership of the buffer in the packet after it is muxed. If that is the case, then I can explicitly take our own reference of it, and release it when the packet object is destroyed.
mikeboers commentedon Jun 9, 2018
Reading the docs, it says "Ownership of the packet remains with the caller, and the decoder will not write to the packet."
So I'm not sure there.
notedit commentedon Jun 9, 2018
@mikeboers i just read ffmpeg's code, av_interleaved_write_frame copy the packet to another packet, and reset the original packet, it does not recycle the packet, just reset.
it seems av_write_frame can fix this.
so will we change av_interleaved_write_frame to av_write_frame or add some options to let user to choose use av_interleaved_write_frame or not?
notedit commentedon Jun 9, 2018
pyav use av_interleaved_write_frame here not avcodec_send_packet
mikeboers commentedon Jun 9, 2018
Lol... look at me going to read the docs and not even looking in the right place. For others, see here.
I think we should increase the reference count when going into this function.
notedit commentedon Jun 9, 2018
increase the reference count or use av_write_frame api. i think
mikeboers commentedon Jun 9, 2018
av_write_framewould require implementing the interleaving in PyAV. That does not sound fun.mikeboers commentedon Jun 9, 2018
The
feature/packet_refsbranch has a small change for this. I don't know how to test it (I tried something simple, but it didn't work).notedit commentedon Jun 9, 2018
Thanks, i will give a test.
Add #334 to changelog.
notedit commentedon Jun 9, 2018
Thanks, works fine now
Add PyAV-Org#334 to changelog.