|
|
|
@ -71,6 +71,7 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
c->curframe = 0; |
|
|
|
|
c->lastframe = -1; |
|
|
|
|
c->curbits = 8; |
|
|
|
|
c->frames_noted = 0; |
|
|
|
|
|
|
|
|
|
st = av_new_stream(s, 0); |
|
|
|
|
if (!st) |
|
|
|
@ -156,15 +157,42 @@ static int mpc_read_close(AVFormatContext *s) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Seek to the given position |
|
|
|
|
* If position is unknown but is within the limits of file |
|
|
|
|
* then packets are skipped unless desired position is reached |
|
|
|
|
* |
|
|
|
|
* Also this function makes use of the fact that timestamp == frameno |
|
|
|
|
*/ |
|
|
|
|
static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) |
|
|
|
|
{ |
|
|
|
|
AVStream *st = s->streams[stream_index]; |
|
|
|
|
MPCContext *c = s->priv_data; |
|
|
|
|
AVPacket pkt1, *pkt = &pkt1; |
|
|
|
|
int ret; |
|
|
|
|
int index = av_index_search_timestamp(st, timestamp, flags); |
|
|
|
|
if (index < 0) |
|
|
|
|
return -1; |
|
|
|
|
c->curframe = st->index_entries[index].pos; |
|
|
|
|
uint32_t lastframe; |
|
|
|
|
|
|
|
|
|
/* if found, seek there */ |
|
|
|
|
if (index >= 0){ |
|
|
|
|
c->curframe = st->index_entries[index].pos; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
/* if timestamp is out of bounds, return error */ |
|
|
|
|
if(timestamp < 0 || timestamp >= c->fcount) |
|
|
|
|
return -1; |
|
|
|
|
/* seek to the furthest known position and read packets until
|
|
|
|
|
we reach desired position */ |
|
|
|
|
lastframe = c->curframe; |
|
|
|
|
if(c->frames_noted) c->curframe = c->frames_noted - 1; |
|
|
|
|
while(c->curframe < timestamp){ |
|
|
|
|
ret = av_read_frame(s, pkt); |
|
|
|
|
if (ret < 0){ |
|
|
|
|
c->curframe = lastframe; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
av_free_packet(pkt); |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|