Added avformat
[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
634 fprintf( stderr, "%f < %f\n", discrepancy * current_pts, (float) real_timecode );
635 if ( discrepancy * current_pts < real_timecode )
636 ignore = 1;
637 }
638
639 // We're finished with this packet regardless
640 av_free_packet( &pkt );
641 }
642
643 // Now handle the audio if we have enough
644 if ( audio_used >= *samples )
645 {
646 *buffer = malloc( *samples * *channels * sizeof( int16_t ) );
647 memcpy( *buffer, audio_buffer, *samples * *channels * sizeof( int16_t ) );
648 audio_used -= *samples;
649 memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * *channels * sizeof( int16_t ) );
650 mlt_properties_set_data( frame_properties, "audio", *buffer, 0, free, NULL );
651 }
652 else
653 {
654 frame->get_audio = NULL;
655 mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
656 audio_used = 0;
657 }
658
659 // Store the number of audio samples still available
660 mlt_properties_set_int( properties, "audio_used", audio_used );
661 }
662 else
663 {
664 // Get silence and don't touch the context
665 frame->get_audio = NULL;
666 mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
667 }
668
669 // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
670 mlt_properties_set_position( properties, "audio_expected", position + 1 );
671
672 return 0;
673 }
674
675 /** Set up audio handling.
676 */
677
678 static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
679 {
680 // Get the properties
681 mlt_properties properties = mlt_producer_properties( this );
682
683 // Fetch the audio_context
684 AVFormatContext *context = mlt_properties_get_data( properties, "audio_context", NULL );
685
686 // Get the audio_index
687 int index = mlt_properties_get_int( properties, "audio_index" );
688
689 // Deal with audio context
690 if ( context != NULL && index != -1 )
691 {
692 // Get the frame properties
693 mlt_properties frame_properties = mlt_frame_properties( frame );
694
695 // Get the audio stream
696 AVStream *stream = context->streams[ index ];
697
698 // Get codec context
699 AVCodecContext *codec_context = &stream->codec;
700
701 // Get the codec
702 AVCodec *codec = mlt_properties_get_data( properties, "audio_codec", NULL );
703
704 // Initialise the codec if necessary
705 if ( codec == NULL )
706 {
707 // Find the codec
708 codec = avcodec_find_decoder( codec_context->codec_id );
709
710 // If we don't have a codec and we can't initialise it, we can't do much more...
711 if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
712 {
713 // Now store the codec with its destructor
714 mlt_properties_set_data( properties, "audio_codec", codec, 0, ( mlt_destructor )avcodec_close, NULL );
715 }
716 else
717 {
718 // Remember that we can't use this later
719 mlt_properties_set_int( properties, "audio_index", -1 );
720 }
721 }
722
723 // No codec, no show...
724 if ( codec != NULL )
725 {
726 frame->get_audio = producer_get_audio;
727 mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
728 }
729 }
730 }
731
732 /** Our get frame implementation.
733 */
734
735 static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index )
736 {
737 // Create an empty frame
738 *frame = mlt_frame_init( );
739
740 // Update timecode on the frame we're creating
741 mlt_frame_set_position( *frame, mlt_producer_position( this ) );
742
743 // Set the position of this producer
744 mlt_properties_set_position( mlt_frame_properties( *frame ), "avformat_position", mlt_producer_get_in( this ) + mlt_producer_position( this ) );
745
746 // Set up the video
747 producer_set_up_video( this, *frame );
748
749 // Set up the audio
750 producer_set_up_audio( this, *frame );
751
752 // Set the aspect_ratio
753 mlt_properties_set_double( mlt_frame_properties( *frame ), "aspect_ratio", mlt_properties_get_double( mlt_producer_properties( this ), "aspect_ratio" ) );
754
755 // Calculate the next timecode
756 mlt_producer_prepare_next( this );
757
758 return 0;
759 }