Exemplo n.º 1
0
/* Return 0 if successful.
 * Return 1 if the same frame was requested at the last call.
 * Return a negative value otherwise. */
int libavsmash_video_get_frame
(
    libavsmash_video_decode_handler_t *vdhp,
    libavsmash_video_output_handler_t *vohp,
    uint32_t                           sample_number
)
{
    if( vohp->vfr2cfr )
    {
        sample_number = libavsmash_vfr2cfr( vdhp, vohp, sample_number );
        if( sample_number == 0 )
            return -1;
    }
    if( sample_number == vdhp->last_sample_number )
        return 1;
    int ret;
    if( (ret = get_requested_picture( vdhp, vdhp->frame_buffer, sample_number )) < 0
     || (ret = update_scaler_configuration_if_needed( &vohp->scaler, &vdhp->config.lh, vdhp->frame_buffer )) < 0 )
        return ret;
    return 0;
}
Exemplo n.º 2
0
int lwlibav_get_video_frame
(
    lwlibav_video_decode_handler_t *vdhp,
    lwlibav_video_output_handler_t *vohp,
    uint32_t                        frame_number
)
{
    if( !vohp->repeat_control )
        return get_requested_picture( vdhp, vdhp->frame_buffer, frame_number );
    /* Get picture to applied the repeat control. */
    uint32_t t = vohp->frame_order_list[frame_number].top;
    uint32_t b = vohp->frame_order_list[frame_number].bottom;
    uint32_t first_field_number  = MIN( t, b );
    uint32_t second_field_number = MAX( t, b );
    /* Check repeat targets and cache datas. */
    enum
    {
        REPEAT_CONTROL_COPIED_FROM_CACHE   = 0x00,
        REPEAT_CONTROL_DECODE_TOP_FIELD    = 0x01,
        REPEAT_CONTROL_DECODE_BOTTOM_FIELD = 0x02,
        REPEAT_CONTROL_DECODE_BOTH_FIELDS  = 0x03,  /* REPEAT_CONTROL_DECODE_TOP_FIELD | REPEAT_CONTROL_DECODE_BOTTOM_FIELD */
        REPEAT_CONTROL_DECODE_ONE_FRAME    = 0x04
    };
    int repeat_control;
    if( first_field_number == second_field_number )
    {
        repeat_control = REPEAT_CONTROL_DECODE_ONE_FRAME;
        if( first_field_number == vohp->frame_cache_numbers[0] )
            return copy_frame( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[0] );
        if( first_field_number == vohp->frame_cache_numbers[1] )
            return copy_frame( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[1] );
        if( first_field_number != vohp->frame_order_list[frame_number - 1].top
         && first_field_number != vohp->frame_order_list[frame_number - 1].bottom
         && first_field_number != vohp->frame_order_list[frame_number + 1].top
         && first_field_number != vohp->frame_order_list[frame_number + 1].bottom )
        {
            if( get_requested_picture( vdhp, vdhp->frame_buffer, first_field_number ) < 0 )
                return -1;
            /* Treat this frame as interlaced. */
            vdhp->frame_buffer->interlaced_frame = 1;
            return 0;
        }
    }
    else
    {
        repeat_control = REPEAT_CONTROL_DECODE_BOTH_FIELDS;
        for( int i = 0; i < REPEAT_CONTROL_CACHE_NUM; i++ )
        {
            if( t == vohp->frame_cache_numbers[i] )
            {
                if( copy_field( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[i], 0 ) < 0 )
                    return -1;
                repeat_control &= ~REPEAT_CONTROL_DECODE_TOP_FIELD;
            }
            if( b == vohp->frame_cache_numbers[i] )
            {
                if( copy_field( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[i], 1 ) < 0 )
                    return -1;
                repeat_control &= ~REPEAT_CONTROL_DECODE_BOTTOM_FIELD;
            }
        }
        if( repeat_control == REPEAT_CONTROL_COPIED_FROM_CACHE )
            return 0;
    }
    /* Decode target frames and copy to output buffer. */
    if( repeat_control == REPEAT_CONTROL_DECODE_BOTH_FIELDS )
    {
        /* Decode 2 frames, and copy each a top and bottom fields. */
        if( get_requested_picture( vdhp, vohp->frame_cache_buffers[0], first_field_number ) < 0 )
            return -1;
        vohp->frame_cache_numbers[0] = first_field_number;
        if( get_requested_picture( vdhp, vohp->frame_cache_buffers[1], second_field_number ) < 0 )
            return -1;
        vohp->frame_cache_numbers[1] = second_field_number;
        if( check_frame_buffer_identical( vohp->frame_cache_buffers[0], vohp->frame_cache_buffers[1] ) )
            return copy_frame( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[0] );
        if( copy_field( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[0], t > b ? 1 : 0 ) < 0
         || copy_field( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[1], t < b ? 1 : 0 ) < 0 )
            return -1;
        return 0;
    }
    else
    {
        /* Decode 1 frame, and copy 1 frame or 1 field. */
        int decode_number = repeat_control == REPEAT_CONTROL_DECODE_ONE_FRAME ? first_field_number
                          : repeat_control == REPEAT_CONTROL_DECODE_TOP_FIELD ? t : b;
        int idx = vohp->frame_cache_numbers[0] > vohp->frame_cache_numbers[1] ? 1 : 0;
        if( get_requested_picture( vdhp, vohp->frame_cache_buffers[idx], decode_number ) < 0 )
            return -1;
        vohp->frame_cache_numbers[idx] = decode_number;
        if( repeat_control == REPEAT_CONTROL_DECODE_ONE_FRAME )
            return copy_frame( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[idx] );
        else
            return copy_field( &vdhp->lh, vdhp->frame_buffer, vohp->frame_cache_buffers[idx],
                               repeat_control == REPEAT_CONTROL_DECODE_TOP_FIELD ? 0 : 1 );
    }
}