2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "stream/stream.h"
29 typedef struct dd_priv
{
35 extern const demuxer_desc_t demuxer_desc_demuxers
;
37 demuxer_t
* new_demuxers_demuxer(demuxer_t
* vd
, demuxer_t
* ad
, demuxer_t
* sd
) {
41 ret
= calloc(1,sizeof(demuxer_t
));
43 priv
= malloc(sizeof(dd_priv_t
));
49 ret
->type
= ret
->file_format
= DEMUXER_TYPE_DEMUXERS
;
50 // Video is the most important :-)
51 ret
->stream
= vd
->stream
;
52 ret
->seekable
= vd
->seekable
&& ad
->seekable
&& sd
->seekable
;
54 ret
->video
= vd
->video
;
55 ret
->audio
= ad
->audio
;
57 if (sd
&& sd
!= vd
&& sd
!= ad
) sd
->sub
->non_interleaved
= 1;
59 // without these, demux_demuxers_fill_buffer will never be called,
60 // but they break the demuxer-specific code in video.c
62 if (vd
) vd
->video
->demuxer
= ret
;
63 if (ad
) ad
->audio
->demuxer
= ret
;
64 if (sd
) sd
->sub
->demuxer
= ret
;
67 // HACK?, necessary for subtitle (and audio and video when implemented) switching
68 memcpy(ret
->v_streams
, vd
->v_streams
, sizeof(ret
->v_streams
));
69 memcpy(ret
->a_streams
, ad
->a_streams
, sizeof(ret
->a_streams
));
70 memcpy(ret
->s_streams
, sd
->s_streams
, sizeof(ret
->s_streams
));
72 ret
->desc
= &demuxer_desc_demuxers
;
77 static int demux_demuxers_fill_buffer(demuxer_t
*demux
,demux_stream_t
*ds
) {
82 // HACK: make sure the subtitles get properly interleaved if with -subfile
83 if (priv
->sd
&& priv
->sd
->sub
!= ds
&&
84 priv
->sd
!= priv
->vd
&& priv
->sd
!= priv
->ad
)
85 ds_get_next_pts(priv
->sd
->sub
);
86 if(priv
->vd
&& priv
->vd
->video
== ds
)
87 return demux_fill_buffer(priv
->vd
,ds
);
88 else if(priv
->ad
&& priv
->ad
->audio
== ds
)
89 return demux_fill_buffer(priv
->ad
,ds
);
90 else if(priv
->sd
&& priv
->sd
->sub
== ds
)
91 return demux_fill_buffer(priv
->sd
,ds
);
93 mp_msg(MSGT_DEMUX
,MSGL_WARN
,MSGTR_MPDEMUX_DEMUXERS_FillBufferError
);
97 static void demux_demuxers_seek(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
) {
102 priv
->ad
->stream
->eof
= 0;
103 priv
->sd
->stream
->eof
= 0;
106 demux_seek(priv
->vd
,rel_seek_secs
,audio_delay
,flags
);
108 pos
= demuxer
->video
->pts
;
110 demux_fill_buffer(priv
->vd
, demuxer
->video
);
111 if (demuxer
->video
->first
)
112 pos
= demuxer
->video
->first
->pts
;
115 if(priv
->ad
!= priv
->vd
) {
116 sh_audio_t
* sh
= demuxer
->audio
->sh
;
117 demux_seek(priv
->ad
,pos
,audio_delay
,1);
118 // In case the demuxer don't set pts
119 if(!demuxer
->audio
->pts
)
120 demuxer
->audio
->pts
= pos
-((ds_tell_pts(demuxer
->audio
)-sh
->a_in_buffer_len
)/(float)sh
->i_bps
);
123 if(priv
->sd
!= priv
->vd
)
124 demux_seek(priv
->sd
,pos
,audio_delay
,1);
128 static void demux_close_demuxers(demuxer_t
* demuxer
) {
129 dd_priv_t
* priv
= demuxer
->priv
;
133 free_demuxer(priv
->vd
);
134 if(priv
->ad
&& priv
->ad
!= priv
->vd
) {
135 // That's a hack to free the audio file stream
136 // It's ok atm but we shouldn't free that here
137 s
= priv
->ad
->stream
;
138 free_demuxer(priv
->ad
);
140 } if(priv
->sd
&& priv
->sd
!= priv
->vd
&& priv
->sd
!= priv
->ad
) {
141 s
= priv
->sd
->stream
;
142 free_demuxer(priv
->sd
);
150 static int demux_demuxers_control(demuxer_t
*demuxer
,int cmd
, void *arg
){
151 dd_priv_t
* priv
= demuxer
->priv
;
153 case DEMUXER_CTRL_GET_TIME_LENGTH
:
154 *((double *)arg
) = demuxer_get_time_length(priv
->vd
);
155 return DEMUXER_CTRL_OK
;
156 case DEMUXER_CTRL_GET_PERCENT_POS
:
157 *((int *)arg
) = demuxer_get_percent_pos(priv
->vd
);
158 return DEMUXER_CTRL_OK
;
160 return DEMUXER_CTRL_NOTIMPL
;
163 const demuxer_desc_t demuxer_desc_demuxers
= {
165 "", // Not selectable
169 DEMUXER_TYPE_DEMUXERS
,
172 demux_demuxers_fill_buffer
,
174 demux_close_demuxers
,
176 demux_demuxers_control