Commit 7b1b45e8 authored by Loren Merritt's avatar Loren Merritt

--cqmfile reads quant matrices in a JM-compatible format.


git-svn-id: svn://svn.videolan.org/x264/trunk@269 df754926-b1dd-0310-bc7b-ec298dee348c
parent 7a77a1e7
......@@ -387,3 +387,34 @@ void *x264_realloc( void *p, int i_size )
#endif
}
/****************************************************************************
* x264_slurp_file:
****************************************************************************/
char *x264_slurp_file( const char *filename )
{
int b_error = 0;
int i_size;
char *buf;
FILE *fh = fopen( filename, "rb" );
if( !fh )
return NULL;
b_error |= fseek( fh, 0, SEEK_END ) < 0;
b_error |= ( i_size = ftell( fh ) ) <= 0;
b_error |= fseek( fh, 0, SEEK_SET ) < 0;
if( b_error )
return NULL;
buf = x264_malloc( i_size+2 );
if( buf == NULL )
return NULL;
b_error |= fread( buf, 1, i_size, fh ) != i_size;
if( buf[i_size-1] != '\n' )
buf[i_size++] = '\n';
buf[i_size] = 0;
fclose( fh );
if( b_error )
{
x264_free( buf );
return NULL;
}
return buf;
}
......@@ -67,6 +67,9 @@ void *x264_malloc( int );
void *x264_realloc( void *p, int i_size );
void x264_free( void * );
/* x264_slurp_file: malloc space for the whole file and read it */
char *x264_slurp_file( const char *filename );
/* mdate: return the current date in microsecond */
int64_t x264_mdate( void );
......
......@@ -21,6 +21,8 @@
*****************************************************************************/
#include "common.h"
#include <stdio.h>
#include <string.h>
static const int dequant4_scale[6][3] =
{
......@@ -105,3 +107,77 @@ void x264_cqm_init( x264_t *h )
}
}
int x264_cqm_parse_jmlist( x264_t *h, const char *buf, const char *name,
uint8_t *cqm, const uint8_t *jvt, int length )
{
char *p;
char *nextvar;
int i;
p = strstr( buf, name );
if( !p )
{
memset( cqm, 16, length );
return 0;
}
p += strlen( name );
if( *p == 'U' || *p == 'V' )
p++;
nextvar = strstr( p, "INT" );
for( i = 0; i < length && (p = strpbrk( p, " \t\n," )) && (p = strpbrk( p, "0123456789" )); i++ )
{
int coef = -1;
sscanf( p, "%d", &coef );
if( i == 0 && coef == 0 )
{
memcpy( cqm, jvt, length );
return 0;
}
if( coef < 1 || coef > 255 )
{
x264_log( h, X264_LOG_ERROR, "bad coefficient in list '%s'\n", name );
return -1;
}
cqm[i] = coef;
}
if( (nextvar && p > nextvar) || i != length )
{
x264_log( h, X264_LOG_ERROR, "not enough coefficients in list '%s'\n", name );
return -1;
}
return 0;
}
int x264_cqm_parse_file( x264_t *h, const char *filename )
{
char *buf, *p;
int b_error = 0;
h->param.i_cqm_preset = X264_CQM_CUSTOM;
buf = x264_slurp_file( filename );
if( !buf )
{
x264_log( h, X264_LOG_ERROR, "can't open file '%s'\n", filename );
return -1;
}
while( (p = strchr( buf, '#' )) != NULL )
memset( p, ' ', strcspn( p, "\n" ) );
b_error |= x264_cqm_parse_jmlist( h, buf, "INTRA4X4_LUMA", h->param.cqm_4iy, x264_cqm_jvt4i, 16 );
b_error |= x264_cqm_parse_jmlist( h, buf, "INTRA4X4_CHROMA", h->param.cqm_4ic, x264_cqm_jvt4i, 16 );
b_error |= x264_cqm_parse_jmlist( h, buf, "INTER4X4_LUMA", h->param.cqm_4py, x264_cqm_jvt4p, 16 );
b_error |= x264_cqm_parse_jmlist( h, buf, "INTER4X4_CHROMA", h->param.cqm_4pc, x264_cqm_jvt4p, 16 );
b_error |= x264_cqm_parse_jmlist( h, buf, "INTRA8X8_LUMA", h->param.cqm_8iy, x264_cqm_jvt8i, 64 );
b_error |= x264_cqm_parse_jmlist( h, buf, "INTER8X8_LUMA", h->param.cqm_8py, x264_cqm_jvt8p, 64 );
x264_free( buf );
return b_error;
}
......@@ -215,5 +215,6 @@ static const uint8_t x264_cqm_flat16[64] =
};
void x264_cqm_init( x264_t *h );
int x264_cqm_parse_file( x264_t *h, const char *filename );
#endif
......@@ -464,6 +464,13 @@ x264_t *x264_encoder_open ( x264_param_t *param )
return NULL;
}
if( h->param.psz_cqm_file )
if( x264_cqm_parse_file( h, h->param.psz_cqm_file ) < 0 )
{
x264_free( h );
return NULL;
}
if( h->param.rc.psz_stat_out )
h->param.rc.psz_stat_out = strdup( h->param.rc.psz_stat_out );
if( h->param.rc.psz_stat_in )
......
......@@ -234,6 +234,8 @@ static void Help( x264_param_t *defaults )
"\n"
" --cqm <string> Preset quant matrices [\"flat\"]\n"
" - jvt, flat\n"
" --cqmfile <string> Read quant matrices from a JM-compatible file\n"
" Overrides any other --cqm* options.\n"
" --cqm4 <list> Set all 4x4 quant matrices\n"
" Takes a comma-separated list of 16 integers.\n"
" --cqm8 <list> Set all 8x8 quant matrices\n"
......@@ -395,6 +397,7 @@ static int Parse( int argc, char **argv,
#define OPT_CQM8 302
#define OPT_CQM8I 303
#define OPT_CQM8P 304
#define OPT_CQMFILE 305
static struct option long_options[] =
{
......@@ -452,6 +455,7 @@ static int Parse( int argc, char **argv,
{ "visualize",no_argument, NULL, OPT_VISUALIZE },
{ "aud", no_argument, NULL, OPT_AUD },
{ "cqm", required_argument, NULL, OPT_CQM },
{ "cqmfile", required_argument, NULL, OPT_CQMFILE },
{ "cqm4", required_argument, NULL, OPT_CQM4 },
{ "cqm4i", required_argument, NULL, OPT_CQM4I },
{ "cqm4iy", required_argument, NULL, OPT_CQM4IY },
......@@ -741,6 +745,9 @@ static int Parse( int argc, char **argv,
return -1;
}
break;
case OPT_CQMFILE:
param->psz_cqm_file = optarg;
break;
case OPT_CQM4:
param->i_cqm_preset = X264_CQM_CUSTOM;
b_error |= parse_cqm( optarg, param->cqm_4iy, 16 );
......
......@@ -26,7 +26,7 @@
#include <stdarg.h>
#define X264_BUILD 32
#define X264_BUILD 33
/* x264_t:
* opaque handler for decoder and encoder */
......@@ -144,6 +144,7 @@ typedef struct
int i_cabac_init_idc;
int i_cqm_preset;
char *psz_cqm_file; /* JM format */
int8_t cqm_4iy[16]; /* used only if i_cqm_preset == X264_CQM_CUSTOM */
int8_t cqm_4ic[16];
int8_t cqm_4py[16];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment