core: don't access demux_stream outside of demux.c, make it private

Generally remove all accesses to demux_stream from all the code, except
inside of demux.c. Make it completely private to demux.c.

This simplifies the code because it removes an extra concept. In demux.c
it is reduced to a simple packet queue. There were other uses of
demux_stream, but they were removed or are removed with this commit.

Remove the extra "ds" argument to demux fill_buffer callback. It was
used by demux_avi and the TV pseudo-demuxer only.

Remove usage of d_video->last_pts from the no-correct-pts code. This
field contains the last PTS retrieved after a packet that is not NOPTS.
We can easily get this value manually because we read the packets
ourselves. Reuse sh_video->last_pts to store the packet PTS values. It
was used only by the correct-pts code before, and like d_video->last_pts,
it is reset on seek. The behavior should be exactly the same.
This commit is contained in:
wm4 2013-07-11 19:17:51 +02:00
parent fa74be880c
commit 6ede485e4b
13 changed files with 97 additions and 123 deletions

View File

@ -566,13 +566,11 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg,
case M_PROPERTY_SET:
angle = demuxer_set_angle(demuxer, *(int *)arg);
if (angle >= 0) {
struct sh_stream *sh_video = demuxer->video->gsh;
if (sh_video)
resync_video_stream(sh_video->video);
if (mpctx->sh_video)
resync_video_stream(mpctx->sh_video);
struct sh_stream *sh_audio = demuxer->audio->gsh;
if (sh_audio)
resync_audio_stream(sh_audio->audio);
if (mpctx->sh_audio)
resync_audio_stream(mpctx->sh_audio);
}
return M_PROPERTY_OK;
case M_PROPERTY_GET_TYPE: {

View File

@ -360,10 +360,9 @@ static double get_main_demux_pts(struct MPContext *mpctx)
{
double main_new_pos = MP_NOPTS_VALUE;
if (mpctx->demuxer) {
for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
struct demux_stream *ds = mpctx->demuxer->ds[type];
if (ds->gsh && main_new_pos == MP_NOPTS_VALUE)
main_new_pos = demux_get_next_pts(ds->gsh);
for (int n = 0; n < mpctx->demuxer->num_streams; n++) {
if (main_new_pos == MP_NOPTS_VALUE)
main_new_pos = demux_get_next_pts(mpctx->demuxer->streams[n]);
}
}
return main_new_pos;
@ -1789,7 +1788,9 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time)
{
struct MPOpts *opts = &mpctx->opts;
// check for frame-drop:
if (mpctx->sh_audio && !mpctx->ao->untimed && !mpctx->sh_audio->ds->eof) {
if (mpctx->sh_audio && !mpctx->ao->untimed &&
!demux_stream_eof(mpctx->sh_audio->gsh))
{
float delay = opts->playback_speed * ao_get_delay(mpctx->ao);
float d = delay - mpctx->delay;
// we should avoid dropping too many frames in sequence unless we
@ -2205,7 +2206,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
return -1;
} else if (res == ASYNC_PLAY_DONE)
return 0;
else if (mpctx->sh_audio->ds->eof)
else if (demux_stream_eof(mpctx->sh_audio->gsh))
audio_eof = true;
}
@ -2338,7 +2339,7 @@ int reinit_video_chain(struct MPContext *mpctx)
vo_update_window_title(mpctx);
if (stream_control(mpctx->sh_video->ds->demuxer->stream,
if (stream_control(mpctx->sh_video->gsh->demuxer->stream,
STREAM_CTRL_GET_ASPECT_RATIO, &ar) != STREAM_UNSUPPORTED)
mpctx->sh_video->stream_aspect = ar;
@ -2438,21 +2439,23 @@ static void filter_video(struct MPContext *mpctx, struct mp_image *frame)
static struct demux_packet *video_read_frame(struct MPContext *mpctx)
{
sh_video_t *sh_video = mpctx->sh_video;
demux_stream_t *d_video = sh_video->ds;
demuxer_t *demuxer = d_video->demuxer;
float pts1 = d_video->last_pts;
demuxer_t *demuxer = sh_video->gsh->demuxer;
float pts1 = sh_video->last_pts;
struct demux_packet *pkt = demux_read_packet(sh_video->gsh);
if (!pkt)
return NULL; // EOF
if (pkt->pts != MP_NOPTS_VALUE)
sh_video->last_pts = pkt->pts;
float frame_time = sh_video->frametime;
// override frame_time for variable/unknown FPS formats:
if (!mpctx->opts.force_fps) {
double next_pts = demux_get_next_pts(sh_video->gsh);
double d = next_pts == MP_NOPTS_VALUE ? d_video->last_pts - pts1
: next_pts - d_video->last_pts;
double d = next_pts == MP_NOPTS_VALUE ? sh_video->last_pts - pts1
: next_pts - sh_video->last_pts;
if (d >= 0) {
if (demuxer->file_format == DEMUXER_TYPE_TV) {
if (d > 0) {
@ -2467,8 +2470,7 @@ static struct demux_packet *video_read_frame(struct MPContext *mpctx)
}
}
sh_video->pts = d_video->last_pts;
sh_video->pts = sh_video->last_pts;
sh_video->next_frame_time = frame_time;
return pkt;
}
@ -2515,7 +2517,7 @@ static void determine_frame_pts(struct MPContext *mpctx)
if (opts->user_pts_assoc_mode)
sh_video->pts_assoc_mode = opts->user_pts_assoc_mode;
else if (sh_video->pts_assoc_mode == 0) {
if (mpctx->sh_video->ds->demuxer->timestamp_type == TIMESTAMP_TYPE_PTS
if (mpctx->sh_video->gsh->demuxer->timestamp_type == TIMESTAMP_TYPE_PTS
&& sh_video->codec_reordered_pts != MP_NOPTS_VALUE)
sh_video->pts_assoc_mode = 1;
else

View File

@ -17,6 +17,7 @@
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define DEMUX_PRIV(x) x
#include <stdio.h>
#include <stdlib.h>
@ -88,6 +89,20 @@ const demuxer_desc_t *const demuxer_list[] = {
NULL
};
typedef struct demux_stream {
enum stream_type stream_type;
int eof; // end of demuxed stream? (true if all buffer empty)
//---------------
int fill_count; // number of unsuccessful tries to get a packet
int packs; // number of packets in buffer
int bytes; // total bytes of packets in buffer
struct demux_packet *head;
struct demux_packet *tail;
struct demuxer *demuxer; // parent demuxer structure (stream handler)
// ---- stream header ----
struct sh_stream *gsh;
} demux_stream_t;
static void add_stream_chapters(struct demuxer *demuxer);
static int packet_destroy(void *ptr)
@ -200,6 +215,19 @@ struct demux_packet *demux_copy_packet(struct demux_packet *dp)
return new;
}
static void ds_free_packs(demux_stream_t *ds)
{
demux_packet_t *dp = ds->head;
while (dp) {
demux_packet_t *dn = dp->next;
free_demux_packet(dp);
dp = dn;
}
ds->head = ds->tail = NULL;
ds->packs = 0; // !!!!!
ds->bytes = 0;
}
static void free_demuxer_stream(struct demux_stream *ds)
{
ds_free_packs(ds);
@ -290,7 +318,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type)
struct sh_video *sht = talloc_zero(demuxer, struct sh_video);
sht->gsh = sh;
sht->opts = sh->opts;
sht->ds = demuxer->video;
sh->video = sht;
break;
}
@ -298,7 +325,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type)
struct sh_audio *sht = talloc_zero(demuxer, struct sh_audio);
sht->gsh = sh;
sht->opts = sh->opts;
sht->ds = demuxer->audio;
sht->samplesize = 2;
sht->sample_format = AF_FORMAT_S16_NE;
sh->audio = sht;
@ -308,7 +334,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type)
struct sh_sub *sht = talloc_zero(demuxer, struct sh_sub);
sht->gsh = sh;
sht->opts = sh->opts;
sht->ds = demuxer->sub;
sh->sub = sht;
break;
}
@ -360,20 +385,7 @@ void free_demuxer(demuxer_t *demuxer)
talloc_free(demuxer);
}
// Returns the same value as demuxer->fill_buffer: 1 ok, 0 EOF/not selected.
int demuxer_add_packet(demuxer_t *demuxer, struct sh_stream *stream,
demux_packet_t *dp)
{
if (!dp || !demuxer_stream_is_selected(demuxer, stream)) {
free_demux_packet(dp);
return 0;
} else {
ds_add_packet(demuxer->ds[stream->type], dp);
return 1;
}
}
void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
static void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
{
// append packet to DS stream:
++ds->packs;
@ -393,6 +405,19 @@ void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
ds->demuxer->video->packs);
}
// Returns the same value as demuxer->fill_buffer: 1 ok, 0 EOF/not selected.
int demuxer_add_packet(demuxer_t *demuxer, struct sh_stream *stream,
demux_packet_t *dp)
{
if (!dp || !demuxer_stream_is_selected(demuxer, stream)) {
free_demux_packet(dp);
return 0;
} else {
ds_add_packet(demuxer->ds[stream->type], dp);
return 1;
}
}
static bool demux_check_queue_full(demuxer_t *demux)
{
int apacks = demux->audio ? demux->audio->packs : 0;
@ -421,10 +446,9 @@ static bool demux_check_queue_full(demuxer_t *demux)
// 0 = EOF or no stream found or invalid type
// 1 = successfully read a packet
int demux_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
static int demux_fill_buffer(demuxer_t *demux)
{
// Note: parameter 'ds' can be NULL!
return demux->desc->fill_buffer ? demux->desc->fill_buffer(demux, ds) : 0;
return demux->desc->fill_buffer ? demux->desc->fill_buffer(demux) : 0;
}
// return value:
@ -465,7 +489,7 @@ static int ds_get_packets(demux_stream_t *ds)
if (demux_check_queue_full(demux))
break;
if (!demux_fill_buffer(demux, ds)) {
if (!demux_fill_buffer(demux)) {
mp_dbg(MSGT_DEMUXER, MSGL_DBG2,
"ds_get_packets()->demux_fill_buffer() failed\n");
break; // EOF
@ -485,21 +509,6 @@ static int ds_get_packets(demux_stream_t *ds)
return 0;
}
void ds_free_packs(demux_stream_t *ds)
{
demux_packet_t *dp = ds->head;
while (dp) {
demux_packet_t *dn = dp->next;
free_demux_packet(dp);
dp = dn;
}
ds->head = ds->tail = NULL;
ds->packs = 0; // !!!!!
ds->bytes = 0;
ds->last_pts = MP_NOPTS_VALUE;
ds->last_pts_bytes = 0;
}
static struct demux_stream *ds_from_sh(struct sh_stream *sh)
{
for (int n = 0; n < STREAM_TYPE_COUNT; n++) {
@ -526,13 +535,6 @@ struct demux_packet *demux_read_packet(struct sh_stream *sh)
ds->bytes -= pkt->len;
ds->packs--;
if (pkt->pts != MP_NOPTS_VALUE) {
ds->last_pts = pkt->pts;
ds->last_pts_bytes = 0;
} else {
ds->last_pts_bytes += pkt->len;
}
if (pkt->stream_pts != MP_NOPTS_VALUE)
sh->demuxer->stream_pts = pkt->stream_pts;
@ -566,6 +568,13 @@ bool demuxer_stream_has_packets_queued(struct demuxer *d, struct sh_stream *stre
return demux_has_packet(stream);
}
// Return whether EOF was returned with an earlier packet read.
bool demux_stream_eof(struct sh_stream *sh)
{
struct demux_stream *ds = ds_from_sh(sh);
return !ds || ds->eof;
}
// ====================================================================
void demuxer_help(void)

View File

@ -88,22 +88,6 @@ enum timestamp_type {
// demux_lavf can pass lavf buffers using FF_INPUT_BUFFER_PADDING_SIZE instead
#define MP_INPUT_BUFFER_PADDING_SIZE 16
typedef struct demux_stream {
enum stream_type stream_type;
double last_pts; // pts of the last packet that was read
int last_pts_bytes; // number of bytes read after last pts stamp
int eof; // end of demuxed stream? (true if all buffer empty)
//---------------
int fill_count; // number of unsuccessful tries to get a packet
int packs; // number of packets in buffer
int bytes; // total bytes of packets in buffer
struct demux_packet *head;
struct demux_packet *tail;
struct demuxer *demuxer; // parent demuxer structure (stream handler)
// ---- stream header ----
struct sh_stream *gsh;
} demux_stream_t;
#define MAX_SH_STREAMS 256
struct demuxer;
@ -126,7 +110,7 @@ typedef struct demuxer_desc {
// Mandatory if safe_check == 1, else optional
int (*check_file)(struct demuxer *demuxer);
/// Get packets from file, return 0 on eof. Mandatory
int (*fill_buffer)(struct demuxer *demuxer, struct demux_stream *ds);
int (*fill_buffer)(struct demuxer *demuxer);
/// Open the demuxer, return demuxer on success, NULL on failure
struct demuxer *(*open)(struct demuxer *demuxer); // Optional
/// Close the demuxer
@ -249,15 +233,11 @@ void free_demuxer(struct demuxer *demuxer);
int demuxer_add_packet(demuxer_t *demuxer, struct sh_stream *stream,
demux_packet_t *dp);
void ds_add_packet(struct demux_stream *ds, struct demux_packet *dp);
int demux_fill_buffer(struct demuxer *demux, struct demux_stream *ds);
void ds_free_packs(struct demux_stream *ds);
struct demux_packet *demux_read_packet(struct sh_stream *sh);
double demux_get_next_pts(struct sh_stream *sh);
bool demux_has_packet(struct sh_stream *sh);
bool demux_stream_eof(struct sh_stream *sh);
struct demuxer *demux_open(struct MPOpts *opts, struct stream *stream,
int file_format, char *filename);

View File

@ -637,7 +637,7 @@ static int destroy_avpacket(void *pkt)
return 0;
}
static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds)
static int demux_lavf_fill_buffer(demuxer_t *demux)
{
lavf_priv_t *priv = demux->priv;
demux_packet_t *dp;

View File

@ -61,7 +61,8 @@ static void demux_seek_mf(demuxer_t *demuxer,float rel_seek_secs,float audio_del
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
static int demux_mf_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
static int demux_mf_fill_buffer(demuxer_t *demuxer)
{
mf_t *mf = demuxer->priv;
if (mf->curr_frame >= mf->nr_of_files)
return 0;
@ -85,7 +86,7 @@ static int demux_mf_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){
dp->pts = mf->curr_frame / mf->sh->fps;
dp->pos = mf->curr_frame;
dp->keyframe = true;
ds_add_packet(demuxer->video, dp);
demuxer_add_packet(demuxer, demuxer->streams[0], dp);
}
talloc_free(data.start);
}
@ -215,11 +216,6 @@ static demuxer_t* demux_open_mf(demuxer_t* demuxer){
goto error;
}
// make sure that the video demuxer stream header knows about its
// parent video demuxer stream (this is getting wacky), or else
// video_read_properties() will choke
sh_video->ds = demuxer->video;
sh_video->disp_w = 0;
sh_video->disp_h = 0;
sh_video->fps = mf_fps;

View File

@ -1962,7 +1962,7 @@ static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
} else
dp->pts =
real_fix_timestamp(dp->buffer, timestamp,
demuxer->video->gsh->video->bih->biCompression,
track->stream->video->bih->biCompression,
&track->rv_kf_base, &track->rv_kf_pts, NULL);
dp->pos = demuxer->filepos;
dp->keyframe = keyframe;
@ -2046,7 +2046,7 @@ static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
if (track->sub_packet_cnt == 0)
track->audio_filepos = demuxer->filepos;
if (++(track->sub_packet_cnt) == sph) {
int apk_usize = demuxer->audio->gsh->audio->wf->nBlockAlign;
int apk_usize = track->stream->audio->wf->nBlockAlign;
track->sub_packet_cnt = 0;
// Release all the audio packets
for (x = 0; x < sph * w / apk_usize; x++) {
@ -2465,7 +2465,7 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
}
}
static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
static int demux_mkv_fill_buffer(demuxer_t *demuxer)
{
for (;;) {
int res;
@ -2657,7 +2657,7 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
: 0;
mkv_d->a_skip_to_keyframe = 1;
demux_mkv_fill_buffer(demuxer, NULL);
demux_mkv_fill_buffer(demuxer);
} else if ((demuxer->movi_end <= 0) || !(flags & SEEK_ABSOLUTE))
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] seek unsupported flags\n");
else {
@ -2696,7 +2696,7 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
mkv_d->skip_to_timecode = index->timecode * mkv_d->tc_scale;
mkv_d->a_skip_to_keyframe = 1;
demux_mkv_fill_buffer(demuxer, NULL);
demux_mkv_fill_buffer(demuxer);
}
}

View File

@ -272,11 +272,9 @@ static int demux_mng_check_file(demuxer_t *demuxer)
/**
* \brief MPlayer callback: Fill buffer from MNG stream.
* \param[in] demuxer demuxer structure
* \param[in] ds demuxer stream
* \return \p 1 on success, \p 0 on error
*/
static int demux_mng_fill_buffer(demuxer_t * demuxer,
demux_stream_t * ds)
static int demux_mng_fill_buffer(demuxer_t * demuxer)
{
mng_priv_t * mng_priv = demuxer->priv;
mng_handle h_mng = mng_priv->h_mng;
@ -340,7 +338,7 @@ static int demux_mng_fill_buffer(demuxer_t * demuxer,
// frame time mechanism (GIF, MATROSKA, MNG) in video.c to work.
dp->pts = (float)mng_priv->show_next_time_ms / 1000.0f;
dp->pos = stream_tell(demuxer->stream);
ds_add_packet(demuxer->video, dp);
demuxer_add_packet(demuxer, demuxer->streams[0], dp);
return 1;
}
@ -417,12 +415,6 @@ static demuxer_t * demux_mng_open(demuxer_t * demuxer)
struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO);
sh_video = sh->video;
// Make sure that the video demuxer stream header knows about its
// parent video demuxer stream (this is getting wacky), or else
// video_read_properties() will choke.
// (Thanks to demux_gif.c for this.)
sh_video->ds = demuxer->video;
// set format of pixels in video packets
sh_video->gsh->codec = "rawvideo";
sh_video->format = MP_FOURCC_RGB32;

View File

@ -72,8 +72,9 @@ static demuxer_t* demux_rawaudio_open(demuxer_t* demuxer) {
return demuxer;
}
static int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
sh_audio_t* sh_audio = demuxer->audio->gsh->audio;
static int demux_rawaudio_fill_buffer(demuxer_t* demuxer)
{
sh_audio_t* sh_audio = demuxer->streams[0]->audio;
int l = sh_audio->wf->nAvgBytesPerSec;
int64_t spos = stream_tell(demuxer->stream);
demux_packet_t* dp;
@ -87,14 +88,14 @@ static int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
l = stream_read(demuxer->stream,dp->buffer,l);
resize_demux_packet(dp, l);
ds_add_packet(ds,dp);
demuxer_add_packet(demuxer, demuxer->streams[0], dp);
return 1;
}
static void demux_rawaudio_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
stream_t* s = demuxer->stream;
sh_audio_t* sh_audio = demuxer->audio->gsh->audio;
sh_audio_t* sh_audio = demuxer->streams[0]->audio;
int64_t base,pos;
base = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : stream_tell(s);

View File

@ -130,7 +130,8 @@ static demuxer_t* demux_rawvideo_open(demuxer_t* demuxer) {
return demuxer;
}
static int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
static int demux_rawvideo_fill_buffer(demuxer_t* demuxer)
{
int64_t spos = stream_tell(demuxer->stream);
demux_packet_t* dp;
int size;
@ -144,27 +145,24 @@ static int demux_rawvideo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
size = stream_read(demuxer->stream, dp->buffer, imgsize);
resize_demux_packet(dp, size);
ds_add_packet(ds, dp);
demuxer_add_packet(demuxer, demuxer->streams[0], dp);
return 1;
}
static void demux_rawvideo_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
stream_t* s = demuxer->stream;
sh_video_t* sh_video = demuxer->video->gsh->video;
int64_t pos;
pos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : stream_tell(s);
if(flags & SEEK_FACTOR)
pos += ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs);
else
pos += (rel_seek_secs*sh_video->i_bps);
pos += (rel_seek_secs*fps*imgsize);
if(pos < 0) pos = 0;
if(demuxer->movi_end && pos > demuxer->movi_end) pos = (demuxer->movi_end-imgsize);
pos/=imgsize;
stream_seek(s,pos*imgsize);
//sh_video->timer=pos * sh_video->frametime;
// printf("demux_rawvideo: streamtell=%d\n",(int)stream_tell(demuxer->stream));
}

View File

@ -1358,7 +1358,7 @@ static int d_check_file(struct demuxer *demuxer)
return DEMUXER_TYPE_SUBREADER;
}
static int d_fill_buffer(struct demuxer *demuxer, struct demux_stream *ds)
static int d_fill_buffer(struct demuxer *demuxer)
{
struct priv *p = demuxer->priv;
struct demux_packet *dp = demux_packet_list_fill(p->pkts, p->num_pkts,

View File

@ -70,11 +70,9 @@ struct sh_stream {
struct MPOpts *opts;
};
#define SH_COMMON \
struct sh_stream *gsh; \
struct MPOpts *opts; \
struct demux_stream *ds; \
/* usually a FourCC, exact meaning depends on gsh->format */ \
unsigned int format; \
int initialized; \

View File

@ -210,7 +210,7 @@ static void tv_scan(tvi_handle_t *tvh)
*/
/* fill demux->video and demux->audio */
static int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
static int demux_tv_fill_buffer(demuxer_t *demux)
{
tvi_handle_t *tvh=(tvi_handle_t*)(demux->priv);
demux_packet_t* dp;