+ Correction to previous patch - fixes pause behaviour with rawvideo
[melted] / src / modules / avformat / producer_avformat.c
index c6c0135..d0ff408 100644 (file)
@@ -242,8 +242,7 @@ static int producer_open( mlt_producer this, char *file )
        }
 
        // Now attempt to open the file
-       error = av_open_input_file( &context, file, format, 0, params );
-       error = error < 0;
+       error = av_open_input_file( &context, file, format, 0, params ) < 0;
        
        // Cleanup AVFormatParameters
        free( standard );
@@ -468,7 +467,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // Seek if necessary
        if ( position != expected )
        {
-               if ( position + 1 == expected )
+               if ( av_frame != NULL && position + 1 == expected )
                {
                        // We're paused - use last image
                        paused = 1;
@@ -491,9 +490,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                }
        }
        
-       // Duplicate the last image if necessary
-       if ( av_frame != NULL && ( paused || mlt_properties_get_double( properties, "_current_time" ) >= real_timecode ) &&
-                av_bypass == 0 )
+       // Duplicate the last image if necessary (see comment on rawvideo below)
+       if ( av_frame != NULL && ( paused || mlt_properties_get_double( properties, "_current_time" ) >= real_timecode ) && av_bypass == 0 )
        {
                // Duplicate it
                convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height );
@@ -508,16 +506,16 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                int must_decode = 1;
 
                // Temporary hack to improve intra frame only
-               if ( !strcmp( codec_context->codec->name, "mjpeg" ) )
+               if ( !strcmp( codec_context->codec->name, "mjpeg" ) || !strcmp( codec_context->codec->name, "rawvideo" ) )
                        must_decode = 0;
 
-               memset( &pkt, 0, sizeof( pkt ) );
+               av_init_packet( &pkt );
 
                // Construct an AVFrame for YUV422 conversion
                if ( av_frame == NULL )
                {
-                       av_frame = calloc( 1, sizeof( AVFrame ) );
-                       mlt_properties_set_data( properties, "av_frame", av_frame, 0, free, NULL );
+                       av_frame = avcodec_alloc_frame( );
+                       mlt_properties_set_data( properties, "av_frame", av_frame, 0, av_free, NULL );
                }
 
                while( ret >= 0 && !got_picture )
@@ -557,36 +555,40 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                                }
                        }
 
-                       // We're finished with this packet regardless
-                       av_free_packet( &pkt );
-               }
-
-               // Now handle the picture if we have one
-               if ( got_picture )
-               {
-                       mlt_properties_set_int( frame_properties, "progressive", !av_frame->interlaced_frame );
-                       mlt_properties_set_int( frame_properties, "top_field_first", av_frame->top_field_first );
+                       // Now handle the picture if we have one
+                       if ( got_picture )
+                       {
+                               mlt_properties_set_int( frame_properties, "progressive", !av_frame->interlaced_frame );
+                               mlt_properties_set_int( frame_properties, "top_field_first", av_frame->top_field_first );
 
-                       convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height );
+                               convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height );
 
-                       mlt_properties_set_data( frame_properties, "image", *buffer, size, (mlt_destructor)mlt_pool_release, NULL );
+                               mlt_properties_set_data( frame_properties, "image", *buffer, size, (mlt_destructor)mlt_pool_release, NULL );
 
-                       if ( current_time == 0 && source_fps != 0 )
-                       {
-                               double fps = mlt_properties_get_double( properties, "fps" );
-                               current_time = ceil( source_fps * ( double )position / fps ) * ( 1 / source_fps );
-                               mlt_properties_set_double( properties, "_current_time", current_time );
-                       }
-                       else
-                       {
-                               mlt_properties_set_double( properties, "_current_time", current_time );
+                               if ( current_time == 0 && source_fps != 0 )
+                               {
+                                       double fps = mlt_properties_get_double( properties, "fps" );
+                                       current_time = ceil( source_fps * ( double )position / fps ) * ( 1 / source_fps );
+                                       mlt_properties_set_double( properties, "_current_time", current_time );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_double( properties, "_current_time", current_time );
+                               }
                        }
+
+                       // We're finished with this packet regardless
+                       av_free_packet( &pkt );
                }
        }
-       
+
+       // Very untidy - for rawvideo, the packet contains the frame, hence the free packet
+       // above will break the pause behaviour - so we wipe the frame now
+       if ( !strcmp( codec_context->codec->name, "rawvideo" ) )
+               mlt_properties_set_data( properties, "av_frame", NULL, 0, NULL, NULL );
+
        // Set the field order property for this frame
-       mlt_properties_set_int( frame_properties, "top_field_first", 
-               mlt_properties_get_int( properties, "top_field_first" ) );
+       mlt_properties_set_int( frame_properties, "top_field_first", mlt_properties_get_int( properties, "top_field_first" ) );
 
        // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
        mlt_properties_set_position( properties, "_video_expected", position + 1 );
@@ -805,7 +807,7 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
                int got_audio = 0;
                int16_t *temp = mlt_pool_alloc( sizeof( int16_t ) * AVCODEC_MAX_AUDIO_FRAME_SIZE );
 
-               memset( &pkt, 0, sizeof( pkt ) );
+               av_init_packet( &pkt );
 
                while( ret >= 0 && !got_audio )
                {
@@ -957,6 +959,8 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
                {
                        mlt_frame_push_audio( frame, producer_get_audio );
                        mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
+                       mlt_properties_set_int( frame_properties, "frequency", codec_context->sample_rate );
+                       mlt_properties_set_int( frame_properties, "channels", codec_context->channels );
                }
        }
 }