mirror of https://github.com/mpv-player/mpv
demux: workaround for -demuxer mpegts -correct-pts
Using -demuxer mpegts -correct-pts triggered the assertion in ds_get_packet2(). This is not surprising, because the correct-pts code was changed to accept _complete_ packets, while all the old demuxers (including the mpegts demuxer) require you to use "partial" packet reads, together with the video_read_frame(). (That function actually parses video frames, so fragments of the original "packets" can be fed to the decoder.) However, it returns out demux_ts packet's are mostly useable. demux_ts still adds an offset (i.e. ds->buffer_pos != 0) to the packets when calling internal parser functions, such as in parse_es.c. While this is unclean design due to mplayer's old video demuxing/decoding path, it can be easily be made work by modifying the packet as returned by ds_get_packet2(). We also have to change the packet freeing code, as demux_packet->buffer doesn't have to point to the start of the memory allocation anymore. MPlayer handles this "correctly" because it doesn't have a function that reads a complete packet.
This commit is contained in:
parent
e8be121580
commit
b477c68aa0
|
@ -106,10 +106,8 @@ static void add_stream_chapters(struct demuxer *demuxer);
|
||||||
static int packet_destroy(void *ptr)
|
static int packet_destroy(void *ptr)
|
||||||
{
|
{
|
||||||
struct demux_packet *dp = ptr;
|
struct demux_packet *dp = ptr;
|
||||||
if (dp->avpacket)
|
talloc_free(dp->avpacket);
|
||||||
talloc_free(dp->avpacket);
|
free(dp->allocation);
|
||||||
else
|
|
||||||
free(dp->buffer);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +138,7 @@ struct demux_packet *new_demux_packet(size_t len)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
|
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
dp->allocation = dp->buffer;
|
||||||
return dp;
|
return dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +164,7 @@ void resize_demux_packet(struct demux_packet *dp, size_t len)
|
||||||
"over 1 GB!\n");
|
"over 1 GB!\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
assert(dp->allocation);
|
||||||
dp->buffer = realloc(dp->buffer, len + MP_INPUT_BUFFER_PADDING_SIZE);
|
dp->buffer = realloc(dp->buffer, len + MP_INPUT_BUFFER_PADDING_SIZE);
|
||||||
if (!dp->buffer) {
|
if (!dp->buffer) {
|
||||||
mp_msg(MSGT_DEMUXER, MSGL_FATAL, "Memory allocation failure!\n");
|
mp_msg(MSGT_DEMUXER, MSGL_FATAL, "Memory allocation failure!\n");
|
||||||
|
@ -172,6 +172,7 @@ void resize_demux_packet(struct demux_packet *dp, size_t len)
|
||||||
}
|
}
|
||||||
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
|
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
|
||||||
dp->len = len;
|
dp->len = len;
|
||||||
|
dp->allocation = dp->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_demux_packet(struct demux_packet *dp)
|
void free_demux_packet(struct demux_packet *dp)
|
||||||
|
@ -228,8 +229,8 @@ demuxer_t *new_demuxer(struct MPOpts *opts, stream_t *stream, int type,
|
||||||
d->seekable = 1;
|
d->seekable = 1;
|
||||||
d->synced = 0;
|
d->synced = 0;
|
||||||
d->filepos = -1;
|
d->filepos = -1;
|
||||||
d->audio = new_demuxer_stream(d, STREAM_VIDEO, a_id);
|
d->audio = new_demuxer_stream(d, STREAM_AUDIO, a_id);
|
||||||
d->video = new_demuxer_stream(d, STREAM_AUDIO, v_id);
|
d->video = new_demuxer_stream(d, STREAM_VIDEO, v_id);
|
||||||
d->sub = new_demuxer_stream(d, STREAM_SUB, s_id);
|
d->sub = new_demuxer_stream(d, STREAM_SUB, s_id);
|
||||||
d->ds[STREAM_VIDEO] = d->video;
|
d->ds[STREAM_VIDEO] = d->video;
|
||||||
d->ds[STREAM_AUDIO] = d->audio;
|
d->ds[STREAM_AUDIO] = d->audio;
|
||||||
|
@ -808,10 +809,16 @@ int ds_get_packet_sub(demux_stream_t *ds, unsigned char **start)
|
||||||
|
|
||||||
struct demux_packet *ds_get_packet2(struct demux_stream *ds, bool repeat_last)
|
struct demux_packet *ds_get_packet2(struct demux_stream *ds, bool repeat_last)
|
||||||
{
|
{
|
||||||
// This shouldn't get used together with partial reads
|
|
||||||
assert(ds->buffer_pos == 0 || ds->buffer_pos >= ds->buffer_size);
|
|
||||||
if (!repeat_last)
|
if (!repeat_last)
|
||||||
ds_fill_buffer(ds);
|
ds_fill_buffer(ds);
|
||||||
|
// This shouldn't get used together with partial reads
|
||||||
|
// However, some old demuxers return parsed packets with an offset in
|
||||||
|
// -correct-pts mode (at least mpegts).
|
||||||
|
// Not all old demuxers will actually work.
|
||||||
|
if (ds->buffer_pos < ds->buffer_size) {
|
||||||
|
ds->current->buffer += ds->buffer_pos;
|
||||||
|
ds->buffer_size -= ds->buffer_pos;
|
||||||
|
}
|
||||||
ds->buffer_pos = ds->buffer_size;
|
ds->buffer_pos = ds->buffer_size;
|
||||||
return ds->current;
|
return ds->current;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ typedef struct demux_packet {
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
bool keyframe;
|
bool keyframe;
|
||||||
struct demux_packet *next;
|
struct demux_packet *next;
|
||||||
|
void *allocation;
|
||||||
struct AVPacket *avpacket; // original libavformat packet (demux_lavf)
|
struct AVPacket *avpacket; // original libavformat packet (demux_lavf)
|
||||||
} demux_packet_t;
|
} demux_packet_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue