Commit ecbc00bf authored by Loren Merritt's avatar Loren Merritt

remove colorspace conversion support, because it has no business in any codec


git-svn-id: svn://svn.videolan.org/x264/trunk@733 df754926-b1dd-0310-bc7b-ec298dee348c
parent 44f5e6bd
......@@ -4,7 +4,7 @@ include config.mak
SRCS = common/mc.c common/predict.c common/pixel.c common/macroblock.c \
common/frame.c common/dct.c common/cpu.c common/cabac.c \
common/common.c common/mdate.c common/csp.c common/set.c \
common/common.c common/mdate.c common/set.c \
common/quant.c \
encoder/analyse.c encoder/me.c encoder/ratecontrol.c \
encoder/set.c encoder/macroblock.c encoder/cabac.c \
......
......@@ -589,63 +589,13 @@ void x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_heig
pic->i_type = X264_TYPE_AUTO;
pic->i_qpplus1 = 0;
pic->img.i_csp = i_csp;
switch( i_csp & X264_CSP_MASK )
{
case X264_CSP_I420:
case X264_CSP_YV12:
pic->img.i_plane = 3;
pic->img.plane[0] = x264_malloc( 3 * i_width * i_height / 2 );
pic->img.plane[1] = pic->img.plane[0] + i_width * i_height;
pic->img.plane[2] = pic->img.plane[1] + i_width * i_height / 4;
pic->img.i_stride[0] = i_width;
pic->img.i_stride[1] = i_width / 2;
pic->img.i_stride[2] = i_width / 2;
break;
case X264_CSP_I422:
pic->img.i_plane = 3;
pic->img.plane[0] = x264_malloc( 2 * i_width * i_height );
pic->img.plane[1] = pic->img.plane[0] + i_width * i_height;
pic->img.plane[2] = pic->img.plane[1] + i_width * i_height / 2;
pic->img.i_stride[0] = i_width;
pic->img.i_stride[1] = i_width / 2;
pic->img.i_stride[2] = i_width / 2;
break;
case X264_CSP_I444:
pic->img.i_plane = 3;
pic->img.plane[0] = x264_malloc( 3 * i_width * i_height );
pic->img.plane[1] = pic->img.plane[0] + i_width * i_height;
pic->img.plane[2] = pic->img.plane[1] + i_width * i_height;
pic->img.i_stride[0] = i_width;
pic->img.i_stride[1] = i_width;
pic->img.i_stride[2] = i_width;
break;
case X264_CSP_YUYV:
pic->img.i_plane = 1;
pic->img.plane[0] = x264_malloc( 2 * i_width * i_height );
pic->img.i_stride[0] = 2 * i_width;
break;
case X264_CSP_RGB:
case X264_CSP_BGR:
pic->img.i_plane = 1;
pic->img.plane[0] = x264_malloc( 3 * i_width * i_height );
pic->img.i_stride[0] = 3 * i_width;
break;
case X264_CSP_BGRA:
pic->img.i_plane = 1;
pic->img.plane[0] = x264_malloc( 4 * i_width * i_height );
pic->img.i_stride[0] = 4 * i_width;
break;
default:
fprintf( stderr, "invalid CSP\n" );
pic->img.i_plane = 0;
break;
}
pic->img.i_plane = 3;
pic->img.plane[0] = x264_malloc( 3 * i_width * i_height / 2 );
pic->img.plane[1] = pic->img.plane[0] + i_width * i_height;
pic->img.plane[2] = pic->img.plane[1] + i_width * i_height / 4;
pic->img.i_stride[0] = i_width;
pic->img.i_stride[1] = i_width / 2;
pic->img.i_stride[2] = i_width / 2;
}
/****************************************************************************
......
......@@ -76,7 +76,6 @@
#include "frame.h"
#include "dct.h"
#include "cabac.h"
#include "csp.h"
#include "quant.h"
/****************************************************************************
......@@ -559,7 +558,6 @@ struct x264_t
x264_mc_functions_t mc;
x264_dct_function_t dctf;
x264_zigzag_function_t zigzagf;
x264_csp_function_t csp;
x264_quant_function_t quantf;
x264_deblock_function_t loopf;
......
/*****************************************************************************
* csp.c: h264 encoder library
*****************************************************************************
* Copyright (C) 2004 Laurent Aimar
* $Id: csp.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"
static inline void plane_copy_vflip( x264_mc_functions_t *mc,
uint8_t *dst, int i_dst,
uint8_t *src, int i_src, int w, int h)
{
mc->plane_copy( dst, i_dst, src + (h -1)*i_src, -i_src, w, h );
}
static inline void plane_subsamplev2( uint8_t *dst, int i_dst,
uint8_t *src, int i_src, int w, int h)
{
for( ; h > 0; h-- )
{
uint8_t *d = dst;
uint8_t *s = src;
int i;
for( i = 0; i < w; i++ )
{
*d++ = ( s[0] + s[i_src] + 1 ) >> 1;
s++;
}
dst += i_dst;
src += 2 * i_src;
}
}
static inline void plane_subsamplev2_vlip( uint8_t *dst, int i_dst,
uint8_t *src, int i_src, int w, int h)
{
plane_subsamplev2( dst, i_dst, src + (2*h-1)*i_src, -i_src, w, h );
}
static inline void plane_subsamplehv2( uint8_t *dst, int i_dst,
uint8_t *src, int i_src, int w, int h)
{
for( ; h > 0; h-- )
{
uint8_t *d = dst;
uint8_t *s = src;
int i;
for( i = 0; i < w; i++ )
{
*d++ = ( s[0] + s[1] + s[i_src] + s[i_src+1] + 1 ) >> 2;
s += 2;
}
dst += i_dst;
src += 2 * i_src;
}
}
static inline void plane_subsamplehv2_vlip( uint8_t *dst, int i_dst,
uint8_t *src, int i_src, int w, int h)
{
plane_subsamplehv2( dst, i_dst, src + (2*h-1)*i_src, -i_src, w, h );
}
static void i420_to_i420( x264_mc_functions_t *mc,
x264_frame_t *frm, x264_image_t *img,
int i_width, int i_height )
{
if( img->i_csp & X264_CSP_VFLIP )
{
plane_copy_vflip( mc, frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
plane_copy_vflip( mc, frm->plane[1], frm->i_stride[1],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
plane_copy_vflip( mc, frm->plane[2], frm->i_stride[2],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
else
{
mc->plane_copy( frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
mc->plane_copy( frm->plane[1], frm->i_stride[1],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
mc->plane_copy( frm->plane[2], frm->i_stride[2],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
}
static void yv12_to_i420( x264_mc_functions_t *mc,
x264_frame_t *frm, x264_image_t *img,
int i_width, int i_height )
{
if( img->i_csp & X264_CSP_VFLIP )
{
plane_copy_vflip( mc, frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
plane_copy_vflip( mc, frm->plane[2], frm->i_stride[2],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
plane_copy_vflip( mc, frm->plane[1], frm->i_stride[1],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
else
{
mc->plane_copy( frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
mc->plane_copy( frm->plane[2], frm->i_stride[2],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
mc->plane_copy( frm->plane[1], frm->i_stride[1],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
}
static void i422_to_i420( x264_mc_functions_t *mc,
x264_frame_t *frm, x264_image_t *img,
int i_width, int i_height )
{
if( img->i_csp & X264_CSP_VFLIP )
{
plane_copy_vflip( mc, frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
plane_subsamplev2_vlip( frm->plane[1], frm->i_stride[1],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
plane_subsamplev2_vlip( frm->plane[2], frm->i_stride[2],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
else
{
mc->plane_copy( frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
plane_subsamplev2( frm->plane[1], frm->i_stride[1],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
plane_subsamplev2( frm->plane[2], frm->i_stride[2],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
}
static void i444_to_i420( x264_mc_functions_t *mc,
x264_frame_t *frm, x264_image_t *img,
int i_width, int i_height )
{
if( img->i_csp & X264_CSP_VFLIP )
{
plane_copy_vflip( mc, frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
plane_subsamplehv2_vlip( frm->plane[1], frm->i_stride[1],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
plane_subsamplehv2_vlip( frm->plane[2], frm->i_stride[2],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
else
{
mc->plane_copy( frm->plane[0], frm->i_stride[0],
img->plane[0], img->i_stride[0],
i_width, i_height );
plane_subsamplehv2( frm->plane[1], frm->i_stride[1],
img->plane[1], img->i_stride[1],
i_width / 2, i_height / 2 );
plane_subsamplehv2( frm->plane[2], frm->i_stride[2],
img->plane[2], img->i_stride[2],
i_width / 2, i_height / 2 );
}
}
static void yuyv_to_i420( x264_mc_functions_t *mc,
x264_frame_t *frm, x264_image_t *img,
int i_width, int i_height )
{
uint8_t *src = img->plane[0];
int i_src= img->i_stride[0];
uint8_t *y = frm->plane[0];
uint8_t *u = frm->plane[1];
uint8_t *v = frm->plane[2];
if( img->i_csp & X264_CSP_VFLIP )
{
src += ( i_height - 1 ) * i_src;
i_src = -i_src;
}
for( ; i_height > 0; i_height -= 2 )
{
uint8_t *ss = src;
uint8_t *yy = y;
uint8_t *uu = u;
uint8_t *vv = v;
int w;
for( w = i_width; w > 0; w -= 2 )
{
*yy++ = ss[0];
*yy++ = ss[2];
*uu++ = ( ss[1] + ss[1+i_src] + 1 ) >> 1;
*vv++ = ( ss[3] + ss[3+i_src] + 1 ) >> 1;
ss += 4;
}
src += i_src;
y += frm->i_stride[0];
u += frm->i_stride[1];
v += frm->i_stride[2];
ss = src;
yy = y;
for( w = i_width; w > 0; w -= 2 )
{
*yy++ = ss[0];
*yy++ = ss[2];
ss += 4;
}
src += i_src;
y += frm->i_stride[0];
}
}
/* Same value than in XviD */
#define BITS 8
#define FIX(f) ((int)((f) * (1 << BITS) + 0.5))
#define Y_R FIX(0.257)
#define Y_G FIX(0.504)
#define Y_B FIX(0.098)
#define Y_ADD 16
#define U_R FIX(0.148)
#define U_G FIX(0.291)
#define U_B FIX(0.439)
#define U_ADD 128
#define V_R FIX(0.439)
#define V_G FIX(0.368)
#define V_B FIX(0.071)
#define V_ADD 128
#define RGB_TO_I420( name, POS_R, POS_G, POS_B, S_RGB ) \
static void name( x264_mc_functions_t *mc, \
x264_frame_t *frm, x264_image_t *img, \
int i_width, int i_height ) \
{ \
uint8_t *src = img->plane[0]; \
int i_src= img->i_stride[0]; \
int i_y = frm->i_stride[0]; \
uint8_t *y = frm->plane[0]; \
uint8_t *u = frm->plane[1]; \
uint8_t *v = frm->plane[2]; \
\
if( img->i_csp & X264_CSP_VFLIP ) \
{ \
src += ( i_height - 1 ) * i_src; \
i_src = -i_src; \
} \
\
for( ; i_height > 0; i_height -= 2 ) \
{ \
uint8_t *ss = src; \
uint8_t *yy = y; \
uint8_t *uu = u; \
uint8_t *vv = v; \
int w; \
\
for( w = i_width; w > 0; w -= 2 ) \
{ \
int cr = 0,cg = 0,cb = 0; \
int r, g, b; \
\
/* Luma */ \
cr = r = ss[POS_R]; \
cg = g = ss[POS_G]; \
cb = b = ss[POS_B]; \
\
yy[0] = Y_ADD + ((Y_R * r + Y_G * g + Y_B * b) >> BITS); \
\
cr+= r = ss[POS_R+i_src]; \
cg+= g = ss[POS_G+i_src]; \
cb+= b = ss[POS_B+i_src]; \
yy[i_y] = Y_ADD + ((Y_R * r + Y_G * g + Y_B * b) >> BITS); \
yy++; \
ss += S_RGB; \
\
cr+= r = ss[POS_R]; \
cg+= g = ss[POS_G]; \
cb+= b = ss[POS_B]; \
\
yy[0] = Y_ADD + ((Y_R * r + Y_G * g + Y_B * b) >> BITS); \
\
cr+= r = ss[POS_R+i_src]; \
cg+= g = ss[POS_G+i_src]; \
cb+= b = ss[POS_B+i_src]; \
yy[i_y] = Y_ADD + ((Y_R * r + Y_G * g + Y_B * b) >> BITS); \
yy++; \
ss += S_RGB; \
\
/* Chroma */ \
*uu++ = (uint8_t)(U_ADD + ((-U_R * cr - U_G * cg + U_B * cb) >> (BITS+2)) ); \
*vv++ = (uint8_t)(V_ADD + (( V_R * cr - V_G * cg - V_B * cb) >> (BITS+2)) ); \
} \
\
src += 2*i_src; \
y += 2*frm->i_stride[0]; \
u += frm->i_stride[1]; \
v += frm->i_stride[2]; \
} \
}
RGB_TO_I420( rgb_to_i420, 0, 1, 2, 3 );
RGB_TO_I420( bgr_to_i420, 2, 1, 0, 3 );
RGB_TO_I420( bgra_to_i420, 2, 1, 0, 4 );
void x264_csp_init( int cpu, int i_csp, x264_csp_function_t *pf )
{
switch( i_csp )
{
case X264_CSP_I420:
pf->convert[X264_CSP_I420] = i420_to_i420;
pf->convert[X264_CSP_I422] = i422_to_i420;
pf->convert[X264_CSP_I444] = i444_to_i420;
pf->convert[X264_CSP_YV12] = yv12_to_i420;
pf->convert[X264_CSP_YUYV] = yuyv_to_i420;
pf->convert[X264_CSP_RGB ] = rgb_to_i420;
pf->convert[X264_CSP_BGR ] = bgr_to_i420;
pf->convert[X264_CSP_BGRA] = bgra_to_i420;
break;
default:
/* For now, can't happen */
fprintf( stderr, "arg in x264_csp_init\n" );
exit( -1 );
break;
}
}
/*****************************************************************************
* csp.h: h264 encoder library
*****************************************************************************
* Copyright (C) 2004 Laurent Aimar
* $Id: csp.h,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.
*****************************************************************************/
#ifndef _CSP_H
#define _CSP_H 1
typedef void (*x264_csp_t) ( x264_mc_functions_t *, x264_frame_t *, x264_image_t *,
int i_width, int i_height );
typedef struct
{
x264_csp_t convert[X264_CSP_MAX];
} x264_csp_function_t;
void x264_csp_init( int cpu, int i_csp, x264_csp_function_t *pf );
#endif
......@@ -52,23 +52,13 @@ x264_frame_t *x264_frame_new( x264_t *h )
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_width[i] = i_width / i_divw;
frame->i_lines[i] = i_lines / i_divh;
frame->i_stride[i] = i_stride >> !!i;
frame->i_width[i] = i_width >> !!i;
frame->i_lines[i] = i_lines >> !!i;
CHECKED_MALLOC( frame->buffer[i],
frame->i_stride[i] * ( frame->i_lines[i] + 2*i_padv / i_divh ) );
frame->i_stride[i] * (i_lines + 2*i_padv) >> !!i );
frame->plane[i] = ((uint8_t*)frame->buffer[i]) +
frame->i_stride[i] * i_padv / i_divh + PADH / i_divw;
((frame->i_stride[i] * i_padv + PADH) >> !!i);
}
frame->filtered[0] = frame->plane[0];
......@@ -161,17 +151,35 @@ void x264_frame_delete( x264_frame_t *frame )
x264_free( frame );
}
void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src )
int 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;
int i;
if( i_csp != X264_CSP_I420 && i_csp != X264_CSP_YV12 )
{
x264_log( h, X264_LOG_ERROR, "Arg invalid CSP\n" );
return -1;
}
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 );
for( i=0; i<3; i++ )
{
int s = (i_csp == X264_CSP_YV12 && i) ? i^3 : i;
uint8_t *plane = src->img.plane[s];
int stride = src->img.i_stride[s];
int width = h->param.i_width >> !!i;
int height = h->param.i_height >> !!i;
if( src->img.i_csp & X264_CSP_VFLIP )
{
plane += (height-1)*stride;
stride = -stride;
}
h->mc.plane_copy( dst->plane[i], dst->i_stride[i], plane, stride, width, height );
}
return 0;
}
......
......@@ -102,7 +102,7 @@ typedef struct
x264_frame_t *x264_frame_new( x264_t *h );
void x264_frame_delete( x264_frame_t *frame );
void x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src );
int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src );
void x264_frame_expand_border( x264_t *h, x264_frame_t *frame, int mb_y, int b_end );
void x264_frame_expand_border_filtered( x264_t *h, x264_frame_t *frame, int mb_y, int b_end );
......
......@@ -671,7 +671,6 @@ x264_t *x264_encoder_open ( x264_param_t *param )
x264_dct_init( h->param.cpu, &h->dctf );
x264_zigzag_init( h->param.cpu, &h->zigzagf, h->param.b_interlaced );
x264_mc_init( h->param.cpu, &h->mc );
x264_csp_init( h->param.cpu, h->param.i_csp, &h->csp );
x264_quant_init( h, h->param.cpu, &h->quantf );
x264_deblock_init( h->param.cpu, &h->loopf );
x264_dct_init_weights();
......@@ -1290,7 +1289,8 @@ int x264_encoder_encode( x264_t *h,
/* 1: Copy the picture to a frame and move it to a buffer */
x264_frame_t *fenc = x264_frame_pop_unused( h );
x264_frame_copy_picture( h, fenc, pic_in );
if( x264_frame_copy_picture( h, fenc, pic_in ) < 0 )
return -1;
if( h->param.i_width != 16 * h->sps->i_mb_width ||
h->param.i_height != 16 * h->sps->i_mb_height )
......
......@@ -35,7 +35,7 @@
#include <stdarg.h>
#define X264_BUILD 57