]> git.sesse.net Git - mlt/blob - src/modules/avformat/producer_avformat.c
fezzik now accepts service:resource and strips \'avformat:\' before fallback avformat...
[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 #include <pthread.h>
34 #include <math.h>
35
36 // Forward references.
37 static int producer_open( mlt_producer this, char *file );
38 static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index );
39
40 // A static flag used to determine if avformat has been initialised
41 static int avformat_initialised = 0;
42 static pthread_mutex_t avformat_mutex;
43
44 void *av_malloc( unsigned int size )
45 {
46         return mlt_pool_alloc( size );
47 }
48
49 void *av_realloc( void *ptr, unsigned int size )
50 {
51         return mlt_pool_realloc( ptr, size );
52 }
53
54 void av_free( void *ptr )
55 {
56         return mlt_pool_release( ptr );
57 }
58
59 /** Constructor for libavformat.
60 */
61
62 mlt_producer producer_avformat_init( char *file )
63 {
64         mlt_producer this = NULL;
65
66         // Check that we have a non-NULL argument
67         if ( file != NULL )
68         {
69                 // Construct the producer
70                 this = calloc( 1, sizeof( struct mlt_producer_s ) );
71
72                 // Initialise it
73                 if ( mlt_producer_init( this, NULL ) == 0 )
74                 {
75                         // Get the properties
76                         mlt_properties properties = mlt_producer_properties( this );
77
78                         // Set the resource property (required for all producers)
79                         mlt_properties_set( properties, "resource", file );
80
81                         // TEST: audio sync tweaking
82                         mlt_properties_set_double( properties, "discrepancy", 1 );
83
84                         // Register our get_frame implementation
85                         this->get_frame = producer_get_frame;
86
87                         // Initialise avformat if necessary
88                         if ( avformat_initialised == 0 )
89                         {
90                                 avformat_initialised = 1;
91                                 pthread_mutex_init( &avformat_mutex, NULL );
92                                 av_register_all( );
93                         }
94
95                         // Open the file
96                         if ( producer_open( this, file ) != 0 )
97                         {
98                                 // Clean up
99                                 mlt_producer_close( this );
100                                 this = NULL;
101                         }
102                 }
103         }
104
105         return this;
106 }
107
108 /** Find the default streams.
109 */
110
111 static void find_default_streams( AVFormatContext *context, int *audio_index, int *video_index )
112 {
113         int i;
114
115         // Allow for multiple audio and video streams in the file and select first of each (if available)
116         for( i = 0; i < context->nb_streams; i++ ) 
117         {
118                 // Get the codec context
119                 AVCodecContext *codec_context = &context->streams[ i ]->codec;
120
121                 // Determine the type and obtain the first index of each type
122                 switch( codec_context->codec_type ) 
123                 {
124                         case CODEC_TYPE_VIDEO:
125                                 if ( *video_index < 0 )
126                                         *video_index = i;
127                                 break;
128                         case CODEC_TYPE_AUDIO:
129                                 if ( *audio_index < 0 )
130                                         *audio_index = i;
131                                 break;
132                         default:
133                                 break;
134                 }
135         }
136 }
137
138 /** Producer file destructor.
139 */
140
141 static void producer_file_close( void *context )
142 {
143         if ( context != NULL )
144         {
145                 // Lock the mutex now
146                 pthread_mutex_lock( &avformat_mutex );
147
148                 // Close the file
149                 av_close_input_file( context );
150
151                 // Unlock the mutex now
152                 pthread_mutex_unlock( &avformat_mutex );
153         }
154 }
155
156 /** Producer file destructor.
157 */
158
159 static void producer_codec_close( void *codec )
160 {
161         if ( codec != NULL )
162         {
163                 // Lock the mutex now
164                 pthread_mutex_lock( &avformat_mutex );
165
166                 // Close the file
167                 avcodec_close( codec );
168
169                 // Unlock the mutex now
170                 pthread_mutex_unlock( &avformat_mutex );
171         }
172 }
173
174 /** Open the file.
175 */
176
177 static int producer_open( mlt_producer this, char *file )
178 {
179         // Return an error code (0 == no error)
180         int error = 0;
181
182         // Context for avformat
183         AVFormatContext *context = NULL;
184
185         // Get the properties
186         mlt_properties properties = mlt_producer_properties( this );
187
188         // We will treat everything with the producer fps
189         double fps = mlt_properties_get_double( properties, "fps" );
190
191         // Lock the mutex now
192         pthread_mutex_lock( &avformat_mutex );
193         
194         // If "MRL", then create AVInputFormat
195         AVInputFormat *format = NULL;
196         AVFormatParameters *params = NULL;
197         char *standard = NULL;
198         char *mrl = strchr( file, ':' );
199         
200         // Only if there is not a protocol specification that avformat can handle
201         if ( mrl && !url_exist( file ) )
202         {
203                 // 'file' becomes format abbreviation
204                 mrl[0] = 0;
205         
206                 // Lookup the format
207                 format = av_find_input_format( file );
208                 
209                 // Eat the format designator
210                 file = ++mrl;
211                 
212                 if ( format )
213                 {
214                         // Allocate params
215                         params = calloc( sizeof( AVFormatParameters ), 1 );
216                         
217                         // These are required by video4linux (defaults)
218                         params->width = 640;
219                         params->height = 480;
220                         params->frame_rate = 25;
221                         params->frame_rate_base = 1;
222                         params->device = file;
223                         params->channels = 2;
224                         params->sample_rate = 48000;
225                 }
226                 
227                 // Parse out params
228                 mrl = strchr( file, '?' );
229                 while ( mrl )
230                 {
231                         mrl[0] = 0;
232                         char *name = strdup( ++mrl );
233                         char *value = strchr( name, '=' );
234                         if ( value )
235                         {
236                                 value[0] = 0;
237                                 value++;
238                                 char *t = strchr( value, '&' );
239                                 if ( t )
240                                         t[0] = 0;
241                                 if ( !strcmp( name, "frame_rate" ) )
242                                         params->frame_rate = atoi( value );
243                                 else if ( !strcmp( name, "frame_rate_base" ) )
244                                         params->frame_rate_base = atoi( value );
245                                 else if ( !strcmp( name, "sample_rate" ) )
246                                         params->sample_rate = atoi( value );
247                                 else if ( !strcmp( name, "channels" ) )
248                                         params->channels = atoi( value );
249                                 else if ( !strcmp( name, "width" ) )
250                                         params->width = atoi( value );
251                                 else if ( !strcmp( name, "height" ) )
252                                         params->height = atoi( value );
253                                 else if ( !strcmp( name, "standard" ) )
254                                 {
255                                         standard = strdup( value );
256                                         params->standard = standard;
257                                 }
258                         }
259                         free( name );
260                         mrl = strchr( mrl, '&' );
261                 }
262         }
263
264         // Now attempt to open the file
265         error = av_open_input_file( &context, file, format, 0, params );
266         error = error < 0;
267         
268         // Cleanup AVFormatParameters
269         free( standard );
270         free( params );
271
272         // If successful, then try to get additional info
273         if ( error == 0 )
274         {
275                 // Get the stream info
276                 error = av_find_stream_info( context ) < 0;
277
278                 // Continue if no error
279                 if ( error == 0 )
280                 {
281                         // We will default to the first audio and video streams found
282                         int audio_index = -1;
283                         int video_index = -1;
284
285                         // Now set properties where we can (use default unknowns if required)
286                         if ( context->duration != AV_NOPTS_VALUE ) 
287                         {
288                                 // This isn't going to be accurate for all formats
289                                 mlt_position frames = ( mlt_position )( ( ( double )context->duration / ( double )AV_TIME_BASE ) * fps );
290                                 mlt_properties_set_position( properties, "out", frames - 2 );
291                                 mlt_properties_set_position( properties, "length", frames - 1 );
292                         }
293
294                         // Find default audio and video streams
295                         find_default_streams( context, &audio_index, &video_index );
296
297                         // Store selected audio and video indexes on properties
298                         mlt_properties_set_int( properties, "audio_index", audio_index );
299                         mlt_properties_set_int( properties, "video_index", video_index );
300
301                         // We're going to cheat here - for a/v files, we will have two contexts (reasoning will be clear later)
302                         if ( audio_index != -1 && video_index != -1 )
303                         {
304                                 // We'll use the open one as our video_context
305                                 mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL );
306
307                                 // And open again for our audio context
308                                 av_open_input_file( &context, file, NULL, 0, NULL );
309                                 av_find_stream_info( context );
310
311                                 // Audio context
312                                 mlt_properties_set_data( properties, "audio_context", context, 0, producer_file_close, NULL );
313                         }
314                         else if ( video_index != -1 )
315                         {
316                                 // We only have a video context
317                                 mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL );
318                         }
319                         else if ( audio_index != -1 )
320                         {
321                                 // We only have an audio context
322                                 mlt_properties_set_data( properties, "audio_context", context, 0, producer_file_close, NULL );
323                         }
324                         else
325                         {
326                                 // Something has gone wrong
327                                 error = -1;
328                         }
329                 }
330         }
331
332         // Unlock the mutex now
333         pthread_mutex_unlock( &avformat_mutex );
334
335         return error;
336 }
337
338 /** Convert a frame position to a time code.
339 */
340
341 static double producer_time_of_frame( mlt_producer this, mlt_position position )
342 {
343         // Get the properties
344         mlt_properties properties = mlt_producer_properties( this );
345
346         // Obtain the fps
347         double fps = mlt_properties_get_double( properties, "fps" );
348
349         // Do the calc
350         return ( double )position / fps;
351 }
352
353 /** Get an image from a frame.
354 */
355
356 static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
357 {
358         // Get the properties from the frame
359         mlt_properties frame_properties = mlt_frame_properties( frame );
360
361         // Obtain the frame number of this frame
362         mlt_position position = mlt_properties_get_position( frame_properties, "avformat_position" );
363
364         // Get the producer 
365         mlt_producer this = mlt_properties_get_data( frame_properties, "avformat_producer", NULL );
366
367         // Get the producer properties
368         mlt_properties properties = mlt_producer_properties( this );
369
370         // Fetch the video_context
371         AVFormatContext *context = mlt_properties_get_data( properties, "video_context", NULL );
372
373         // Get the video_index
374         int index = mlt_properties_get_int( properties, "video_index" );
375
376         // Obtain the expected frame numer
377         mlt_position expected = mlt_properties_get_position( properties, "video_expected" );
378
379         // Calculate the real time code
380         double real_timecode = producer_time_of_frame( this, position ) + mlt_properties_get_double( properties, "_v_pts_offset" );
381
382         // Get the video stream
383         AVStream *stream = context->streams[ index ];
384
385         // Get codec context
386         AVCodecContext *codec_context = &stream->codec;
387
388         // Packet
389         AVPacket pkt;
390
391         // Get the conversion frame
392         AVPicture *output = mlt_properties_get_data( properties, "video_output_frame", NULL );
393
394         // Special case pause handling flag
395         int paused = 0;
396
397         // Special case ffwd handling
398         int ignore = 0;
399
400         // Current time calcs
401         double current_time = mlt_properties_get_double( properties, "current_time" );
402
403         // We may want to use the source fps if available
404         double source_fps = mlt_properties_get_double( properties, "source_fps" );
405
406         // Set the result arguments that we know here (only *buffer is now required)
407         *format = mlt_image_yuv422;
408         *width = codec_context->width;
409         *height = codec_context->height;
410
411         // Set this on the frame properties
412         mlt_properties_set_int( frame_properties, "width", *width );
413         mlt_properties_set_int( frame_properties, "height", *height );
414
415         // Lock the mutex now
416         pthread_mutex_lock( &avformat_mutex );
417
418         // Construct an AVFrame for YUV422 conversion
419         if ( output == NULL )
420         {
421                 int size = avpicture_get_size( PIX_FMT_YUV422, *width, *height );
422                 size += *width * 2;
423                 uint8_t *buf = mlt_pool_alloc( size );
424                 output = mlt_pool_alloc( sizeof( AVPicture ) );
425                 //memset( output, 0, sizeof( AVPicture ) );
426                 avpicture_fill( output, buf, PIX_FMT_YUV422, *width, *height );
427                 mlt_properties_set_data( properties, "video_output_frame", output, 0, ( mlt_destructor )mlt_pool_release, NULL );
428                 mlt_properties_set_data( properties, "video_output_buffer", buf, 0, ( mlt_destructor )mlt_pool_release, NULL );
429         }
430
431         // Seek if necessary
432         if ( position != expected )
433         {
434                 if ( position + 1 == expected )
435                 {
436                         // We're paused - use last image
437                         paused = 1;
438                 }
439                 else if ( position > expected && ( position - expected ) < 250 )
440                 {
441                         // Fast forward - seeking is inefficient for small distances - just ignore following frames
442                         ignore = position - expected;
443                 }
444                 else
445                 {
446                         // Set to the real timecode
447                         av_seek_frame( context, -1, real_timecode * 1000000.0 );
448         
449                         // Remove the cached info relating to the previous position
450                         mlt_properties_set_double( properties, "current_time", real_timecode );
451                         mlt_properties_set_data( properties, "current_image", NULL, 0, NULL, NULL );
452                 }
453         }
454         
455         // Duplicate the last image if necessary
456         if ( mlt_properties_get_data( properties, "current_image", NULL ) != NULL &&
457                  ( paused || mlt_properties_get_double( properties, "current_time" ) >= real_timecode ) )
458         {
459                 // Get current image and size
460                 int size = 0;
461                 uint8_t *image = mlt_properties_get_data( properties, "current_image", &size );
462
463                 // Duplicate it
464                 *buffer = mlt_pool_alloc( size );
465                 memcpy( *buffer, image, size );
466
467                 // Set this on the frame properties
468                 mlt_properties_set_data( frame_properties, "image", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
469         }
470         else
471         {
472                 int ret = 0;
473                 int got_picture = 0;
474                 AVFrame frame;
475
476                 memset( &pkt, 0, sizeof( pkt ) );
477                 memset( &frame, 0, sizeof( frame ) );
478
479                 while( ret >= 0 && !got_picture )
480                 {
481                         // Read a packet
482                         ret = av_read_frame( context, &pkt );
483
484                         // We only deal with video from the selected video_index
485                         if ( ret >= 0 && pkt.stream_index == index && pkt.size > 0 )
486                         {
487                                 // Decode the image
488                                 ret = avcodec_decode_video( codec_context, &frame, &got_picture, pkt.data, pkt.size );
489
490                                 if ( got_picture )
491                                 {
492                                         if ( pkt.pts != AV_NOPTS_VALUE && pkt.pts != 0  )
493                                         {
494                                                 if ( current_time == 0 )
495                                                 {
496                                                         mlt_properties_set_double( properties, "_v_pts_offset", ( double )( pkt.pts / 1000000 ) );
497                                                         real_timecode += pkt.pts / 1000000;
498                                                 }
499                                                 current_time = ( double )pkt.pts / 1000000.0;
500                                         }
501                                         else
502                                                 current_time = real_timecode;
503
504                                         // Handle ignore
505                                         if ( current_time < real_timecode )
506                                         {
507                                                 ignore = 0;
508                                                 got_picture = 0;
509                                         }
510                                         else if ( current_time >= real_timecode )
511                                         {
512                                                 //current_time = real_timecode;
513                                                 ignore = 0;
514                                         }
515                                         else if ( ignore -- )
516                                         {
517                                                 got_picture = 0;
518                                         }
519                                 }
520                         }
521
522                         // We're finished with this packet regardless
523                         av_free_packet( &pkt );
524                 }
525
526                 // Now handle the picture if we have one
527                 if ( got_picture )
528                 {
529                         // Get current image and size
530                         int size = 0;
531                         uint8_t *image = mlt_properties_get_data( properties, "current_image", &size );
532
533                         if ( image == NULL || size != *width * *height * 2 )
534                         {
535                                 size = *width * ( *height + 1 ) * 2;
536                                 image = mlt_pool_alloc( size );
537                                 mlt_properties_set_data( properties, "current_image", image, size, ( mlt_destructor )mlt_pool_release, NULL );
538                         }
539
540                         *buffer = mlt_pool_alloc( size );
541
542                         // EXPERIMENTAL IMAGE NORMALISATIONS
543                         if ( codec_context->pix_fmt == PIX_FMT_YUV420P )
544                         {
545                                 register int i, j;
546                                 register int half = *width >> 1;
547                                 register uint8_t *Y = ( ( AVPicture * )&frame )->data[ 0 ];
548                                 register uint8_t *U = ( ( AVPicture * )&frame )->data[ 1 ];
549                                 register uint8_t *V = ( ( AVPicture * )&frame )->data[ 2 ];
550                                 register uint8_t *d = *buffer;
551                                 register uint8_t *y, *u, *v;
552
553                                 i = *height >> 1;
554                                 while ( i -- )
555                                 {
556                                         y = Y;
557                                         u = U;
558                                         v = V;
559                                         j = half;
560                                         while ( j -- )
561                                         {
562                                                 *d ++ = *y ++;
563                                                 *d ++ = *u ++;
564                                                 *d ++ = *y ++;
565                                                 *d ++ = *v ++;
566                                         }
567
568                                         Y += ( ( AVPicture * )&frame )->linesize[ 0 ];
569                                         y = Y;
570                                         u = U;
571                                         v = V;
572                                         j = half;
573                                         while ( j -- )
574                                         {
575                                                 *d ++ = *y ++;
576                                                 *d ++ = *u ++;
577                                                 *d ++ = *y ++;
578                                                 *d ++ = *v ++;
579                                         }
580
581                                         Y += ( ( AVPicture * )&frame )->linesize[ 0 ];
582                                         U += ( ( AVPicture * )&frame )->linesize[ 1 ];
583                                         V += ( ( AVPicture * )&frame )->linesize[ 2 ];
584                                 }
585                         }
586                         else
587                         {
588                                 img_convert( output, PIX_FMT_YUV422, (AVPicture *)&frame, codec_context->pix_fmt, *width, *height );
589                                 memcpy( *buffer, output->data[ 0 ], size );
590                         }
591
592                         memcpy( image, *buffer, size );
593                         mlt_properties_set_data( frame_properties, "image", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
594
595                         if ( current_time == 0 && source_fps != 0 )
596                         {
597                                 double fps = mlt_properties_get_double( properties, "fps" );
598                                 current_time = ceil( source_fps * ( double )position / fps ) * ( 1 / source_fps );
599                                 mlt_properties_set_double( properties, "current_time", current_time );
600                         }
601                         else
602                         {
603                                 mlt_properties_set_double( properties, "current_time", current_time );
604                         }
605                 }
606         }
607
608         // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
609         mlt_properties_set_position( properties, "video_expected", position + 1 );
610
611         // Unlock the mutex now
612         pthread_mutex_unlock( &avformat_mutex );
613
614         return 0;
615 }
616
617 /** Set up video handling.
618 */
619
620 static void producer_set_up_video( mlt_producer this, mlt_frame frame )
621 {
622         // Get the properties
623         mlt_properties properties = mlt_producer_properties( this );
624
625         // Fetch the video_context
626         AVFormatContext *context = mlt_properties_get_data( properties, "video_context", NULL );
627
628         // Get the video_index
629         int index = mlt_properties_get_int( properties, "video_index" );
630
631         // Get the frame properties
632         mlt_properties frame_properties = mlt_frame_properties( frame );
633
634         // Lock the mutex now
635         pthread_mutex_lock( &avformat_mutex );
636
637         if ( context != NULL && index != -1 )
638         {
639                 // Get the video stream
640                 AVStream *stream = context->streams[ index ];
641
642                 // Get codec context
643                 AVCodecContext *codec_context = &stream->codec;
644
645                 // Get the codec
646                 AVCodec *codec = mlt_properties_get_data( properties, "video_codec", NULL );
647
648                 // Initialise the codec if necessary
649                 if ( codec == NULL )
650                 {
651                         // Find the codec
652                         codec = avcodec_find_decoder( codec_context->codec_id );
653
654                         // If we don't have a codec and we can't initialise it, we can't do much more...
655                         if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
656                         {
657                                 // Now store the codec with its destructor
658                                 mlt_properties_set_data( properties, "video_codec", codec_context, 0, producer_codec_close, NULL );
659                         }
660                         else
661                         {
662                                 // Remember that we can't use this later
663                                 mlt_properties_set_int( properties, "video_index", -1 );
664                         }
665                 }
666
667                 // No codec, no show...
668                 if ( codec != NULL )
669                 {
670                         double aspect_ratio = 1;
671                         double source_fps = 0;
672
673                         // Set aspect ratio
674                         if ( codec_context->sample_aspect_ratio.num > 0 )
675                                 aspect_ratio = av_q2d( codec_context->sample_aspect_ratio );
676
677                         mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio );
678                         //fprintf( stderr, "AVFORMAT: sample aspect %f %dx%d\n", av_q2d( codec_context->sample_aspect_ratio ), codec_context->width, codec_context->height );
679
680                         // Determine the fps
681                         source_fps = ( double )codec_context->frame_rate / ( codec_context->frame_rate_base == 0 ? 1 : codec_context->frame_rate_base );
682
683                         // We'll use fps if it's available
684                         if ( source_fps > 0 && source_fps < 30 )
685                                 mlt_properties_set_double( properties, "source_fps", source_fps );
686                         
687                         // Set the width and height
688                         mlt_properties_set_int( frame_properties, "width", codec_context->width );
689                         mlt_properties_set_int( frame_properties, "height", codec_context->height );
690
691                         mlt_frame_push_get_image( frame, producer_get_image );
692                         mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
693                 }
694                 else
695                 {
696                         mlt_properties_set_int( frame_properties, "test_image", 1 );
697                 }
698         }
699         else
700         {
701                 mlt_properties_set_int( frame_properties, "test_image", 1 );
702         }
703
704         // Unlock the mutex now
705         pthread_mutex_unlock( &avformat_mutex );
706 }
707
708 /** Get the audio from a frame.
709 */
710
711 static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
712 {
713         // Get the properties from the frame
714         mlt_properties frame_properties = mlt_frame_properties( frame );
715
716         // Obtain the frame number of this frame
717         mlt_position position = mlt_properties_get_position( frame_properties, "avformat_position" );
718
719         // Get the producer 
720         mlt_producer this = mlt_properties_get_data( frame_properties, "avformat_producer", NULL );
721
722         // Get the producer properties
723         mlt_properties properties = mlt_producer_properties( this );
724
725         // Fetch the audio_context
726         AVFormatContext *context = mlt_properties_get_data( properties, "audio_context", NULL );
727
728         // Get the audio_index
729         int index = mlt_properties_get_int( properties, "audio_index" );
730
731         // Obtain the expected frame numer
732         mlt_position expected = mlt_properties_get_position( properties, "audio_expected" );
733
734         // Obtain the resample context if it exists (not always needed)
735         ReSampleContext *resample = mlt_properties_get_data( properties, "audio_resample", NULL );
736
737         // Obtain the audio buffer
738         int16_t *audio_buffer = mlt_properties_get_data( properties, "audio_buffer", NULL );
739
740         // Get amount of audio used
741         int audio_used =  mlt_properties_get_int( properties, "audio_used" );
742
743         // Calculate the real time code
744         double real_timecode = producer_time_of_frame( this, position );
745
746         // Get the audio stream
747         AVStream *stream = context->streams[ index ];
748
749         // Get codec context
750         AVCodecContext *codec_context = &stream->codec;
751
752         // Packet
753         AVPacket pkt;
754
755         // Number of frames to ignore (for ffwd)
756         int ignore = 0;
757
758         // Flag for paused (silence) 
759         int paused = 0;
760         int locked = 0;
761
762         // Lock the mutex now
763         pthread_mutex_lock( &avformat_mutex );
764
765         // Check for resample and create if necessary
766         if ( resample == NULL )
767         {
768                 // Create the resampler
769                 resample = audio_resample_init( *channels, codec_context->channels, *frequency, codec_context->sample_rate );
770
771                 // And store it on properties
772                 mlt_properties_set_data( properties, "audio_resample", resample, 0, ( mlt_destructor )audio_resample_close, NULL );
773         }
774
775         // Check for audio buffer and create if necessary
776         if ( audio_buffer == NULL )
777         {
778                 // Allocate the audio buffer
779                 audio_buffer = mlt_pool_alloc( AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( int16_t ) );
780
781                 // And store it on properties for reuse
782                 mlt_properties_set_data( properties, "audio_buffer", audio_buffer, 0, ( mlt_destructor )mlt_pool_release, NULL );
783         }
784
785         // Seek if necessary
786         if ( position != expected )
787         {
788                 if ( position + 1 == expected )
789                 {
790                         // We're paused - silence required
791                         paused = 1;
792                 }
793                 else if ( position > expected && ( position - expected ) < 250 )
794                 {
795                         // Fast forward - seeking is inefficient for small distances - just ignore following frames
796                         ignore = position - expected;
797                 }
798                 else
799                 {
800                         // Set to the real timecode
801                         av_seek_frame( context, -1, real_timecode * 1000000.0 );
802
803                         // Clear the usage in the audio buffer
804                         audio_used = 0;
805
806                         locked = 1;
807                 }
808         }
809
810         // Get the audio if required
811         if ( !paused )
812         {
813                 int ret = 0;
814                 int got_audio = 0;
815                 int16_t *temp = mlt_pool_alloc( sizeof( int16_t ) * AVCODEC_MAX_AUDIO_FRAME_SIZE );
816
817                 memset( &pkt, 0, sizeof( pkt ) );
818
819                 while( ret >= 0 && !got_audio )
820                 {
821                         // Check if the buffer already contains the samples required
822                         if ( audio_used >= *samples && ignore == 0 )
823                         {
824                                 got_audio = 1;
825                                 break;
826                         }
827
828                         // Read a packet
829                         ret = av_read_frame( context, &pkt );
830
831                 int len = pkt.size;
832                 uint8_t *ptr = pkt.data;
833                         int data_size;
834
835                         // We only deal with video from the selected video_index
836                         while ( ptr != NULL && ret >= 0 && pkt.stream_index == index && len > 0 )
837                         {
838                                 // Decode the audio
839                                 ret = avcodec_decode_audio( codec_context, temp, &data_size, ptr, len );
840
841                                 if ( ret < 0 )
842                                 {
843                                         ret = 0;
844                                         break;
845                                 }
846
847                                 len -= ret;
848                                 ptr += ret;
849
850                                 if ( data_size > 0 )
851                                 {
852                                         int size_out = audio_resample( resample, &audio_buffer[ audio_used * *channels ], temp, data_size / ( codec_context->channels * sizeof( int16_t ) ) );
853
854                                         audio_used += size_out;
855
856                                         // Handle ignore
857                                         while ( ignore && audio_used > *samples )
858                                         {
859                                                 ignore --;
860                                                 audio_used -= *samples;
861                                                 memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * sizeof( int16_t ) );
862                                         }
863                                 }
864
865                                 // If we're behind, ignore this packet
866                                 float current_pts = (float)pkt.pts / 1000000.0;
867                                 double discrepancy = mlt_properties_get_double( properties, "discrepancy" );
868                                 if ( current_pts != 0 && real_timecode != 0 )
869                                 {
870                                         if ( discrepancy != 1 )
871                                                 discrepancy = ( discrepancy + ( real_timecode / current_pts ) ) / 2;
872                                         else
873                                                 discrepancy = real_timecode / current_pts;
874                                         if ( discrepancy > 0.9 && discrepancy < 1.1 )
875                                                 discrepancy = 1.0;
876                                         else
877                                                 discrepancy = floor( discrepancy + 0.5 );
878
879                                         if ( discrepancy == 0 )
880                                                 discrepancy = 1.0;
881
882                                         mlt_properties_set_double( properties, "discrepancy", discrepancy );
883                                 }
884
885                                 if ( !ignore && discrepancy * current_pts <= ( real_timecode - 0.02 ) )
886                                         ignore = 1;
887                         }
888
889                         // We're finished with this packet regardless
890                         av_free_packet( &pkt );
891                 }
892
893                 *buffer = mlt_pool_alloc( *samples * *channels * sizeof( int16_t ) );
894                 mlt_properties_set_data( frame_properties, "audio", *buffer, 0, ( mlt_destructor )mlt_pool_release, NULL );
895
896                 // Now handle the audio if we have enough
897                 if ( audio_used >= *samples )
898                 {
899                         memcpy( *buffer, audio_buffer, *samples * *channels * sizeof( int16_t ) );
900                         audio_used -= *samples;
901                         memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * *channels * sizeof( int16_t ) );
902                 }
903                 else
904                 {
905                         memset( *buffer, 0, *samples * *channels * sizeof( int16_t ) );
906                 }
907                 
908                 // Store the number of audio samples still available
909                 mlt_properties_set_int( properties, "audio_used", audio_used );
910
911                 // Release the temporary audio
912                 mlt_pool_release( temp );
913         }
914         else
915         {
916                 // Get silence and don't touch the context
917                 frame->get_audio = NULL;
918                 mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
919         }
920
921         // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
922         mlt_properties_set_position( properties, "audio_expected", position + 1 );
923
924         // Unlock the mutex now
925         pthread_mutex_unlock( &avformat_mutex );
926
927         return 0;
928 }
929
930 /** Set up audio handling.
931 */
932
933 static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
934 {
935         // Get the properties
936         mlt_properties properties = mlt_producer_properties( this );
937
938         // Fetch the audio_context
939         AVFormatContext *context = mlt_properties_get_data( properties, "audio_context", NULL );
940
941         // Get the audio_index
942         int index = mlt_properties_get_int( properties, "audio_index" );
943
944         // Lock the mutex now
945         pthread_mutex_lock( &avformat_mutex );
946
947         // Deal with audio context
948         if ( context != NULL && index != -1 )
949         {
950                 // Get the frame properties
951                 mlt_properties frame_properties = mlt_frame_properties( frame );
952
953                 // Get the audio stream
954                 AVStream *stream = context->streams[ index ];
955
956                 // Get codec context
957                 AVCodecContext *codec_context = &stream->codec;
958
959                 // Get the codec
960                 AVCodec *codec = mlt_properties_get_data( properties, "audio_codec", NULL );
961
962                 // Initialise the codec if necessary
963                 if ( codec == NULL )
964                 {
965                         // Find the codec
966                         codec = avcodec_find_decoder( codec_context->codec_id );
967
968                         // If we don't have a codec and we can't initialise it, we can't do much more...
969                         if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
970                         {
971                                 // Now store the codec with its destructor
972                                 mlt_properties_set_data( properties, "audio_codec", codec_context, 0, producer_codec_close, NULL );
973
974                         }
975                         else
976                         {
977                                 // Remember that we can't use this later
978                                 mlt_properties_set_int( properties, "audio_index", -1 );
979                         }
980                 }
981
982                 // No codec, no show...
983                 if ( codec != NULL )
984                 {
985                         frame->get_audio = producer_get_audio;
986                         mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
987                 }
988         }
989
990         // Unlock the mutex now
991         pthread_mutex_unlock( &avformat_mutex );
992 }
993
994 /** Our get frame implementation.
995 */
996
997 static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index )
998 {
999         // Create an empty frame
1000         *frame = mlt_frame_init( );
1001
1002         // Update timecode on the frame we're creating
1003         mlt_frame_set_position( *frame, mlt_producer_position( this ) );
1004
1005         // Set the position of this producer
1006         mlt_properties_set_position( mlt_frame_properties( *frame ), "avformat_position", mlt_producer_get_in( this ) + mlt_producer_position( this ) );
1007
1008         // Set up the video
1009         producer_set_up_video( this, *frame );
1010
1011         // Set up the audio
1012         producer_set_up_audio( this, *frame );
1013
1014         // Set the aspect_ratio
1015         mlt_properties_set_double( mlt_frame_properties( *frame ), "aspect_ratio", mlt_properties_get_double( mlt_producer_properties( this ), "aspect_ratio" ) );
1016
1017         // Calculate the next timecode
1018         mlt_producer_prepare_next( this );
1019
1020         return 0;
1021 }