PyAV-Org / PyAV

Pythonic bindings for FFmpeg's libraries.
https://pyav.basswood-io.com/
BSD 3-Clause "New" or "Revised" License
2.44k stars 359 forks source link

Failing to decode audio with manually created audio decoder #1470

Closed caliangxie closed 1 month ago

caliangxie commented 1 month ago

Overview

I am trying to decode audio packets from a Hikvision camera stream using a AudioCodecContext that was created outside the input container.

I need to manually create the audio decoder as I am sending the packets to another process and I need to decode the packets there instead. I was planning on sending over the parameters of the original decoder and recreating the decoder with those parameters.

Expected behavior

I expect the decoding to proceed successfully.

Actual behavior

An internal BugError is thrown.

Traceback:

Traceback (most recent call last):
  File "/tmp/test.py", line 14, in <module>
    for frame in new_cc.decode(packet):
  File "av/codec/context.pyx", line 450, in av.codec.context.CodecContext.decode
  File "av/codec/context.pyx", line 465, in av.codec.context.CodecContext.decode
  File "av/codec/context.pyx", line 366, in av.codec.context.CodecContext._send_packet_and_recv
  File "av/codec/context.pyx", line 390, in av.codec.context.CodecContext._recv_frame
  File "av/error.pyx", line 326, in av.error.err_check
av.error.BugError: [Errno 558323010] Internal bug, should not have happened

Investigation

Reproduction

import av
from av.audio.format import AudioFormat

container = av.open('./video.avi')

audio_stream = container.streams.audio[0]
original_cc = audio_stream.codec_context
new_cc = av.Codec(original_cc.name).create()
new_cc.format = AudioFormat(original_cc.format.name)
layout = av.AudioLayout(original_cc.layout.name)
new_cc.layout = layout

for packet in container.demux(audio=0):
    for frame in new_cc.decode(packet):
        print('decoded', frame)

A sample video is placed in the zip that is attached to this issue.

Versions

Research

I have done the following:

Additional context

The camera is a Hikvision DS-2CD2443G0-I(W) that is using the following parameters for the codecs: Audio:

WyattBlue commented 1 month ago

I need to manually create the audio decoder as I am sending the packets to another process

No no no no no no. This is not how this works. This is not how any of this works. Decoding packets depends on the original container and decoder. Your new_cc variable could never decode packets correctly because of how ffmpeg works.