mirror of
https://github.com/mpv-player/mpv
synced 2024-12-18 21:06:00 +00:00
demux_mkv: store streams sequentially in demuxer->[avs]_streams
demux_mkv used the Matroska TrackNumber as the array offset in demuxer stream lists. The TrackNumber entry stored in the file can be an arbitrary 64-bit value, and some of the code could try reading from the arrays with that offset, causing a crash if the file had insane values. Fill the arrays sequentially instead. Also add some checks to make the handling of too high stream counts more robust.
This commit is contained in:
parent
90bedd0b87
commit
fc39d48465
@ -92,6 +92,7 @@ typedef struct mkv_content_encoding {
|
|||||||
typedef struct mkv_track {
|
typedef struct mkv_track {
|
||||||
int tnum;
|
int tnum;
|
||||||
char *name;
|
char *name;
|
||||||
|
int id; // -aid / -sid / -vid option value
|
||||||
|
|
||||||
char *codec_id;
|
char *codec_id;
|
||||||
int ms_compat;
|
int ms_compat;
|
||||||
@ -192,8 +193,7 @@ typedef struct mkv_demuxer {
|
|||||||
int64_t skip_to_timecode;
|
int64_t skip_to_timecode;
|
||||||
int v_skip_to_keyframe, a_skip_to_keyframe;
|
int v_skip_to_keyframe, a_skip_to_keyframe;
|
||||||
|
|
||||||
int last_aid;
|
int num_audio_tracks;
|
||||||
int audio_tracks[MAX_A_STREAMS];
|
|
||||||
} mkv_demuxer_t;
|
} mkv_demuxer_t;
|
||||||
|
|
||||||
#define REALHEADER_SIZE 16
|
#define REALHEADER_SIZE 16
|
||||||
@ -237,14 +237,11 @@ static bool is_parsed_header(struct mkv_demuxer *mkv_d, off_t pos)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mkv_track_t *demux_mkv_find_track_by_num(mkv_demuxer_t *d, int n,
|
static mkv_track_t *find_track_by_num(struct mkv_demuxer *d, int n, int type)
|
||||||
int type)
|
|
||||||
{
|
{
|
||||||
int i, id;
|
for (int i = 0; i < d->num_tracks; i++)
|
||||||
|
|
||||||
for (i = 0, id = 0; i < d->num_tracks; i++)
|
|
||||||
if (d->tracks[i] != NULL && d->tracks[i]->type == type)
|
if (d->tracks[i] != NULL && d->tracks[i]->type == type)
|
||||||
if (id++ == n)
|
if (d->tracks[i]->id == n)
|
||||||
return d->tracks[i];
|
return d->tracks[i];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1094,6 +1091,10 @@ static void display_create_tracks(demuxer_t *demuxer)
|
|||||||
switch (mkv_d->tracks[i]->type) {
|
switch (mkv_d->tracks[i]->type) {
|
||||||
case MATROSKA_TRACK_VIDEO:
|
case MATROSKA_TRACK_VIDEO:
|
||||||
type = "video";
|
type = "video";
|
||||||
|
mkv_d->tracks[i]->id = -1;
|
||||||
|
if (vid == MAX_V_STREAMS)
|
||||||
|
break;
|
||||||
|
mkv_d->tracks[i]->id = vid;
|
||||||
demux_mkv_open_video(demuxer, mkv_d->tracks[i], vid);
|
demux_mkv_open_video(demuxer, mkv_d->tracks[i], vid);
|
||||||
if (mkv_d->tracks[i]->name)
|
if (mkv_d->tracks[i]->name)
|
||||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", vid,
|
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", vid,
|
||||||
@ -1102,6 +1103,10 @@ static void display_create_tracks(demuxer_t *demuxer)
|
|||||||
break;
|
break;
|
||||||
case MATROSKA_TRACK_AUDIO:
|
case MATROSKA_TRACK_AUDIO:
|
||||||
type = "audio";
|
type = "audio";
|
||||||
|
mkv_d->tracks[i]->id = -1;
|
||||||
|
if (aid == MAX_A_STREAMS)
|
||||||
|
break;
|
||||||
|
mkv_d->tracks[i]->id = aid;
|
||||||
demux_mkv_open_audio(demuxer, mkv_d->tracks[i], aid);
|
demux_mkv_open_audio(demuxer, mkv_d->tracks[i], aid);
|
||||||
if (mkv_d->tracks[i]->name)
|
if (mkv_d->tracks[i]->name)
|
||||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", aid,
|
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", aid,
|
||||||
@ -1113,6 +1118,10 @@ static void display_create_tracks(demuxer_t *demuxer)
|
|||||||
break;
|
break;
|
||||||
case MATROSKA_TRACK_SUBTITLE:
|
case MATROSKA_TRACK_SUBTITLE:
|
||||||
type = "subtitles";
|
type = "subtitles";
|
||||||
|
mkv_d->tracks[i]->id = -1;
|
||||||
|
if (sid == MAX_S_STREAMS)
|
||||||
|
break;
|
||||||
|
mkv_d->tracks[i]->id = sid;
|
||||||
demux_mkv_open_sub(demuxer, mkv_d->tracks[i], sid);
|
demux_mkv_open_sub(demuxer, mkv_d->tracks[i], sid);
|
||||||
if (mkv_d->tracks[i]->name)
|
if (mkv_d->tracks[i]->name)
|
||||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", sid,
|
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", sid,
|
||||||
@ -1133,6 +1142,7 @@ static void display_create_tracks(demuxer_t *demuxer)
|
|||||||
mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id,
|
mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id,
|
||||||
str);
|
str);
|
||||||
}
|
}
|
||||||
|
mkv_d->num_audio_tracks = aid;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -1272,7 +1282,7 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sh_v = new_sh_video_vid(demuxer, track->tnum, vid);
|
sh_v = new_sh_video(demuxer, vid);
|
||||||
sh_v->bih = bih;
|
sh_v->bih = bih;
|
||||||
sh_v->format = sh_v->bih->biCompression;
|
sh_v->format = sh_v->bih->biCompression;
|
||||||
if (track->v_frate == 0.0)
|
if (track->v_frate == 0.0)
|
||||||
@ -1304,11 +1314,9 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||||
int aid)
|
int aid)
|
||||||
{
|
{
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
sh_audio_t *sh_a = new_sh_audio(demuxer, aid);
|
||||||
sh_audio_t *sh_a = new_sh_audio_aid(demuxer, track->tnum, aid);
|
|
||||||
if (!sh_a)
|
if (!sh_a)
|
||||||
return 1;
|
return 1;
|
||||||
mkv_d->audio_tracks[mkv_d->last_aid] = track->tnum;
|
|
||||||
|
|
||||||
if (track->language && (strcmp(track->language, "und") != 0))
|
if (track->language && (strcmp(track->language, "und") != 0))
|
||||||
sh_a->lang = strdup(track->language);
|
sh_a->lang = strdup(track->language);
|
||||||
@ -1391,7 +1399,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
mp_tmsg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported audio "
|
mp_tmsg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported audio "
|
||||||
"codec ID '%s' for track %u or missing/faulty\n[mkv] "
|
"codec ID '%s' for track %u or missing/faulty\n[mkv] "
|
||||||
"private codec data.\n", track->codec_id, track->tnum);
|
"private codec data.\n", track->codec_id, track->tnum);
|
||||||
free_sh_audio(demuxer, track->tnum);
|
free_sh_audio(demuxer, track->id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1577,7 +1585,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
} else if (track->a_formattag == mmioFOURCC('W', 'V', 'P', 'K') || track->a_formattag == mmioFOURCC('T', 'R', 'H', 'D')) { /* do nothing, still works */
|
} else if (track->a_formattag == mmioFOURCC('W', 'V', 'P', 'K') || track->a_formattag == mmioFOURCC('T', 'R', 'H', 'D')) { /* do nothing, still works */
|
||||||
} else if (!track->ms_compat
|
} else if (!track->ms_compat
|
||||||
|| (track->private_size < sizeof(WAVEFORMATEX))) {
|
|| (track->private_size < sizeof(WAVEFORMATEX))) {
|
||||||
free_sh_audio(demuxer, track->tnum);
|
free_sh_audio(demuxer, track->id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1590,7 +1598,7 @@ static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
if (track->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN) {
|
if (track->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN) {
|
||||||
int size;
|
int size;
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
sh_sub_t *sh = new_sh_sub_sid(demuxer, track->tnum, sid);
|
sh_sub_t *sh = new_sh_sub(demuxer, sid);
|
||||||
track->sh_sub = sh;
|
track->sh_sub = sh;
|
||||||
sh->type = 't';
|
sh->type = 't';
|
||||||
if (track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB)
|
if (track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB)
|
||||||
@ -1713,20 +1721,20 @@ static int demux_mkv_open(demuxer_t *demuxer)
|
|||||||
/* no track has the 'default' flag set */
|
/* no track has the 'default' flag set */
|
||||||
/* let's take the first video track */
|
/* let's take the first video track */
|
||||||
for (i = 0; i < mkv_d->num_tracks; i++)
|
for (i = 0; i < mkv_d->num_tracks; i++)
|
||||||
if (mkv_d->tracks[i]->type == MATROSKA_TRACK_VIDEO) {
|
if (mkv_d->tracks[i]->type == MATROSKA_TRACK_VIDEO
|
||||||
|
&& track->id >= 0) {
|
||||||
track = mkv_d->tracks[i];
|
track = mkv_d->tracks[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (demuxer->video->id != -2) /* -2 = no video at all */
|
} else if (demuxer->video->id != -2) /* -2 = no video at all */
|
||||||
track =
|
track = find_track_by_num(mkv_d, demuxer->video->id,
|
||||||
demux_mkv_find_track_by_num(mkv_d, demuxer->video->id,
|
MATROSKA_TRACK_VIDEO);
|
||||||
MATROSKA_TRACK_VIDEO);
|
|
||||||
|
|
||||||
if (track && demuxer->v_streams[track->tnum]) {
|
if (track && demuxer->v_streams[track->id]) {
|
||||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] Will play video track %u.\n",
|
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] Will play video track %u.\n",
|
||||||
track->tnum);
|
track->tnum);
|
||||||
demuxer->video->id = track->tnum;
|
demuxer->video->id = track->id;
|
||||||
demuxer->video->sh = demuxer->v_streams[track->tnum];
|
demuxer->video->sh = demuxer->v_streams[track->id];
|
||||||
} else {
|
} else {
|
||||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] No video track found/wanted.\n");
|
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] No video track found/wanted.\n");
|
||||||
demuxer->video->id = -2;
|
demuxer->video->id = -2;
|
||||||
@ -1747,31 +1755,20 @@ static int demux_mkv_open(demuxer_t *demuxer)
|
|||||||
/* no track has the 'default' flag set */
|
/* no track has the 'default' flag set */
|
||||||
/* let's take the first audio track */
|
/* let's take the first audio track */
|
||||||
for (i = 0; i < mkv_d->num_tracks; i++)
|
for (i = 0; i < mkv_d->num_tracks; i++)
|
||||||
if (mkv_d->tracks[i]->type == MATROSKA_TRACK_AUDIO) {
|
if (mkv_d->tracks[i]->type == MATROSKA_TRACK_AUDIO
|
||||||
|
&& track->id >= 0) {
|
||||||
track = mkv_d->tracks[i];
|
track = mkv_d->tracks[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (track && demuxer->a_streams[track->tnum]) {
|
if (track && demuxer->a_streams[track->id]) {
|
||||||
demuxer->audio->id = track->tnum;
|
demuxer->audio->id = track->id;
|
||||||
demuxer->audio->sh = demuxer->a_streams[track->tnum];
|
demuxer->audio->sh = demuxer->a_streams[track->id];
|
||||||
} else {
|
} else {
|
||||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] No audio track found/wanted.\n");
|
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[mkv] No audio track found/wanted.\n");
|
||||||
demuxer->audio->id = -2;
|
demuxer->audio->id = -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (demuxer->audio->id != -2)
|
|
||||||
for (i = 0; i < mkv_d->num_tracks; i++) {
|
|
||||||
if (mkv_d->tracks[i]->type != MATROSKA_TRACK_AUDIO)
|
|
||||||
continue;
|
|
||||||
if (demuxer->a_streams[track->tnum]) {
|
|
||||||
mkv_d->last_aid++;
|
|
||||||
if (mkv_d->last_aid == MAX_A_STREAMS)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->end_pos == 0 || (mkv_d->indexes == NULL && index_mode < 0))
|
if (s->end_pos == 0 || (mkv_d->indexes == NULL && index_mode < 0))
|
||||||
demuxer->seekable = 0;
|
demuxer->seekable = 0;
|
||||||
else {
|
else {
|
||||||
@ -2165,7 +2162,8 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
free(lace_size);
|
free(lace_size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (num == demuxer->audio->id) {
|
if (track->type == MATROSKA_TRACK_AUDIO
|
||||||
|
&& track->id == demuxer->audio->id) {
|
||||||
ds = demuxer->audio;
|
ds = demuxer->audio;
|
||||||
|
|
||||||
if (mkv_d->a_skip_to_keyframe) {
|
if (mkv_d->a_skip_to_keyframe) {
|
||||||
@ -2192,7 +2190,8 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
}
|
}
|
||||||
} else if (tc < mkv_d->skip_to_timecode)
|
} else if (tc < mkv_d->skip_to_timecode)
|
||||||
use_this_block = 0;
|
use_this_block = 0;
|
||||||
else if (num == demuxer->video->id) {
|
else if (track->type == MATROSKA_TRACK_VIDEO
|
||||||
|
&& track->id == demuxer->video->id) {
|
||||||
ds = demuxer->video;
|
ds = demuxer->video;
|
||||||
if (mkv_d->v_skip_to_keyframe) {
|
if (mkv_d->v_skip_to_keyframe) {
|
||||||
if (simpleblock) {
|
if (simpleblock) {
|
||||||
@ -2201,7 +2200,8 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
} else if (block_bref != 0 || block_fref != 0)
|
} else if (block_bref != 0 || block_fref != 0)
|
||||||
use_this_block = 0;
|
use_this_block = 0;
|
||||||
}
|
}
|
||||||
} else if (num == demuxer->sub->id) {
|
} else if (track->type == MATROSKA_TRACK_SUBTITLE
|
||||||
|
&& track->id == demuxer->sub->id) {
|
||||||
ds = demuxer->sub;
|
ds = demuxer->sub;
|
||||||
if (track->subtitle_type != MATROSKA_SUBTYPE_VOBSUB) {
|
if (track->subtitle_type != MATROSKA_SUBTYPE_VOBSUB) {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
@ -2408,6 +2408,15 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
|||||||
static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
||||||
float audio_delay, int flags)
|
float audio_delay, int flags)
|
||||||
{
|
{
|
||||||
|
mkv_demuxer_t *mkv_d = demuxer->priv;
|
||||||
|
uint64_t v_tnum = -1;
|
||||||
|
if (demuxer->video->id >= 0)
|
||||||
|
v_tnum = find_track_by_num(mkv_d, demuxer->video->id,
|
||||||
|
MATROSKA_TRACK_VIDEO)->tnum;
|
||||||
|
uint64_t a_tnum = -1;
|
||||||
|
if (demuxer->audio->id >= 0)
|
||||||
|
a_tnum = find_track_by_num(mkv_d, demuxer->audio->id,
|
||||||
|
MATROSKA_TRACK_VIDEO)->tnum;
|
||||||
if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
|
if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
|
||||||
if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0)
|
if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0)
|
||||||
flags |= SEEK_BACKWARD;
|
flags |= SEEK_BACKWARD;
|
||||||
@ -2421,7 +2430,6 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
|||||||
free_cached_dps(demuxer);
|
free_cached_dps(demuxer);
|
||||||
if (!(flags & SEEK_FACTOR)) { /* time in secs */
|
if (!(flags & SEEK_FACTOR)) { /* time in secs */
|
||||||
mkv_index_t *index = NULL;
|
mkv_index_t *index = NULL;
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
|
||||||
stream_t *s = demuxer->stream;
|
stream_t *s = demuxer->stream;
|
||||||
int64_t target_timecode = 0, diff, min_diff = 0xFFFFFFFFFFFFFFFLL;
|
int64_t target_timecode = 0, diff, min_diff = 0xFFFFFFFFFFFFFFFLL;
|
||||||
int i;
|
int i;
|
||||||
@ -2495,7 +2503,7 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
|||||||
stream_seek(s, cluster_pos);
|
stream_seek(s, cluster_pos);
|
||||||
} else {
|
} else {
|
||||||
int seek_id = (demuxer->video->id < 0) ?
|
int seek_id = (demuxer->video->id < 0) ?
|
||||||
demuxer->audio->id : demuxer->video->id;
|
a_tnum : v_tnum;
|
||||||
|
|
||||||
/* let's find the entry in the indexes with the smallest */
|
/* let's find the entry in the indexes with the smallest */
|
||||||
/* difference to the wanted timecode. */
|
/* difference to the wanted timecode. */
|
||||||
@ -2545,7 +2553,6 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
|||||||
} else if ((demuxer->movi_end <= 0) || !(flags & SEEK_ABSOLUTE))
|
} else if ((demuxer->movi_end <= 0) || !(flags & SEEK_ABSOLUTE))
|
||||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] seek unsupported flags\n");
|
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] seek unsupported flags\n");
|
||||||
else {
|
else {
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
|
||||||
stream_t *s = demuxer->stream;
|
stream_t *s = demuxer->stream;
|
||||||
uint64_t target_filepos;
|
uint64_t target_filepos;
|
||||||
mkv_index_t *index = NULL;
|
mkv_index_t *index = NULL;
|
||||||
@ -2558,7 +2565,7 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
|||||||
|
|
||||||
target_filepos = (uint64_t) (demuxer->movi_end * rel_seek_secs);
|
target_filepos = (uint64_t) (demuxer->movi_end * rel_seek_secs);
|
||||||
for (i = 0; i < mkv_d->num_indexes; i++)
|
for (i = 0; i < mkv_d->num_indexes; i++)
|
||||||
if (mkv_d->indexes[i].tnum == demuxer->video->id)
|
if (mkv_d->indexes[i].tnum == v_tnum)
|
||||||
if ((index == NULL)
|
if ((index == NULL)
|
||||||
|| ((mkv_d->indexes[i].filepos >= target_filepos)
|
|| ((mkv_d->indexes[i].filepos >= target_filepos)
|
||||||
&& ((index->filepos < target_filepos)
|
&& ((index->filepos < target_filepos)
|
||||||
@ -2607,13 +2614,12 @@ static int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg)
|
|||||||
sh_audio_t *sh = demuxer->a_streams[demuxer->audio->id];
|
sh_audio_t *sh = demuxer->a_streams[demuxer->audio->id];
|
||||||
int aid = *(int *) arg;
|
int aid = *(int *) arg;
|
||||||
if (aid < 0)
|
if (aid < 0)
|
||||||
aid = (sh->aid + 1) % mkv_d->last_aid;
|
aid = (sh->aid + 1) % mkv_d->num_audio_tracks;
|
||||||
if (aid != sh->aid) {
|
if (aid != sh->aid) {
|
||||||
mkv_track_t *track =
|
mkv_track_t *track =
|
||||||
demux_mkv_find_track_by_num(mkv_d, aid,
|
find_track_by_num(mkv_d, aid, MATROSKA_TRACK_AUDIO);
|
||||||
MATROSKA_TRACK_AUDIO);
|
|
||||||
if (track) {
|
if (track) {
|
||||||
demuxer->audio->id = track->tnum;
|
demuxer->audio->id = track->id;
|
||||||
sh = demuxer->a_streams[demuxer->audio->id];
|
sh = demuxer->a_streams[demuxer->audio->id];
|
||||||
ds_free_packs(demuxer->audio);
|
ds_free_packs(demuxer->audio);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user