Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
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-gpu
Commits
28e9ed29
Commit
28e9ed29
authored
Jul 07, 2004
by
Gildas Bazin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/demux/mp4/mp4.c: a couple of fixes for track selection when seeking.
parent
85f1cd8a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
65 additions
and
76 deletions
+65
-76
modules/demux/mp4/mp4.c
modules/demux/mp4/mp4.c
+65
-76
No files found.
modules/demux/mp4/mp4.c
View file @
28e9ed29
...
@@ -496,7 +496,8 @@ static int Demux( demux_t *p_demux )
...
@@ -496,7 +496,8 @@ static int Demux( demux_t *p_demux )
unsigned
int
i_track_selected
;
unsigned
int
i_track_selected
;
/* check for newly selected/unselected track */
/* check for newly selected/unselected track */
for
(
i_track
=
0
,
i_track_selected
=
0
;
i_track
<
p_sys
->
i_tracks
;
i_track
++
)
for
(
i_track
=
0
,
i_track_selected
=
0
;
i_track
<
p_sys
->
i_tracks
;
i_track
++
)
{
{
mp4_track_t
*
tk
=
&
p_sys
->
track
[
i_track
];
mp4_track_t
*
tk
=
&
p_sys
->
track
[
i_track
];
...
@@ -641,8 +642,8 @@ static int Demux( demux_t *p_demux )
...
@@ -641,8 +642,8 @@ static int Demux( demux_t *p_demux )
}
}
/*****************************************************************************
/*****************************************************************************
* Seek: Got to i_date
* Seek: Got to i_date
******************************************************************************/
******************************************************************************/
static
int
Seek
(
demux_t
*
p_demux
,
mtime_t
i_date
)
static
int
Seek
(
demux_t
*
p_demux
,
mtime_t
i_date
)
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
unsigned
int
i_track
;
unsigned
int
i_track
;
...
@@ -655,13 +656,9 @@ static int Seek ( demux_t *p_demux, mtime_t i_date )
...
@@ -655,13 +656,9 @@ static int Seek ( demux_t *p_demux, mtime_t i_date )
for
(
i_track
=
0
;
i_track
<
p_sys
->
i_tracks
;
i_track
++
)
for
(
i_track
=
0
;
i_track
<
p_sys
->
i_tracks
;
i_track
++
)
{
{
mp4_track_t
*
tk
=
&
p_sys
->
track
[
i_track
];
mp4_track_t
*
tk
=
&
p_sys
->
track
[
i_track
];
if
(
tk
->
b_ok
&&
tk
->
b_selected
)
{
MP4_TrackSeek
(
p_demux
,
tk
,
i_date
);
MP4_TrackSeek
(
p_demux
,
tk
,
i_date
);
}
}
}
return
VLC_SUCCESS
;
return
(
1
);
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -1019,8 +1016,7 @@ static int TrackCreateSamplesIndex( demux_t *p_demux,
...
@@ -1019,8 +1016,7 @@ static int TrackCreateSamplesIndex( demux_t *p_demux,
}
}
msg_Dbg
(
p_demux
,
msg_Dbg
(
p_demux
,
"track[Id 0x%x] read %d samples length:"
I64Fd
"s"
,
"track[Id 0x%x] read %d samples length:"
I64Fd
"s"
,
p_demux_track
->
i_track_ID
,
p_demux_track
->
i_track_ID
,
p_demux_track
->
i_sample_count
,
p_demux_track
->
i_sample_count
,
i_last_dts
/
p_demux_track
->
i_timescale
);
i_last_dts
/
p_demux_track
->
i_timescale
);
...
@@ -1032,10 +1028,8 @@ static int TrackCreateSamplesIndex( demux_t *p_demux,
...
@@ -1032,10 +1028,8 @@ static int TrackCreateSamplesIndex( demux_t *p_demux,
* TrackCreateES:
* TrackCreateES:
* Create ES and PES to init decoder if needed, for a track starting at i_chunk
* Create ES and PES to init decoder if needed, for a track starting at i_chunk
*/
*/
static
int
TrackCreateES
(
demux_t
*
p_demux
,
static
int
TrackCreateES
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
,
mp4_track_t
*
p_track
,
unsigned
int
i_chunk
,
es_out_id_t
**
pp_es
)
unsigned
int
i_chunk
,
es_out_id_t
**
pp_es
)
{
{
MP4_Box_t
*
p_sample
;
MP4_Box_t
*
p_sample
;
MP4_Box_t
*
p_esds
;
MP4_Box_t
*
p_esds
;
...
@@ -1305,10 +1299,8 @@ static int TrackCreateES ( demux_t *p_demux,
...
@@ -1305,10 +1299,8 @@ static int TrackCreateES ( demux_t *p_demux,
/* given a time it return sample/chunk
/* given a time it return sample/chunk
* it also update elst field of the track
* it also update elst field of the track
*/
*/
static
int
TrackTimeToSampleChunk
(
demux_t
*
p_demux
,
static
int
TrackTimeToSampleChunk
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
,
mp4_track_t
*
p_track
,
int64_t
i_start
,
uint32_t
*
pi_chunk
,
int64_t
i_start
,
uint32_t
*
pi_chunk
,
uint32_t
*
pi_sample
)
uint32_t
*
pi_sample
)
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
...
@@ -1333,7 +1325,7 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
...
@@ -1333,7 +1325,7 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
/* now calculate i_start for this elst */
/* now calculate i_start for this elst */
/* offset */
/* offset */
i_start
-=
p_track
->
i_elst_time
*
(
int64_t
)
1000000
/
p_sys
->
i_timescale
;
i_start
-=
p_track
->
i_elst_time
*
I64C
(
1000000
)
/
p_sys
->
i_timescale
;
if
(
i_start
<
0
)
if
(
i_start
<
0
)
{
{
*
pi_chunk
=
0
;
*
pi_chunk
=
0
;
...
@@ -1351,8 +1343,8 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
...
@@ -1351,8 +1343,8 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
i_start
+=
elst
->
i_media_time
[
p_track
->
i_elst
];
i_start
+=
elst
->
i_media_time
[
p_track
->
i_elst
];
}
}
msg_Dbg
(
p_demux
,
"elst (%d) gives "
I64Fd
"ms (movie)-> "
I64Fd
"ms (track)"
,
msg_Dbg
(
p_demux
,
"elst (%d) gives "
I64Fd
"ms (movie)-> "
I64Fd
p_track
->
i_elst
,
"ms (track)"
,
p_track
->
i_elst
,
i_mvt
*
1000
/
p_sys
->
i_timescale
,
i_mvt
*
1000
/
p_sys
->
i_timescale
,
i_start
*
1000
/
p_track
->
i_timescale
);
i_start
*
1000
/
p_track
->
i_timescale
);
}
}
...
@@ -1403,15 +1395,16 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
...
@@ -1403,15 +1395,16 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
{
{
break
;
break
;
}
}
i_sample
+=
(
i_start
-
i_dts
)
/
p_track
->
chunk
[
i_chunk
].
p_sample_delta_dts
[
i_index
];
i_sample
+=
(
i_start
-
i_dts
)
/
p_track
->
chunk
[
i_chunk
].
p_sample_delta_dts
[
i_index
];
break
;
break
;
}
}
}
}
if
(
i_sample
>=
p_track
->
i_sample_count
)
if
(
i_sample
>=
p_track
->
i_sample_count
)
{
{
msg_Warn
(
p_demux
,
msg_Warn
(
p_demux
,
"track[Id 0x%x] will be disabled "
"
track[Id 0x%x] will be disabled
(seeking too far) chunk=%d sample=%d"
,
"(seeking too far) chunk=%d sample=%d"
,
p_track
->
i_track_ID
,
i_chunk
,
i_sample
);
p_track
->
i_track_ID
,
i_chunk
,
i_sample
);
return
(
VLC_EGENERIC
);
return
(
VLC_EGENERIC
);
}
}
...
@@ -1461,9 +1454,8 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
...
@@ -1461,9 +1454,8 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
}
}
else
else
{
{
msg_Dbg
(
p_demux
,
msg_Dbg
(
p_demux
,
"track[Id 0x%x] does not provide Sync "
"track[Id 0x%x] does not provide Sync Sample Box (stss)"
,
"Sample Box (stss)"
,
p_track
->
i_track_ID
);
p_track
->
i_track_ID
);
}
}
*
pi_chunk
=
i_chunk
;
*
pi_chunk
=
i_chunk
;
...
@@ -1472,30 +1464,28 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
...
@@ -1472,30 +1464,28 @@ static int TrackTimeToSampleChunk( demux_t *p_demux,
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
int
TrackGotoChunkSample
(
demux_t
*
p_demux
,
static
int
TrackGotoChunkSample
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
,
mp4_track_t
*
p_track
,
unsigned
int
i_chunk
,
unsigned
int
i_sample
)
unsigned
int
i_chunk
,
unsigned
int
i_sample
)
{
{
vlc_bool_t
b_reselect
=
VLC_FALSE
;
vlc_bool_t
b_reselect
=
VLC_FALSE
;
/* now see if actual es is ok */
/* now see if actual es is ok */
if
(
p_track
->
i_chunk
<
0
||
if
(
p_track
->
i_chunk
<
0
||
p_track
->
i_chunk
>=
p_track
->
i_chunk_count
||
p_track
->
i_chunk
>=
p_track
->
i_chunk_count
-
1
||
p_track
->
chunk
[
p_track
->
i_chunk
].
i_sample_description_index
!=
p_track
->
chunk
[
p_track
->
i_chunk
].
i_sample_description_index
!=
p_track
->
chunk
[
i_chunk
].
i_sample_description_index
)
p_track
->
chunk
[
i_chunk
].
i_sample_description_index
)
{
{
msg_Warn
(
p_demux
,
"recreate ES"
);
msg_Warn
(
p_demux
,
"recreate ES for track[Id 0x%x]"
,
p_track
->
i_track_ID
);
es_out_Control
(
p_demux
->
out
,
ES_OUT_GET_ES_STATE
,
p_track
->
p_es
,
&
b_reselect
);
es_out_Control
(
p_demux
->
out
,
ES_OUT_GET_ES_STATE
,
p_track
->
p_es
,
&
b_reselect
);
es_out_Del
(
p_demux
->
out
,
p_track
->
p_es
);
es_out_Del
(
p_demux
->
out
,
p_track
->
p_es
);
p_track
->
p_es
=
NULL
;
p_track
->
p_es
=
NULL
;
if
(
TrackCreateES
(
p_demux
,
if
(
TrackCreateES
(
p_demux
,
p_track
,
i_chunk
,
&
p_track
->
p_es
)
)
p_track
,
i_chunk
,
&
p_track
->
p_es
)
)
{
{
msg_Err
(
p_demux
,
"cannot create es for track[Id 0x%x]"
,
msg_Err
(
p_demux
,
"cannot create es for track[Id 0x%x]"
,
p_track
->
i_track_ID
);
p_track
->
i_track_ID
);
...
@@ -1524,9 +1514,8 @@ static int TrackGotoChunkSample( demux_t *p_demux,
...
@@ -1524,9 +1514,8 @@ static int TrackGotoChunkSample( demux_t *p_demux,
* Parse track information and create all needed data to run a track
* Parse track information and create all needed data to run a track
* If it succeed b_ok is set to 1 else to 0
* If it succeed b_ok is set to 1 else to 0
****************************************************************************/
****************************************************************************/
static
void
MP4_TrackCreate
(
demux_t
*
p_demux
,
static
void
MP4_TrackCreate
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
,
mp4_track_t
*
p_track
,
MP4_Box_t
*
p_box_trak
)
MP4_Box_t
*
p_box_trak
)
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
...
@@ -1707,7 +1696,9 @@ static void MP4_TrackCreate( demux_t *p_demux,
...
@@ -1707,7 +1696,9 @@ static void MP4_TrackCreate( demux_t *p_demux,
int i;
int i;
for( i = 0; i < p_track->i_chunk_count; i++ )
for( i = 0; i < p_track->i_chunk_count; i++ )
{
{
fprintf( stderr, "%-5d sample_count=%d pts=%lld\n", i, p_track->chunk[i].i_sample_count, p_track->chunk[i].i_first_dts );
fprintf( stderr, "%-5d sample_count=%d pts=%lld\n",
i, p_track->chunk[i].i_sample_count,
p_track->chunk[i].i_first_dts );
}
}
}
}
...
@@ -1720,8 +1711,7 @@ static void MP4_TrackCreate( demux_t *p_demux,
...
@@ -1720,8 +1711,7 @@ static void MP4_TrackCreate( demux_t *p_demux,
****************************************************************************
****************************************************************************
* Destroy a track created by MP4_TrackCreate.
* Destroy a track created by MP4_TrackCreate.
****************************************************************************/
****************************************************************************/
static
void
MP4_TrackDestroy
(
demux_t
*
p_demux
,
static
void
MP4_TrackDestroy
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
)
mp4_track_t
*
p_track
)
{
{
unsigned
int
i_chunk
;
unsigned
int
i_chunk
;
...
@@ -1747,8 +1737,7 @@ static void MP4_TrackDestroy( demux_t *p_demux,
...
@@ -1747,8 +1737,7 @@ static void MP4_TrackDestroy( demux_t *p_demux,
}
}
}
}
static
int
MP4_TrackSelect
(
demux_t
*
p_demux
,
static
int
MP4_TrackSelect
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
,
mp4_track_t
*
p_track
,
mtime_t
i_start
)
mtime_t
i_start
)
{
{
if
(
!
p_track
->
b_ok
)
if
(
!
p_track
->
b_ok
)
...
@@ -1758,8 +1747,7 @@ static int MP4_TrackSelect ( demux_t *p_demux,
...
@@ -1758,8 +1747,7 @@ static int MP4_TrackSelect ( demux_t *p_demux,
if
(
p_track
->
b_selected
)
if
(
p_track
->
b_selected
)
{
{
msg_Warn
(
p_demux
,
msg_Warn
(
p_demux
,
"track[Id 0x%x] already selected"
,
"track[Id 0x%x] already selected"
,
p_track
->
i_track_ID
);
p_track
->
i_track_ID
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -1767,8 +1755,7 @@ static int MP4_TrackSelect ( demux_t *p_demux,
...
@@ -1767,8 +1755,7 @@ static int MP4_TrackSelect ( demux_t *p_demux,
return
MP4_TrackSeek
(
p_demux
,
p_track
,
i_start
);
return
MP4_TrackSeek
(
p_demux
,
p_track
,
i_start
);
}
}
static
void
MP4_TrackUnselect
(
demux_t
*
p_demux
,
static
void
MP4_TrackUnselect
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
)
mp4_track_t
*
p_track
)
{
{
if
(
!
p_track
->
b_ok
)
if
(
!
p_track
->
b_ok
)
{
{
...
@@ -1777,21 +1764,20 @@ static void MP4_TrackUnselect(demux_t *p_demux,
...
@@ -1777,21 +1764,20 @@ static void MP4_TrackUnselect(demux_t *p_demux,
if
(
!
p_track
->
b_selected
)
if
(
!
p_track
->
b_selected
)
{
{
msg_Warn
(
p_demux
,
msg_Warn
(
p_demux
,
"track[Id 0x%x] already unselected"
,
"track[Id 0x%x] already unselected"
,
p_track
->
i_track_ID
);
p_track
->
i_track_ID
);
return
;
return
;
}
}
if
(
p_track
->
p_es
)
if
(
p_track
->
p_es
)
{
{
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_ES_STATE
,
p_track
->
p_es
,
VLC_FALSE
);
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_ES_STATE
,
p_track
->
p_es
,
VLC_FALSE
);
}
}
p_track
->
b_selected
=
VLC_FALSE
;
p_track
->
b_selected
=
VLC_FALSE
;
}
}
static
int
MP4_TrackSeek
(
demux_t
*
p_demux
,
static
int
MP4_TrackSeek
(
demux_t
*
p_demux
,
mp4_track_t
*
p_track
,
mp4_track_t
*
p_track
,
mtime_t
i_start
)
mtime_t
i_start
)
{
{
uint32_t
i_chunk
;
uint32_t
i_chunk
;
...
@@ -1802,21 +1788,22 @@ static int MP4_TrackSeek ( demux_t *p_demux,
...
@@ -1802,21 +1788,22 @@ static int MP4_TrackSeek ( demux_t *p_demux,
return
(
VLC_EGENERIC
);
return
(
VLC_EGENERIC
);
}
}
if
(
TrackTimeToSampleChunk
(
p_demux
,
p_track
->
b_selected
=
VLC_FALSE
;
p_track
,
i_start
,
if
(
TrackTimeToSampleChunk
(
p_demux
,
p_track
,
i_start
,
&
i_chunk
,
&
i_sample
)
)
&
i_chunk
,
&
i_sample
)
)
{
{
msg_Warn
(
p_demux
,
msg_Warn
(
p_demux
,
"cannot select track[Id 0x%x]"
,
"cannot select track[Id 0x%x]"
,
p_track
->
i_track_ID
);
p_track
->
i_track_ID
);
return
(
VLC_EGENERIC
);
return
(
VLC_EGENERIC
);
}
}
p_track
->
b_selected
=
VLC_TRUE
;
p_track
->
b_selected
=
VLC_TRUE
;
if
(
TrackGotoChunkSample
(
p_demux
,
p_track
,
i_chunk
,
i_sample
)
)
if
(
TrackGotoChunkSample
(
p_demux
,
p_track
,
i_chunk
,
i_sample
)
==
VLC_SUCCESS
)
{
{
p_track
->
b_selected
=
VLC_
FALS
E
;
p_track
->
b_selected
=
VLC_
TRU
E
;
}
}
return
(
p_track
->
b_selected
?
VLC_SUCCESS
:
VLC_EGENERIC
);
return
(
p_track
->
b_selected
?
VLC_SUCCESS
:
VLC_EGENERIC
);
}
}
...
@@ -1954,12 +1941,11 @@ static int MP4_TrackNextSample( demux_t *p_demux,
...
@@ -1954,12 +1941,11 @@ static int MP4_TrackNextSample( demux_t *p_demux,
p_track
->
chunk
[
p_track
->
i_chunk
].
i_sample_first
+
p_track
->
chunk
[
p_track
->
i_chunk
].
i_sample_first
+
p_track
->
chunk
[
p_track
->
i_chunk
].
i_sample_count
)
p_track
->
chunk
[
p_track
->
i_chunk
].
i_sample_count
)
{
{
if
(
TrackGotoChunkSample
(
p_demux
,
if
(
TrackGotoChunkSample
(
p_demux
,
p_track
,
p_track
->
i_chunk
+
1
,
p_track
,
p_track
->
i_chunk
+
1
,
p_track
->
i_sample
)
)
p_track
->
i_sample
)
)
{
{
msg_Warn
(
p_demux
,
"track[0x%x] will be disabled (cannot restart decoder)"
,
p_track
->
i_track_ID
);
msg_Warn
(
p_demux
,
"track[0x%x] will be disabled "
"(cannot restart decoder)"
,
p_track
->
i_track_ID
);
MP4_TrackUnselect
(
p_demux
,
p_track
);
MP4_TrackUnselect
(
p_demux
,
p_track
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
@@ -1970,19 +1956,23 @@ static int MP4_TrackNextSample( demux_t *p_demux,
...
@@ -1970,19 +1956,23 @@ static int MP4_TrackNextSample( demux_t *p_demux,
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
MP4_Box_data_elst_t
*
elst
=
p_track
->
p_elst
->
data
.
p_elst
;
MP4_Box_data_elst_t
*
elst
=
p_track
->
p_elst
->
data
.
p_elst
;
int64_t
i_mvt
=
MP4_TrackGetPTS
(
p_demux
,
p_track
)
*
p_sys
->
i_timescale
/
(
int64_t
)
1000000
;
int64_t
i_mvt
=
MP4_TrackGetPTS
(
p_demux
,
p_track
)
*
p_sys
->
i_timescale
/
(
int64_t
)
1000000
;
if
(
p_track
->
i_elst
<
elst
->
i_entry_count
&&
if
(
p_track
->
i_elst
<
elst
->
i_entry_count
&&
i_mvt
>=
p_track
->
i_elst_time
+
elst
->
i_segment_duration
[
p_track
->
i_elst
]
)
i_mvt
>=
p_track
->
i_elst_time
+
elst
->
i_segment_duration
[
p_track
->
i_elst
]
)
{
{
MP4_TrackSetELST
(
p_demux
,
p_track
,
MP4_TrackGetPTS
(
p_demux
,
p_track
)
);
MP4_TrackSetELST
(
p_demux
,
p_track
,
MP4_TrackGetPTS
(
p_demux
,
p_track
)
);
}
}
}
}
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
void
MP4_TrackSetELST
(
demux_t
*
p_demux
,
mp4_track_t
*
tk
,
int64_t
i_time
)
static
void
MP4_TrackSetELST
(
demux_t
*
p_demux
,
mp4_track_t
*
tk
,
int64_t
i_time
)
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
int
i_elst_last
=
tk
->
i_elst
;
int
i_elst_last
=
tk
->
i_elst
;
...
@@ -2024,4 +2014,3 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk, int64_t i_time
...
@@ -2024,4 +2014,3 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk, int64_t i_time
msg_Warn
(
p_demux
,
"elst old=%d new=%d"
,
i_elst_last
,
tk
->
i_elst
);
msg_Warn
(
p_demux
,
"elst old=%d new=%d"
,
i_elst_last
,
tk
->
i_elst
);
}
}
}
}
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