2 * producer_avformat.c -- avformat producer
3 * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
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.
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.
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.
22 #include "producer_avformat.h"
25 #include <framework/mlt_frame.h>
27 // ffmpeg Header files
28 #include <ffmpeg/avformat.h>
30 // System header files
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
);
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
;
44 /** Constructor for libavformat.
47 mlt_producer
producer_avformat_init( char *file
)
49 mlt_producer
this = NULL
;
51 // Check that we have a non-NULL argument
54 // Construct the producer
55 this = calloc( 1, sizeof( struct mlt_producer_s
) );
58 if ( mlt_producer_init( this, NULL
) == 0 )
61 mlt_properties properties
= mlt_producer_properties( this );
63 // Set the resource property (required for all producers)
64 mlt_properties_set( properties
, "resource", file
);
66 // TEST: audio sync tweaking
67 mlt_properties_set_double( properties
, "discrepancy", 1 );
69 // Register our get_frame implementation
70 this->get_frame
= producer_get_frame
;
72 // Initialise avformat if necessary
73 if ( avformat_initialised
== 0 )
75 pthread_mutex_init( &avformat_mutex
, NULL
);
76 avformat_initialised
= 1;
81 if ( producer_open( this, file
) != 0 )
84 mlt_producer_close( this );
93 /** Find the default streams.
96 static void find_default_streams( AVFormatContext
*context
, int *audio_index
, int *video_index
)
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
++ )
103 // Get the codec context
104 AVCodecContext
*codec_context
= &context
->streams
[ i
]->codec
;
106 // Determine the type and obtain the first index of each type
107 switch( codec_context
->codec_type
)
109 case CODEC_TYPE_VIDEO
:
110 if ( *video_index
< 0 )
113 case CODEC_TYPE_AUDIO
:
114 if ( *audio_index
< 0 )
123 /** Producer file destructor.
126 static void producer_file_close( void *context
)
128 if ( context
!= NULL
)
130 // Lock the mutex now
131 pthread_mutex_lock( &avformat_mutex
);
134 av_close_input_file( context
);
136 // Unlock the mutex now
137 pthread_mutex_unlock( &avformat_mutex
);
141 /** Producer file destructor.
144 static void producer_codec_close( void *codec
)
148 // Lock the mutex now
149 pthread_mutex_lock( &avformat_mutex
);
152 avcodec_close( codec
);
154 // Unlock the mutex now
155 pthread_mutex_unlock( &avformat_mutex
);
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 ;-)).
170 static int producer_open( mlt_producer
this, char *file
)
172 // Return an error code (0 == no error)
175 // Context for avformat
176 AVFormatContext
*context
= NULL
;
178 // Get the properties
179 mlt_properties properties
= mlt_producer_properties( this );
181 // We will treat everything with the producer fps
182 double fps
= mlt_properties_get_double( properties
, "fps" );
184 // Lock the mutex now
185 pthread_mutex_lock( &avformat_mutex
);
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 );
192 // If successful, then try to get additional info
195 // Get the stream info
196 error
= av_find_stream_info( context
) < 0;
198 // Continue if no error
201 // We will default to the first audio and video streams found
202 int audio_index
= -1;
203 int video_index
= -1;
205 // Now set properties where we can (use default unknowns if required)
206 if ( context
->duration
!= AV_NOPTS_VALUE
)
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 );
214 // Find default audio and video streams
215 find_default_streams( context
, &audio_index
, &video_index
);
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
);
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 )
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
);
227 // And open again for our audio context
228 av_open_input_file( &context
, file
, NULL
, 0, NULL
);
229 av_find_stream_info( context
);
232 mlt_properties_set_data( properties
, "audio_context", context
, 0, producer_file_close
, NULL
);
234 else if ( video_index
!= -1 )
236 // We only have a video context
237 mlt_properties_set_data( properties
, "video_context", context
, 0, producer_file_close
, NULL
);
239 else if ( audio_index
!= -1 )
241 // We only have an audio context
242 mlt_properties_set_data( properties
, "audio_context", context
, 0, producer_file_close
, NULL
);
246 // Something has gone wrong
252 // Unlock the mutex now
253 pthread_mutex_unlock( &avformat_mutex
);
258 /** Convert a frame position to a time code.
261 static double producer_time_of_frame( mlt_producer
this, mlt_position position
)
263 // Get the properties
264 mlt_properties properties
= mlt_producer_properties( this );
267 double fps
= mlt_properties_get_double( properties
, "fps" );
270 return ( double )position
/ fps
;
273 /** Get an image from a frame.
276 static int producer_get_image( mlt_frame frame
, uint8_t **buffer
, mlt_image_format
*format
, int *width
, int *height
, int writable
)
278 // Get the properties from the frame
279 mlt_properties frame_properties
= mlt_frame_properties( frame
);
281 // Obtain the frame number of this frame
282 mlt_position position
= mlt_properties_get_position( frame_properties
, "avformat_position" );
285 mlt_producer
this = mlt_properties_get_data( frame_properties
, "avformat_producer", NULL
);
287 // Get the producer properties
288 mlt_properties properties
= mlt_producer_properties( this );
290 // Fetch the video_context
291 AVFormatContext
*context
= mlt_properties_get_data( properties
, "video_context", NULL
);
293 // Get the video_index
294 int index
= mlt_properties_get_int( properties
, "video_index" );
296 // Obtain the expected frame numer
297 mlt_position expected
= mlt_properties_get_position( properties
, "video_expected" );
299 // Calculate the real time code
300 double real_timecode
= producer_time_of_frame( this, position
);
302 // Get the video stream
303 AVStream
*stream
= context
->streams
[ index
];
306 AVCodecContext
*codec_context
= &stream
->codec
;
311 // Get the conversion frame
312 AVPicture
*output
= mlt_properties_get_data( properties
, "video_output_frame", NULL
);
314 // Special case pause handling flag
317 // Special case ffwd handling
320 // Current time calcs
321 double current_time
= 0;
323 // We may want to use the source fps if available
324 double source_fps
= mlt_properties_get_double( properties
, "source_fps" );
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
;
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
);
335 // Lock the mutex now
336 pthread_mutex_lock( &avformat_mutex
);
338 // Construct an AVFrame for YUV422 conversion
339 if ( output
== NULL
)
341 int size
= avpicture_get_size( PIX_FMT_YUV422
, *width
, *height
);
342 void *frame_release
= NULL
;
343 void *buffer_release
= NULL
;
345 uint8_t *buf
= mlt_pool_allocate( size
, &buffer_release
);
346 output
= mlt_pool_allocate( sizeof( AVPicture
), &frame_release
);
347 memset( output
, 0, sizeof( AVPicture
) );
348 avpicture_fill( output
, buf
, PIX_FMT_YUV422
, *width
, *height
);
349 mlt_properties_set_data( properties
, "video_output_frame_release", frame_release
, 0, ( mlt_destructor
)mlt_pool_release
, NULL
);
350 mlt_properties_set_data( properties
, "video_output_buffer_release", buffer_release
, 0, ( mlt_destructor
)mlt_pool_release
, NULL
);
351 mlt_properties_set_data( properties
, "video_output_frame", output
, 0, NULL
, NULL
);
352 mlt_properties_set_data( properties
, "video_output_buffer", buf
, 0, NULL
, NULL
);
356 if ( position
!= expected
)
358 if ( position
+ 1 == expected
)
360 // We're paused - use last image
363 else if ( position
> expected
&& ( position
- expected
) < 250 )
365 // Fast forward - seeking is inefficient for small distances - just ignore following frames
366 ignore
= position
- expected
;
370 // Set to the real timecode
371 av_seek_frame( context
, -1, real_timecode
* 1000000.0 );
373 // Remove the cached info relating to the previous position
374 mlt_properties_set_double( properties
, "current_time", 0 );
375 mlt_properties_set_data( properties
, "current_image", NULL
, 0, NULL
, NULL
);
379 // Duplicate the last image if necessary
380 if ( mlt_properties_get_data( properties
, "current_image", NULL
) != NULL
&&
381 ( paused
|| mlt_properties_get_double( properties
, "current_time" ) >= real_timecode
) )
383 // Get current image and size
385 uint8_t *image
= mlt_properties_get_data( properties
, "current_image", &size
);
388 void *release
= NULL
;
389 *buffer
= mlt_pool_allocate( size
, &release
);
390 memcpy( *buffer
, image
, size
);
392 // Set this on the frame properties
393 mlt_properties_set_data( frame_properties
, "image_release", release
, 0, ( mlt_destructor
)mlt_pool_release
, NULL
);
394 mlt_properties_set_data( frame_properties
, "image", *buffer
, size
, NULL
, NULL
);
402 memset( &pkt
, 0, sizeof( pkt
) );
403 memset( &frame
, 0, sizeof( frame
) );
405 while( ret
>= 0 && !got_picture
)
408 ret
= av_read_frame( context
, &pkt
);
410 // We only deal with video from the selected video_index
411 if ( ret
>= 0 && pkt
.stream_index
== index
&& pkt
.size
> 0 )
413 current_time
= ( double )pkt
.pts
/ 1000000.0;
416 // Wouldn't it be great if I could use this...
417 //if ( (float)pkt.pts / 1000000.0 >= real_timecode )
418 ret
= avcodec_decode_video( codec_context
, &frame
, &got_picture
, pkt
.data
, pkt
.size
);
423 if ( current_time
< real_timecode
)
428 else if ( current_time
>= real_timecode
)
432 else if ( got_picture
&& ignore
-- )
439 // We're finished with this packet regardless
440 av_free_packet( &pkt
);
443 // Now handle the picture if we have one
446 // Get current image and size
448 void *release
= NULL
;
449 uint8_t *image
= mlt_properties_get_data( properties
, "current_image", &size
);
451 if ( image
== NULL
|| size
!= *width
* *height
* 2 )
453 void *current_image_release
= NULL
;
454 size
= *width
* ( *height
+ 1 ) * 2;
455 image
= mlt_pool_allocate( size
, ¤t_image_release
);
456 mlt_properties_set_data( properties
, "current_image_release", current_image_release
, 0, ( mlt_destructor
)mlt_pool_release
, NULL
);
457 mlt_properties_set_data( properties
, "current_image", image
, size
, NULL
, NULL
);
460 *buffer
= mlt_pool_allocate( size
, &release
);
461 img_convert( output
, PIX_FMT_YUV422
, (AVPicture
*)&frame
, codec_context
->pix_fmt
, *width
, *height
);
462 memcpy( image
, output
->data
[ 0 ], size
);
463 memcpy( *buffer
, output
->data
[ 0 ], size
);
464 mlt_properties_set_data( frame_properties
, "image_release", release
, 0, ( mlt_destructor
)mlt_pool_release
, NULL
);
465 mlt_properties_set_data( frame_properties
, "image", *buffer
, size
, NULL
, NULL
);
467 if ( current_time
== 0 && source_fps
!= 0 )
469 double fps
= mlt_properties_get_double( properties
, "fps" );
470 current_time
= ceil( source_fps
* ( double )position
/ fps
) * ( 1 / source_fps
);
471 mlt_properties_set_double( properties
, "current_time", current_time
);
475 mlt_properties_set_double( properties
, "current_time", current_time
);
480 // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
481 mlt_properties_set_position( properties
, "video_expected", position
+ 1 );
483 // Unlock the mutex now
484 pthread_mutex_unlock( &avformat_mutex
);
489 /** Set up video handling.
492 static void producer_set_up_video( mlt_producer
this, mlt_frame frame
)
494 // Get the properties
495 mlt_properties properties
= mlt_producer_properties( this );
497 // Fetch the video_context
498 AVFormatContext
*context
= mlt_properties_get_data( properties
, "video_context", NULL
);
500 // Get the video_index
501 int index
= mlt_properties_get_int( properties
, "video_index" );
503 // Get the frame properties
504 mlt_properties frame_properties
= mlt_frame_properties( frame
);
506 // Lock the mutex now
507 pthread_mutex_lock( &avformat_mutex
);
509 if ( context
!= NULL
&& index
!= -1 )
511 // Get the video stream
512 AVStream
*stream
= context
->streams
[ index
];
515 AVCodecContext
*codec_context
= &stream
->codec
;
518 AVCodec
*codec
= mlt_properties_get_data( properties
, "video_codec", NULL
);
520 // Initialise the codec if necessary
524 codec
= avcodec_find_decoder( codec_context
->codec_id
);
526 // If we don't have a codec and we can't initialise it, we can't do much more...
527 if ( codec
!= NULL
&& avcodec_open( codec_context
, codec
) >= 0 )
529 double aspect_ratio
= 0;
530 double source_fps
= 0;
533 if ( codec_context
->sample_aspect_ratio
.num
== 0)
536 aspect_ratio
= av_q2d( codec_context
->sample_aspect_ratio
) * codec_context
->width
/ codec_context
->height
;
538 if (aspect_ratio
<= 0.0)
539 aspect_ratio
= ( double )codec_context
->width
/ ( double )codec_context
->height
;
541 mlt_properties_set_double( properties
, "aspect_ratio", aspect_ratio
);
542 fprintf( stderr
, "AVFORMAT: sample aspect %f\n", aspect_ratio
);
545 source_fps
= ( double )codec_context
->frame_rate
/ codec_context
->frame_rate_base
;
547 // We'll use fps if it's available
548 if ( source_fps
> 0 && source_fps
< 30 )
549 mlt_properties_set_double( properties
, "source_fps", source_fps
);
551 // Now store the codec with its destructor
552 mlt_properties_set_data( properties
, "video_codec", codec_context
, 0, producer_codec_close
, NULL
);
554 // Set to the real timecode
555 av_seek_frame( context
, -1, 0 );
559 // Remember that we can't use this later
560 mlt_properties_set_int( properties
, "video_index", -1 );
564 // No codec, no show...
567 mlt_frame_push_get_image( frame
, producer_get_image
);
568 mlt_properties_set_data( frame_properties
, "avformat_producer", this, 0, NULL
, NULL
);
572 mlt_properties_set_int( frame_properties
, "test_image", 1 );
577 mlt_properties_set_int( frame_properties
, "test_image", 1 );
580 // Unlock the mutex now
581 pthread_mutex_unlock( &avformat_mutex
);
584 /** Get the audio from a frame.
587 static int producer_get_audio( mlt_frame frame
, int16_t **buffer
, mlt_audio_format
*format
, int *frequency
, int *channels
, int *samples
)
589 // Get the properties from the frame
590 mlt_properties frame_properties
= mlt_frame_properties( frame
);
592 // Obtain the frame number of this frame
593 mlt_position position
= mlt_properties_get_position( frame_properties
, "avformat_position" );
596 mlt_producer
this = mlt_properties_get_data( frame_properties
, "avformat_producer", NULL
);
598 // Get the producer properties
599 mlt_properties properties
= mlt_producer_properties( this );
601 // Fetch the audio_context
602 AVFormatContext
*context
= mlt_properties_get_data( properties
, "audio_context", NULL
);
604 // Get the audio_index
605 int index
= mlt_properties_get_int( properties
, "audio_index" );
607 // Obtain the expected frame numer
608 mlt_position expected
= mlt_properties_get_position( properties
, "audio_expected" );
610 // Obtain the resample context if it exists (not always needed)
611 ReSampleContext
*resample
= mlt_properties_get_data( properties
, "audio_resample", NULL
);
613 // Obtain the audio buffer
614 int16_t *audio_buffer
= mlt_properties_get_data( properties
, "audio_buffer", NULL
);
616 // Get amount of audio used
617 int audio_used
= mlt_properties_get_int( properties
, "audio_used" );
619 // Calculate the real time code
620 double real_timecode
= producer_time_of_frame( this, position
);
622 // Get the audio stream
623 AVStream
*stream
= context
->streams
[ index
];
626 AVCodecContext
*codec_context
= &stream
->codec
;
631 // Number of frames to ignore (for ffwd)
634 // Flag for paused (silence)
638 // Lock the mutex now
639 pthread_mutex_lock( &avformat_mutex
);
641 // Check for resample and create if necessary
642 if ( resample
== NULL
)
644 // Create the resampler
645 resample
= audio_resample_init( *channels
, codec_context
->channels
, *frequency
, codec_context
->sample_rate
);
647 // And store it on properties
648 mlt_properties_set_data( properties
, "audio_resample", resample
, 0, ( mlt_destructor
)audio_resample_close
, NULL
);
651 // Check for audio buffer and create if necessary
652 if ( audio_buffer
== NULL
)
654 // Audio buffer release pointer
655 void *buffer_release
= NULL
;
657 // Allocate the audio buffer
658 audio_buffer
= mlt_pool_allocate( AVCODEC_MAX_AUDIO_FRAME_SIZE
* sizeof( int16_t ), &buffer_release
);
660 // And store it on properties for reuse
661 mlt_properties_set_data( properties
, "audio_buffer_release", buffer_release
, 0, ( mlt_destructor
)mlt_pool_release
, NULL
);
662 mlt_properties_set_data( properties
, "audio_buffer", audio_buffer
, 0, NULL
, NULL
);
666 if ( position
!= expected
)
668 if ( position
+ 1 == expected
)
670 // We're paused - silence required
673 else if ( position
> expected
&& ( position
- expected
) < 250 )
675 // Fast forward - seeking is inefficient for small distances - just ignore following frames
676 ignore
= position
- expected
;
680 // Set to the real timecode
681 av_seek_frame( context
, -1, real_timecode
* 1000000.0 );
683 // Clear the usage in the audio buffer
690 // Get the audio if required
695 void *temp_release
= NULL
;
696 int16_t *temp
= mlt_pool_allocate( sizeof( int16_t ) * AVCODEC_MAX_AUDIO_FRAME_SIZE
, &temp_release
);
698 memset( &pkt
, 0, sizeof( pkt
) );
700 while( ret
>= 0 && !got_audio
)
702 // Check if the buffer already contains the samples required
703 if ( audio_used
>= *samples
&& ignore
== 0 )
710 ret
= av_read_frame( context
, &pkt
);
713 uint8_t *ptr
= pkt
.data
;
716 // We only deal with video from the selected video_index
717 while ( ptr
!= NULL
&& ret
>= 0 && pkt
.stream_index
== index
&& len
> 0 )
720 ret
= avcodec_decode_audio( codec_context
, temp
, &data_size
, ptr
, len
);
733 int size_out
= audio_resample( resample
, &audio_buffer
[ audio_used
* *channels
], temp
, data_size
/ ( codec_context
->channels
* sizeof( int16_t ) ) );
735 audio_used
+= size_out
;
738 while ( ignore
&& audio_used
> *samples
)
741 audio_used
-= *samples
;
742 memmove( audio_buffer
, &audio_buffer
[ *samples
* *channels
], audio_used
* sizeof( int16_t ) );
746 // If we're behind, ignore this packet
747 float current_pts
= (float)pkt
.pts
/ 1000000.0;
748 double discrepancy
= mlt_properties_get_double( properties
, "discrepancy" );
749 if ( current_pts
!= 0 && real_timecode
!= 0 )
751 if ( discrepancy
!= 1 )
752 discrepancy
= ( discrepancy
+ ( real_timecode
/ current_pts
) ) / 2;
754 discrepancy
= real_timecode
/ current_pts
;
755 if ( discrepancy
> 0.9 && discrepancy
< 1.1 )
758 discrepancy
= floor( discrepancy
+ 0.5 );
760 if ( discrepancy
== 0 )
763 mlt_properties_set_double( properties
, "discrepancy", discrepancy
);
766 if ( discrepancy
* current_pts
<= ( real_timecode
- 0.02 ) )
770 // We're finished with this packet regardless
771 av_free_packet( &pkt
);
774 // Now handle the audio if we have enough
775 if ( audio_used
>= *samples
)
777 void *buffer_release
= NULL
;
778 *buffer
= mlt_pool_allocate( *samples
* *channels
* sizeof( int16_t ), &buffer_release
);
779 memcpy( *buffer
, audio_buffer
, *samples
* *channels
* sizeof( int16_t ) );
780 audio_used
-= *samples
;
781 memmove( audio_buffer
, &audio_buffer
[ *samples
* *channels
], audio_used
* *channels
* sizeof( int16_t ) );
782 mlt_properties_set_data( frame_properties
, "audio_release", buffer_release
, 0, ( mlt_destructor
)mlt_pool_release
, NULL
);
783 mlt_properties_set_data( frame_properties
, "audio", *buffer
, 0, NULL
, NULL
);
787 frame
->get_audio
= NULL
;
788 mlt_frame_get_audio( frame
, buffer
, format
, frequency
, channels
, samples
);
792 // Store the number of audio samples still available
793 mlt_properties_set_int( properties
, "audio_used", audio_used
);
795 // Release the temporary audio
796 mlt_pool_release( temp_release
);
800 // Get silence and don't touch the context
801 frame
->get_audio
= NULL
;
802 mlt_frame_get_audio( frame
, buffer
, format
, frequency
, channels
, samples
);
805 // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
806 mlt_properties_set_position( properties
, "audio_expected", position
+ 1 );
808 // Unlock the mutex now
809 pthread_mutex_unlock( &avformat_mutex
);
814 /** Set up audio handling.
817 static void producer_set_up_audio( mlt_producer
this, mlt_frame frame
)
819 // Get the properties
820 mlt_properties properties
= mlt_producer_properties( this );
822 // Fetch the audio_context
823 AVFormatContext
*context
= mlt_properties_get_data( properties
, "audio_context", NULL
);
825 // Get the audio_index
826 int index
= mlt_properties_get_int( properties
, "audio_index" );
828 // Lock the mutex now
829 pthread_mutex_lock( &avformat_mutex
);
831 // Deal with audio context
832 if ( context
!= NULL
&& index
!= -1 )
834 // Get the frame properties
835 mlt_properties frame_properties
= mlt_frame_properties( frame
);
837 // Get the audio stream
838 AVStream
*stream
= context
->streams
[ index
];
841 AVCodecContext
*codec_context
= &stream
->codec
;
844 AVCodec
*codec
= mlt_properties_get_data( properties
, "audio_codec", NULL
);
846 // Initialise the codec if necessary
850 codec
= avcodec_find_decoder( codec_context
->codec_id
);
852 // If we don't have a codec and we can't initialise it, we can't do much more...
853 if ( codec
!= NULL
&& avcodec_open( codec_context
, codec
) >= 0 )
855 // Now store the codec with its destructor
856 mlt_properties_set_data( properties
, "audio_codec", codec_context
, 0, producer_codec_close
, NULL
);
861 // Remember that we can't use this later
862 mlt_properties_set_int( properties
, "audio_index", -1 );
866 // No codec, no show...
869 frame
->get_audio
= producer_get_audio
;
870 mlt_properties_set_data( frame_properties
, "avformat_producer", this, 0, NULL
, NULL
);
874 // Unlock the mutex now
875 pthread_mutex_unlock( &avformat_mutex
);
878 /** Our get frame implementation.
881 static int producer_get_frame( mlt_producer
this, mlt_frame_ptr frame
, int index
)
883 // Create an empty frame
884 *frame
= mlt_frame_init( );
886 // Update timecode on the frame we're creating
887 mlt_frame_set_position( *frame
, mlt_producer_position( this ) );
889 // Set the position of this producer
890 mlt_properties_set_position( mlt_frame_properties( *frame
), "avformat_position", mlt_producer_get_in( this ) + mlt_producer_position( this ) );
893 producer_set_up_video( this, *frame
);
896 producer_set_up_audio( this, *frame
);
898 // Set the aspect_ratio
899 mlt_properties_set_double( mlt_frame_properties( *frame
), "aspect_ratio", mlt_properties_get_double( mlt_producer_properties( this ), "aspect_ratio" ) );
901 // Calculate the next timecode
902 mlt_producer_prepare_next( this );