vorbis producer added, clean up on clip handling in multitrack
[melted] / src / modules / avformat / producer_avformat.c
1 /*
2 * producer_avformat.c -- avformat producer
3 * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 // Local header files
22 #include "producer_avformat.h"
23
24 // MLT Header files
25 #include <framework/mlt_frame.h>
26
27 // ffmpeg Header files
28 #include <ffmpeg/avformat.h>
29
30 // System header files
31 #include <stdlib.h>
32 #include <string.h>
33 #include <pthread.h>
34
35 // Forward references.
36 static int producer_open( mlt_producer this, char *file );
37 static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index );
38
39 // A static flag used to determine if avformat has been initialised
40 static int avformat_initialised = 0;
41 static pthread_mutex_t avformat_mutex;
42
43 /** Constructor for libavformat.
44 */
45
46 mlt_producer producer_avformat_init( char *file )
47 {
48 mlt_producer this = NULL;
49
50 // Check that we have a non-NULL argument
51 if ( file != NULL )
52 {
53 // Construct the producer
54 this = calloc( 1, sizeof( struct mlt_producer_s ) );
55
56 // Initialise it
57 if ( mlt_producer_init( this, NULL ) == 0 )
58 {
59 // Get the properties
60 mlt_properties properties = mlt_producer_properties( this );
61
62 // Set the resource property (required for all producers)
63 mlt_properties_set( properties, "resource", file );
64
65 // TEST: audio sync tweaking
66 mlt_properties_set_double( properties, "discrepancy", 1 );
67
68 // Register our get_frame implementation
69 this->get_frame = producer_get_frame;
70
71 // Initialise avformat if necessary
72 if ( avformat_initialised == 0 )
73 {
74 pthread_mutex_init( &avformat_mutex, NULL );
75 avformat_initialised = 1;
76 av_register_all( );
77 }
78
79 // Open the file
80 if ( producer_open( this, file ) != 0 )
81 {
82 // Clean up
83 mlt_producer_close( this );
84 this = NULL;
85 }
86 }
87 }
88
89 return this;
90 }
91
92 /** Find the default streams.
93 */
94
95 static void find_default_streams( AVFormatContext *context, int *audio_index, int *video_index )
96 {
97 int i;
98
99 // Allow for multiple audio and video streams in the file and select first of each (if available)
100 for( i = 0; i < context->nb_streams; i++ )
101 {
102 // Get the codec context
103 AVCodecContext *codec_context = &context->streams[ i ]->codec;
104
105 // Determine the type and obtain the first index of each type
106 switch( codec_context->codec_type )
107 {
108 case CODEC_TYPE_VIDEO:
109 if ( *video_index < 0 )
110 *video_index = i;
111 break;
112 case CODEC_TYPE_AUDIO:
113 if ( *audio_index < 0 )
114 *audio_index = i;
115 break;
116 default:
117 break;
118 }
119 }
120 }
121
122 /** Producer file destructor.
123 */
124
125 static void producer_file_close( void *context )
126 {
127 if ( context != NULL )
128 {
129 // Lock the mutex now
130 pthread_mutex_lock( &avformat_mutex );
131
132 // Close the file
133 av_close_input_file( context );
134
135 // Unlock the mutex now
136 pthread_mutex_unlock( &avformat_mutex );
137 }
138 }
139
140 /** Producer file destructor.
141 */
142
143 static void producer_codec_close( void *codec )
144 {
145 if ( codec != NULL )
146 {
147 // Lock the mutex now
148 pthread_mutex_lock( &avformat_mutex );
149
150 // Close the file
151 avcodec_close( codec );
152
153 // Unlock the mutex now
154 pthread_mutex_unlock( &avformat_mutex );
155 }
156 }
157
158 /** Open the file.
159
160 NOTE: We need to have a valid [PAL or NTSC] frame rate before we can determine the
161 number of frames in the file. However, this is at odds with the way things work - the
162 constructor needs to provide in/out points before the user of the producer is able
163 to specify properties :-/. However, the PAL/NTSC distinction applies to all producers
164 and while we currently accept whatever the producer provides, this will not work in
165 the more general case. Plans are afoot... and this one will work without modification
166 (in theory anyway ;-)).
167 */
168
169 static int producer_open( mlt_producer this, char *file )
170 {
171 // Return an error code (0 == no error)
172 int error = 0;
173
174 // Context for avformat
175 AVFormatContext *context = NULL;
176
177 // Get the properties
178 mlt_properties properties = mlt_producer_properties( this );
179
180 // We will treat everything with the producer fps
181 double fps = mlt_properties_get_double( properties, "fps" );
182
183 // Lock the mutex now
184 pthread_mutex_lock( &avformat_mutex );
185
186 // Now attempt to open the file
187 error = av_open_input_file( &context, file, NULL, 0, NULL ) < 0;
188
189 // If successful, then try to get additional info
190 if ( error == 0 )
191 {
192 // Get the stream info
193 error = av_find_stream_info( context ) < 0;
194
195 // Continue if no error
196 if ( error == 0 )
197 {
198 // We will default to the first audio and video streams found
199 int audio_index = -1;
200 int video_index = -1;
201
202 // Now set properties where we can (use default unknowns if required)
203 if ( context->duration != AV_NOPTS_VALUE )
204 {
205 // This isn't going to be accurate for all formats
206 mlt_position frames = ( mlt_position )( ( ( double )context->duration / ( double )AV_TIME_BASE ) * fps );
207 mlt_properties_set_position( properties, "out", frames - 1 );
208 mlt_properties_set_position( properties, "length", frames );
209 }
210
211 // Find default audio and video streams
212 find_default_streams( context, &audio_index, &video_index );
213
214 // Store selected audio and video indexes on properties
215 mlt_properties_set_int( properties, "audio_index", audio_index );
216 mlt_properties_set_int( properties, "video_index", video_index );
217
218 // We're going to cheat here - for a/v files, we will have two contexts (reasoning will be clear later)
219 if ( audio_index != -1 && video_index != -1 )
220 {
221 // We'll use the open one as our video_context
222 mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL );
223
224 // And open again for our audio context
225 av_open_input_file( &context, file, NULL, 0, NULL );
226 av_find_stream_info( context );
227
228 // Audio context
229 mlt_properties_set_data( properties, "audio_context", context, 0, producer_file_close, NULL );
230 }
231 else if ( video_index != -1 )
232 {
233 // We only have a video context
234 mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL );
235 }
236 else if ( audio_index != -1 )
237 {
238 // We only have an audio context
239 mlt_properties_set_data( properties, "audio_context", context, 0, producer_file_close, NULL );
240 }
241 else
242 {
243 // Something has gone wrong
244 error = -1;
245 }
246 }
247 }
248
249 // Unlock the mutex now
250 pthread_mutex_unlock( &avformat_mutex );
251
252 return error;
253 }
254
255 /** Convert a frame position to a time code.
256 */
257
258 static double producer_time_of_frame( mlt_producer this, mlt_position position )
259 {
260 // Get the properties
261 mlt_properties properties = mlt_producer_properties( this );
262
263 // Obtain the fps
264 double fps = mlt_properties_get_double( properties, "fps" );
265
266 // Do the calc
267 return ( double )position / fps;
268 }
269
270 /** Get an image from a frame.
271 */
272
273 static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
274 {
275 // Get the properties from the frame
276 mlt_properties frame_properties = mlt_frame_properties( frame );
277
278 // Obtain the frame number of this frame
279 mlt_position position = mlt_properties_get_position( frame_properties, "avformat_position" );
280
281 // Get the producer
282 mlt_producer this = mlt_properties_get_data( frame_properties, "avformat_producer", NULL );
283
284 // Get the producer properties
285 mlt_properties properties = mlt_producer_properties( this );
286
287 // Fetch the video_context
288 AVFormatContext *context = mlt_properties_get_data( properties, "video_context", NULL );
289
290 // Get the video_index
291 int index = mlt_properties_get_int( properties, "video_index" );
292
293 // Obtain the expected frame numer
294 mlt_position expected = mlt_properties_get_position( properties, "video_expected" );
295
296 // Calculate the real time code
297 double real_timecode = producer_time_of_frame( this, position );
298
299 // Get the video stream
300 AVStream *stream = context->streams[ index ];
301
302 // Get codec context
303 AVCodecContext *codec_context = &stream->codec;
304
305 // Packet
306 AVPacket pkt;
307
308 // Get the conversion frame
309 AVPicture *output = mlt_properties_get_data( properties, "video_output_frame", NULL );
310
311 // Special case pause handling flag
312 int paused = 0;
313
314 // Special case ffwd handling
315 int ignore = 0;
316
317 // Current time calcs
318 double current_time = 0;
319
320 // Set the result arguments that we know here (only *buffer is now required)
321 *format = mlt_image_yuv422;
322 *width = codec_context->width;
323 *height = codec_context->height;
324
325 // Set this on the frame properties
326 mlt_properties_set_int( frame_properties, "width", *width );
327 mlt_properties_set_int( frame_properties, "height", *height );
328
329 // Lock the mutex now
330 pthread_mutex_lock( &avformat_mutex );
331
332 // Construct an AVFrame for YUV422 conversion
333 if ( output == NULL )
334 {
335 int size = avpicture_get_size( PIX_FMT_YUV422, *width, *height );
336 uint8_t *buf = malloc( size );
337 output = malloc( sizeof( AVPicture ) );
338 avpicture_fill( output, buf, PIX_FMT_YUV422, *width, *height );
339 mlt_properties_set_data( properties, "video_output_frame", output, 0, av_free, NULL );
340 mlt_properties_set_data( properties, "video_output_buffer", buf, 0, free, NULL );
341 }
342
343 // Seek if necessary
344 if ( position != expected )
345 {
346 if ( position + 1 == expected )
347 {
348 // We're paused - use last image
349 paused = 1;
350 }
351 else if ( position > expected && ( position - expected ) < 250 )
352 {
353 // Fast forward - seeking is inefficient for small distances - just ignore following frames
354 ignore = position - expected;
355 }
356 else
357 {
358 // Set to the real timecode
359 av_seek_frame( context, -1, real_timecode * 1000000.0 );
360
361 // Remove the cached info relating to the previous position
362 mlt_properties_set_double( properties, "current_time", 0 );
363 mlt_properties_set_data( properties, "current_image", NULL, 0, NULL, NULL );
364 }
365 }
366
367 // Duplicate the last image if necessary
368 if ( mlt_properties_get_data( properties, "current_image", NULL ) != NULL &&
369 ( paused || mlt_properties_get_double( properties, "current_time" ) > real_timecode ) )
370 {
371 // Get current image and size
372 int size = 0;
373 uint8_t *image = mlt_properties_get_data( properties, "current_image", &size );
374
375 // Duplicate it
376 *buffer = malloc( size );
377 memcpy( *buffer, image, size );
378
379 // Set this on the frame properties
380 mlt_properties_set_data( frame_properties, "image", *buffer, size, free, NULL );
381 }
382 else
383 {
384 int ret = 0;
385 int got_picture = 0;
386 AVFrame frame;
387
388 memset( &pkt, 0, sizeof( pkt ) );
389 memset( &frame, 0, sizeof( frame ) );
390
391 while( ret >= 0 && !got_picture )
392 {
393 // Read a packet
394 ret = av_read_frame( context, &pkt );
395
396 // We only deal with video from the selected video_index
397 if ( ret >= 0 && pkt.stream_index == index && pkt.size > 0 )
398 {
399 // Decode the image
400 // Wouldn't it be great if I could use this...
401 //if ( (float)pkt.pts / 1000000.0 >= real_timecode )
402 ret = avcodec_decode_video( codec_context, &frame, &got_picture, pkt.data, pkt.size );
403
404 // Handle ignore
405 if ( (float)pkt.pts / 1000000.0 < real_timecode )
406 {
407 ignore = 0;
408 got_picture = 0;
409 }
410 else if ( (float)pkt.pts / 1000000.0 >= real_timecode )
411 {
412 ignore = 0;
413 }
414 else if ( got_picture && ignore -- )
415 {
416 got_picture = 0;
417 }
418
419 current_time = ( double )pkt.pts / 1000000.0;
420 }
421
422 // We're finished with this packet regardless
423 av_free_packet( &pkt );
424 }
425
426 // Now handle the picture if we have one
427 if ( got_picture )
428 {
429 // Get current image and size
430 int size = 0;
431 uint8_t *image = mlt_properties_get_data( properties, "current_image", &size );
432
433 if ( image == NULL || size != *width * *height * 2 )
434 {
435 size = *width * *height * 2;
436 image = malloc( size );
437 mlt_properties_set_data( properties, "current_image", image, size, free, NULL );
438 }
439
440 *buffer = malloc( size );
441 img_convert( output, PIX_FMT_YUV422, (AVPicture *)&frame, codec_context->pix_fmt, *width, *height );
442 memcpy( image, output->data[ 0 ], size );
443 memcpy( *buffer, output->data[ 0 ], size );
444 mlt_properties_set_data( frame_properties, "image", *buffer, size, free, NULL );
445 mlt_properties_set_double( properties, "current_time", current_time );
446 }
447 }
448
449 // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
450 mlt_properties_set_position( properties, "video_expected", position + 1 );
451
452 // Unlock the mutex now
453 pthread_mutex_unlock( &avformat_mutex );
454
455 return 0;
456 }
457
458 /** Set up video handling.
459 */
460
461 static void producer_set_up_video( mlt_producer this, mlt_frame frame )
462 {
463 // Get the properties
464 mlt_properties properties = mlt_producer_properties( this );
465
466 // Fetch the video_context
467 AVFormatContext *context = mlt_properties_get_data( properties, "video_context", NULL );
468
469 // Get the video_index
470 int index = mlt_properties_get_int( properties, "video_index" );
471
472 // Lock the mutex now
473 pthread_mutex_lock( &avformat_mutex );
474
475 if ( context != NULL && index != -1 )
476 {
477 // Get the frame properties
478 mlt_properties frame_properties = mlt_frame_properties( frame );
479
480 // Get the video stream
481 AVStream *stream = context->streams[ index ];
482
483 // Get codec context
484 AVCodecContext *codec_context = &stream->codec;
485
486 // Get the codec
487 AVCodec *codec = mlt_properties_get_data( properties, "video_codec", NULL );
488
489 // Initialise the codec if necessary
490 if ( codec == NULL )
491 {
492 // Find the codec
493 codec = avcodec_find_decoder( codec_context->codec_id );
494
495 // If we don't have a codec and we can't initialise it, we can't do much more...
496 if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
497 {
498 double aspect_ratio = 0;
499
500 // Set aspect ratio
501 if ( codec_context->sample_aspect_ratio.num == 0)
502 aspect_ratio = 0;
503 else
504 aspect_ratio = av_q2d( codec_context->sample_aspect_ratio ) * codec_context->width / codec_context->height;
505
506 if (aspect_ratio <= 0.0)
507 aspect_ratio = ( double )codec_context->width / ( double )codec_context->height;
508
509 mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio );
510
511 // Now store the codec with its destructor
512 mlt_properties_set_data( properties, "video_codec", codec_context, 0, producer_codec_close, NULL );
513
514 // Set to the real timecode
515 av_seek_frame( context, -1, 0 );
516 }
517 else
518 {
519 // Remember that we can't use this later
520 mlt_properties_set_int( properties, "video_index", -1 );
521 }
522 }
523
524 // No codec, no show...
525 if ( codec != NULL )
526 {
527 mlt_frame_push_get_image( frame, producer_get_image );
528 mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
529 }
530 }
531
532 // Unlock the mutex now
533 pthread_mutex_unlock( &avformat_mutex );
534 }
535
536 /** Get the audio from a frame.
537 */
538
539 static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
540 {
541 // Get the properties from the frame
542 mlt_properties frame_properties = mlt_frame_properties( frame );
543
544 // Obtain the frame number of this frame
545 mlt_position position = mlt_properties_get_position( frame_properties, "avformat_position" );
546
547 // Get the producer
548 mlt_producer this = mlt_properties_get_data( frame_properties, "avformat_producer", NULL );
549
550 // Get the producer properties
551 mlt_properties properties = mlt_producer_properties( this );
552
553 // Fetch the audio_context
554 AVFormatContext *context = mlt_properties_get_data( properties, "audio_context", NULL );
555
556 // Get the audio_index
557 int index = mlt_properties_get_int( properties, "audio_index" );
558
559 // Obtain the expected frame numer
560 mlt_position expected = mlt_properties_get_position( properties, "audio_expected" );
561
562 // Obtain the resample context if it exists (not always needed)
563 ReSampleContext *resample = mlt_properties_get_data( properties, "audio_resample", NULL );
564
565 // Obtain the audio buffer
566 int16_t *audio_buffer = mlt_properties_get_data( properties, "audio_buffer", NULL );
567
568 // Get amount of audio used
569 int audio_used = mlt_properties_get_int( properties, "audio_used" );
570
571 // Calculate the real time code
572 double real_timecode = producer_time_of_frame( this, position );
573
574 // Get the audio stream
575 AVStream *stream = context->streams[ index ];
576
577 // Get codec context
578 AVCodecContext *codec_context = &stream->codec;
579
580 // Packet
581 AVPacket pkt;
582
583 // Number of frames to ignore (for ffwd)
584 int ignore = 0;
585
586 // Flag for paused (silence)
587 int paused = 0;
588
589 // Lock the mutex now
590 pthread_mutex_lock( &avformat_mutex );
591
592 // Check for resample and create if necessary
593 if ( resample == NULL )
594 {
595 // Create the resampler
596 resample = audio_resample_init( *channels, codec_context->channels, *frequency, codec_context->sample_rate );
597
598 // And store it on properties
599 mlt_properties_set_data( properties, "audio_resample", resample, 0, ( mlt_destructor )audio_resample_close, NULL );
600 }
601
602 // Check for audio buffer and create if necessary
603 if ( audio_buffer == NULL )
604 {
605 // Allocate the audio buffer
606 audio_buffer = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( int16_t ) );
607
608 // And store it on properties for reuse
609 mlt_properties_set_data( properties, "audio_buffer", audio_buffer, 0, free, NULL );
610 }
611
612 // Seek if necessary
613 if ( position != expected )
614 {
615 if ( position + 1 == expected )
616 {
617 // We're paused - silence required
618 paused = 1;
619 }
620 else if ( position > expected && ( position - expected ) < 250 )
621 {
622 // Fast forward - seeking is inefficient for small distances - just ignore following frames
623 ignore = position - expected;
624 }
625 else
626 {
627 // Set to the real timecode
628 av_seek_frame( context, -1, real_timecode * 1000000.0 );
629
630 // Clear the usage in the audio buffer
631 audio_used = 0;
632 }
633 }
634
635 // Get the audio if required
636 if ( !paused )
637 {
638 int ret = 0;
639 int got_audio = 0;
640 int16_t temp[ AVCODEC_MAX_AUDIO_FRAME_SIZE / 2 ];
641
642 memset( &pkt, 0, sizeof( pkt ) );
643
644 while( ret >= 0 && !got_audio )
645 {
646 // Check if the buffer already contains the samples required
647 if ( audio_used >= *samples && ignore == 0 )
648 {
649 got_audio = 1;
650 break;
651 }
652
653 // Read a packet
654 ret = av_read_frame( context, &pkt );
655
656 int len = pkt.size;
657 uint8_t *ptr = pkt.data;
658 int data_size;
659
660 if ( ptr == NULL || len == 0 )
661 break;
662
663 // We only deal with video from the selected video_index
664 while ( ret >= 0 && pkt.stream_index == index && len > 0 )
665 {
666 // Decode the audio
667 ret = avcodec_decode_audio( codec_context, temp, &data_size, ptr, len );
668
669 if ( ret < 0 )
670 break;
671
672 len -= ret;
673 ptr += ret;
674
675 if ( data_size > 0 )
676 {
677 int size_out = audio_resample( resample, &audio_buffer[ audio_used * *channels ], temp, data_size / ( codec_context->channels * sizeof( int16_t ) ) );
678
679 audio_used += size_out;
680
681 // Handle ignore
682 while ( ignore && audio_used > *samples )
683 {
684 ignore --;
685 audio_used -= *samples;
686 memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * sizeof( int16_t ) );
687 }
688 }
689
690 // If we're behind, ignore this packet
691 float current_pts = (float)pkt.pts / 1000000.0;
692 double discrepancy = mlt_properties_get_double( properties, "discrepancy" );
693 if ( discrepancy * current_pts < real_timecode )
694 ignore = 1;
695 }
696
697 // We're finished with this packet regardless
698 av_free_packet( &pkt );
699 }
700
701 // Now handle the audio if we have enough
702 if ( audio_used >= *samples )
703 {
704 *buffer = malloc( *samples * *channels * sizeof( int16_t ) );
705 memcpy( *buffer, audio_buffer, *samples * *channels * sizeof( int16_t ) );
706 audio_used -= *samples;
707 memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * *channels * sizeof( int16_t ) );
708 mlt_properties_set_data( frame_properties, "audio", *buffer, 0, free, NULL );
709 }
710 else
711 {
712 frame->get_audio = NULL;
713 mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
714 audio_used = 0;
715 }
716
717 // Store the number of audio samples still available
718 mlt_properties_set_int( properties, "audio_used", audio_used );
719 }
720 else
721 {
722 // Get silence and don't touch the context
723 frame->get_audio = NULL;
724 mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
725 }
726
727 // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
728 mlt_properties_set_position( properties, "audio_expected", position + 1 );
729
730 // Unlock the mutex now
731 pthread_mutex_unlock( &avformat_mutex );
732
733 return 0;
734 }
735
736 /** Set up audio handling.
737 */
738
739 static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
740 {
741 // Get the properties
742 mlt_properties properties = mlt_producer_properties( this );
743
744 // Fetch the audio_context
745 AVFormatContext *context = mlt_properties_get_data( properties, "audio_context", NULL );
746
747 // Get the audio_index
748 int index = mlt_properties_get_int( properties, "audio_index" );
749
750 // Lock the mutex now
751 pthread_mutex_lock( &avformat_mutex );
752
753 // Deal with audio context
754 if ( context != NULL && index != -1 )
755 {
756 // Get the frame properties
757 mlt_properties frame_properties = mlt_frame_properties( frame );
758
759 // Get the audio stream
760 AVStream *stream = context->streams[ index ];
761
762 // Get codec context
763 AVCodecContext *codec_context = &stream->codec;
764
765 // Get the codec
766 AVCodec *codec = mlt_properties_get_data( properties, "audio_codec", NULL );
767
768 // Initialise the codec if necessary
769 if ( codec == NULL )
770 {
771 // Find the codec
772 codec = avcodec_find_decoder( codec_context->codec_id );
773
774 // If we don't have a codec and we can't initialise it, we can't do much more...
775 if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
776 {
777 // Now store the codec with its destructor
778 mlt_properties_set_data( properties, "audio_codec", codec_context, 0, producer_codec_close, NULL );
779 }
780 else
781 {
782 // Remember that we can't use this later
783 mlt_properties_set_int( properties, "audio_index", -1 );
784 }
785 }
786
787 // No codec, no show...
788 if ( codec != NULL )
789 {
790 frame->get_audio = producer_get_audio;
791 mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
792 }
793 }
794
795 // Unlock the mutex now
796 pthread_mutex_unlock( &avformat_mutex );
797 }
798
799 /** Our get frame implementation.
800 */
801
802 static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index )
803 {
804 // Create an empty frame
805 *frame = mlt_frame_init( );
806
807 // Update timecode on the frame we're creating
808 mlt_frame_set_position( *frame, mlt_producer_position( this ) );
809
810 // Set the position of this producer
811 mlt_properties_set_position( mlt_frame_properties( *frame ), "avformat_position", mlt_producer_get_in( this ) + mlt_producer_position( this ) );
812
813 // Set up the video
814 producer_set_up_video( this, *frame );
815
816 // Set up the audio
817 producer_set_up_audio( this, *frame );
818
819 // Set the aspect_ratio
820 mlt_properties_set_double( mlt_frame_properties( *frame ), "aspect_ratio", mlt_properties_get_double( mlt_producer_properties( this ), "aspect_ratio" ) );
821
822 // Calculate the next timecode
823 mlt_producer_prepare_next( this );
824
825 return 0;
826 }