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