]> git.sesse.net Git - mlt/commitdiff
Add image caching to avformat producer.
authorDan Dennedy <dan@dennedy.org>
Wed, 3 Feb 2010 06:48:31 +0000 (22:48 -0800)
committerDan Dennedy <dan@dennedy.org>
Fri, 5 Feb 2010 04:46:53 +0000 (20:46 -0800)
This not only helps with very short seeking around a point especially on
AVCHD but also will help immensely with YADIF.

src/modules/avformat/producer_avformat.c

index 3291b4bd5d7b22c92747b9aa3eb8858d1b273bb8..950ee1c5b81f559f0ab02d1881c0a3c890580436 100644 (file)
@@ -94,6 +94,7 @@ struct producer_avformat_s
        int max_frequency;
        unsigned int invalid_pts_counter;
        double resample_factor;
+       mlt_cache image_cache;
 #ifdef VDPAU
        struct
        {
@@ -830,6 +831,21 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // Get the producer properties
        mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
 
+       // Get the image cache
+       if ( ! this->image_cache )
+               this->image_cache = mlt_cache_init();
+       mlt_cache_item item = mlt_cache_get( this->image_cache, (void*) position );
+       *buffer = mlt_cache_item_data( item, NULL );
+       if ( *buffer )
+       {
+               // Cache hit
+               mlt_properties_set_data( frame_properties, "avformat.image_cache", item, 0, ( mlt_destructor )mlt_cache_item_close, NULL );
+               mlt_properties_set_data( frame_properties, "image", *buffer, 0, NULL, NULL );
+               goto exit_get_image;
+       }
+       // Cache miss
+       int image_size = 0;
+
        avformat_lock();
 
        // Fetch the video format context
@@ -965,7 +981,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                          || ( !use_new_seek && this->current_position > req_position ) ) )
        {
                // Duplicate it
-               if ( allocate_buffer( frame_properties, codec_context, buffer, format, width, height ) )
+               if ( ( image_size = allocate_buffer( frame_properties, codec_context, buffer, format, width, height ) ) )
 #ifdef VDPAU
                        if ( this->vdpau && this->vdpau->buffer )
                        {
@@ -1133,7 +1149,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                        // Now handle the picture if we have one
                        if ( got_picture )
                        {
-                               if ( allocate_buffer( frame_properties, codec_context, buffer, format, width, height ) )
+                               if ( ( image_size = allocate_buffer( frame_properties, codec_context, buffer, format, width, height ) ) )
                                {
 #ifdef VDPAU
                                        if ( this->vdpau )
@@ -1196,6 +1212,15 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 
        avformat_unlock();
 
+       if ( this->got_picture && image_size > 0 )
+       {
+               // Copy buffer to image cache   
+               uint8_t *image = mlt_pool_alloc( image_size );
+               memcpy( image, *buffer, image_size );
+               mlt_cache_put( this->image_cache, (void*) position, image, image_size, mlt_pool_release );
+       }
+
+exit_get_image:
        // Set the progressive flag
        mlt_properties_set_int( frame_properties, "progressive", 
                !this->av_frame->interlaced_frame || !!mlt_properties_get_int( properties, "force_progressive" ) );
@@ -1969,6 +1994,8 @@ static void producer_avformat_close( producer_avformat this )
 #ifdef VDPAU
        vdpau_producer_close( this );
 #endif
+       if ( this->image_cache )
+               mlt_cache_close( this->image_cache );
        free( this );
 }