⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frame.c.svn-base

📁 X264最新源码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * frame.c: h264 encoder library ***************************************************************************** * Copyright (C) 2003 Laurent Aimar * $Id: frame.c,v 1.1 2004/06/03 19:27:06 fenrir Exp $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************/#include "common.h"#define PADH 32#define PADV 32x264_frame_t *x264_frame_new( x264_t *h ){    x264_frame_t *frame = x264_malloc( sizeof(x264_frame_t) );    int i, j;    int i_mb_count = h->mb.i_mb_count;    int i_stride;    int i_lines;    int i_padv = PADV << h->param.b_interlaced;    if( !frame ) return NULL;    memset( frame, 0, sizeof(x264_frame_t) );    /* allocate frame data (+64 for extra data for me) */    i_stride = ( ( h->param.i_width  + 15 ) & -16 )+ 2*PADH;    i_lines  = ( ( h->param.i_height + 15 ) & -16 );    if( h->param.b_interlaced )        i_lines = ( i_lines + 31 ) & -32;    frame->i_plane = 3;    for( i = 0; i < 3; i++ )    {        int i_divh = 1;        int i_divw = 1;        if( i > 0 )        {            if( h->param.i_csp == X264_CSP_I420 )                i_divh = i_divw = 2;            else if( h->param.i_csp == X264_CSP_I422 )                i_divw = 2;        }        frame->i_stride[i] = i_stride / i_divw;        frame->i_lines[i] = i_lines / i_divh;        CHECKED_MALLOC( frame->buffer[i],                        frame->i_stride[i] * ( frame->i_lines[i] + 2*i_padv / i_divh ) );        frame->plane[i] = ((uint8_t*)frame->buffer[i]) +                          frame->i_stride[i] * i_padv / i_divh + PADH / i_divw;    }    frame->i_stride[3] = 0;    frame->i_lines[3] = 0;    frame->buffer[3] = NULL;    frame->plane[3] = NULL;    frame->filtered[0] = frame->plane[0];    for( i = 0; i < 3; i++ )    {        CHECKED_MALLOC( frame->buffer[4+i],                        frame->i_stride[0] * ( frame->i_lines[0] + 2*i_padv ) );        frame->filtered[i+1] = ((uint8_t*)frame->buffer[4+i]) +                                frame->i_stride[0] * i_padv + PADH;    }    if( h->frames.b_have_lowres )    {        frame->i_stride_lowres = frame->i_stride[0]/2 + PADH;        frame->i_lines_lowres = frame->i_lines[0]/2;        for( i = 0; i < 4; i++ )        {            CHECKED_MALLOC( frame->buffer_lowres[i],                            frame->i_stride_lowres * ( frame->i_lines[0]/2 + 2*i_padv ) );            frame->lowres[i] = ((uint8_t*)frame->buffer_lowres[i]) +                                frame->i_stride_lowres * i_padv + PADH;        }    }    if( h->param.analyse.i_me_method == X264_ME_ESA )    {        CHECKED_MALLOC( frame->buffer[7],                        2 * frame->i_stride[0] * (frame->i_lines[0] + 2*i_padv) * sizeof(uint16_t) );        frame->integral = (uint16_t*)frame->buffer[7] + frame->i_stride[0] * i_padv + PADH;    }    frame->i_poc = -1;    frame->i_type = X264_TYPE_AUTO;    frame->i_qpplus1 = 0;    frame->i_pts = -1;    frame->i_frame = -1;    frame->i_frame_num = -1;    frame->i_lines_completed = -1;    CHECKED_MALLOC( frame->mb_type, i_mb_count * sizeof(int8_t));    CHECKED_MALLOC( frame->mv[0], 2*16 * i_mb_count * sizeof(int16_t) );    CHECKED_MALLOC( frame->ref[0], 4 * i_mb_count * sizeof(int8_t) );    if( h->param.i_bframe )    {        CHECKED_MALLOC( frame->mv[1], 2*16 * i_mb_count * sizeof(int16_t) );        CHECKED_MALLOC( frame->ref[1], 4 * i_mb_count * sizeof(int8_t) );    }    else    {        frame->mv[1]  = NULL;        frame->ref[1] = NULL;    }    CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );    CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );    for( i = 0; i < h->param.i_bframe + 2; i++ )        for( j = 0; j < h->param.i_bframe + 2; j++ )            CHECKED_MALLOC( frame->i_row_satds[i][j], i_lines/16 * sizeof(int) );    pthread_mutex_init( &frame->mutex, NULL );    pthread_cond_init( &frame->cv, NULL );    return frame;fail:    x264_frame_delete( frame );    return NULL;}void x264_frame_delete( x264_frame_t *frame ){    int i, j;    for( i = 0; i < 8; i++ )        x264_free( frame->buffer[i] );    for( i = 0; i < 4; i++ )        x264_free( frame->buffer_lowres[i] );    for( i = 0; i < X264_BFRAME_MAX+2; i++ )        for( j = 0; j < X264_BFRAME_MAX+2; j++ )            x264_free( frame->i_row_satds[i][j] );    x264_free( frame->i_row_bits );    x264_free( frame->i_row_qp );    x264_free( frame->mb_type );    x264_free( frame->mv[0] );    x264_free( frame->mv[1] );    x264_free( frame->ref[0] );    x264_free( frame->ref[1] );    pthread_mutex_destroy( &frame->mutex );    pthread_cond_destroy( &frame->cv );    x264_free( frame );}void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src ){    int i_csp = src->img.i_csp & X264_CSP_MASK;    dst->i_type     = src->i_type;    dst->i_qpplus1  = src->i_qpplus1;    dst->i_pts      = src->i_pts;    if( i_csp <= X264_CSP_NONE  || i_csp >= X264_CSP_MAX )        x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );    else        h->csp.convert[i_csp]( &h->mc, dst, &src->img, h->param.i_width, h->param.i_height );}static void plane_expand_border( uint8_t *pix, int i_stride, int i_width, int i_height, int i_padh, int i_padv, int b_pad_top, int b_pad_bottom ){#define PPIXEL(x, y) ( pix + (x) + (y)*i_stride )    int y;    for( y = 0; y < i_height; y++ )    {        /* left band */        memset( PPIXEL(-i_padh, y), PPIXEL(0, y)[0], i_padh );        /* right band */        memset( PPIXEL(i_width, y), PPIXEL(i_width-1, y)[0], i_padh );    }    /* upper band */    if( b_pad_top )    for( y = 0; y < i_padv; y++ )        memcpy( PPIXEL(-i_padh, -y-1), PPIXEL(-i_padh, 0), i_width+2*i_padh );    /* lower band */    if( b_pad_bottom )    for( y = 0; y < i_padv; y++ )        memcpy( PPIXEL(-i_padh, i_height+y), PPIXEL(-i_padh, i_height-1), i_width+2*i_padh );#undef PPIXEL}void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end ){    int i;    int b_start = !mb_y;    if( mb_y & h->sh.b_mbaff )        return;    for( i = 0; i < frame->i_plane; i++ )    {        int stride = frame->i_stride[i];        int width = 16*h->sps->i_mb_width >> !!i;        int height = (b_end ? 16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff : 16) >> !!i;        int padh = PADH >> !!i;        int padv = PADV >> !!i;        // buffer: 2 chroma, 3 luma (rounded to 4) because deblocking goes beyond the top of the mb        uint8_t *pix = frame->plane[i] + X264_MAX(0, (16*mb_y-4)*stride >> !!i);        if( b_end && !b_start )            height += 4 >> (!!i + h->sh.b_mbaff);        if( h->sh.b_mbaff )        {            plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );            plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );        }        else        {            plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );        }    }}void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end ){    /* during filtering, 8 extra pixels were filtered on each edge.        we want to expand border from the last filtered pixel */    int b_start = !mb_y;    int stride = frame->i_stride[0];    int width = 16*h->sps->i_mb_width + 16;    int height = b_end ? (16*(h->sps->i_mb_height - mb_y) >> h->sh.b_mbaff) + 16 : 16;    int padh = PADH - 8;    int padv = PADV - 8;    int i;    for( i = 1; i < 4; i++ )    {        // buffer: 8 luma, to match the hpel filter        uint8_t *pix = frame->filtered[i] + (16*mb_y - (8 << h->sh.b_mbaff)) * stride - 8;        if( h->sh.b_mbaff )        {            plane_expand_border( pix, stride*2, width, height, padh, padv, b_start, b_end );            plane_expand_border( pix+stride, stride*2, width, height, padh, padv, b_start, b_end );        }        else        {            plane_expand_border( pix, stride, width, height, padh, padv, b_start, b_end );        }    }}void x264_frame_expand_border_lowres( x264_frame_t *frame ){    int i;    for( i = 0; i < 4; i++ )        plane_expand_border( frame->lowres[i], frame->i_stride_lowres, frame->i_stride_lowres - 2*PADH, frame->i_lines_lowres, PADH, PADV, 1, 1 );}void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame ){    int i, y;    for( i = 0; i < frame->i_plane; i++ )    {        int i_subsample = i ? 1 : 0;        int i_width = h->param.i_width >> i_subsample;        int i_height = h->param.i_height >> i_subsample;        int i_padx = ( h->sps->i_mb_width * 16 - h->param.i_width ) >> i_subsample;        int i_pady = ( h->sps->i_mb_height * 16 - h->param.i_height ) >> i_subsample;        if( i_padx )        {            for( y = 0; y < i_height; y++ )                memset( &frame->plane[i][y*frame->i_stride[i] + i_width],                         frame->plane[i][y*frame->i_stride[i] + i_width - 1],                         i_padx );        }        if( i_pady )        {            //FIXME interlace? or just let it pad using the wrong field            for( y = i_height; y < i_height + i_pady; y++ )                memcpy( &frame->plane[i][y*frame->i_stride[i]],                        &frame->plane[i][(i_height-1)*frame->i_stride[i]],                        i_width + i_padx );        }    }}/* cavlc + 8x8 transform stores nnz per 16 coeffs for the purpose of * entropy coding, but per 64 coeffs for the purpose of deblocking */void munge_cavlc_nnz_row( x264_t *h, int mb_y, uint8_t (*buf)[16] ){    uint32_t (*src)[6] = (uint32_t(*)[6])h->mb.non_zero_count + mb_y * h->sps->i_mb_width;    int8_t *transform = h->mb.mb_transform_size + mb_y * h->sps->i_mb_width;    int x;    for( x=0; x<h->sps->i_mb_width; x++ )    {        memcpy( buf+x, src+x, 16 );        if( transform[x] )        {            if( src[x][0] ) src[x][0] = 0x01010101;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -