Пример #1
0
int vs_setup_video_rendering
(
    lw_video_output_handler_t *lw_vohp,
    AVCodecContext            *ctx,
    VSVideoInfo               *vi,
    VSMap                     *out,
    int                        width,
    int                        height
)
{
    vs_video_output_handler_t *vs_vohp = (vs_video_output_handler_t *)lw_vohp->private_handler;
    const VSAPI *vsapi = vs_vohp->vsapi;
    enum AVPixelFormat output_pixel_format;
    int                enable_scaler;
    if( determine_colorspace_conversion( vs_vohp, ctx->pix_fmt, &output_pixel_format, &enable_scaler ) )
    {
        set_error_on_init( out, vsapi, "lsmas: %s is not supported", av_get_pix_fmt_name( ctx->pix_fmt ) );
        return -1;
    }
    vs_vohp->direct_rendering &= vs_check_dr_available( ctx, ctx->pix_fmt );
    int (*dr_get_buffer)( struct AVCodecContext *, AVFrame *, int ) = vs_vohp->direct_rendering ? vs_video_get_buffer : NULL;
    setup_video_rendering( lw_vohp, enable_scaler, SWS_FAST_BILINEAR,
                           width, height, output_pixel_format,
                           ctx, dr_get_buffer );
    if( vs_vohp->variable_info )
    {
        vi->format = NULL;
        vi->width  = 0;
        vi->height = 0;
        /* Unused */
        //lw_vohp->output_width  = 0;
        //lw_vohp->output_height = 0;
    }
    else
    {
        vi->format = vsapi->getFormatPreset( vs_vohp->vs_output_pixel_format, vs_vohp->core );
        vi->width  = lw_vohp->output_width;
        vi->height = lw_vohp->output_height;
        vs_vohp->background_frame = vsapi->newVideoFrame( vi->format, vi->width, vi->height, NULL, vs_vohp->core );
        if( !vs_vohp->background_frame )
        {
            set_error_on_init( out, vsapi, "lsmas: failed to allocate memory for the background black frame data." );
            return -1;
        }
        vs_vohp->make_black_background( vs_vohp->background_frame, vsapi );
    }
    return 0;
}
Пример #2
0
func_get_buffer_t *setup_video_rendering
(
    lw_video_output_handler_t *lw_vohp,
    AVCodecContext            *ctx,
    VSVideoInfo               *vi,
    int                        width,
    int                        height
)
{
    vs_video_output_handler_t *vs_vohp = (vs_video_output_handler_t *)lw_vohp->private_handler;
    vs_vohp->direct_rendering &= vs_check_dr_available( ctx, ctx->pix_fmt );
    if( vs_vohp->variable_info )
    {
        vi->format = NULL;
        vi->width  = 0;
        vi->height = 0;
    }
    else
    {
        const VSAPI *vsapi = vs_vohp->vsapi;
        vi->format = vsapi->getFormatPreset( vs_vohp->vs_output_pixel_format, vs_vohp->core );
        vi->width  = width;
        vi->height = height;
        if( vs_vohp->direct_rendering )
        {
            /* Align output width and height for direct rendering. */
            int linesize_align[AV_NUM_DATA_POINTERS];
            enum AVPixelFormat input_pixel_format = ctx->pix_fmt;
            ctx->pix_fmt = lw_vohp->scaler.output_pixel_format;
            avcodec_align_dimensions2( ctx, &vi->width, &vi->height, linesize_align );
            ctx->pix_fmt = input_pixel_format;
        }
        vs_vohp->background_frame = vsapi->newVideoFrame( vi->format, vi->width, vi->height, NULL, vs_vohp->core );
        if( !vs_vohp->background_frame )
            return NULL;
        vs_vohp->make_black_background( vs_vohp->background_frame, vsapi );
    }
    lw_vohp->output_width  = vi->width;
    lw_vohp->output_height = vi->height;
    /* Set up custom get_buffer() for direct rendering if available. */
    if( vs_vohp->direct_rendering )
    {
        ctx->get_buffer2 = vs_video_get_buffer;
        ctx->opaque      = lw_vohp;
        ctx->flags      |= CODEC_FLAG_EMU_EDGE;
    }
    return ctx->get_buffer2;
}
Пример #3
0
static int vs_video_get_buffer
(
    AVCodecContext *ctx,
    AVFrame        *av_frame,
    int             flags
)
{
    av_frame->opaque = NULL;
    lw_video_output_handler_t *lw_vohp = (lw_video_output_handler_t *)ctx->opaque;
    vs_video_output_handler_t *vs_vohp = (vs_video_output_handler_t *)lw_vohp->private_handler;
    enum AVPixelFormat pix_fmt = av_frame->format;
    avoid_yuv_scale_conversion( &pix_fmt );
    av_frame->format = pix_fmt; /* Don't use AV_PIX_FMT_YUVJ*. */
    if( (!vs_vohp->variable_info && lw_vohp->scaler.output_pixel_format != pix_fmt)
     || !vs_check_dr_available( ctx, pix_fmt ) )
        return avcodec_default_get_buffer2( ctx, av_frame, flags );
    /* New VapourSynth video frame buffer. */
    vs_video_buffer_handler_t *vs_vbhp = malloc( sizeof(vs_video_buffer_handler_t) );
    if( !vs_vbhp )
    {
        av_frame_unref( av_frame );
        return AVERROR( ENOMEM );
    }
    av_frame->opaque = vs_vbhp;
    avcodec_align_dimensions2( ctx, &av_frame->width, &av_frame->height, av_frame->linesize );
    VSFrameRef *vs_frame_buffer = new_output_video_frame( vs_vohp, av_frame, NULL, NULL, 0,
                                                          vs_vohp->frame_ctx, vs_vohp->core, vs_vohp->vsapi );
    if( !vs_frame_buffer )
    {
        free( vs_vbhp );
        av_frame_unref( av_frame );
        return AVERROR( ENOMEM );
    }
    vs_vbhp->vs_frame_buffer = vs_frame_buffer;
    vs_vbhp->vsapi           = vs_vohp->vsapi;
    /* Create frame buffers for the decoder.
     * The callback vs_video_release_buffer_handler() shall be called when no reference to the video buffer handler is present.
     * The callback vs_video_unref_buffer_handler() decrements the reference-counter by 1. */
    memset( av_frame->buf,      0, sizeof(av_frame->buf) );
    memset( av_frame->data,     0, sizeof(av_frame->data) );
    memset( av_frame->linesize, 0, sizeof(av_frame->linesize) );
    AVBufferRef *vs_buffer_handler = av_buffer_create( NULL, 0, vs_video_release_buffer_handler, vs_vbhp, 0 );
    if( !vs_buffer_handler )
    {
        vs_video_release_buffer_handler( vs_vbhp, NULL );
        av_frame_unref( av_frame );
        return AVERROR( ENOMEM );
    }
    vs_vohp->component_reorder = get_component_reorder( pix_fmt );
    for( int i = 0; i < 3; i++ )
        if( vs_create_plane_buffer( vs_vbhp, vs_buffer_handler, av_frame, i, vs_vohp->component_reorder[i] ) < 0 )
            goto fail;
    /* Here, a variable 'vs_buffer_handler' itself is not referenced by any pointer. */
    av_buffer_unref( &vs_buffer_handler );
    av_frame->nb_extended_buf = 0;
    av_frame->extended_data   = av_frame->data;
    return 0;
fail:
    av_frame_unref( av_frame );
    av_buffer_unref( &vs_buffer_handler );
    return AVERROR( ENOMEM );
}