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.
26 #include "aviheader.h"
29 #include "stream/stream.h"
35 muxer_t
*muxer_new_muxer(int type
,stream_t
*stream
){
36 muxer_t
* muxer
=calloc(1,sizeof(muxer_t
));
39 muxer
->stream
= stream
;
42 if(! muxer_init_muxer_mpeg(muxer
))
45 case MUXER_TYPE_RAWVIDEO
:
46 if(! muxer_init_muxer_rawvideo(muxer
))
49 case MUXER_TYPE_RAWAUDIO
:
50 if(! muxer_init_muxer_rawaudio(muxer
))
53 #ifdef CONFIG_LIBAVFORMAT
55 if(! muxer_init_muxer_lavf(muxer
))
61 if(! muxer_init_muxer_avi(muxer
))
71 /* buffer frames until we either:
72 * (a) have at least one frame from each stream
73 * (b) run out of memory */
74 void muxer_write_chunk(muxer_stream_t
*s
, size_t len
, unsigned int flags
, double dts
, double pts
) {
75 if(dts
== MP_NOPTS_VALUE
) dts
= s
->timer
;
76 if(pts
== MP_NOPTS_VALUE
) pts
= s
->timer
; // this is wrong
78 if (s
->muxer
->muxbuf_skip_buffer
) {
79 s
->muxer
->cont_write_chunk(s
, len
, flags
, dts
, pts
);
82 int num
= s
->muxer
->muxbuf_num
++;
85 tmp
= realloc_struct(s
->muxer
->muxbuf
, (num
+1), sizeof(muxbuf_t
));
87 mp_tmsg(MSGT_MUXER
, MSGL_FATAL
, "Muxer frame buffer cannot reallocate memory!\n");
90 s
->muxer
->muxbuf
= tmp
;
91 buf
= s
->muxer
->muxbuf
+ num
;
93 /* buffer this frame */
99 buf
->buffer
= malloc(len
);
101 mp_tmsg(MSGT_MUXER
, MSGL_FATAL
, "Muxer frame buffer cannot allocate memory!\n");
104 memcpy(buf
->buffer
, s
->buffer
, buf
->len
);
107 /* see if we need to keep buffering */
108 s
->muxer
->muxbuf_skip_buffer
= 1;
109 for (num
= 0; s
->muxer
->streams
[num
]; ++num
)
110 if (!s
->muxer
->streams
[num
]->muxbuf_seen
)
111 s
->muxer
->muxbuf_skip_buffer
= 0;
113 /* see if we can flush buffer now */
114 if (s
->muxer
->muxbuf_skip_buffer
) {
115 mp_tmsg(MSGT_MUXER
, MSGL_V
, "Muxer frame buffer sending %d frame(s) to the muxer.\n", s
->muxer
->muxbuf_num
);
117 /* fix parameters for all streams */
118 for (num
= 0; s
->muxer
->streams
[num
]; ++num
) {
119 muxer_stream_t
*str
= s
->muxer
->streams
[num
];
120 if(str
->muxer
->fix_stream_parameters
)
121 muxer_stream_fix_parameters(str
->muxer
, str
);
125 if (s
->muxer
->cont_write_header
)
126 muxer_write_header(s
->muxer
);
128 /* send all buffered frames to muxer */
129 for (num
= 0; num
< s
->muxer
->muxbuf_num
; ++num
) {
131 buf
= s
->muxer
->muxbuf
+ num
;
134 /* 1. save timer and buffer (might have changed by now) */
135 tmp_buf
.dts
= s
->timer
;
136 tmp_buf
.buffer
= s
->buffer
;
138 /* 2. move stored timer and buffer into stream and mux it */
140 s
->buffer
= buf
->buffer
;
141 s
->muxer
->cont_write_chunk(s
, buf
->len
, buf
->flags
, buf
->dts
, buf
->pts
);
143 /* 3. restore saved timer and buffer */
144 s
->timer
= tmp_buf
.dts
;
145 s
->buffer
= tmp_buf
.buffer
;
148 free(s
->muxer
->muxbuf
);
149 s
->muxer
->muxbuf_num
= 0;
153 /* this code moved directly from muxer_avi.c */
155 if(s
->h
.dwSampleSize
){
157 s
->h
.dwLength
+=len
/s
->h
.dwSampleSize
;
158 if(len
%s
->h
.dwSampleSize
) mp_tmsg(MSGT_MUXER
, MSGL_WARN
, "Warning, len isn't divisible by samplesize!\n");
163 s
->timer
=(double)s
->h
.dwLength
*s
->h
.dwScale
/s
->h
.dwRate
;