avfilter/avf_showspectrum: add option to control dynamic range for colors
This commit is contained in:
		
							parent
							
								
									2146b65553
								
							
						
					
					
						commit
						2678b4f81b
					
				@ -26914,6 +26914,10 @@ Set upper frame rate limit. Default is @code{auto}, unlimited.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@item legend
 | 
					@item legend
 | 
				
			||||||
Draw time and frequency axes and legends. Default is disabled.
 | 
					Draw time and frequency axes and legends. Default is disabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item drange
 | 
				
			||||||
 | 
					Set dynamic range used to calculate intensity color values. Default is 120dBFS.
 | 
				
			||||||
 | 
					Allowed range is from 10 to 200.
 | 
				
			||||||
@end table
 | 
					@end table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The usage is very similar to the showwaves filter; see the examples in that
 | 
					The usage is very similar to the showwaves filter; see the examples in that
 | 
				
			||||||
@ -27087,6 +27091,10 @@ Set start frequency from which to display spectrogram. Default is @code{0}.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@item stop
 | 
					@item stop
 | 
				
			||||||
Set stop frequency to which to display spectrogram. Default is @code{0}.
 | 
					Set stop frequency to which to display spectrogram. Default is @code{0}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@item drange
 | 
				
			||||||
 | 
					Set dynamic range used to calculate intensity color values. Default is 120dBFS.
 | 
				
			||||||
 | 
					Allowed range is from 10 to 200.
 | 
				
			||||||
@end table
 | 
					@end table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@subsection Examples
 | 
					@subsection Examples
 | 
				
			||||||
 | 
				
			|||||||
@ -101,6 +101,8 @@ typedef struct ShowSpectrumContext {
 | 
				
			|||||||
    int single_pic;
 | 
					    int single_pic;
 | 
				
			||||||
    int legend;
 | 
					    int legend;
 | 
				
			||||||
    int start_x, start_y;
 | 
					    int start_x, start_y;
 | 
				
			||||||
 | 
					    float drange;
 | 
				
			||||||
 | 
					    float dmin, dscale;
 | 
				
			||||||
    int (*plot_channel)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
 | 
					    int (*plot_channel)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
 | 
				
			||||||
} ShowSpectrumContext;
 | 
					} ShowSpectrumContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -181,6 +183,7 @@ static const AVOption showspectrum_options[] = {
 | 
				
			|||||||
    { "stop",  "stop frequency",  OFFSET(stop),  AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
 | 
					    { "stop",  "stop frequency",  OFFSET(stop),  AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
 | 
				
			||||||
    { "fps",   "set video rate",  OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = "auto"}, 0, 0, FLAGS },
 | 
					    { "fps",   "set video rate",  OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = "auto"}, 0, 0, FLAGS },
 | 
				
			||||||
    { "legend", "draw legend", OFFSET(legend), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS },
 | 
					    { "legend", "draw legend", OFFSET(legend), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS },
 | 
				
			||||||
 | 
					    { "drange", "set dynamic range in dBFS", OFFSET(drange), AV_OPT_TYPE_FLOAT, {.dbl = 120}, 10, 200, FLAGS },
 | 
				
			||||||
    { NULL }
 | 
					    { NULL }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -871,10 +874,10 @@ static int draw_legend(AVFilterContext *ctx, int samples)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (y = 0; ch == 0 && y < h; y += h / 10) {
 | 
					        for (y = 0; ch == 0 && y < h; y += h / 10) {
 | 
				
			||||||
            float value = 120.f * log10f(1.f - y / (float)h);
 | 
					            float value = s->drange * log10f(1.f - y / (float)h);
 | 
				
			||||||
            char *text;
 | 
					            char *text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (value < -120)
 | 
					            if (value < -s->drange)
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            text = av_asprintf("%.0f dB", value);
 | 
					            text = av_asprintf("%.0f dB", value);
 | 
				
			||||||
            if (!text)
 | 
					            if (!text)
 | 
				
			||||||
@ -925,7 +928,7 @@ static float get_value(AVFilterContext *ctx, int ch, int y)
 | 
				
			|||||||
        a = av_clipf(powf(a, 0.20), 0, 1);
 | 
					        a = av_clipf(powf(a, 0.20), 0, 1);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case LOG:
 | 
					    case LOG:
 | 
				
			||||||
        a = 1.f + log10f(av_clipf(a, 1e-6, 1)) / 6.f; // zero = -120dBFS
 | 
					        a = 1.f + log10f(av_clipf(a, s->dmin, 1.f)) * s->dscale;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        av_assert0(0);
 | 
					        av_assert0(0);
 | 
				
			||||||
@ -999,6 +1002,9 @@ static int config_output(AVFilterLink *outlink)
 | 
				
			|||||||
    int i, fft_size, h, w, ret;
 | 
					    int i, fft_size, h, w, ret;
 | 
				
			||||||
    float overlap;
 | 
					    float overlap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->dmin = expf(-s->drange * M_LN10 / 20.f);
 | 
				
			||||||
 | 
					    s->dscale = -1.f / log10f(s->dmin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (s->fscale) {
 | 
					    switch (s->fscale) {
 | 
				
			||||||
    case F_LINEAR: s->plot_channel = plot_channel_lin; break;
 | 
					    case F_LINEAR: s->plot_channel = plot_channel_lin; break;
 | 
				
			||||||
    case F_LOG:    s->plot_channel = plot_channel_log; break;
 | 
					    case F_LOG:    s->plot_channel = plot_channel_log; break;
 | 
				
			||||||
@ -1641,6 +1647,7 @@ static const AVOption showspectrumpic_options[] = {
 | 
				
			|||||||
    { "rotation", "color rotation", OFFSET(rotation), AV_OPT_TYPE_FLOAT, {.dbl = 0}, -1, 1, FLAGS },
 | 
					    { "rotation", "color rotation", OFFSET(rotation), AV_OPT_TYPE_FLOAT, {.dbl = 0}, -1, 1, FLAGS },
 | 
				
			||||||
    { "start", "start frequency", OFFSET(start), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
 | 
					    { "start", "start frequency", OFFSET(start), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
 | 
				
			||||||
    { "stop",  "stop frequency",  OFFSET(stop),  AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
 | 
					    { "stop",  "stop frequency",  OFFSET(stop),  AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT32_MAX, FLAGS },
 | 
				
			||||||
 | 
					    { "drange", "set dynamic range in dBFS", OFFSET(drange), AV_OPT_TYPE_FLOAT, {.dbl = 120}, 10, 200, FLAGS },
 | 
				
			||||||
    { NULL }
 | 
					    { NULL }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user