mirror of
https://github.com/mpv-player/mpv
synced 2025-01-20 06:11:10 +00:00
demux, vd_ffmpeg: fix demux keyframe flag, set AV_PKT_FLAG_KEY
There was some confusion about the "flags" field in demuxer packets. Demuxers set it to either 1 or 0x10 to indicate a keyframe (and the field was not used to indicate anything else). This didn't cause visible problems because nothing read the value. Replace the "flags" field with a boolean "keyframe" field. Set AV_PKT_FLAG_KEY based on this field in packets fed to libavcodec video decoders (looks like PNG and ZeroCodec are the only ones which depend on values from demuxer; previously this was hardcoded to true for PNG). Make demux_mf set the keyframe field in every packet. This matters for PNG files now that the demuxer flag is forwarded to libavcodec. Fix logic setting the field in demux_mkv. It had probably not been updated when adding SimpleBlock support. This probably makes no difference for any current practical use.
This commit is contained in:
parent
5f3c3f8c32
commit
8079f4ff82
@ -642,8 +642,10 @@ static struct mp_image *decode(struct sh_video *sh, struct demux_packet *packet,
|
|||||||
av_init_packet(&pkt);
|
av_init_packet(&pkt);
|
||||||
pkt.data = data;
|
pkt.data = data;
|
||||||
pkt.size = len;
|
pkt.size = len;
|
||||||
// HACK: make PNGs decode normally instead of as CorePNG delta frames
|
/* Some codecs (ZeroCodec, some cases of PNG) may want keyframe info
|
||||||
pkt.flags = AV_PKT_FLAG_KEY;
|
* from demuxer. */
|
||||||
|
if (packet && packet->keyframe)
|
||||||
|
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||||
if (packet && packet->avpacket) {
|
if (packet && packet->avpacket) {
|
||||||
pkt.side_data = packet->avpacket->side_data;
|
pkt.side_data = packet->avpacket->side_data;
|
||||||
pkt.side_data_elems = packet->avpacket->side_data_elems;
|
pkt.side_data_elems = packet->avpacket->side_data_elems;
|
||||||
|
@ -177,7 +177,7 @@ static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,in
|
|||||||
dp->pts=time*0.0000001;
|
dp->pts=time*0.0000001;
|
||||||
else
|
else
|
||||||
dp->pts=time*0.001;
|
dp->pts=time*0.001;
|
||||||
dp->flags=keyframe;
|
dp->keyframe = keyframe;
|
||||||
// if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur);
|
// if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur);
|
||||||
dp->pos=demux->filepos;
|
dp->pos=demux->filepos;
|
||||||
ds->asf_packet=dp;
|
ds->asf_packet=dp;
|
||||||
@ -595,7 +595,8 @@ static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,float audio_de
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(d_video->flags&1) break; // found a keyframe!
|
if (d_video->keyframe)
|
||||||
|
break;
|
||||||
if(!ds_fill_buffer(d_video)) break; // skip frame. EOF?
|
if(!ds_fill_buffer(d_video)) break; // skip frame. EOF?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,6 @@ static int demux_film_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
|||||||
return 0;
|
return 0;
|
||||||
dp->pts = film_chunk.pts;
|
dp->pts = film_chunk.pts;
|
||||||
dp->pos = film_chunk.chunk_offset;
|
dp->pos = film_chunk.chunk_offset;
|
||||||
dp->flags = 0;
|
|
||||||
|
|
||||||
// adjust the data before queuing it:
|
// adjust the data before queuing it:
|
||||||
// 8-bit: signed -> unsigned
|
// 8-bit: signed -> unsigned
|
||||||
@ -197,7 +196,7 @@ static int demux_film_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
|||||||
|
|
||||||
dp->pts = film_chunk.pts;
|
dp->pts = film_chunk.pts;
|
||||||
dp->pos = film_chunk.chunk_offset;
|
dp->pos = film_chunk.chunk_offset;
|
||||||
dp->flags = (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0;
|
dp->keyframe = film_chunk.syncinfo1 & 0x80000000;
|
||||||
|
|
||||||
// fix the CVID chunk size
|
// fix the CVID chunk size
|
||||||
cvid_size = film_chunk.chunk_size - length_fix_bytes;
|
cvid_size = film_chunk.chunk_size - length_fix_bytes;
|
||||||
|
@ -816,7 +816,7 @@ static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds)
|
|||||||
av_q2d(priv->avfc->streams[id]->time_base);
|
av_q2d(priv->avfc->streams[id]->time_base);
|
||||||
}
|
}
|
||||||
dp->pos = demux->filepos;
|
dp->pos = demux->filepos;
|
||||||
dp->flags = !!(pkt->flags & AV_PKT_FLAG_KEY);
|
dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
|
||||||
// append packet to DS stream:
|
// append packet to DS stream:
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -66,7 +66,7 @@ static int demux_mf_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
|
|||||||
if ( !fread( dp->buffer,file_size,1,f ) ) return 0;
|
if ( !fread( dp->buffer,file_size,1,f ) ) return 0;
|
||||||
dp->pts=mf->curr_frame / sh_video->fps;
|
dp->pts=mf->curr_frame / sh_video->fps;
|
||||||
dp->pos=mf->curr_frame;
|
dp->pos=mf->curr_frame;
|
||||||
dp->flags=0;
|
dp->keyframe = true;
|
||||||
// append packet to DS stream:
|
// append packet to DS stream:
|
||||||
ds_add_packet( demuxer->video,dp );
|
ds_add_packet( demuxer->video,dp );
|
||||||
}
|
}
|
||||||
|
@ -1840,7 +1840,7 @@ static int demux_mkv_read_block_lacing(uint8_t *buffer, uint64_t *size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
|
static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
|
||||||
uint8_t *buffer, uint32_t size, int64_t block_bref)
|
uint8_t *buffer, uint32_t size, bool keyframe)
|
||||||
{
|
{
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
||||||
demux_packet_t *dp;
|
demux_packet_t *dp;
|
||||||
@ -1860,13 +1860,13 @@ static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
biCompression, &track->rv_kf_base,
|
biCompression, &track->rv_kf_base,
|
||||||
&track->rv_kf_pts, NULL);
|
&track->rv_kf_pts, NULL);
|
||||||
dp->pos = demuxer->filepos;
|
dp->pos = demuxer->filepos;
|
||||||
dp->flags = block_bref ? 0 : 0x10;
|
dp->keyframe = keyframe;
|
||||||
|
|
||||||
ds_add_packet(demuxer->video, dp);
|
ds_add_packet(demuxer->video, dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
|
static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
|
||||||
uint8_t *buffer, uint32_t size, int64_t block_bref)
|
uint8_t *buffer, uint32_t size, bool keyframe)
|
||||||
{
|
{
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
||||||
int sps = track->sub_packet_size;
|
int sps = track->sub_packet_size;
|
||||||
@ -1952,7 +1952,7 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
dp->pts = (x * apk_usize % w) ? 0 :
|
dp->pts = (x * apk_usize % w) ? 0 :
|
||||||
track->audio_timestamp[x * apk_usize / w];
|
track->audio_timestamp[x * apk_usize / w];
|
||||||
dp->pos = track->audio_filepos; // all equal
|
dp->pos = track->audio_filepos; // all equal
|
||||||
dp->flags = x ? 0 : 0x10; // Mark first packet as keyframe
|
dp->keyframe = !x; // Mark first packet as keyframe
|
||||||
ds_add_packet(demuxer->audio, dp);
|
ds_add_packet(demuxer->audio, dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1966,14 +1966,14 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
|
|||||||
track->ra_pts = mkv_d->last_pts;
|
track->ra_pts = mkv_d->last_pts;
|
||||||
|
|
||||||
dp->pos = demuxer->filepos;
|
dp->pos = demuxer->filepos;
|
||||||
dp->flags = block_bref ? 0 : 0x10;
|
dp->keyframe = keyframe;
|
||||||
ds_add_packet(demuxer->audio, dp);
|
ds_add_packet(demuxer->audio, dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
||||||
uint64_t block_duration, int64_t block_bref,
|
uint64_t block_duration, bool keyframe,
|
||||||
int64_t block_fref, uint8_t simpleblock)
|
bool simpleblock)
|
||||||
{
|
{
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
||||||
mkv_track_t *track = NULL;
|
mkv_track_t *track = NULL;
|
||||||
@ -1995,6 +1995,8 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
length -= tmp + 2;
|
length -= tmp + 2;
|
||||||
old_length = length;
|
old_length = length;
|
||||||
flags = block[0];
|
flags = block[0];
|
||||||
|
if (simpleblock)
|
||||||
|
keyframe = flags & 0x80;
|
||||||
if (demux_mkv_read_block_lacing(block, &length, &laces, &lace_size))
|
if (demux_mkv_read_block_lacing(block, &length, &laces, &lace_size))
|
||||||
return 0;
|
return 0;
|
||||||
block += old_length - length;
|
block += old_length - length;
|
||||||
@ -2015,13 +2017,8 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
&& track->id == demuxer->audio->id) {
|
&& 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)
|
||||||
if (simpleblock) {
|
use_this_block = keyframe;
|
||||||
if (!(flags & 0x80)) /*current frame isn't a keyframe */
|
|
||||||
use_this_block = 0;
|
|
||||||
} else if (block_bref != 0)
|
|
||||||
use_this_block = 0;
|
|
||||||
}
|
|
||||||
if (mkv_d->v_skip_to_keyframe)
|
if (mkv_d->v_skip_to_keyframe)
|
||||||
use_this_block = 0;
|
use_this_block = 0;
|
||||||
|
|
||||||
@ -2043,13 +2040,8 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
else if (track->type == MATROSKA_TRACK_VIDEO
|
else if (track->type == MATROSKA_TRACK_VIDEO
|
||||||
&& track->id == demuxer->video->id) {
|
&& 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) {
|
use_this_block = keyframe;
|
||||||
if (!(flags & 0x80)) /*current frame isn't a keyframe */
|
|
||||||
use_this_block = 0;
|
|
||||||
} else if (block_bref != 0 || block_fref != 0)
|
|
||||||
use_this_block = 0;
|
|
||||||
}
|
|
||||||
} else if (track->type == MATROSKA_TRACK_SUBTITLE
|
} else if (track->type == MATROSKA_TRACK_SUBTITLE
|
||||||
&& track->id == demuxer->sub->id) {
|
&& track->id == demuxer->sub->id) {
|
||||||
ds = demuxer->sub;
|
ds = demuxer->sub;
|
||||||
@ -2069,10 +2061,10 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
for (i = 0; i < laces; i++) {
|
for (i = 0; i < laces; i++) {
|
||||||
if (ds == demuxer->video && track->realmedia)
|
if (ds == demuxer->video && track->realmedia)
|
||||||
handle_realvideo(demuxer, track, block, lace_size[i],
|
handle_realvideo(demuxer, track, block, lace_size[i],
|
||||||
block_bref);
|
keyframe);
|
||||||
else if (ds == demuxer->audio && track->realmedia)
|
else if (ds == demuxer->audio && track->realmedia)
|
||||||
handle_realaudio(demuxer, track, block, lace_size[i],
|
handle_realaudio(demuxer, track, block, lace_size[i],
|
||||||
block_bref);
|
keyframe);
|
||||||
else {
|
else {
|
||||||
int size = lace_size[i];
|
int size = lace_size[i];
|
||||||
demux_packet_t *dp;
|
demux_packet_t *dp;
|
||||||
@ -2083,8 +2075,7 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
|
|||||||
memcpy(dp->buffer, buffer, size);
|
memcpy(dp->buffer, buffer, size);
|
||||||
if (buffer != block)
|
if (buffer != block)
|
||||||
talloc_free(buffer);
|
talloc_free(buffer);
|
||||||
dp->flags = (block_bref == 0
|
dp->keyframe = keyframe;
|
||||||
&& block_fref == 0) ? 0x10 : 0;
|
|
||||||
/* If default_duration is 0, assume no pts value is known
|
/* If default_duration is 0, assume no pts value is known
|
||||||
* for packets after the first one (rather than all pts
|
* for packets after the first one (rather than all pts
|
||||||
* values being the same) */
|
* values being the same) */
|
||||||
@ -2122,7 +2113,7 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
|||||||
while (1) {
|
while (1) {
|
||||||
while (mkv_d->cluster_size > 0) {
|
while (mkv_d->cluster_size > 0) {
|
||||||
uint64_t block_duration = 0, block_length = 0;
|
uint64_t block_duration = 0, block_length = 0;
|
||||||
int64_t block_bref = 0, block_fref = 0;
|
bool keyframe = true;
|
||||||
uint8_t *block = NULL;
|
uint8_t *block = NULL;
|
||||||
|
|
||||||
while (mkv_d->blockgroup_size > 0) {
|
while (mkv_d->blockgroup_size > 0) {
|
||||||
@ -2157,10 +2148,8 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
|||||||
free(block);
|
free(block);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (num <= 0)
|
if (num)
|
||||||
block_bref = num;
|
keyframe = false;
|
||||||
else
|
|
||||||
block_fref = num;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EBML_ID_INVALID:
|
case EBML_ID_INVALID:
|
||||||
@ -2177,8 +2166,7 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
|||||||
|
|
||||||
if (block) {
|
if (block) {
|
||||||
int res = handle_block(demuxer, block, block_length,
|
int res = handle_block(demuxer, block, block_length,
|
||||||
block_duration, block_bref, block_fref,
|
block_duration, keyframe, false);
|
||||||
0);
|
|
||||||
free(block);
|
free(block);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2216,8 +2204,7 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
|||||||
}
|
}
|
||||||
l = tmp + block_length;
|
l = tmp + block_length;
|
||||||
res = handle_block(demuxer, block, block_length,
|
res = handle_block(demuxer, block, block_length,
|
||||||
block_duration, block_bref,
|
block_duration, false, true);
|
||||||
block_fref, 1);
|
|
||||||
free(block);
|
free(block);
|
||||||
mkv_d->cluster_size -= l + il;
|
mkv_d->cluster_size -= l + il;
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
|
@ -2195,7 +2195,6 @@ if(trak->pos==0 && trak->stream_header_len>0){
|
|||||||
trak->stream_header = NULL;
|
trak->stream_header = NULL;
|
||||||
trak->stream_header_len = 0;
|
trak->stream_header_len = 0;
|
||||||
dp->pts=pts;
|
dp->pts=pts;
|
||||||
dp->flags=0;
|
|
||||||
dp->pos=pos; // FIXME?
|
dp->pos=pos; // FIXME?
|
||||||
ds_add_packet(ds,dp);
|
ds_add_packet(ds,dp);
|
||||||
} else
|
} else
|
||||||
|
@ -238,7 +238,7 @@ static int demux_nut_fill_buffer(demuxer_t * demuxer, demux_stream_t * dsds) {
|
|||||||
dp->pts = pts;
|
dp->pts = pts;
|
||||||
|
|
||||||
dp->pos = demuxer->filepos;
|
dp->pos = demuxer->filepos;
|
||||||
dp->flags= (pd.flags & NUT_FLAG_KEY) ? 0x10 : 0;
|
dp->keyframe = pd.flags & NUT_FLAG_KEY;
|
||||||
|
|
||||||
{int len = pd.len;
|
{int len = pd.len;
|
||||||
while ((ret = nut_read_frame(nut, &len, dp->buffer + pd.len-len)) == NUT_ERR_EAGAIN);
|
while ((ret = nut_read_frame(nut, &len, dp->buffer + pd.len-len)) == NUT_ERR_EAGAIN);
|
||||||
|
@ -258,13 +258,13 @@ static int demux_ogg_get_page_stream(ogg_demuxer_t *ogg_d,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char *demux_ogg_read_packet(ogg_stream_t *os, ogg_packet *pack,
|
static unsigned char *demux_ogg_read_packet(ogg_stream_t *os, ogg_packet *pack,
|
||||||
float *pts, int *flags,
|
float *pts, bool *keyframe,
|
||||||
int samplesize)
|
int samplesize)
|
||||||
{
|
{
|
||||||
unsigned char *data = pack->packet;
|
unsigned char *data = pack->packet;
|
||||||
|
|
||||||
*pts = MP_NOPTS_VALUE;
|
*pts = MP_NOPTS_VALUE;
|
||||||
*flags = 0;
|
*keyframe = false;
|
||||||
|
|
||||||
if (os->vorbis) {
|
if (os->vorbis) {
|
||||||
if (*pack->packet & PACKET_TYPE_HEADER) {
|
if (*pack->packet & PACKET_TYPE_HEADER) {
|
||||||
@ -283,7 +283,7 @@ static unsigned char *demux_ogg_read_packet(ogg_stream_t *os, ogg_packet *pack,
|
|||||||
if (os->lastsize > 0)
|
if (os->lastsize > 0)
|
||||||
pack->granulepos += os->lastsize;
|
pack->granulepos += os->lastsize;
|
||||||
} else
|
} else
|
||||||
*flags = 1;
|
*keyframe = true;
|
||||||
if (vi)
|
if (vi)
|
||||||
*pts = pack->granulepos / (float)vi->rate;
|
*pts = pack->granulepos / (float)vi->rate;
|
||||||
os->lastsize = blocksize;
|
os->lastsize = blocksize;
|
||||||
@ -306,7 +306,7 @@ static unsigned char *demux_ogg_read_packet(ogg_stream_t *os, ogg_packet *pack,
|
|||||||
if (pack->granulepos >= 0) {
|
if (pack->granulepos >= 0) {
|
||||||
os->lastpos = pack->granulepos >> keyframe_granule_shift;
|
os->lastpos = pack->granulepos >> keyframe_granule_shift;
|
||||||
os->lastpos += pack->granulepos & iframemask;
|
os->lastpos += pack->granulepos & iframemask;
|
||||||
*flags = (pack->granulepos & iframemask) == 0;
|
*keyframe = (pack->granulepos & iframemask) == 0;
|
||||||
} else {
|
} else {
|
||||||
os->lastpos++;
|
os->lastpos++;
|
||||||
}
|
}
|
||||||
@ -332,7 +332,7 @@ static unsigned char *demux_ogg_read_packet(ogg_stream_t *os, ogg_packet *pack,
|
|||||||
pack->granulepos = os->lastpos + (os->lastsize ? os->lastsize : 1);
|
pack->granulepos = os->lastpos + (os->lastsize ? os->lastsize : 1);
|
||||||
// If we already have a timestamp it can be a syncpoint
|
// If we already have a timestamp it can be a syncpoint
|
||||||
if (*pack->packet & PACKET_IS_SYNCPOINT)
|
if (*pack->packet & PACKET_IS_SYNCPOINT)
|
||||||
*flags = 1;
|
*keyframe = true;
|
||||||
*pts = pack->granulepos / os->samplerate;
|
*pts = pack->granulepos / os->samplerate;
|
||||||
// Save the packet length and timestamp
|
// Save the packet length and timestamp
|
||||||
os->lastsize = 0;
|
os->lastsize = 0;
|
||||||
@ -474,10 +474,6 @@ static int demux_ogg_add_packet(demux_stream_t *ds, ogg_stream_t *os,
|
|||||||
int id, ogg_packet *pack)
|
int id, ogg_packet *pack)
|
||||||
{
|
{
|
||||||
demuxer_t *d = ds->demuxer;
|
demuxer_t *d = ds->demuxer;
|
||||||
demux_packet_t *dp;
|
|
||||||
unsigned char *data;
|
|
||||||
float pts = 0;
|
|
||||||
int flags = 0;
|
|
||||||
int samplesize = 1;
|
int samplesize = 1;
|
||||||
|
|
||||||
// If packet is an comment header then we try to get comments at first
|
// If packet is an comment header then we try to get comments at first
|
||||||
@ -520,7 +516,10 @@ static int demux_ogg_add_packet(demux_stream_t *ds, ogg_stream_t *os,
|
|||||||
if (ds == d->audio && ((sh_audio_t*)ds->sh)->format == FOURCC_VORBIS) {
|
if (ds == d->audio && ((sh_audio_t*)ds->sh)->format == FOURCC_VORBIS) {
|
||||||
samplesize = ((sh_audio_t *)ds->sh)->samplesize;
|
samplesize = ((sh_audio_t *)ds->sh)->samplesize;
|
||||||
}
|
}
|
||||||
data = demux_ogg_read_packet(os, pack, &pts, &flags, samplesize);
|
bool keyframe;
|
||||||
|
float pts;
|
||||||
|
unsigned char *data;
|
||||||
|
data = demux_ogg_read_packet(os, pack, &pts, &keyframe, samplesize);
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -530,14 +529,15 @@ static int demux_ogg_add_packet(demux_stream_t *ds, ogg_stream_t *os,
|
|||||||
vo_osd_changed(OSDTYPE_SUBTITLE);
|
vo_osd_changed(OSDTYPE_SUBTITLE);
|
||||||
}
|
}
|
||||||
/// Send the packet
|
/// Send the packet
|
||||||
|
struct demux_packet *dp;
|
||||||
dp = new_demux_packet(pack->bytes - (data - pack->packet));
|
dp = new_demux_packet(pack->bytes - (data - pack->packet));
|
||||||
memcpy(dp->buffer, data, pack->bytes - (data - pack->packet));
|
memcpy(dp->buffer, data, pack->bytes - (data - pack->packet));
|
||||||
dp->pts = pts;
|
dp->pts = pts;
|
||||||
dp->flags = flags;
|
dp->keyframe = keyframe;
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
mp_msg(MSGT_DEMUX, MSGL_DBG2,
|
mp_msg(MSGT_DEMUX, MSGL_DBG2,
|
||||||
"New dp: %p ds=%p pts=%5.3f len=%d flag=%d \n",
|
"New dp: %p ds=%p pts=%5.3f len=%d keyframe=%d \n",
|
||||||
dp, ds, pts, dp->len, flags);
|
dp, ds, pts, dp->len, keyframe);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,12 +606,12 @@ static void demux_ogg_scan_stream(demuxer_t *demuxer)
|
|||||||
p = 0;
|
p = 0;
|
||||||
while (ogg_stream_packetout(oss, &op) == 1) {
|
while (ogg_stream_packetout(oss, &op) == 1) {
|
||||||
float pts;
|
float pts;
|
||||||
int flags;
|
bool keyframe;
|
||||||
|
|
||||||
demux_ogg_read_packet(os, &op, &pts, &flags, samplesize);
|
demux_ogg_read_packet(os, &op, &pts, &keyframe, samplesize);
|
||||||
if (op.granulepos >= 0) {
|
if (op.granulepos >= 0) {
|
||||||
ogg_d->final_granulepos = op.granulepos;
|
ogg_d->final_granulepos = op.granulepos;
|
||||||
if (ogg_d->initial_granulepos == MP_NOPTS_VALUE && (flags & 1)) {
|
if (ogg_d->initial_granulepos == MP_NOPTS_VALUE && keyframe) {
|
||||||
ogg_d->initial_granulepos = op.granulepos;
|
ogg_d->initial_granulepos = op.granulepos;
|
||||||
if (index_mode != 2 && ogg_d->pos < demuxer->movi_end - 2 * 270000) {
|
if (index_mode != 2 && ogg_d->pos < demuxer->movi_end - 2 * 270000) {
|
||||||
//the 270000 are just a wild guess
|
//the 270000 are just a wild guess
|
||||||
@ -621,7 +621,7 @@ static void demux_ogg_scan_stream(demuxer_t *demuxer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index_mode == 2 && (flags || (os->vorbis && op.granulepos >= 0))) {
|
if (index_mode == 2 && (keyframe || (os->vorbis && op.granulepos >= 0))) {
|
||||||
if (ogg_d->num_syncpoint > SIZE_MAX / sizeof(ogg_syncpoint_t) - 1)
|
if (ogg_d->num_syncpoint > SIZE_MAX / sizeof(ogg_syncpoint_t) - 1)
|
||||||
break;
|
break;
|
||||||
ogg_d->syncpoints = realloc_struct(ogg_d->syncpoints, (ogg_d->num_syncpoint + 1), sizeof(ogg_syncpoint_t));
|
ogg_d->syncpoints = realloc_struct(ogg_d->syncpoints, (ogg_d->num_syncpoint + 1), sizeof(ogg_syncpoint_t));
|
||||||
@ -1415,7 +1415,7 @@ static void demux_ogg_seek(demuxer_t *demuxer, float rel_seek_secs,
|
|||||||
int np;
|
int np;
|
||||||
int is_gp_valid;
|
int is_gp_valid;
|
||||||
float pts;
|
float pts;
|
||||||
int is_keyframe;
|
bool is_keyframe;
|
||||||
int samplesize = 1;
|
int samplesize = 1;
|
||||||
ogg_int64_t granulepos_orig;
|
ogg_int64_t granulepos_orig;
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#ifndef MPLAYER_DEMUX_PACKET_H
|
#ifndef MPLAYER_DEMUX_PACKET_H
|
||||||
#define MPLAYER_DEMUX_PACKET_H
|
#define MPLAYER_DEMUX_PACKET_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
// Holds one packet/frame/whatever
|
// Holds one packet/frame/whatever
|
||||||
@ -29,7 +30,7 @@ typedef struct demux_packet {
|
|||||||
double stream_pts;
|
double stream_pts;
|
||||||
off_t pos; // position in index (AVI) or file (MPG)
|
off_t pos; // position in index (AVI) or file (MPG)
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
int flags; // keyframe, etc
|
bool keyframe;
|
||||||
int refcount; // counter for the master packet, if 0, buffer can be free()d
|
int refcount; // counter for the master packet, if 0, buffer can be free()d
|
||||||
struct demux_packet *master; //in clones, pointer to the master packet
|
struct demux_packet *master; //in clones, pointer to the master packet
|
||||||
struct demux_packet *next;
|
struct demux_packet *next;
|
||||||
|
@ -794,7 +794,7 @@ got_audio:
|
|||||||
if (x * apk_usize % w == 0)
|
if (x * apk_usize % w == 0)
|
||||||
dp->pts = priv->audio_timestamp[x * apk_usize / w];
|
dp->pts = priv->audio_timestamp[x * apk_usize / w];
|
||||||
dp->pos = priv->audio_filepos; // all equal
|
dp->pos = priv->audio_filepos; // all equal
|
||||||
dp->flags = x ? 0 : 0x10; // Mark first packet as keyframe
|
dp->keyframe = !x; // Mark first packet as keyframe
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -839,7 +839,7 @@ got_audio:
|
|||||||
dp->pts = timestamp/1000.0;
|
dp->pts = timestamp/1000.0;
|
||||||
priv->a_pts=timestamp;
|
priv->a_pts=timestamp;
|
||||||
dp->pos = demuxer->filepos;
|
dp->pos = demuxer->filepos;
|
||||||
dp->flags = (flags & 0x2) ? 0x10 : 0;
|
dp->keyframe = flags & 0x2;
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
|
|
||||||
} // codec_id check, codec default case
|
} // codec_id check, codec default case
|
||||||
@ -1003,7 +1003,7 @@ got_video:
|
|||||||
dp = new_demux_packet(sizeof(dp_hdr_t)+vpkg_length+8*(1+2*(vpkg_header&0x3F)));
|
dp = new_demux_packet(sizeof(dp_hdr_t)+vpkg_length+8*(1+2*(vpkg_header&0x3F)));
|
||||||
// the timestamp seems to be in milliseconds
|
// the timestamp seems to be in milliseconds
|
||||||
dp->pos = demuxer->filepos;
|
dp->pos = demuxer->filepos;
|
||||||
dp->flags = (flags & 0x2) ? 0x10 : 0;
|
dp->keyframe = flags & 0x2;
|
||||||
ds->asf_seq = vpkg_seqnum;
|
ds->asf_seq = vpkg_seqnum;
|
||||||
dp_hdr=(dp_hdr_t*)dp->buffer;
|
dp_hdr=(dp_hdr_t*)dp->buffer;
|
||||||
dp_hdr->chunks=0;
|
dp_hdr->chunks=0;
|
||||||
|
@ -139,7 +139,7 @@ static int demux_ra_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds)
|
|||||||
memcpy(dp->buffer, ra_priv->audio_buf + x * len, len);
|
memcpy(dp->buffer, ra_priv->audio_buf + x * len, len);
|
||||||
dp->pts = x ? 0 : demuxer->filepos / ra_priv->data_size;
|
dp->pts = x ? 0 : demuxer->filepos / ra_priv->data_size;
|
||||||
dp->pos = demuxer->filepos; // all equal
|
dp->pos = demuxer->filepos; // all equal
|
||||||
dp->flags = x ? 0 : 0x10; // Mark first packet as keyframe
|
dp->keyframe = !x; // Mark first packet as keyframe
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -148,7 +148,6 @@ static int demux_ra_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds)
|
|||||||
|
|
||||||
dp->pts = demuxer->filepos / ra_priv->data_size;
|
dp->pts = demuxer->filepos / ra_priv->data_size;
|
||||||
dp->pos = demuxer->filepos;
|
dp->pos = demuxer->filepos;
|
||||||
dp->flags = 0;
|
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3132,7 +3132,7 @@ static int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet,
|
|||||||
}
|
}
|
||||||
memmove(p, es->start, es->size);
|
memmove(p, es->start, es->size);
|
||||||
*dp_offset += es->size;
|
*dp_offset += es->size;
|
||||||
(*dp)->flags = 0;
|
(*dp)->keyframe = 0;
|
||||||
(*dp)->pos = stream_tell(demuxer->stream);
|
(*dp)->pos = stream_tell(demuxer->stream);
|
||||||
(*dp)->pts = es->pts;
|
(*dp)->pts = es->pts;
|
||||||
// subtitle packets must be returned immediately if possible
|
// subtitle packets must be returned immediately if possible
|
||||||
|
@ -294,7 +294,6 @@ static void demux_ty_CopyToDemuxPacket( demux_stream_t *ds,
|
|||||||
if (pts != MP_NOPTS_VALUE)
|
if (pts != MP_NOPTS_VALUE)
|
||||||
dp->pts = pts / 90000.0;
|
dp->pts = pts / 90000.0;
|
||||||
dp->pos = pos;
|
dp->pos = pos;
|
||||||
dp->flags = 0;
|
|
||||||
ds_add_packet( ds, dp );
|
ds_add_packet( ds, dp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,6 @@ static int demux_y4m_fill_buffer(demuxer_t *demux, demux_stream_t *dsds) {
|
|||||||
dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps;
|
dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps;
|
||||||
priv->framenum++;
|
priv->framenum++;
|
||||||
dp->pos=demux->filepos;
|
dp->pos=demux->filepos;
|
||||||
dp->flags=0;
|
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -185,7 +185,7 @@ static struct demux_packet *create_packet(size_t len)
|
|||||||
dp->duration = -1;
|
dp->duration = -1;
|
||||||
dp->stream_pts = MP_NOPTS_VALUE;
|
dp->stream_pts = MP_NOPTS_VALUE;
|
||||||
dp->pos = 0;
|
dp->pos = 0;
|
||||||
dp->flags = 0;
|
dp->keyframe = false;
|
||||||
dp->refcount = 1;
|
dp->refcount = 1;
|
||||||
dp->master = NULL;
|
dp->master = NULL;
|
||||||
dp->buffer = NULL;
|
dp->buffer = NULL;
|
||||||
@ -599,14 +599,14 @@ void ds_clear_parser(demux_stream_t *ds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ds_read_packet(demux_stream_t *ds, stream_t *stream, int len,
|
void ds_read_packet(demux_stream_t *ds, stream_t *stream, int len,
|
||||||
double pts, off_t pos, int flags)
|
double pts, off_t pos, bool keyframe)
|
||||||
{
|
{
|
||||||
demux_packet_t *dp = new_demux_packet(len);
|
demux_packet_t *dp = new_demux_packet(len);
|
||||||
len = stream_read(stream, dp->buffer, len);
|
len = stream_read(stream, dp->buffer, len);
|
||||||
resize_demux_packet(dp, len);
|
resize_demux_packet(dp, len);
|
||||||
dp->pts = pts;
|
dp->pts = pts;
|
||||||
dp->pos = pos;
|
dp->pos = pos;
|
||||||
dp->flags = flags;
|
dp->keyframe = keyframe;
|
||||||
// append packet to DS stream:
|
// append packet to DS stream:
|
||||||
ds_add_packet(ds, dp);
|
ds_add_packet(ds, dp);
|
||||||
}
|
}
|
||||||
@ -650,7 +650,7 @@ int ds_fill_buffer(demux_stream_t *ds)
|
|||||||
ds->pts_bytes += p->len; // !!!
|
ds->pts_bytes += p->len; // !!!
|
||||||
if (p->stream_pts != MP_NOPTS_VALUE)
|
if (p->stream_pts != MP_NOPTS_VALUE)
|
||||||
demux->stream_pts = p->stream_pts;
|
demux->stream_pts = p->stream_pts;
|
||||||
ds->flags = p->flags;
|
ds->keyframe = p->keyframe;
|
||||||
// unlink packet:
|
// unlink packet:
|
||||||
ds->bytes -= p->len;
|
ds->bytes -= p->len;
|
||||||
ds->current = p;
|
ds->current = p;
|
||||||
|
@ -135,7 +135,7 @@ typedef struct demux_stream {
|
|||||||
off_t pos; // position in the input stream (file)
|
off_t pos; // position in the input stream (file)
|
||||||
off_t dpos; // position in the demuxed stream
|
off_t dpos; // position in the demuxed stream
|
||||||
int pack_no; // serial number of packet
|
int pack_no; // serial number of packet
|
||||||
int flags; // flags of current packet (keyframe etc)
|
bool keyframe; // keyframe flag of current packet
|
||||||
int non_interleaved; // 1 if this stream is not properly interleaved,
|
int non_interleaved; // 1 if this stream is not properly interleaved,
|
||||||
// so e.g. subtitle handling must do explicit reads.
|
// so e.g. subtitle handling must do explicit reads.
|
||||||
//---------------
|
//---------------
|
||||||
@ -315,7 +315,7 @@ void free_demuxer(struct demuxer *demuxer);
|
|||||||
|
|
||||||
void ds_add_packet(struct demux_stream *ds, struct demux_packet *dp);
|
void ds_add_packet(struct demux_stream *ds, struct demux_packet *dp);
|
||||||
void ds_read_packet(struct demux_stream *ds, struct stream *stream, int len,
|
void ds_read_packet(struct demux_stream *ds, struct stream *stream, int len,
|
||||||
double pts, off_t pos, int flags);
|
double pts, off_t pos, bool keyframe);
|
||||||
|
|
||||||
int demux_fill_buffer(struct demuxer *demux, struct demux_stream *ds);
|
int demux_fill_buffer(struct demuxer *demux, struct demux_stream *ds);
|
||||||
int ds_fill_buffer(struct demux_stream *ds);
|
int ds_fill_buffer(struct demux_stream *ds);
|
||||||
|
@ -636,7 +636,7 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
|
|||||||
if(video_codec == VIDEO_MPEG12){
|
if(video_codec == VIDEO_MPEG12){
|
||||||
sh_video->pts+=frame_time;
|
sh_video->pts+=frame_time;
|
||||||
if(picture_coding_type==1)
|
if(picture_coding_type==1)
|
||||||
d_video->flags |= 1;
|
d_video->keyframe = true;
|
||||||
if(picture_coding_type<=2 && sh_video->i_pts){
|
if(picture_coding_type<=2 && sh_video->i_pts){
|
||||||
sh_video->pts=sh_video->i_pts;
|
sh_video->pts=sh_video->i_pts;
|
||||||
sh_video->i_pts=pts;
|
sh_video->i_pts=pts;
|
||||||
|
@ -2785,8 +2785,8 @@ static double update_video_nocorrect_pts(struct MPContext *mpctx)
|
|||||||
decoded_frame = mp_dvdnav_restore_smpi(mpctx, &in_size, &packet, NULL);
|
decoded_frame = mp_dvdnav_restore_smpi(mpctx, &in_size, &packet, NULL);
|
||||||
if (in_size >= 0 && !decoded_frame)
|
if (in_size >= 0 && !decoded_frame)
|
||||||
#endif
|
#endif
|
||||||
decoded_frame = decode_video(sh_video, NULL, packet, in_size,
|
decoded_frame = decode_video(sh_video, sh_video->ds->current, packet,
|
||||||
framedrop_type, sh_video->pts);
|
in_size, framedrop_type, sh_video->pts);
|
||||||
#ifdef CONFIG_DVDNAV
|
#ifdef CONFIG_DVDNAV
|
||||||
// Save last still frame for future display
|
// Save last still frame for future display
|
||||||
mp_dvdnav_save_smpi(mpctx, in_size, packet, decoded_frame);
|
mp_dvdnav_save_smpi(mpctx, in_size, packet, decoded_frame);
|
||||||
|
@ -233,7 +233,7 @@ static int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
|
|||||||
len = tvh->functions->get_audio_framesize(tvh->priv);
|
len = tvh->functions->get_audio_framesize(tvh->priv);
|
||||||
|
|
||||||
dp=new_demux_packet(len);
|
dp=new_demux_packet(len);
|
||||||
dp->flags|=1; /* Keyframe */
|
dp->keyframe = true;
|
||||||
dp->pts=tvh->functions->grab_audio_frame(tvh->priv, dp->buffer,len);
|
dp->pts=tvh->functions->grab_audio_frame(tvh->priv, dp->buffer,len);
|
||||||
ds_add_packet(demux->audio,dp);
|
ds_add_packet(demux->audio,dp);
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ static int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
|
|||||||
{
|
{
|
||||||
len = tvh->functions->get_video_framesize(tvh->priv);
|
len = tvh->functions->get_video_framesize(tvh->priv);
|
||||||
dp=new_demux_packet(len);
|
dp=new_demux_packet(len);
|
||||||
dp->flags|=1; /* Keyframe */
|
dp->keyframe = true;
|
||||||
dp->pts=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len);
|
dp->pts=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len);
|
||||||
ds_add_packet(demux->video,dp);
|
ds_add_packet(demux->video,dp);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user