8 #include "stream/stream.h"
12 typedef struct dd_priv
{
18 extern const demuxer_desc_t demuxer_desc_demuxers
;
20 demuxer_t
* new_demuxers_demuxer(demuxer_t
* vd
, demuxer_t
* ad
, demuxer_t
* sd
) {
24 ret
= calloc(1,sizeof(demuxer_t
));
26 priv
= malloc(sizeof(dd_priv_t
));
32 ret
->type
= ret
->file_format
= DEMUXER_TYPE_DEMUXERS
;
33 // Video is the most important :-)
34 ret
->stream
= vd
->stream
;
35 ret
->seekable
= vd
->seekable
&& ad
->seekable
&& sd
->seekable
;
37 ret
->video
= vd
->video
;
38 ret
->audio
= ad
->audio
;
41 ret
->desc
= &demuxer_desc_demuxers
;
46 static int demux_demuxers_fill_buffer(demuxer_t
*demux
,demux_stream_t
*ds
) {
51 if(ds
->demuxer
== priv
->vd
)
52 return demux_fill_buffer(priv
->vd
,ds
);
53 else if(ds
->demuxer
== priv
->ad
)
54 return demux_fill_buffer(priv
->ad
,ds
);
55 else if(ds
->demuxer
== priv
->sd
)
56 return demux_fill_buffer(priv
->sd
,ds
);
58 mp_msg(MSGT_DEMUX
,MSGL_WARN
,MSGTR_MPDEMUX_DEMUXERS_FillBufferError
);
62 static void demux_demuxers_seek(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
) {
67 priv
->ad
->stream
->eof
= 0;
68 priv
->sd
->stream
->eof
= 0;
71 demux_seek(priv
->vd
,rel_seek_secs
,audio_delay
,flags
);
73 pos
= demuxer
->video
->pts
;
75 demux_fill_buffer(priv
->vd
, demuxer
->video
);
76 if (demuxer
->video
->first
)
77 pos
= demuxer
->video
->first
->pts
;
80 if(priv
->ad
!= priv
->vd
) {
81 sh_audio_t
* sh
= demuxer
->audio
->sh
;
82 demux_seek(priv
->ad
,pos
,audio_delay
,1);
83 // In case the demuxer don't set pts
84 if(!demuxer
->audio
->pts
)
85 demuxer
->audio
->pts
= pos
-((ds_tell_pts(demuxer
->audio
)-sh
->a_in_buffer_len
)/(float)sh
->i_bps
);
88 if(priv
->sd
!= priv
->vd
)
89 demux_seek(priv
->sd
,pos
,audio_delay
,1);
93 static void demux_close_demuxers(demuxer_t
* demuxer
) {
94 dd_priv_t
* priv
= demuxer
->priv
;
98 free_demuxer(priv
->vd
);
99 if(priv
->ad
&& priv
->ad
!= priv
->vd
) {
100 // That's a hack to free the audio file stream
101 // It's ok atm but we shouldn't free that here
102 s
= priv
->ad
->stream
;
103 free_demuxer(priv
->ad
);
105 } if(priv
->sd
&& priv
->sd
!= priv
->vd
&& priv
->sd
!= priv
->ad
) {
106 s
= priv
->sd
->stream
;
107 free_demuxer(priv
->sd
);
115 static int demux_demuxers_control(demuxer_t
*demuxer
,int cmd
, void *arg
){
116 dd_priv_t
* priv
= demuxer
->priv
;
118 case DEMUXER_CTRL_GET_TIME_LENGTH
:
119 *((double *)arg
) = demuxer_get_time_length(priv
->vd
);
120 return DEMUXER_CTRL_OK
;
121 case DEMUXER_CTRL_GET_PERCENT_POS
:
122 *((int *)arg
) = demuxer_get_percent_pos(priv
->vd
);
123 return DEMUXER_CTRL_OK
;
125 return DEMUXER_CTRL_NOTIMPL
;
128 const demuxer_desc_t demuxer_desc_demuxers
= {
130 "", // Not selectable
134 DEMUXER_TYPE_DEMUXERS
,
137 demux_demuxers_fill_buffer
,
139 demux_close_demuxers
,
141 demux_demuxers_control