Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
GSoC
GSoC2018
macOS
vlc
Commits
141d5e26
Commit
141d5e26
authored
Feb 10, 2016
by
François Cartegnie
🤞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
demux: ts: add support for ETT tables
parent
5723baeb
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
329 additions
and
65 deletions
+329
-65
modules/demux/mpeg/ts_psip.c
modules/demux/mpeg/ts_psip.c
+326
-65
modules/demux/mpeg/ts_streams_private.h
modules/demux/mpeg/ts_streams_private.h
+3
-0
No files found.
modules/demux/mpeg/ts_psip.c
View file @
141d5e26
...
...
@@ -64,9 +64,13 @@
struct
ts_psip_context_t
{
dvbpsi_atsc_mgt_t
*
p_mgt
;
/* Used to match (EITx,ETTx)<->PIDn */
dvbpsi_atsc_stt_t
*
p_stt
;
/* Time reference for EIT/EAS */
dvbpsi_atsc_vct_t
*
p_vct
;
/* Required for EIT vchannel -> program remapping */
atsc_a65_handle_t
*
p_a65
;
/* Shared Handle to avoid iconv reopens */
uint16_t
i_tabletype
;
/* Only used by EIT/ETT pid */
DECL_ARRAY
(
dvbpsi_atsc_ett_t
*
)
etts
;
/* For ETT pid, used on new EIT update */
DECL_ARRAY
(
dvbpsi_atsc_eit_t
*
)
eits
;
/* For EIT pid, used on new ETT update */
};
ts_psip_context_t
*
ts_psip_context_New
()
...
...
@@ -74,24 +78,153 @@ ts_psip_context_t * ts_psip_context_New()
ts_psip_context_t
*
p_ctx
=
malloc
(
sizeof
(
*
p_ctx
));
if
(
likely
(
p_ctx
))
{
p_ctx
->
p_mgt
=
NULL
;
p_ctx
->
p_stt
=
NULL
;
p_ctx
->
p_vct
=
NULL
;
p_ctx
->
p_a65
=
NULL
;
p_ctx
->
i_tabletype
=
0
;
ARRAY_INIT
(
p_ctx
->
etts
);
ARRAY_INIT
(
p_ctx
->
eits
);
}
return
p_ctx
;
}
void
ts_psip_context_Delete
(
ts_psip_context_t
*
p_ctx
)
{
assert
(
!
p_ctx
->
p_mgt
||
!
p_ctx
->
etts
.
i_size
);
assert
(
!
p_ctx
->
p_vct
||
!
p_ctx
->
eits
.
i_size
);
if
(
p_ctx
->
p_mgt
)
dvbpsi_atsc_DeleteMGT
(
p_ctx
->
p_mgt
);
if
(
p_ctx
->
p_stt
)
dvbpsi_atsc_DeleteSTT
(
p_ctx
->
p_stt
);
if
(
p_ctx
->
p_vct
)
dvbpsi_atsc_DeleteVCT
(
p_ctx
->
p_vct
);
if
(
p_ctx
->
p_a65
)
atsc_a65_handle_Release
(
p_ctx
->
p_a65
);
/* Things only used for ETT/EIT */
for
(
int
i
=
0
;
i
<
p_ctx
->
etts
.
i_size
;
i
++
)
dvbpsi_atsc_DeleteETT
(
p_ctx
->
etts
.
p_elems
[
i
]
);
for
(
int
i
=
0
;
i
<
p_ctx
->
eits
.
i_size
;
i
++
)
dvbpsi_atsc_DeleteEIT
(
p_ctx
->
eits
.
p_elems
[
i
]
);
ARRAY_RESET
(
p_ctx
->
etts
);
ARRAY_RESET
(
p_ctx
->
eits
);
free
(
p_ctx
);
}
static
ts_pid_t
*
ATSC_GetSiblingxTTPID
(
ts_pid_list_t
*
p_list
,
const
dvbpsi_atsc_mgt_t
*
p_mgt
,
ts_psip_t
*
p_psip
)
{
uint16_t
i_lookup
;
assert
(
p_psip
->
p_ctx
->
i_tabletype
);
if
(
p_psip
->
p_ctx
->
i_tabletype
>=
ATSC_TABLE_TYPE_ETT_0
)
i_lookup
=
p_psip
->
p_ctx
->
i_tabletype
-
ATSC_TABLE_TYPE_ETT_0
+
ATSC_TABLE_TYPE_EIT_0
;
else
i_lookup
=
p_psip
->
p_ctx
->
i_tabletype
-
ATSC_TABLE_TYPE_EIT_0
+
ATSC_TABLE_TYPE_ETT_0
;
for
(
const
dvbpsi_atsc_mgt_table_t
*
p_tab
=
p_mgt
->
p_first_table
;
p_tab
;
p_tab
=
p_tab
->
p_next
)
{
if
(
p_tab
->
i_table_type
==
i_lookup
)
return
ts_pid_Get
(
p_list
,
p_tab
->
i_table_type_pid
);
}
return
NULL
;
}
static
inline
uint32_t
toETMId
(
uint16_t
i_vchannel
,
uint16_t
i_event_id
)
{
return
(
i_vchannel
<<
16
)
|
(
i_event_id
<<
2
)
|
0x02
;
}
static
inline
void
fromETMId
(
uint32_t
i_etm_id
,
uint16_t
*
pi_vchannel
,
uint16_t
*
pi_event_id
)
{
*
pi_vchannel
=
i_etm_id
>>
16
;
*
pi_event_id
=
(
i_etm_id
&
0xFFFF
)
>>
2
;
}
static
const
dvbpsi_atsc_ett_t
*
ATSC_ETTFindByETMId
(
ts_psip_context_t
*
p_ettctx
,
uint32_t
i_etm_id
,
uint8_t
i_version
)
{
int
i
;
ARRAY_BSEARCH
(
p_ettctx
->
etts
,
->
i_etm_id
,
uint32_t
,
i_etm_id
,
i
);
if
(
i
!=
-
1
&&
p_ettctx
->
etts
.
p_elems
[
i
]
->
i_version
==
i_version
)
return
p_ettctx
->
etts
.
p_elems
[
i
];
return
NULL
;
}
static
const
dvbpsi_atsc_eit_event_t
*
ATSC_EventFindByETMId
(
ts_psip_context_t
*
p_eitctx
,
uint32_t
i_etm_id
,
uint8_t
i_version
)
{
uint16_t
i_vchannel_id
,
i_event_id
;
fromETMId
(
i_etm_id
,
&
i_vchannel_id
,
&
i_event_id
);
for
(
int
i
=
0
;
i
<
p_eitctx
->
eits
.
i_size
;
i
++
)
{
dvbpsi_atsc_eit_t
*
p_eit
=
p_eitctx
->
eits
.
p_elems
[
i
];
if
(
p_eit
->
i_version
!=
i_version
||
p_eit
->
i_source_id
!=
i_vchannel_id
)
continue
;
for
(
const
dvbpsi_atsc_eit_event_t
*
p_evt
=
p_eit
->
p_first_event
;
p_evt
;
p_evt
=
p_evt
->
p_next
)
{
if
(
p_evt
->
i_event_id
==
i_event_id
)
return
p_evt
;
}
}
return
NULL
;
}
static
void
ATSC_EITInsert
(
ts_psip_context_t
*
p_ctx
,
dvbpsi_atsc_eit_t
*
p_eit
)
{
for
(
int
i
=
0
;
i
<
p_ctx
->
eits
.
i_size
;
i
++
)
{
dvbpsi_atsc_eit_t
*
p_cur_eit
=
p_ctx
->
eits
.
p_elems
[
i
];
if
(
p_cur_eit
->
i_source_id
==
p_eit
->
i_source_id
)
{
dvbpsi_atsc_DeleteEIT
(
p_cur_eit
);
/* Updated version */
p_ctx
->
eits
.
p_elems
[
i
]
=
p_eit
;
return
;
}
}
ARRAY_APPEND
(
p_ctx
->
eits
,
p_eit
);
}
static
void
ATSC_CleanETTByChannelVersion
(
ts_psip_context_t
*
p_ctx
,
uint16_t
i_channel
,
uint8_t
i_version
)
{
int
i
=
0
;
while
(
i
<
p_ctx
->
etts
.
i_size
)
{
dvbpsi_atsc_ett_t
*
p
=
p_ctx
->
etts
.
p_elems
[
i
];
uint16_t
i_curchan
=
p
->
i_etm_id
>>
16
;
if
(
i_channel
<
i_curchan
)
break
;
/* because ordered */
if
(
i_curchan
==
i_channel
&&
p
->
i_version
!=
i_version
)
{
dvbpsi_atsc_DeleteETT
(
p
);
ARRAY_REMOVE
(
p_ctx
->
etts
,
i
);
}
else
i
++
;
}
}
static
void
ATSC_InsertETTOrdered
(
ts_psip_context_t
*
p_ctx
,
dvbpsi_atsc_ett_t
*
p_ett
)
{
int
i
=
0
;
for
(
;
i
<
p_ctx
->
etts
.
i_size
;
i
++
)
{
dvbpsi_atsc_ett_t
*
p
=
p_ctx
->
etts
.
p_elems
[
i
];
if
(
p
->
i_etm_id
>=
p_ett
->
i_etm_id
)
{
if
(
p
->
i_etm_id
==
p_ett
->
i_etm_id
)
{
dvbpsi_atsc_DeleteETT
(
p
);
p_ctx
->
etts
.
p_elems
[
i
]
=
p_ett
;
return
;
}
break
;
}
}
ARRAY_INSERT
(
p_ctx
->
etts
,
p_ett
,
i
);
}
static
bool
ATSC_TranslateVChannelToProgram
(
const
dvbpsi_atsc_vct_t
*
p_vct
,
uint16_t
i_channel
,
uint16_t
*
pi_program
)
{
...
...
@@ -163,6 +296,82 @@ static const char * ATSC_A53_get_service_type( uint8_t i_type )
} while(0);
#endif
static
time_t
ATSC_AddVLCEPGEvent
(
demux_t
*
p_demux
,
ts_psip_context_t
*
p_basectx
,
const
dvbpsi_atsc_eit_event_t
*
p_evt
,
const
dvbpsi_atsc_ett_t
*
p_ett
,
vlc_epg_t
*
p_epg
)
{
#ifndef ATSC_DEBUG_EIT
VLC_UNUSED
(
p_demux
);
#endif
char
*
psz_title
=
atsc_a65_Decode_multiple_string
(
p_basectx
->
p_a65
,
p_evt
->
i_title
,
p_evt
->
i_title_length
);
char
*
psz_shortdesc_text
=
NULL
;
char
*
psz_longdesc_text
=
NULL
;
time_t
i_start
=
atsc_a65_GPSTimeToEpoch
(
p_evt
->
i_start_time
,
p_basectx
->
p_stt
->
i_gps_utc_offset
);
EIT_DEBUG_TIMESHIFT
(
i_start
);
for
(
const
dvbpsi_descriptor_t
*
p_dr
=
p_evt
->
p_first_descriptor
;
p_dr
;
p_dr
=
p_dr
->
p_next
)
{
switch
(
p_dr
->
i_tag
)
{
case
ATSC_DESCRIPTOR_CONTENT_ADVISORY
:
{
const
uint8_t
*
p_data
=
p_dr
->
p_data
;
size_t
i_data
=
p_dr
->
i_length
;
uint8_t
i_ratings_count
=
p_dr
->
p_data
[
0
]
&
0x3F
;
p_data
++
;
i_data
--
;
for
(
;
i_ratings_count
&&
i_data
>
3
;
i_ratings_count
--
)
{
uint8_t
i_rated_dimensions
=
p_data
[
1
];
if
(
(
size_t
)
i_rated_dimensions
*
2
+
3
>
i_data
)
/* one more sanity check */
break
;
uint8_t
desclen
=
p_data
[(
size_t
)
2
+
2
*
i_rated_dimensions
];
p_data
+=
(
size_t
)
3
+
2
*
i_rated_dimensions
;
i_data
-=
(
size_t
)
3
+
2
*
i_rated_dimensions
;
if
(
desclen
>
i_data
)
break
;
if
(
unlikely
(
psz_shortdesc_text
)
)
free
(
psz_shortdesc_text
);
psz_shortdesc_text
=
atsc_a65_Decode_multiple_string
(
p_basectx
->
p_a65
,
p_data
,
desclen
);
if
(
psz_shortdesc_text
)
/* Only keep first for now */
break
;
p_data
+=
desclen
;
i_data
-=
desclen
;
}
}
default:
break
;
}
}
/* Try to match ETT */
if
(
p_ett
)
{
psz_longdesc_text
=
atsc_a65_Decode_multiple_string
(
p_basectx
->
p_a65
,
p_ett
->
p_etm_data
,
p_ett
->
i_etm_length
);
}
if
(
i_start
>
VLC_TS_INVALID
&&
psz_title
)
{
#ifdef ATSC_DEBUG_EIT
msg_Dbg
(
p_demux
,
"EIT Event time %ld +%d %s id 0x%x"
,
i_start
,
p_evt
->
i_length_seconds
,
psz_title
,
p_evt
->
i_event_id
);
#endif
vlc_epg_AddEvent
(
p_epg
,
i_start
,
p_evt
->
i_length_seconds
,
psz_title
,
psz_shortdesc_text
,
psz_longdesc_text
,
0
);
}
free
(
psz_title
);
free
(
psz_shortdesc_text
);
free
(
psz_longdesc_text
);
return
i_start
;
}
static
void
ATSC_EIT_Callback
(
void
*
p_pid
,
dvbpsi_atsc_eit_t
*
p_eit
)
{
ts_pid_t
*
p_eit_pid
=
(
ts_pid_t
*
)
p_pid
;
...
...
@@ -176,26 +385,29 @@ static void ATSC_EIT_Callback( void *p_pid, dvbpsi_atsc_eit_t* p_eit )
demux_t
*
p_demux
=
(
demux_t
*
)
p_eit_pid
->
u
.
p_psip
->
handle
->
p_sys
;
ts_pid_t
*
p_base_pid
=
GetPID
(
p_demux
->
p_sys
,
ATSC_BASE_PID
);
ts_psip_t
*
p_basepsip
=
p_base_pid
->
u
.
p_psip
;
ts_psip_context_t
*
p_ctx
=
p_basepsip
->
p_ctx
;
ts_psip_context_t
*
p_
base
ctx
=
p_basepsip
->
p_ctx
;
if
(
!
p_eit
->
b_current_next
||
unlikely
(
p_base_pid
->
type
!=
TYPE_PSIP
||
!
p_ctx
->
p_stt
||
!
p_ctx
->
p_vct
)
)
unlikely
(
p_base_pid
->
type
!=
TYPE_PSIP
||
!
p_
base
ctx
->
p_stt
||
!
p_
base
ctx
->
p_vct
)
)
{
dvbpsi_atsc_DeleteEIT
(
p_eit
);
return
;
}
uint16_t
i_program_number
;
if
(
!
ATSC_TranslateVChannelToProgram
(
p_ctx
->
p_vct
,
p_eit
->
i_source_id
,
&
i_program_number
)
)
if
(
!
ATSC_TranslateVChannelToProgram
(
p_
base
ctx
->
p_vct
,
p_eit
->
i_source_id
,
&
i_program_number
)
)
{
msg_Warn
(
p_demux
,
"Received EIT for unkown channel %d"
,
p_eit
->
i_source_id
);
dvbpsi_atsc_DeleteEIT
(
p_eit
);
return
;
}
const
ts_pid_t
*
pid_sibling_ett
=
ATSC_GetSiblingxTTPID
(
&
p_demux
->
p_sys
->
pids
,
p_basectx
->
p_mgt
,
p_eit_pid
->
u
.
p_psip
);
/* Get System Time for finding and setting current event */
time_t
i_current_time
=
atsc_a65_GPSTimeToEpoch
(
p_ctx
->
p_stt
->
i_system_time
,
p_ctx
->
p_stt
->
i_gps_utc_offset
);
time_t
i_current_time
=
atsc_a65_GPSTimeToEpoch
(
p_
base
ctx
->
p_stt
->
i_system_time
,
p_
base
ctx
->
p_stt
->
i_gps_utc_offset
);
EIT_DEBUG_TIMESHIFT
(
i_current_time
);
...
...
@@ -206,73 +418,26 @@ static void ATSC_EIT_Callback( void *p_pid, dvbpsi_atsc_eit_t* p_eit )
return
;
}
if
(
!
p_ctx
->
p_a65
&&
!
(
p_ctx
->
p_a65
=
atsc_a65_handle_New
(
NULL
))
)
if
(
!
p_
base
ctx
->
p_a65
&&
!
(
p_
base
ctx
->
p_a65
=
atsc_a65_handle_New
(
NULL
))
)
goto
end
;
time_t
i_current_event_start_time
=
0
;
for
(
const
dvbpsi_atsc_eit_event_t
*
p_evt
=
p_eit
->
p_first_event
;
p_evt
;
p_evt
=
p_evt
->
p_next
)
{
char
*
psz_title
=
atsc_a65_Decode_multiple_string
(
p_ctx
->
p_a65
,
p_evt
->
i_title
,
p_evt
->
i_title_length
);
char
*
psz_shortdesc_text
=
NULL
;
/* Try to match ETT */
const
dvbpsi_atsc_ett_t
*
p_ett
=
NULL
;
if
(
pid_sibling_ett
)
p_ett
=
ATSC_ETTFindByETMId
(
pid_sibling_ett
->
u
.
p_psip
->
p_ctx
,
toETMId
(
p_eit
->
i_source_id
,
p_evt
->
i_event_id
),
p_eit
->
i_version
);
time_t
i_start
=
atsc_a65_GPSTimeToEpoch
(
p_evt
->
i_start_time
,
p_ctx
->
p_stt
->
i_gps_utc_offset
);
EIT_DEBUG_TIMESHIFT
(
i_start
);
/* Add Event to EPG based on EIT / available ETT */
time_t
i_start
=
ATSC_AddVLCEPGEvent
(
p_demux
,
p_basectx
,
p_evt
,
p_ett
,
p_epg
);
/* Try to find current event */
if
(
i_start
<=
i_current_time
&&
i_start
+
p_evt
->
i_length_seconds
>
i_current_time
)
i_current_event_start_time
=
i_start
;
for
(
const
dvbpsi_descriptor_t
*
p_dr
=
p_evt
->
p_first_descriptor
;
p_dr
;
p_dr
=
p_dr
->
p_next
)
{
switch
(
p_dr
->
i_tag
)
{
case
ATSC_DESCRIPTOR_CONTENT_ADVISORY
:
{
const
uint8_t
*
p_data
=
p_dr
->
p_data
;
size_t
i_data
=
p_dr
->
i_length
;
uint8_t
i_ratings_count
=
p_dr
->
p_data
[
0
]
&
0x3F
;
p_data
++
;
i_data
--
;
for
(
;
i_ratings_count
&&
i_data
>
3
;
i_ratings_count
--
)
{
uint8_t
i_rated_dimensions
=
p_data
[
1
];
if
(
(
size_t
)
i_rated_dimensions
*
2
+
3
>
i_data
)
/* one more sanity check */
break
;
uint8_t
desclen
=
p_data
[(
size_t
)
2
+
2
*
i_rated_dimensions
];
p_data
+=
(
size_t
)
3
+
2
*
i_rated_dimensions
;
i_data
-=
(
size_t
)
3
+
2
*
i_rated_dimensions
;
if
(
desclen
>
i_data
)
break
;
if
(
unlikely
(
psz_shortdesc_text
)
)
free
(
psz_shortdesc_text
);
psz_shortdesc_text
=
atsc_a65_Decode_multiple_string
(
p_ctx
->
p_a65
,
p_data
,
desclen
);
if
(
psz_shortdesc_text
)
/* Only keep first for now */
break
;
p_data
+=
desclen
;
i_data
-=
desclen
;
}
}
default:
break
;
}
}
if
(
i_start
>
VLC_TS_INVALID
&&
psz_title
)
{
#ifdef ATSC_DEBUG_EIT
msg_Dbg
(
p_demux
,
"EIT Event vchannel/program %d/%d time %ld +%d %s"
,
p_eit
->
i_source_id
,
i_program_number
,
i_start
,
p_evt
->
i_length_seconds
,
psz_title
);
#endif
vlc_epg_AddEvent
(
p_epg
,
i_start
,
p_evt
->
i_length_seconds
,
psz_title
,
psz_shortdesc_text
,
NULL
,
0
);
}
free
(
psz_title
);
free
(
psz_shortdesc_text
);
}
/* Update epg current time from system time ( required for pruning ) */
...
...
@@ -284,7 +449,82 @@ static void ATSC_EIT_Callback( void *p_pid, dvbpsi_atsc_eit_t* p_eit )
end:
vlc_epg_Delete
(
p_epg
);
dvbpsi_atsc_DeleteEIT
(
p_eit
);
ATSC_EITInsert
(
p_eit_pid
->
u
.
p_psip
->
p_ctx
,
p_eit
);
}
static
void
ATSC_ETT_Callback
(
void
*
p_pid
,
dvbpsi_atsc_ett_t
*
p_ett
)
{
ts_pid_t
*
p_ett_pid
=
(
ts_pid_t
*
)
p_pid
;
if
(
unlikely
(
p_ett_pid
->
type
!=
TYPE_PSIP
)
)
{
assert
(
p_ett_pid
->
type
==
TYPE_PSIP
);
dvbpsi_atsc_DeleteETT
(
p_ett
);
return
;
}
demux_t
*
p_demux
=
(
demux_t
*
)
p_ett_pid
->
u
.
p_psip
->
handle
->
p_sys
;
ts_pid_t
*
p_base_pid
=
GetPID
(
p_demux
->
p_sys
,
ATSC_BASE_PID
);
ts_psip_t
*
p_basepsip
=
p_base_pid
->
u
.
p_psip
;
ts_psip_context_t
*
p_basectx
=
p_basepsip
->
p_ctx
;
if
(
p_ett
->
i_etm_id
&
0x02
)
/* Event ETT */
{
ts_psip_context_t
*
p_ctx
=
p_ett_pid
->
u
.
p_psip
->
p_ctx
;
uint16_t
i_vchannel_id
,
i_event_id
;
fromETMId
(
p_ett
->
i_etm_id
,
&
i_vchannel_id
,
&
i_event_id
);
uint16_t
i_program_number
;
if
(
!
ATSC_TranslateVChannelToProgram
(
p_basectx
->
p_vct
,
i_vchannel_id
,
&
i_program_number
)
)
{
msg_Warn
(
p_demux
,
"Received EIT for unkown channel %d"
,
i_vchannel_id
);
dvbpsi_atsc_DeleteETT
(
p_ett
);
return
;
}
/* If ETT with that version isn't already in list (inserted when matched eit is present) */
if
(
ATSC_ETTFindByETMId
(
p_ctx
,
p_ett
->
i_etm_id
,
p_ett
->
i_version
)
==
NULL
)
{
const
dvbpsi_atsc_mgt_t
*
p_mgt
=
ts_pid_Get
(
&
p_demux
->
p_sys
->
pids
,
ATSC_BASE_PID
)
->
u
.
p_psip
->
p_ctx
->
p_mgt
;
ts_pid_t
*
p_sibling_eit
=
ATSC_GetSiblingxTTPID
(
&
p_demux
->
p_sys
->
pids
,
p_mgt
,
p_ett_pid
->
u
.
p_psip
);
if
(
p_sibling_eit
)
{
const
dvbpsi_atsc_eit_event_t
*
p_event
=
ATSC_EventFindByETMId
(
p_sibling_eit
->
u
.
p_psip
->
p_ctx
,
p_ett
->
i_etm_id
,
p_ett
->
i_version
);
if
(
p_event
)
{
#ifdef ATSC_DEBUG_EIT
msg_Dbg
(
p_demux
,
"Should update EIT %x (matched EIT)"
,
p_event
->
i_event_id
);
#endif
vlc_epg_t
*
p_epg
=
vlc_epg_New
(
NULL
);
if
(
likely
(
p_epg
)
)
{
(
void
)
ATSC_AddVLCEPGEvent
(
p_demux
,
p_basectx
,
p_event
,
p_ett
,
p_epg
);
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_GROUP_EPG
,
(
int
)
i_program_number
,
p_epg
);
#ifdef ATSC_DEBUG_EIT
msg_Dbg
(
p_demux
,
"Updated event %x with ETT"
,
p_event
->
i_event_id
);
#endif
vlc_epg_Delete
(
p_epg
);
}
}
/* Insert to avoid duplicated event, and to be available to EIT if didn't appear yet */
ATSC_InsertETTOrdered
(
p_ctx
,
p_ett
);
ATSC_CleanETTByChannelVersion
(
p_ctx
,
i_vchannel_id
,
p_ett
->
i_version
);
return
;
}
}
}
dvbpsi_atsc_DeleteETT
(
p_ett
);
}
static
void
ATSC_ETT_RawCallback
(
dvbpsi_t
*
p_handle
,
const
dvbpsi_psi_section_t
*
p_section
,
void
*
p_base_pid
)
{
VLC_UNUSED
(
p_handle
);
dvbpsi_atsc_ett_t
*
p_ett
=
DVBPlague_ETT_Decode
(
p_section
);
if
(
p_ett
)
/* Send to real callback */
ATSC_ETT_Callback
(
p_base_pid
,
p_ett
);
}
static
void
ATSC_VCT_Callback
(
void
*
p_cb_basepid
,
dvbpsi_atsc_vct_t
*
p_vct
)
...
...
@@ -410,6 +650,9 @@ static void ATSC_MGT_Callback( void *p_cb_basepid, dvbpsi_atsc_mgt_t* p_mgt )
}
}
if
(
p_mgtpsip
->
p_ctx
->
p_mgt
)
dvbpsi_atsc_DeleteMGT
(
p_mgtpsip
->
p_ctx
->
p_mgt
);
p_mgtpsip
->
p_ctx
->
p_mgt
=
p_mgt
;
p_mgtpsip
->
i_version
=
p_mgt
->
i_version
;
for
(
const
dvbpsi_atsc_mgt_table_t
*
p_tab
=
p_mgt
->
p_first_table
;
...
...
@@ -434,11 +677,27 @@ static void ATSC_MGT_Callback( void *p_cb_basepid, dvbpsi_atsc_mgt_t* p_mgt )
if
(
PIDSetup
(
p_demux
,
TYPE_PSIP
,
pid
,
NULL
)
)
{
SetPIDFilter
(
p_demux
->
p_sys
,
pid
,
true
);
pid
->
u
.
p_psip
->
p_ctx
->
i_tabletype
=
p_tab
->
i_table_type
;
ATSC_Ready_SubDecoders
(
pid
->
u
.
p_psip
->
handle
,
pid
);
msg_Dbg
(
p_demux
,
" * pid=%d reserved for ATSC EIT"
,
pid
->
i_pid
);
ARRAY_APPEND
(
p_mgtpsip
->
eit
,
pid
);
}
}
else
if
(
p_tab
->
i_table_type
>=
ATSC_TABLE_TYPE_ETT_0
&&
p_tab
->
i_table_type
<=
ATSC_TABLE_TYPE_ETT_0
+
ATSC_EIT_MAX_DEPTH_MIN1
&&
p_tab
->
i_table_type
<=
ATSC_TABLE_TYPE_ETT_127
&&
p_tab
->
i_table_type_pid
!=
p_base_pid
->
i_pid
)
{
ts_pid_t
*
pid
=
GetPID
(
p_demux
->
p_sys
,
p_tab
->
i_table_type_pid
);
if
(
PIDSetup
(
p_demux
,
TYPE_PSIP
,
pid
,
NULL
)
)
{
SetPIDFilter
(
p_demux
->
p_sys
,
pid
,
true
);
pid
->
u
.
p_psip
->
p_ctx
->
i_tabletype
=
p_tab
->
i_table_type
;
ATSC_Ready_SubDecoders
(
pid
->
u
.
p_psip
->
handle
,
pid
);
msg_Dbg
(
p_demux
,
" * pid=%d reserved for ATSC ETT"
,
pid
->
i_pid
);
ARRAY_APPEND
(
p_mgtpsip
->
eit
,
pid
);
}
}
msg_Dbg
(
p_demux
,
" * pid=%d transport for ATSC PSIP type %x"
,
p_tab
->
i_table_type_pid
,
p_tab
->
i_table_type
);
}
...
...
@@ -449,8 +708,6 @@ static void ATSC_MGT_Callback( void *p_cb_basepid, dvbpsi_atsc_mgt_t* p_mgt )
{
msg_Dbg
(
p_demux
,
" * pid=%d listening for EAS"
,
p_base_pid
->
i_pid
);
}
dvbpsi_atsc_DeleteMGT
(
p_mgt
);
}
static
void
ATSC_STT_Callback
(
void
*
p_cb_basepid
,
dvbpsi_atsc_stt_t
*
p_stt
)
...
...
@@ -509,12 +766,16 @@ static void ATSC_NewTable_Callback( dvbpsi_t *p_dvbpsi, uint8_t i_table_id,
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_dvbpsi
->
p_sys
;
assert
(
((
ts_pid_t
*
)
p_cb_pid
)
->
type
==
TYPE_PSIP
);
const
ts_pid_t
*
p_base_pid
=
GetPID
(
p_demux
->
p_sys
,
ATSC_BASE_PID
);
const
ts_pid_t
*
p_base_pid
=
ts_pid_Get
(
&
p_demux
->
p_sys
->
pids
,
ATSC_BASE_PID
);
if
(
!
p_base_pid
->
u
.
p_psip
->
p_ctx
->
p_vct
)
return
;
switch
(
i_table_id
)
{
case
ATSC_ETT_TABLE_ID
:
ATSC_ATTACH_WITH_FIXED_DECODER
(
p_dvbpsi
,
ETT
,
ATSC_ETT_TABLE_ID
,
i_extension
,
p_cb_pid
);
break
;
case
ATSC_EIT_TABLE_ID
:
ATSC_ATTACH
(
p_dvbpsi
,
EIT
,
ATSC_EIT_TABLE_ID
,
i_extension
,
p_cb_pid
);
break
;
...
...
modules/demux/mpeg/ts_streams_private.h
View file @
141d5e26
...
...
@@ -125,6 +125,9 @@ struct ts_psip_t
int
i_version
;
ts_pes_es_t
*
p_eas_es
;
ts_psip_context_t
*
p_ctx
;
/* Used to track list of active pid for eit/ett, to call PIDRelease on them.
VCT table could have been used, but PIDSetup can fail, and we can't alter
the VCT table accordingly without going ahead of more troubles */
DECL_ARRAY
(
ts_pid_t
*
)
eit
;
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment