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