11 #include "aviheader.h"
21 muxer_t
*muxer_new_muxer(int type
,FILE *f
){
22 muxer_t
* muxer
=calloc(1,sizeof(muxer_t
));
28 if(! muxer_init_muxer_mpeg(muxer
))
31 case MUXER_TYPE_RAWVIDEO
:
32 if(! muxer_init_muxer_rawvideo(muxer
))
35 case MUXER_TYPE_RAWAUDIO
:
36 if(! muxer_init_muxer_rawaudio(muxer
))
39 #if defined(USE_LIBAVFORMAT) || defined(USE_LIBAVFORMAT_SO)
41 if(! muxer_init_muxer_lavf(muxer
))
47 if(! muxer_init_muxer_avi(muxer
))
57 /* buffer frames until we either:
58 * (a) have at least one frame from each stream
59 * (b) run out of memory */
60 void muxer_write_chunk(muxer_stream_t
*s
, size_t len
, unsigned int flags
, double dts
, double pts
) {
61 if(dts
== MP_NOPTS_VALUE
) dts
= s
->timer
;
62 if(pts
== MP_NOPTS_VALUE
) pts
= s
->timer
; // this is wrong
64 if (s
->muxer
->muxbuf_skip_buffer
) {
65 s
->muxer
->cont_write_chunk(s
, len
, flags
, dts
, pts
);
68 int num
= s
->muxer
->muxbuf_num
++;
71 tmp
= realloc(s
->muxer
->muxbuf
, (num
+1) * sizeof(muxbuf_t
));
73 mp_msg(MSGT_MUXER
, MSGL_FATAL
, MSGTR_MuxbufReallocErr
);
76 s
->muxer
->muxbuf
= tmp
;
77 buf
= s
->muxer
->muxbuf
+ num
;
79 /* buffer this frame */
85 buf
->buffer
= malloc(len
);
87 mp_msg(MSGT_MUXER
, MSGL_FATAL
, MSGTR_MuxbufMallocErr
);
90 memcpy(buf
->buffer
, s
->buffer
, buf
->len
);
93 /* see if we need to keep buffering */
94 s
->muxer
->muxbuf_skip_buffer
= 1;
95 for (num
= 0; s
->muxer
->streams
[num
]; ++num
)
96 if (!s
->muxer
->streams
[num
]->muxbuf_seen
)
97 s
->muxer
->muxbuf_skip_buffer
= 0;
99 /* see if we can flush buffer now */
100 if (s
->muxer
->muxbuf_skip_buffer
) {
101 mp_msg(MSGT_MUXER
, MSGL_V
, MSGTR_MuxbufSending
, s
->muxer
->muxbuf_num
);
103 /* fix parameters for all streams */
104 for (num
= 0; s
->muxer
->streams
[num
]; ++num
) {
105 muxer_stream_t
*str
= s
->muxer
->streams
[num
];
106 if(str
->muxer
->fix_stream_parameters
)
107 muxer_stream_fix_parameters(str
->muxer
, str
);
111 if (s
->muxer
->cont_write_header
)
112 muxer_write_header(s
->muxer
);
114 /* send all buffered frames to muxer */
115 for (num
= 0; num
< s
->muxer
->muxbuf_num
; ++num
) {
117 buf
= s
->muxer
->muxbuf
+ num
;
120 /* 1. save timer and buffer (might have changed by now) */
121 tmp_buf
.dts
= s
->timer
;
122 tmp_buf
.buffer
= s
->buffer
;
124 /* 2. move stored timer and buffer into stream and mux it */
126 s
->buffer
= buf
->buffer
;
127 s
->muxer
->cont_write_chunk(s
, buf
->len
, buf
->flags
, buf
->dts
, buf
->pts
);
129 /* 3. restore saved timer and buffer */
130 s
->timer
= tmp_buf
.dts
;
131 s
->buffer
= tmp_buf
.buffer
;
134 free(s
->muxer
->muxbuf
);
135 s
->muxer
->muxbuf_num
= 0;
139 /* this code moved directly from muxer_avi.c */
141 if(s
->h
.dwSampleSize
){
143 s
->h
.dwLength
+=len
/s
->h
.dwSampleSize
;
144 if(len
%s
->h
.dwSampleSize
) mp_msg(MSGT_MUXER
, MSGL_WARN
, MSGTR_WarningLenIsntDivisible
);
149 s
->timer
=(double)s
->h
.dwLength
*s
->h
.dwScale
/s
->h
.dwRate
;