Skip to content

Commit 31d5d22

Browse files
committed
support AVC3
1 parent 22e7ae8 commit 31d5d22

File tree

4 files changed

+31
-64
lines changed

4 files changed

+31
-64
lines changed

lib/membrane_mp4/demuxer/isom.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ defmodule Membrane.MP4.Demuxer.ISOM do
4040
any_of(
4141
%Membrane.AAC{config: {:esds, _esds}},
4242
%Membrane.H264{
43-
stream_structure: {:avc1, _dcr},
43+
stream_structure: {_avc, _dcr},
4444
alignment: :au
4545
},
4646
%Membrane.H265{

lib/membrane_mp4/muxer/isom.ex

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ defmodule Membrane.MP4.Muxer.ISOM do
1717
any_of(
1818
%Membrane.AAC{config: {:esds, _esds}},
1919
%Membrane.H264{
20-
stream_structure: {:avc1, _dcr},
20+
stream_structure: {_avc, _dcr},
2121
alignment: :au
2222
},
2323
%Membrane.H265{
@@ -96,25 +96,28 @@ defmodule Membrane.MP4.Muxer.ISOM do
9696
@impl true
9797
def handle_stream_format(
9898
Pad.ref(:input, pad_ref) = pad,
99-
stream_format,
99+
%type{} = stream_format,
100100
ctx,
101101
state
102102
) do
103-
cond do
103+
case ctx.pads[pad].stream_format do
104104
# Handle receiving the first stream format on the given pad
105-
is_nil(ctx.pads[pad].stream_format) ->
105+
nil ->
106106
update_in(state, [:pad_to_track, pad_ref], fn track_id ->
107107
Track.new(track_id, stream_format, state.chunk_duration)
108108
end)
109109

110-
# Handle receiving all but the first stream format on the given pad,
111-
# when stream format is duplicated - ignore
112-
ctx.pads[pad].stream_format == stream_format ->
110+
# Handle receiving a stream format of the same type
111+
%^type{} ->
113112
state
114113

115114
# otherwise we can assume that output will be corrupted
116-
true ->
117-
raise "ISOM Muxer doesn't support variable parameters"
115+
previos_format ->
116+
raise """
117+
Unsupported stream_format change on pad #{inspect(pad_ref)}, \
118+
previous format: #{inspect(previos_format)}
119+
new format: #{inspect(stream_format)}
120+
"""
118121
end
119122
|> then(&{[], &1})
120123
end

test/fixtures/isom/ref_video_vp.mp4

181 KB
Binary file not shown.

test/membrane_mp4/muxer/isom/integration_test.exs

Lines changed: 18 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ defmodule Membrane.MP4.Muxer.ISOM.IntegrationTest do
6262
perform_test(pid, "video")
6363
end
6464

65+
test "variable parameters H264 track" do
66+
prepare_test("video")
67+
68+
structure = [
69+
child(:file, %Membrane.File.Source{location: "test/fixtures/in_video_vp.h264"})
70+
|> child(:parser, %Membrane.H264.Parser{
71+
generate_best_effort_timestamps: %{framerate: {30, 1}},
72+
output_stream_structure: :avc3
73+
})
74+
|> child(:muxer, %Membrane.MP4.Muxer.ISOM{chunk_duration: Time.seconds(1)})
75+
|> child(:sink, %Membrane.File.Sink{location: out_path_for("video_vp")})
76+
]
77+
78+
pid = Pipeline.start_link_supervised!(spec: structure)
79+
80+
perform_test(pid, "video_vp")
81+
end
82+
6583
test "single H265 track" do
6684
prepare_test("video_hevc")
6785

@@ -210,58 +228,4 @@ defmodule Membrane.MP4.Muxer.ISOM.IntegrationTest do
210228
perform_test(pid, "two_tracks_fast_start")
211229
end
212230
end
213-
214-
describe "When fed a variable parameter h264 stream, Muxer.ISOM should" do
215-
test "raise when stream format's inband_parameters are not used" do
216-
structure = [
217-
child(:file, %Membrane.File.Source{location: "test/fixtures/in_video_vp.h264"})
218-
|> child(:parser, %Membrane.H264.Parser{
219-
generate_best_effort_timestamps: %{framerate: {30, 1}},
220-
output_stream_structure: :avc1
221-
})
222-
|> child(:muxer, %Membrane.MP4.Muxer.ISOM{
223-
chunk_duration: Time.seconds(1),
224-
fast_start: true
225-
})
226-
|> child(:sink, Membrane.Fake.Sink.Buffers)
227-
]
228-
229-
{:ok, _supervisor_pid, pid} = Pipeline.start(spec: structure)
230-
monitor_ref = Process.monitor(pid)
231-
232-
assert_receive {:DOWN, ^monitor_ref, :process, ^pid,
233-
{:membrane_child_crash, :muxer,
234-
{%RuntimeError{
235-
message: "ISOM Muxer doesn't support variable parameters"
236-
}, _stacktrace}}},
237-
1_000
238-
end
239-
end
240-
241-
describe "ctts table" do
242-
test "should not be stored when dts and pts values are equal" do
243-
prepare_test("video")
244-
245-
structure = [
246-
child(:file, %Membrane.File.Source{location: "test/fixtures/in_video.h264"})
247-
|> child(:parser, %Membrane.H264.Parser{
248-
generate_best_effort_timestamps: %{framerate: {30, 1}, add_dts_offset: false},
249-
output_stream_structure: :avc1
250-
})
251-
|> child(:muxer, %Membrane.MP4.Muxer.ISOM{chunk_duration: Time.seconds(1)})
252-
|> child(:sink, %Membrane.File.Sink{location: out_path_for("video")})
253-
]
254-
255-
pid = Pipeline.start_link_supervised!(spec: structure)
256-
257-
assert_end_of_stream(pid, :sink, :input)
258-
refute_sink_buffer(pid, :sink, _buffer, 0)
259-
260-
assert :ok == Pipeline.terminate(pid)
261-
262-
assert {parsed_out, <<>>} = out_path_for("video") |> File.read!() |> Container.parse!()
263-
assert Container.get_box(parsed_out, [:moov, :trak, :mdia, :minf, :stbl, :stts])
264-
refute Container.get_box(parsed_out, [:moov, :trak, :mdia, :minf, :stbl, :ctts])
265-
end
266-
end
267231
end

0 commit comments

Comments
 (0)