]> git.sesse.net Git - mlt/commitdiff
Add consumer-fatal-error event to avformat consumer.
authorDan Dennedy <dan@dennedy.org>
Thu, 9 Dec 2010 08:20:41 +0000 (00:20 -0800)
committerDan Dennedy <dan@dennedy.org>
Thu, 9 Dec 2010 08:20:41 +0000 (00:20 -0800)
This addresses Kdenlive bug 1894.
When the avformat consumer has a fatal error, it will fire an event.
Melt intercepts the event and exits with failure.

src/framework/mlt_log.c
src/melt/melt.c
src/modules/avformat/consumer_avformat.c

index 568b2d71b7fc0ce243b720f541c435b08a09fed0..980cb48894373adfeaf974d2765569de3f04e9f4 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <string.h>
 
-static int log_level = MLT_LOG_PANIC;
+static int log_level = MLT_LOG_FATAL;
 
 void default_callback( void* ptr, int level, const char* fmt, va_list vl )
 {
index b8e974d704c4c618c58d30253e73f3dcefa03710..60db45f5a6c0689b7a259a46f3dc5d2d2cd52c0c 100644 (file)
@@ -431,6 +431,12 @@ static void query_services( mlt_repository repo, mlt_service_type type )
        fprintf( stderr, "...\n" );
 }
 
+static void on_fatal_error( mlt_properties owner, mlt_consumer consumer )
+{
+       mlt_consumer_stop( consumer );
+       exit( EXIT_FAILURE );
+}
+
 int main( int argc, char **argv )
 {
        int i;
@@ -635,6 +641,7 @@ query_all:
                        mlt_consumer_connect( consumer, MLT_PRODUCER_SERVICE( melt ) );
 
                        // Start the consumer
+                       mlt_events_listen( properties, consumer, "consumer-fatal-error", ( mlt_listener )on_fatal_error );
                        mlt_consumer_start( consumer );
 
                        // Transport functionality
index 6475df56a2508f9a27bf2f6c753ec359a3b108b2..6e834a9816a30175cd1c518595a233539e952c31 100644 (file)
@@ -24,6 +24,7 @@
 #include <framework/mlt_frame.h>
 #include <framework/mlt_profile.h>
 #include <framework/mlt_log.h>
+#include <framework/mlt_events.h>
 
 // System header files
 #include <stdio.h>
@@ -195,6 +196,8 @@ mlt_consumer consumer_avformat_init( mlt_profile profile, char *arg )
                this->start = consumer_start;
                this->stop = consumer_stop;
                this->is_stopped = consumer_is_stopped;
+               
+               mlt_events_register( properties, "consumer-fatal-error", NULL );
        }
 
        // Return this
@@ -1323,7 +1326,11 @@ static void *consumer_thread( void *arg )
                                                if ( pkt.size > 0 )
                                                {
                                                        if ( av_interleaved_write_frame( oc, &pkt ) )
-                                                               mlt_log_error( MLT_CONSUMER_SERVICE( this ), "error writing audio frame %d\n", frames - 1 );
+                                                       {
+                                                               mlt_log_fatal( MLT_CONSUMER_SERVICE( this ), "error writing audio frame\n" );
+                                                               mlt_events_fire( properties, "consumer-fatal-error", NULL );
+                                                               goto on_fatal_error;
+                                                       }
                                                }
 
                                                mlt_log_debug( MLT_CONSUMER_SERVICE( this ), " frame_size %d\n", codec->frame_size );
@@ -1343,7 +1350,7 @@ static void *consumer_thread( void *arg )
                                // Write video
                                if ( mlt_deque_count( queue ) )
                                {
-                                       int out_size, ret;
+                                       int out_size, ret = 0;
                                        AVCodecContext *c;
 
                                        frame = mlt_deque_pop_front( queue );
@@ -1479,6 +1486,12 @@ static void *consumer_thread( void *arg )
                                                }
                                        }
                                        frame_count++;
+                                       if ( ret )
+                                       {
+                                               mlt_log_fatal( MLT_CONSUMER_SERVICE( this ), "error writing video frame\n" );
+                                               mlt_events_fire( properties, "consumer-fatal-error", NULL );
+                                               goto on_fatal_error;
+                                       }
                                        mlt_frame_close( frame );
                                }
                                else
@@ -1542,8 +1555,9 @@ static void *consumer_thread( void *arg )
                        pkt.data = audio_outbuf;
                        if ( av_interleaved_write_frame( oc, &pkt ) != 0 )
                        {
-                               mlt_log_error( MLT_CONSUMER_SERVICE( this ), "%s: error writing flushed audio frame\n", __FILE__ );
-                               break;
+                               mlt_log_fatal( MLT_CONSUMER_SERVICE( this ), "error writing flushed audio frame\n" );
+                               mlt_events_fire( properties, "consumer-fatal-error", NULL );
+                               goto on_fatal_error;
                        }
                }
 
@@ -1570,8 +1584,9 @@ static void *consumer_thread( void *arg )
                        // write the compressed frame in the media file
                        if ( av_interleaved_write_frame( oc, &pkt ) != 0 )
                        {
-                               mlt_log_error( MLT_CONSUMER_SERVICE(this), "error writing flushed video frame\n" );
-                               break;
+                               mlt_log_fatal( MLT_CONSUMER_SERVICE(this), "error writing flushed video frame\n" );
+                               mlt_events_fire( properties, "consumer-fatal-error", NULL );
+                               goto on_fatal_error;
                        }
                        // Dual pass logging
                        if ( mlt_properties_get_data( properties, "_logfile", NULL ) && c->stats_out )
@@ -1579,6 +1594,8 @@ static void *consumer_thread( void *arg )
                }
        }
 
+on_fatal_error:
+       
        // Write the trailer, if any
        av_write_trailer( oc );