12 #include "stream/stream.h"
19 muxer_t
*muxer_new_muxer(int type
,stream_t
*stream
){
20 muxer_t
* muxer
=calloc(1,sizeof(muxer_t
));
23 muxer
->stream
= stream
;
26 if(! muxer_init_muxer_mpeg(muxer
))
29 case MUXER_TYPE_RAWVIDEO
:
30 if(! muxer_init_muxer_rawvideo(muxer
))
33 case MUXER_TYPE_RAWAUDIO
:
34 if(! muxer_init_muxer_rawaudio(muxer
))
37 #ifdef CONFIG_LIBAVFORMAT
39 if(! muxer_init_muxer_lavf(muxer
))
45 if(! muxer_init_muxer_avi(muxer
))
55 /* buffer frames until we either:
56 * (a) have at least one frame from each stream
57 * (b) run out of memory */
58 void muxer_write_chunk(muxer_stream_t
*s
, size_t len
, unsigned int flags
, double dts
, double pts
) {
59 if(dts
== MP_NOPTS_VALUE
) dts
= s
->timer
;
60 if(pts
== MP_NOPTS_VALUE
) pts
= s
->timer
; // this is wrong
62 if (s
->muxer
->muxbuf_skip_buffer
) {
63 s
->muxer
->cont_write_chunk(s
, len
, flags
, dts
, pts
);
66 int num
= s
->muxer
->muxbuf_num
++;
69 tmp
= realloc_struct(s
->muxer
->muxbuf
, (num
+1), sizeof(muxbuf_t
));
71 mp_msg(MSGT_MUXER
, MSGL_FATAL
, MSGTR_MuxbufReallocErr
);
74 s
->muxer
->muxbuf
= tmp
;
75 buf
= s
->muxer
->muxbuf
+ num
;
77 /* buffer this frame */
83 buf
->buffer
= malloc(len
);
85 mp_msg(MSGT_MUXER
, MSGL_FATAL
, MSGTR_MuxbufMallocErr
);
88 memcpy(buf
->buffer
, s
->buffer
, buf
->len
);
91 /* see if we need to keep buffering */
92 s
->muxer
->muxbuf_skip_buffer
= 1;
93 for (num
= 0; s
->muxer
->streams
[num
]; ++num
)
94 if (!s
->muxer
->streams
[num
]->muxbuf_seen
)
95 s
->muxer
->muxbuf_skip_buffer
= 0;
97 /* see if we can flush buffer now */
98 if (s
->muxer
->muxbuf_skip_buffer
) {
99 mp_msg(MSGT_MUXER
, MSGL_V
, MSGTR_MuxbufSending
, s
->muxer
->muxbuf_num
);
101 /* fix parameters for all streams */
102 for (num
= 0; s
->muxer
->streams
[num
]; ++num
) {
103 muxer_stream_t
*str
= s
->muxer
->streams
[num
];
104 if(str
->muxer
->fix_stream_parameters
)
105 muxer_stream_fix_parameters(str
->muxer
, str
);
109 if (s
->muxer
->cont_write_header
)
110 muxer_write_header(s
->muxer
);
112 /* send all buffered frames to muxer */
113 for (num
= 0; num
< s
->muxer
->muxbuf_num
; ++num
) {
115 buf
= s
->muxer
->muxbuf
+ num
;
118 /* 1. save timer and buffer (might have changed by now) */
119 tmp_buf
.dts
= s
->timer
;
120 tmp_buf
.buffer
= s
->buffer
;
122 /* 2. move stored timer and buffer into stream and mux it */
124 s
->buffer
= buf
->buffer
;
125 s
->muxer
->cont_write_chunk(s
, buf
->len
, buf
->flags
, buf
->dts
, buf
->pts
);
127 /* 3. restore saved timer and buffer */
128 s
->timer
= tmp_buf
.dts
;
129 s
->buffer
= tmp_buf
.buffer
;
132 free(s
->muxer
->muxbuf
);
133 s
->muxer
->muxbuf_num
= 0;
137 /* this code moved directly from muxer_avi.c */
139 if(s
->h
.dwSampleSize
){
141 s
->h
.dwLength
+=len
/s
->h
.dwSampleSize
;
142 if(len
%s
->h
.dwSampleSize
) mp_msg(MSGT_MUXER
, MSGL_WARN
, MSGTR_WarningLenIsntDivisible
);
147 s
->timer
=(double)s
->h
.dwLength
*s
->h
.dwScale
/s
->h
.dwRate
;