Current section

Files

Jump to
membrane_mpegts_plugin lib membrane_element_mpegts program_map_table.ex
Raw

lib/membrane_element_mpegts/program_map_table.ex

defmodule Membrane.MPEG.TS.ProgramMapTable do
@moduledoc false
defstruct [:pcr_pid, program_info: [], streams: %{}]
@type t :: %__MODULE__{
streams: map(),
program_info: list(),
pcr_pid: 0..8191
}
@type stream_type_id_t :: 0..255
@type stream_id_t :: 0..8191
@type stream :: %{
stream_type: atom,
stream_type_id: stream_type_id_t
}
@type streams :: %{
required(stream_id_t) => stream
}
@spec parse(binary()) :: {:ok, t()} | {:error, :malformed_entry}
def parse(<<
_reserved::3,
pcr_pid::13,
_reserved2::4,
program_info_length::12,
rest::binary
>>) do
with {:ok, {program_info, rest}} <- parse_program_info(program_info_length, rest),
{:ok, streams} <- parse_streams(rest) do
result = %__MODULE__{
program_info: program_info,
streams: streams,
pcr_pid: pcr_pid
}
{:ok, result}
end
end
defp parse_program_info(descriptors, data)
defp parse_program_info(0, date), do: {:ok, {[], date}}
defp parse_streams(data, acc \\ %{})
defp parse_streams(<<>>, acc), do: {:ok, acc}
# TODO handle es_info (Page 54, Rec. ITU-T H.222.0 (03/2017))
defp parse_streams(
<<
stream_type_id::8,
_reserved::3,
elementary_pid::13,
_reserved1::4,
program_info_length::12,
_program_info::binary-size(program_info_length),
rest::binary
>>,
acc
) do
stream = %{
stream_type_id: stream_type_id,
stream_type: parse_stream_assigment(stream_type_id)
}
result = Map.put(acc, elementary_pid, stream)
parse_streams(rest, result)
end
defp parse_streams(_, _) do
{:error, :malformed_entry}
end
# Based on https://en.wikipedia.org/wiki/Program-specific_information#Elementary_stream_types
defp parse_stream_assigment(0x01), do: :MPEG1_VIDEO
defp parse_stream_assigment(0x02), do: :MPEG2_VIDEO
defp parse_stream_assigment(0x03), do: :MPEG1_AUDIO
defp parse_stream_assigment(0x04), do: :MPEG2_AUDIO
defp parse_stream_assigment(0x0F), do: :AAC
defp parse_stream_assigment(0x1B), do: :H264
defp parse_stream_assigment(0x1F), do: :MPEG4_SVC
defp parse_stream_assigment(0x20), do: :MPEG4_MVC
defp parse_stream_assigment(0x24), do: :H265
end