@@ -193,45 +193,109 @@ func (w *writer) Decoder(DecoderMapFunc) (Decoder, error) {
193
193
return nil , ErrOutOfOrder .With ("not an input stream" )
194
194
}
195
195
196
- func (w * writer ) Mux (context.Context , MuxFunc ) error {
197
- return ErrNotImplemented
198
-
199
- /*
200
- while (1) {
201
- AVStream *in_stream, *out_stream;
202
-
203
- ret = av_read_frame(ifmt_ctx, pkt);
204
- if (ret < 0)
205
- break;
206
-
207
- in_stream = ifmt_ctx->streams[pkt->stream_index];
208
- if (pkt->stream_index >= stream_mapping_size ||
209
- stream_mapping[pkt->stream_index] < 0) {
210
- av_packet_unref(pkt);
211
- continue;
212
- }
213
-
214
- pkt->stream_index = stream_mapping[pkt->stream_index];
215
- out_stream = ofmt_ctx->streams[pkt->stream_index];
216
- log_packet(ifmt_ctx, pkt, "in");
217
-
218
- // copy packet
219
- av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
220
- pkt->pos = -1;
221
- log_packet(ofmt_ctx, pkt, "out");
222
-
223
- ret = av_interleaved_write_frame(ofmt_ctx, pkt);
224
- // pkt is now blank (av_interleaved_write_frame() takes ownership of
225
- // its contents and resets pkt), so that no unreferencing is necessary.
226
- // This would be different if one used av_write_frame().
227
- if (ret < 0) {
228
- fprintf(stderr, "Error muxing packet\n");
229
- break;
230
- }
231
- }
232
- */
196
+ func (w * writer ) Mux (ctx context.Context , fn MuxFunc ) error {
197
+ // Check fn
198
+ if fn == nil {
199
+ return ErrBadParameter .With ("nil mux function" )
200
+ }
201
+
202
+ // Create a new map of encoders
203
+ encoders := make (map [int ]* encoder , len (w .encoder ))
204
+ for k , v := range w .encoder {
205
+ encoders [k ] = v
206
+ }
207
+
208
+ FOR_LOOP:
209
+ for {
210
+ select {
211
+ case <- ctx .Done ():
212
+ break FOR_LOOP
213
+ default :
214
+ // Loop until no more encoders are available to send packets
215
+ if len (encoders ) == 0 {
216
+ break FOR_LOOP
217
+ }
218
+
219
+ // Find the first encoder which should return a packet
220
+ next_time := 0
221
+ next_stream := 0
222
+ for stream := range encoders {
223
+ if next_time == 0 || encoder .nextTime () < next_time {
224
+ next_time = encoder .nextTime ()
225
+ next_stream = stream
226
+ }
227
+ }
228
+
229
+ // Get a packet from the encoder
230
+ packet , err := encoders [next_stream ].encode (fn )
231
+ if errors .Is (err , io .EOF ) {
232
+ break FOR_LOOP
233
+ } else if err != nil {
234
+ return err
235
+ } else if packet == nil {
236
+ // Remove the encoder from the map
237
+ delete (encoders , next_stream )
238
+ continue FOR_LOOP
239
+ }
240
+
241
+ // Send the packet to the muxer
242
+ //av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
243
+ // Packet's stream_index field must be set to the index of the corresponding stream in s->streams.
244
+ // The timestamps (pts, dts) must be set to correct values in the stream's timebase
245
+ // (unless the output format is flagged with the AVFMT_NOTIMESTAMPS flag, then they can be set
246
+ // to AV_NOPTS_VALUE). The dts for subsequent packets in one stream must be strictly increasing
247
+ // (unless the output format is flagged with the AVFMT_TS_NONSTRICT, then they merely have to
248
+ // be nondecreasing). duration should also be set if known.
249
+ if err := ff .AVCodec_interleaved_write_frame (w .output , packet ); err != nil {
250
+ return err
251
+ }
252
+ }
253
+ }
254
+
255
+ // Flush
256
+ if err := ff .AVCodec_interleaved_write_frame (w .output , nil ); err != nil {
257
+ return err
258
+ }
259
+
260
+ // Return the context error, which will be nil if the loop ended normally
261
+ return ctx .Err ()
233
262
}
234
263
264
+ /*
265
+ while (1) {
266
+ AVStream *in_stream, *out_stream;
267
+
268
+ ret = av_read_frame(ifmt_ctx, pkt);
269
+ if (ret < 0)
270
+ break;
271
+
272
+ in_stream = ifmt_ctx->streams[pkt->stream_index];
273
+ if (pkt->stream_index >= stream_mapping_size ||
274
+ stream_mapping[pkt->stream_index] < 0) {
275
+ av_packet_unref(pkt);
276
+ continue;
277
+ }
278
+
279
+ pkt->stream_index = stream_mapping[pkt->stream_index];
280
+ out_stream = ofmt_ctx->streams[pkt->stream_index];
281
+ log_packet(ifmt_ctx, pkt, "in");
282
+
283
+ // copy packet
284
+ av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
285
+ pkt->pos = -1;
286
+ log_packet(ofmt_ctx, pkt, "out");
287
+
288
+ ret = av_interleaved_write_frame(ofmt_ctx, pkt);
289
+ // pkt is now blank (av_interleaved_write_frame() takes ownership of
290
+ // its contents and resets pkt), so that no unreferencing is necessary.
291
+ // This would be different if one used av_write_frame().
292
+ if (ret < 0) {
293
+ fprintf(stderr, "Error muxing packet\n");
294
+ break;
295
+ }
296
+ }
297
+ */
298
+
235
299
// Return OUTPUT and combination of DEVICE and STREAM
236
300
func (w * writer ) Type () MediaType {
237
301
return OUTPUT
0 commit comments