Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
6eddafe7
Commit
6eddafe7
authored
Jan 17, 2013
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
asf demux: rewrite DemuxPacket
Split it in several functions
parent
dee92870
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
205 additions
and
215 deletions
+205
-215
modules/demux/asf/asf.c
modules/demux/asf/asf.c
+205
-215
No files found.
modules/demux/asf/asf.c
View file @
6eddafe7
...
...
@@ -408,289 +408,279 @@ static inline int GetValue2b(int *var, const uint8_t *p, int *skip, int left, in
}
}
st
atic
int
DemuxPacket
(
demux_t
*
p_demux
)
st
ruct
asf_packet_t
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
int
i_data_packet_min
=
p_sys
->
p_fp
->
i_min_data_packet_size
;
const
uint8_t
*
p_peek
;
int
property
;
int
length
;
int
padding_length
;
uint32_t
send_time
;
bool
multiple
;
int
length_type
;
/* buffer handling for this ASF packet */
int
i_skip
;
int
peek_size
;
if
(
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
i_data_packet_min
)
<
i_data_packet_min
)
{
msg_Warn
(
p_demux
,
"cannot peek while getting new packet, EOF ?"
);
return
0
;
}
peek_size
=
i_data_packet_min
;
i_skip
=
0
;
const
uint8_t
*
p_peek
;
int
left
;
};
/* *** parse error correction if present *** */
if
(
p_peek
[
0
]
&
0x80
)
{
unsigned
int
i_error_correction_data_length
=
p_peek
[
0
]
&
0x0f
;
unsigned
int
i_opaque_data_present
=
(
p_peek
[
0
]
>>
4
)
&
0x01
;
unsigned
int
i_error_correction_length_type
=
(
p_peek
[
0
]
>>
5
)
&
0x03
;
i_skip
+=
1
;
// skip error correction flags
static
void
SendPacket
(
demux_t
*
p_demux
,
asf_track_t
*
tk
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
if
(
i_error_correction_length_type
!=
0x00
||
i_opaque_data_present
!=
0
||
i_error_correction_data_length
!=
0x02
)
{
goto
loop_error_recovery
;
}
block_t
*
p_gather
=
block_ChainGather
(
tk
->
p_frame
);
i_skip
+=
i_error_correction_data_length
;
}
else
{
msg_Warn
(
p_demux
,
"p_peek[0]&0x80 != 0x80"
);
}
if
(
p_gather
->
i_dts
>
VLC_TS_INVALID
)
tk
->
i_time
=
p_gather
->
i_dts
-
VLC_TS_0
;
/* sanity check */
if
(
i_skip
+
2
>=
i_data_packet_min
)
{
goto
loop_error_recovery
;
}
if
(
p_sys
->
i_time
<
0
)
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
p_gather
->
i_dts
);
int
i_packet_flags
=
p_peek
[
i_skip
];
i_skip
++
;
int
i_packet_property
=
p_peek
[
i_skip
];
i_skip
++
;
int
b_packet_multiple_payload
=
i_packet_flags
&
0x01
;
es_out_Send
(
p_demux
->
out
,
tk
->
p_es
,
p_gather
);
int
i_packet_length
=
i_data_packet_min
;
int
i_packet_sequence
=
0
;
int
i_packet_padding_length
=
0
;
tk
->
p_frame
=
NULL
;
}
if
(
GetValue2b
(
&
i_packet_length
,
p_peek
,
&
i_skip
,
peek_size
-
i_skip
,
i_packet_flags
>>
5
)
<
0
)
goto
loop_error_recovery
;
if
(
GetValue2b
(
&
i_packet_sequence
,
p_peek
,
&
i_skip
,
peek_size
-
i_skip
,
i_packet_flags
>>
1
)
<
0
)
goto
loop_error_recovery
;
if
(
GetValue2b
(
&
i_packet_padding_length
,
p_peek
,
&
i_skip
,
peek_size
-
i_skip
,
i_packet_flags
>>
3
)
<
0
)
goto
loop_error_recovery
;
static
int
DemuxSubPayload
(
demux_t
*
p_demux
,
asf_track_t
*
tk
,
int
i_sub_payload_data_length
,
mtime_t
i_pts
,
int
i_media_object_offset
)
{
/* FIXME I don't use i_media_object_number, sould I ? */
if
(
tk
->
p_frame
&&
i_media_object_offset
==
0
)
SendPacket
(
p_demux
,
tk
)
;
if
(
i_packet_padding_length
>
i_packet_length
)
{
msg_Warn
(
p_demux
,
"
Too large padding: %d"
,
i_packet_padding_length
);
goto
loop_error_recovery
;
block_t
*
p_frag
=
stream_Block
(
p_demux
->
s
,
i_sub_payload_data_length
);
if
(
p_frag
==
NULL
)
{
msg_Warn
(
p_demux
,
"
cannot read data"
);
return
-
1
;
}
if
(
i_packet_length
<
i_data_packet_min
)
{
/* if packet length too short, there is extra padding */
i
_packet_padding_length
+=
i_data_packet_min
-
i_packet_length
;
i_packet_length
=
i_data_packet_min
;
if
(
tk
->
p_frame
==
NULL
)
{
p_frag
->
i_pts
=
VLC_TS_0
+
i_pts
;
p_frag
->
i_dts
=
VLC_TS_0
+
p_frag
->
i_pts
;
//FIXME: VLC_TS_0 * 2 ?
i
f
(
tk
->
i_cat
==
VIDEO_ES
)
p_frag
->
i_pts
=
VLC_TS_INVALID
;
}
uint32_t
i_packet_send_time
=
GetDWLE
(
p_peek
+
i_skip
);
i_skip
+=
4
;
/* uint16_t i_packet_duration = GetWLE( p_peek + i_skip ); */
i_skip
+=
2
;
block_ChainAppend
(
&
tk
->
p_frame
,
p_frag
);
int
i_packet_size_left
=
i_packet_length
;
return
0
;
}
int
i_payload_count
=
1
;
int
i_payload_length_type
=
0x02
;
//unused
if
(
b_packet_multiple_payload
)
{
i_payload_count
=
p_peek
[
i_skip
]
&
0x3f
;
i_payload_length_type
=
(
p_peek
[
i_skip
]
>>
6
)
&
0x03
;
i_skip
++
;
}
static
int
DemuxPayload
(
demux_t
*
p_demux
,
struct
asf_packet_t
*
pkt
,
int
i_payload
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
if
(
pkt
->
i_skip
>=
pkt
->
left
)
return
-
1
;
int
i_packet_keyframe
=
pkt
->
p_peek
[
pkt
->
i_skip
]
>>
7
;
unsigned
int
i_stream_number
=
pkt
->
p_peek
[
pkt
->
i_skip
++
]
&
0x7f
;
for
(
int
i_payload
=
0
;
i_payload
<
i_payload_count
;
i_payload
++
)
{
int
i_media_object_number
=
0
;
int
i_media_object_offset
;
if
(
GetValue2b
(
&
i_media_object_number
,
pkt
->
p_peek
,
&
pkt
->
i_skip
,
pkt
->
left
-
pkt
->
i_skip
,
pkt
->
property
>>
4
)
<
0
)
return
-
1
;
int
i_media_object_offset
=
0
;
if
(
GetValue2b
(
&
i_media_object_offset
,
pkt
->
p_peek
,
&
pkt
->
i_skip
,
pkt
->
left
-
pkt
->
i_skip
,
pkt
->
property
>>
2
)
<
0
)
return
-
1
;
int
i_replicated_data_length
=
0
;
int
i_payload_data_length
=
0
;
int
i_sub_payload_data_length
;
int
i_tmp
=
0
;
if
(
GetValue2b
(
&
i_replicated_data_length
,
pkt
->
p_peek
,
&
pkt
->
i_skip
,
pkt
->
left
-
pkt
->
i_skip
,
pkt
->
property
)
<
0
)
return
-
1
;
mtime_t
i_pts
;
mtime_t
i_pts_delta
;
if
(
i_skip
>=
i_packet_size_left
)
{
/* prevent some segfault with invalid file */
break
;
}
int
i_packet_keyframe
=
p_peek
[
i_skip
]
>>
7
;
unsigned
int
i_stream_number
=
p_peek
[
i_skip
++
]
&
0x7f
;
if
(
GetValue2b
(
&
i_media_object_number
,
p_peek
,
&
i_skip
,
peek_size
-
i_skip
,
i_packet_property
>>
4
)
<
0
)
break
;
if
(
GetValue2b
(
&
i_tmp
,
p_peek
,
&
i_skip
,
peek_size
-
i_skip
,
i_packet_property
>>
2
)
<
0
)
break
;
if
(
GetValue2b
(
&
i_replicated_data_length
,
p_peek
,
&
i_skip
,
peek_size
-
i_skip
,
i_packet_property
)
<
0
)
break
;
if
(
i_replicated_data_length
>
1
)
// should be at least 8 bytes
{
i_pts
=
(
mtime_t
)
GetDWLE
(
p_peek
+
i_skip
+
4
)
*
1000
;
i_skip
+=
i_replicated_data_length
;
i_pts_delta
=
0
;
i_pts
=
(
mtime_t
)
GetDWLE
(
pkt
->
p_peek
+
pkt
->
i_skip
+
4
);
pkt
->
i_skip
+=
i_replicated_data_length
;
i_media_object_offset
=
i_tmp
;
if
(
i_skip
>=
i_packet_size_left
)
{
break
;
}
if
(
pkt
->
i_skip
>=
pkt
->
left
)
return
-
1
;
}
else
if
(
i_replicated_data_length
==
1
)
{
/* msg_Dbg( p_demux, "found compressed payload" ); */
i_pts
=
(
mtime_t
)
i_tmp
*
1000
;
i_pts_delta
=
(
mtime_t
)
p_peek
[
i_skip
]
*
1000
;
i_skip
++
;
i_pts
=
(
mtime_t
)
i_media_object_offset
+
(
mtime_t
)
pkt
->
p_peek
[
pkt
->
i_skip
]
*
i_payload
;
pkt
->
i_skip
++
;
i_media_object_offset
=
0
;
}
else
{
i_pts
=
(
mtime_t
)
i_packet_send_time
*
1000
;
i_pts_delta
=
0
;
i_media_object_offset
=
i_tmp
;
i_pts
=
(
mtime_t
)
pkt
->
send_time
*
1000
;
}
i_pts
=
__MAX
(
i_pts
-
p_sys
->
p_fp
->
i_preroll
*
1000
,
0
);
if
(
b_packet_multiple_payload
)
{
i_payload_data_length
=
0
;
if
(
GetValue2b
(
&
i_payload_data_length
,
p_peek
,
&
i_skip
,
peek_size
-
i_skip
,
i_payload_length_type
)
<
0
)
break
;
}
else
{
i_payload_data_length
=
i_packet_length
-
i_packet_padding_length
-
i_skip
;
}
i_pts
-=
p_sys
->
p_fp
->
i_preroll
;
if
(
i_pts
<
0
)
i_pts
=
0
;
// FIXME?
i_pts
*=
1000
;
// FIXME ?
int
i_payload_data_length
=
0
;
if
(
pkt
->
multiple
)
{
if
(
GetValue2b
(
&
i_payload_data_length
,
pkt
->
p_peek
,
&
pkt
->
i_skip
,
pkt
->
left
-
pkt
->
i_skip
,
pkt
->
length_type
)
<
0
)
return
-
1
;
}
else
i_payload_data_length
=
pkt
->
length
-
pkt
->
padding_length
-
pkt
->
i_skip
;
if
(
i_payload_data_length
<
0
||
i_payload_data_length
>
pkt
->
left
)
return
-
1
;
if
(
i_payload_data_length
<
0
||
i_payload_data_length
>
i_packet_size_left
)
{
break
;
}
#ifdef ASF_DEBUG
msg_Dbg
(
p_demux
,
"payload(%d/
%d) stream_number:%d media_object_number:%d media_object_offset:%d replicated_data_length:%d payload_data_length %d"
,
i_payload
+
1
,
i_payload_count
,
i_stream_number
,
i_media_object_number
,
"payload(
%d) stream_number:%d media_object_number:%d media_object_offset:%d replicated_data_length:%d payload_data_length %d"
,
i_payload
+
1
,
i_stream_number
,
i_media_object_number
,
i_media_object_offset
,
i_replicated_data_length
,
i_payload_data_length
);
#endif
asf_track_t
*
tk
=
p_sys
->
track
[
i_stream_number
];
if
(
tk
==
NULL
)
{
msg_Warn
(
p_demux
,
"undeclared stream[Id 0x%x]"
,
i_stream_number
);
i_skip
+=
i_payload_data_length
;
continue
;
// over payload
msg_Warn
(
p_demux
,
"undeclared stream[Id 0x%x]"
,
i_stream_number
);
goto
skip
;
}
if
(
p_sys
->
i_wait_keyframe
&&
!
(
i_stream_number
==
p_sys
->
i_seek_track
&&
i_packet_keyframe
&&
!
i_media_object_offset
)
)
if
(
p_sys
->
i_wait_keyframe
&&
!
i_media_object_offset
&&
(
i_stream_number
!=
p_sys
->
i_seek_track
||
!
i_packet_keyframe
)
)
{
i_skip
+=
i_payload_data_length
;
p_sys
->
i_wait_keyframe
--
;
continue
;
// over payload
goto
skip
;
}
p_sys
->
i_wait_keyframe
=
0
;
if
(
!
tk
->
p_es
)
goto
skip
;
while
(
i_payload_data_length
)
{
i_skip
+
=
i_payload_data_length
;
continue
;
}
int
i_sub_payload_data_length
=
i_payload_data_length
;
if
(
i_replicated_data_length
==
1
)
i_sub_payload_data_length
=
pkt
->
p_peek
[
pkt
->
i_skip
++
];
stream_Read
(
p_demux
->
s
,
NULL
,
pkt
->
i_skip
);
for
(
int
i_payload_data_pos
=
0
;
i_payload_data_pos
<
i_payload_data_length
&&
i_packet_size_left
>
0
;
i_payload_data_pos
+=
i_sub_payload_data_length
)
{
block_t
*
p_frag
;
int
i_read
;
if
(
DemuxSubPayload
(
p_demux
,
tk
,
i_sub_payload_data_length
,
i_pts
,
i_media_object_offset
)
<
0
)
return
-
1
;
// read sub payload length
if
(
i_replicated_data_length
==
1
)
{
i_sub_payload_data_length
=
p_peek
[
i_skip
];
i_skip
++
;
i_payload_data_pos
++
;
}
else
{
i_sub_payload_data_length
=
i_payload_data_length
;
pkt
->
left
-=
pkt
->
i_skip
+
i_sub_payload_data_length
;
pkt
->
i_skip
=
0
;
if
(
pkt
->
left
>
0
&&
stream_Peek
(
p_demux
->
s
,
&
pkt
->
p_peek
,
pkt
->
left
)
<
pkt
->
left
)
{
msg_Warn
(
p_demux
,
"cannot peek, EOF ?"
);
return
-
1
;
}
/* FIXME I don't use i_media_object_number, sould I ? */
if
(
tk
->
p_frame
&&
i_media_object_offset
==
0
)
{
/* send complete packet to decoder */
block_t
*
p_gather
=
block_ChainGather
(
tk
->
p_frame
);
i_payload_data_length
-=
i_sub_payload_data_length
;
}
if
(
p_gather
->
i_dts
>
VLC_TS_INVALID
)
tk
->
i_time
=
p_gather
->
i_dts
-
VLC_TS_0
;
return
0
;
if
(
p_sys
->
i_time
<
0
)
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
VLC_TS_0
+
tk
->
i_time
);
skip:
pkt
->
i_skip
+=
i_payload_data_length
;
return
0
;
}
es_out_Send
(
p_demux
->
out
,
tk
->
p_es
,
p_gather
);
static
int
DemuxPacket
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
tk
->
p_frame
=
NULL
;
}
int
i_data_packet_min
=
p_sys
->
p_fp
->
i_min_data_packet_size
;
i_read
=
i_sub_payload_data_length
+
i_skip
;
if
(
(
p_frag
=
stream_Block
(
p_demux
->
s
,
i_read
)
)
==
NULL
)
const
uint8_t
*
p_peek
;
if
(
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
i_data_packet_min
)
<
i_data_packet_min
)
{
msg_Warn
(
p_demux
,
"cannot read data
"
);
msg_Warn
(
p_demux
,
"cannot peek while getting new packet, EOF ?
"
);
return
0
;
}
i_packet_size_left
-=
i_read
;
peek_size
=
0
;
int
i_skip
=
0
;
p_frag
->
p_buffer
+=
i_skip
;
p_frag
->
i_buffer
-=
i_skip
;
/* *** parse error correction if present *** */
if
(
p_peek
[
0
]
&
0x80
)
{
unsigned
int
i_error_correction_data_length
=
p_peek
[
0
]
&
0x0f
;
unsigned
int
i_opaque_data_present
=
(
p_peek
[
0
]
>>
4
)
&
0x01
;
unsigned
int
i_error_correction_length_type
=
(
p_peek
[
0
]
>>
5
)
&
0x03
;
i_skip
+=
1
;
// skip error correction flags
if
(
tk
->
p_frame
==
NULL
)
if
(
i_error_correction_length_type
!=
0x00
||
i_opaque_data_present
!=
0
||
i_error_correction_data_length
!=
0x02
)
{
p_frag
->
i_pts
=
VLC_TS_0
+
i_pts
+
i_payload
*
(
mtime_t
)
i_pts_delta
;
if
(
tk
->
i_cat
!=
VIDEO_ES
)
p_frag
->
i_dts
=
VLC_TS_0
+
p_frag
->
i_pts
;
goto
loop_error_recovery
;
}
i_skip
+=
i_error_correction_data_length
;
}
else
msg_Warn
(
p_demux
,
"no error correction"
);
/* sanity check */
if
(
i_skip
+
2
>=
i_data_packet_min
)
goto
loop_error_recovery
;
struct
asf_packet_t
pkt
;
int
i_packet_flags
=
p_peek
[
i_skip
];
i_skip
++
;
pkt
.
property
=
p_peek
[
i_skip
];
i_skip
++
;
pkt
.
multiple
=
!!
(
i_packet_flags
&
0x01
);
pkt
.
length
=
i_data_packet_min
;
pkt
.
padding_length
=
0
;
if
(
GetValue2b
(
&
pkt
.
length
,
p_peek
,
&
i_skip
,
i_data_packet_min
-
i_skip
,
i_packet_flags
>>
5
)
<
0
)
goto
loop_error_recovery
;
int
i_packet_sequence
;
if
(
GetValue2b
(
&
i_packet_sequence
,
p_peek
,
&
i_skip
,
i_data_packet_min
-
i_skip
,
i_packet_flags
>>
1
)
<
0
)
goto
loop_error_recovery
;
if
(
GetValue2b
(
&
pkt
.
padding_length
,
p_peek
,
&
i_skip
,
i_data_packet_min
-
i_skip
,
i_packet_flags
>>
3
)
<
0
)
goto
loop_error_recovery
;
if
(
pkt
.
padding_length
>
pkt
.
length
)
{
p_frag
->
i_dts
=
VLC_TS_0
+
p_frag
->
i_pts
;
p_frag
->
i_pts
=
VLC_TS_INVALID
;
msg_Warn
(
p_demux
,
"Too large padding: %d"
,
pkt
.
padding_length
)
;
goto
loop_error_recovery
;
}
if
(
pkt
.
length
<
i_data_packet_min
)
{
/* if packet length too short, there is extra padding */
pkt
.
padding_length
+=
i_data_packet_min
-
pkt
.
length
;
pkt
.
length
=
i_data_packet_min
;
}
block_ChainAppend
(
&
tk
->
p_frame
,
p_frag
);
pkt
.
send_time
=
GetDWLE
(
p_peek
+
i_skip
);
i_skip
+=
4
;
/* uint16_t i_packet_duration = GetWLE( p_peek + i_skip ); */
i_skip
+=
2
;
i_skip
=
0
;
if
(
i_packet_size_left
>
0
)
{
if
(
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
i_packet_size_left
)
<
i_packet_size_left
)
if
(
pkt
.
length
<=
0
||
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
pkt
.
length
)
<
pkt
.
length
)
{
msg_Warn
(
p_demux
,
"cannot peek, EOF ?"
);
return
0
;
}
peek_size
=
i_packet_size_left
;
}
}
int
i_payload_count
=
1
;
pkt
.
length_type
=
0x02
;
//unused
if
(
pkt
.
multiple
)
{
i_payload_count
=
p_peek
[
i_skip
]
&
0x3f
;
pkt
.
length_type
=
(
p_peek
[
i_skip
]
>>
6
)
&
0x03
;
i_skip
++
;
}
if
(
i_packet_size_left
>
0
)
#ifdef ASF_DEBUG
msg_Dbg
(
p_demux
,
"%d payloads"
,
i_payload_count
);
#endif
pkt
.
i_skip
=
i_skip
;
pkt
.
p_peek
=
p_peek
;
pkt
.
left
=
pkt
.
length
;
for
(
int
i_payload
=
0
;
i_payload
<
i_payload_count
;
i_payload
++
)
if
(
DemuxPayload
(
p_demux
,
&
pkt
,
i_payload
)
<
0
)
return
0
;
if
(
pkt
.
left
>
0
)
{
#ifdef ASF_DEBUG
if
(
i_packet_size_left
>
i_packet_
padding_length
)
if
(
pkt
.
left
>
pkt
.
padding_length
)
msg_Warn
(
p_demux
,
"Didn't read %d bytes in the packet"
,
i_packet_size_left
-
i_packet_
padding_length
);
else
if
(
i_packet_size_left
<
i_packet_
padding_length
)
pkt
.
left
-
pkt
.
padding_length
);
else
if
(
pkt
.
left
<
pkt
.
padding_length
)
msg_Warn
(
p_demux
,
"Read %d too much bytes in the packet"
,
i_packet_padding_length
-
i_packet_size_
left
);
pkt
.
padding_length
-
pkt
.
left
);
#endif
if
(
stream_Read
(
p_demux
->
s
,
NULL
,
i_packet_size_left
)
<
i_packet_size_left
)
if
(
stream_Read
(
p_demux
->
s
,
NULL
,
pkt
.
left
)
<
pkt
.
left
)
{
msg_Err
(
p_demux
,
"cannot skip data, EOF ?"
);
return
0
;
...
...
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