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