@ -53,6 +53,7 @@ struct hist_node {
enum {
STATS_MODE_ALL_FRAMES ,
STATS_MODE_DIFF_FRAMES ,
STATS_MODE_SINGLE_FRAMES ,
NB_STATS_MODE
} ;
@ -80,9 +81,10 @@ typedef struct {
static const AVOption palettegen_options [ ] = {
{ " max_colors " , " set the maximum number of colors to use in the palette " , OFFSET ( max_colors ) , AV_OPT_TYPE_INT , { . i64 = 256 } , 4 , 256 , FLAGS } ,
{ " reserve_transparent " , " reserve a palette entry for transparency " , OFFSET ( reserve_transparent ) , AV_OPT_TYPE_BOOL , { . i64 = 1 } , 0 , 1 , FLAGS } ,
{ " stats_mode " , " set statistics mode " , OFFSET ( stats_mode ) , AV_OPT_TYPE_INT , { . i64 = STATS_MODE_ALL_FRAMES } , 0 , NB_STATS_MODE , FLAGS , " mode " } ,
{ " stats_mode " , " set statistics mode " , OFFSET ( stats_mode ) , AV_OPT_TYPE_INT , { . i64 = STATS_MODE_ALL_FRAMES } , 0 , NB_STATS_MODE - 1 , FLAGS , " mode " } ,
{ " full " , " compute full frame histograms " , 0 , AV_OPT_TYPE_CONST , { . i64 = STATS_MODE_ALL_FRAMES } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
{ " diff " , " compute histograms only for the part that differs from previous frame " , 0 , AV_OPT_TYPE_CONST , { . i64 = STATS_MODE_DIFF_FRAMES } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
{ " single " , " compute new histogram for each frame " , 0 , AV_OPT_TYPE_CONST , { . i64 = STATS_MODE_SINGLE_FRAMES } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
{ NULL }
} ;
@ -480,8 +482,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext * ctx = inlink - > dst ;
PaletteGenContext * s = ctx - > priv ;
const int ret = s - > prev_frame ? update_histogram_diff ( s - > histogram , s - > prev_frame , in )
: update_histogram_frame ( s - > histogram , in ) ;
int ret = s - > prev_frame ? update_histogram_diff ( s - > histogram , s - > prev_frame , in )
: update_histogram_frame ( s - > histogram , in ) ;
if ( ret > 0 )
s - > nb_refs + = ret ;
@ -489,6 +491,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
if ( s - > stats_mode = = STATS_MODE_DIFF_FRAMES ) {
av_frame_free ( & s - > prev_frame ) ;
s - > prev_frame = in ;
} else if ( s - > stats_mode = = STATS_MODE_SINGLE_FRAMES ) {
AVFrame * out ;
int i ;
out = get_palette_frame ( ctx ) ;
out - > pts = in - > pts ;
av_frame_free ( & in ) ;
ret = ff_filter_frame ( ctx - > outputs [ 0 ] , out ) ;
for ( i = 0 ; i < HIST_SIZE ; i + + )
av_freep ( & s - > histogram [ i ] . entries ) ;
av_freep ( & s - > refs ) ;
s - > nb_refs = 0 ;
s - > nb_boxes = 0 ;
memset ( s - > boxes , 0 , sizeof ( s - > boxes ) ) ;
memset ( s - > histogram , 0 , sizeof ( s - > histogram ) ) ;
} else {
av_frame_free ( & in ) ;
}
@ -507,7 +524,7 @@ static int request_frame(AVFilterLink *outlink)
int r ;
r = ff_request_frame ( inlink ) ;
if ( r = = AVERROR_EOF & & ! s - > palette_pushed & & s - > nb_refs ) {
if ( r = = AVERROR_EOF & & ! s - > palette_pushed & & s - > nb_refs & & s - > stats_mode ! = STATS_MODE_SINGLE_FRAMES ) {
r = ff_filter_frame ( outlink , get_palette_frame ( ctx ) ) ;
s - > palette_pushed = 1 ;
return r ;