Skip to content

Commit

Permalink
[streams] populate added stream with codec param
Browse files Browse the repository at this point in the history
avformat_new_stream(AVFormatContext *s, const AVCodec *c) does not use its
second parameter [1], so the codec type for the stream is not populated until
avcodec_parameters_from_context() [2] is called.

[1]: https://ffmpeg.org/doxygen/trunk/group__lavf__core.html#gadcb0fd3e507d9b58fe78f61f8ad39827
[2]: https://ffmpeg.org/doxygen/trunk/codec__par_8c_source.html#l00099

Co-authored-by: Jeremy Lainé <jeremy.laine@m4x.org>
  • Loading branch information
HanzCEO and jlaine committed Jan 31, 2023
1 parent 1ab3bf6 commit 6982d81
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
6 changes: 6 additions & 0 deletions av/container/output.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ cdef class OutputContainer(Container):
if self.ptr.oformat.flags & lib.AVFMT_GLOBALHEADER:
codec_context.flags |= lib.AV_CODEC_FLAG_GLOBAL_HEADER

# Initialise stream codec parameters to populate the codec type.
#
# Subsequent changes to the codec context will be applied just before
# encoding starts in `start_encoding()`.
err_check(lib.avcodec_parameters_from_context(stream.codecpar, codec_context))

# Construct the user-land stream
cdef CodecContext py_codec_context = wrap_codec_context(codec_context, codec)
cdef Stream py_stream = wrap_stream(self, stream, py_codec_context)
Expand Down
7 changes: 7 additions & 0 deletions tests/test_encode.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class TestBasicVideoEncoding(TestCase):
def test_default_options(self):
with av.open(self.sandboxed("output.mov"), "w") as output:
stream = output.add_stream("mpeg4")
self.assertIn(stream, output.streams.video)
self.assertEqual(stream.average_rate, Fraction(24, 1))
self.assertEqual(stream.time_base, None)

Expand All @@ -152,6 +153,7 @@ def test_encoding_with_pts(self):

with av.open(path, "w") as output:
stream = output.add_stream("libx264", 24)
self.assertIn(stream, output.streams.video)
stream.width = WIDTH
stream.height = HEIGHT
stream.pix_fmt = "yuv420p"
Expand Down Expand Up @@ -182,6 +184,7 @@ class TestBasicAudioEncoding(TestCase):
def test_default_options(self):
with av.open(self.sandboxed("output.mov"), "w") as output:
stream = output.add_stream("mp2")
self.assertIn(stream, output.streams.audio)
self.assertEqual(stream.time_base, None)

# codec context properties
Expand All @@ -203,6 +206,7 @@ def test_transcode(self):
sample_fmt = "s16"

stream = output.add_stream("mp2", sample_rate)
self.assertIn(stream, output.streams.audio)

ctx = stream.codec_context
ctx.time_base = sample_rate
Expand Down Expand Up @@ -241,11 +245,13 @@ class TestEncodeStreamSemantics(TestCase):
def test_stream_index(self):
with av.open(self.sandboxed("output.mov"), "w") as output:
vstream = output.add_stream("mpeg4", 24)
self.assertIn(vstream, output.streams.video)
vstream.pix_fmt = "yuv420p"
vstream.width = 320
vstream.height = 240

astream = output.add_stream("mp2", 48000)
self.assertIn(astream, output.streams.audio)
astream.channels = 2
astream.format = "s16"

Expand Down Expand Up @@ -277,6 +283,7 @@ def test_stream_index(self):
def test_set_id_and_time_base(self):
with av.open(self.sandboxed("output.mov"), "w") as output:
stream = output.add_stream("mp2")
self.assertIn(stream, output.streams.audio)

# set id
self.assertEqual(stream.id, 0)
Expand Down

0 comments on commit 6982d81

Please sign in to comment.