All pastes #3679427 Raw Edit

avfilter

public unlisted cpp v1 · immutable
#3679427 ·published 2016-08-09 07:46 UTC
rendered paste body
        int init(const frame_type_ptr& frame)        {            ARLOG_DEBUG( "Initializing" );            if ( !avfilter_register_all_called )            {                avfilter_register_all();                avfilter_register_all_called = true;            }            is_initialized_ = true;            char args[512];            int ret = 0;            AVFilter *buffersrc  = avfilter_get_by_name("buffer");            AVFilter *buffersink = avfilter_get_by_name("buffersink");            AVFilterInOut *outputs = avfilter_inout_alloc( );            AVFilterInOut *inputs = avfilter_inout_alloc( );            boost::shared_ptr< AVFilterInOut * > i_ptr( &inputs, &destroy_avfilterinout );            boost::shared_ptr< AVFilterInOut * > o_ptr( &outputs, &destroy_avfilterinout );            enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_NONE };            filter_graph_ = avfilter_graph_alloc();            if (!outputs || !inputs || !filter_graph_)            {                ret = AVERROR(ENOMEM);                return ret;            }            avfilter_graph_set_auto_convert( filter_graph_, AVFILTER_AUTO_CONVERT_ALL );            /* buffer video source: the decoded frames from the decoder will be inserted here. */            snprintf(args, sizeof(args),                     "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:frame_rate=%d/%d",                     frame->width(), frame->height(), image::ML_to_AV(frame->ml_pixel_format()),                     frame->get_fps_den(), frame->get_fps_num(),                     frame->get_sar_num(), frame->get_sar_den(),                     frame->get_fps_num(), frame->get_fps_den());            ret = avfilter_graph_create_filter(&buffersrc_ctx_, buffersrc, "in", args, NULL, filter_graph_);            if (ret < 0)            {                ARLOG_ERR( "Cannot create buffer source with %s" )( args );                return ret;            }            /* buffer video sink: to terminate the filter chain. */            ret = avfilter_graph_create_filter(&buffersink_ctx_, buffersink, "out", NULL, NULL, filter_graph_);            if (ret < 0)            {                ARLOG_ERR( "Cannot create buffer sink" );                return ret;            }            ret = av_opt_set_int_list(buffersink_ctx_, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);            if (ret < 0)            {                ARLOG_ERR( "Cannot set output pixel format" );                return ret;            }            /*             * Set the endpoints for the filter graph. The filter_graph will             * be linked to the graph described by filters_descr.             */            /*             * The buffer source output must be connected to the input pad of             * the first filter described by filters_descr; since the first             * filter input label is not specified, it is set to "in" by             * default.             */            outputs->name        = av_strdup("in");            outputs->filter_ctx = buffersrc_ctx_;            outputs->pad_idx    = 0;            outputs->next        = NULL;            /*             * The buffer sink input must be connected to the output pad of             * the last filter described by filters_descr; since the last             * filter output label is not specified, it is set to "out" by             * default.             */            inputs->name       = av_strdup("out");            inputs->filter_ctx = buffersink_ctx_;            inputs->pad_idx    = 0;            inputs->next       = NULL;            // Generate the full graph            std::string filters_descr = generate_graph_string( );            ARLOG_DEBUG3( "Parsing '%s'" )( filters_descr );            if ((ret = avfilter_graph_parse_ptr(filter_graph_, filters_descr.c_str(), &inputs, &outputs, NULL)) < 0)                return ret;            if ((ret = avfilter_graph_config(filter_graph_, NULL)) < 0)                return ret;            fps_out_ = av_buffersink_get_frame_rate( buffersink_ctx_ );            frame->get_fps( fps_in_.num, fps_in_.den );            ARLOG_DEBUG3( "Input frame rate: %d:%d, Output frame rate: %d:%d" )( fps_in_.num )( fps_in_.den )( fps_out_.num )( fps_out_.den );            return ret;        }        ml::image_type_ptr flush_filter_graph( )        {            ARLOG_DEBUG3( "Time to flush. (%1%, %2%)" )(get_position())(eof_position_);            int limit = 5;            ml::image_type_ptr image;            while( !image )            {                int ret = av_buffersrc_add_frame_flags(buffersrc_ctx_, NULL, AV_BUFFERSRC_FLAG_KEEP_REF);                ARENFORCE_MSG( ret >= 0, "Error (%1%) while flushing the filtergraph")(ret);                image = get_image_from_filter_graph();                ARENFORCE_MSG( image || -- limit, "Too many iterations - abandoning avfilter flush" );            }            expected_position_ = -1;            return image;        }        image_type_ptr get_image_from_filter_graph( )        {            boost::shared_ptr< AVFrame > av_frame_out( av_frame_alloc( ), &destroy_avframe );            int ret = av_buffersink_get_frame(buffersink_ctx_, av_frame_out.get( ));            std::cerr << "ret: " << ret << std::endl;            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)                return image_type_ptr();            ARENFORCE( ret >= 0 );            return convert_to_oil(rescale_context_, av_frame_out.get( ), (AVPixelFormat)av_frame_out->format, av_frame_out->width, av_frame_out->height );        }        void do_filter( frame_type_ptr& frame )        {            if ( !is_initialized_ || frame->get_position() != expected_position_ )            {                reset_context();                init( frame );            }            ARENFORCE_MSG( is_initialized_, "filter graph is not initialized" );            if ( frame && frame->has_image( ) )            {                std::cerr << "received: " << frame->get_position( ) << std::endl;                AVFrame* av_frame = av_frame_alloc();                const image_type_ptr& image = frame->get_image();                const int num_planes = image->plane_count();                for( int p = 0; p < num_planes; ++p )                {                    av_frame->data[ p ] = static_cast< uint8_t * >( image->ptr( p ) );                    av_frame->linesize[ p ] = image->pitch( p );                }                av_frame->width = image->width();                av_frame->height= image->height();                av_frame->format = image::ML_to_AV( image->ml_pixel_format() );                AVRational sar = {image->get_sar_num(), image->get_sar_den()};                av_frame->sample_aspect_ratio = sar;                                av_frame->pts = frame->get_position();                av_frame->interlaced_frame = image->field_order() != image::progressive;                av_frame->top_field_first = image->field_order() == image::top_field_first;                int ret = av_buffersrc_add_frame_flags(buffersrc_ctx_, av_frame, AV_BUFFERSRC_FLAG_KEEP_REF);                ARENFORCE_MSG( ret >= 0, "Error (%1%) while feeding the filtergraph with %2%")(ret)(av_frame);                av_frame_free( &av_frame );            }            expected_position_ = frame->get_position() + 1;        }