Mejore la calidad de la imagen ajustando el brillo y el contraste de su vídeo.
/boonya/article/details/79753091
/u 010029439/article/details/84754395
¡Gracias de antemano, dos grandes maestros!
Puedes consultar el código fuente de ffmpeg, doc\examples\filtering_video.c, un ejemplo de filtrado de vídeo, ¿para ffmpeg? \libavfilter\vf_eq.c, ajusta el brillo y el contraste para mejorar la calidad de la imagen.
Línea de comando de referencia:
ffmpeg.exe-I test.mp4-VF eq =contrast=1:brightness=0.1 out.mp4
Establecer brillo, Ajustes de contraste, saturación y gamma aproximados.
Este filtro admite las siguientes opciones:
Contraste
Establece la expresión de contraste. El valor debe ser un número de punto flotante entre -2,0 y 2,0. El valor es 0.
Inteligente
Establece la expresión de brillo. El valor debe ser un número de punto flotante entre -1,0 y 1,0 y el valor predeterminado es 0.
Remojo
Establece la expresión de saturación. El valor debe ser un número de coma flotante entre 0 y 3,0; el valor predeterminado es 1.
————————————————
Filtrado de vídeos públicos inseguros{
#Variables regionales de miembros de clase
AVFilterGraph * m_filter_graph = nulo;
AVFilterContext * m_buffer fregadero_CTX = nulo;
AVFilterContext * m_buffersrc_CTX = nulo;
AVFrame * m_filt_frame = nulo
Objeto m_lock_record = nuevo Objeto();?
¿#endregion?
public int Init(int ancho, int alto, int contraste, int brillo) {
Bloquear (m_lock_record) {
// ¿Segmento de código clave?
if (m_filter_graph! = null)?
retorno-1;?
Contraste = contraste lt1 ?1: contraste
contraste = contraste gt9 ?9: contraste
Brillo = brillo lt1 ?1: brillo
p>
p>
Brillo = brillo gt9 ?9: brillo
contraste flotante _ f = 1 ((flotante)(contraste-5))/10; p>brillo flotante _ f = 0 ((float)(brillo-5))/10;
Cadena filter_description = cadena.
format(" eq = contraste = " contraste _ f . ToString() " : brillo = " brillo _ f . ToString()
Devuelve init_filters(ancho, alto, filters_descr
); p>}
}
Public int Reset(int ancho, int alto, int contraste, int brillo) {
deinit();?
Regresar Init(ancho, alto, contraste, brillo);?
}
Filtro int público (marco av * marco _ src, AVFrame **frame_dst)? {?
Bloquear(m_lock_record){
*frame_dst = frame_src?
if (m_filter_graph == null) {
return-1;?
}
int ret?
//AV_BUFFERSRC_FLAG_KEEP_REF = 8,?
ret = ffmpeg .av_buffersrc_add_frame_flags(m_buffersrc_CTX,frame_src,8);
if(ret lt;0)?
¿Devolver ret?
ret = ffmpeg . av_buffer fregadero_get_frame(m_buffer fregadero_CTX, m_filt_frame);?
if(ret lt; 0)
¿Devolver ret?
* frame_dst = m_filt_frame;?
Devuelve 0;?
}?
}
public void UnrefFrame() {
Bloqueo(m_lock_record) {
si (m_filter_graph == nulo)?
Volver;?
ffmpeg .av_frame_unref(m_filt_frame);?
}?
}?
public void Deinit()? {?
if (m_filter_graph == nulo)?
Volver;?
if(m_filter_graph!= null)? {?
¿Fijo (AVFilterGraph * * filter_graph = & m_filter_graph)?
ffmpeg .av filter_graph_free(filtro_graph);?
}?
if (m_filt_frame!= null)? {?
¿Fijo (AVFrame * * filt _ frame = ampm_filt_frame)?
ffmpeg .av_frame_free(filt_frame)
);?
}?
}?
privado int init _ filters(int ancho, int alto, cadena filters_descr) {
int ret = 0;?
ffmpeg .av filter_register_all();?
//AVPixelFormat. AV_PIX_FMT_YUV 420 p = 0;?
Parámetro de cadena = cadena. Formato("video_size=" ancho.ToString() "x" alto.ToString() ":pix_fmt = 0:time_base = 1/20");?
filtro av * buffer src = ffmpeg filtro av _ get _ by _ name(" buffer ");?
filtro av * sumidero de búfer = ffmpeg filtro av _ get _ por _ nombre(" sumidero de búfer ");?
AVFilterInOut * salidas = ffmpeg filtro av _ inout _ alloc();?
AVFilterInOut * entradas = ffmpeg filtro av _ inout _ alloc();?
//av tiempo_base racional;?
int * pix _ fmts = (int *) ffmpeg .
pix_fmts[0] = (int)AVPixelFormat. AV_PIX_FMT_YUV 420p;?
pix_fmts[1]=(int)AVPixelFormat. AV_PIX_FMT_Ninguno;?
//AVPixelFormat pix _ fmts[]= { AVPixelFormat. AV_PIX_FMT_YUV420P, formato AVPixel.
AV_PIX_FMT_None};?
m_filter_graph = ffmpeg .av filter_graph_alloc();?
if(salidas == nulo | | entradas == nulo | | m_filter_graph == nulo)? {?
ret =-1;?
Ir al final;?
}?
fixed(AVFilterContext * * buffersrc _ CTX = amp; m_buffersrc_ctx) {?
ret = ffmpeg . av filter_graph_create_filter(buffersrc_CTX, buffer src, "in", args, null, m_filter_graph);?
if(ret lt; 0)?{?
Ir al final;?
}?
}?
fixed(AVFilterContext * * sumidero de búfer _ CTX = amp; m_buffersink_ctx) {?
ret = ffmpeg .av filter_graph_create_filter(buffersink_CTX,buffer disipador,"out",null,null,m_filter_graph);?
if(ret lt; 0){?
Ir al final;?
}?
}
int size =(int)ffmpeg . av_int_list_length_for_size(1,(void*) pix_fmts, unchecked((ulong)AVPixelFormat.AV_PIX_FMT_None ));?
ret = ffmpeg. av_opt_set_bin(m_buffer fregadero_CTX, "pix_fmts", (byte*)pix_fmts, tamaño, ffmpeg.
AV_OPT_SEARCH_CHILDREN);?
if(ret lt; 0)?
Ir al final;?
Salida->nombre = ffmpeg.av_strdup("en");?
salida->filter_ctx = m_buffersrc_ctx?
salida->pad_idx = 0;?
Salida->siguiente = nulo?
Entrada->nombre = ffmpeg.av_strdup("fuera");?
entrada->filter_ctx = m_buffersink_ctx?
entrada->pad_idx = 0;?
Entrada->siguiente = nulo?
ret = ffmpeg . av filter_graph_parse_ptr(m_filter_graph, filters_descr, entrada y salida del amplificador. salida, nulo);?
if(ret lt; 0)?
Ir al final;?
ret = ffmpeg .av filter_graph_config(m_filter_graph,null);?
if(ret lt; 0)?
Ir al final;?
m_filt_frame = ffmpeg.
final:?
ffmpeg .filtro av _ inout _ free(amp; entrada);?
ffmpeg .av filter_inout_free(amp;salida);?
ffmpeg .av_free(pix_fmts);?
if(ret lt; 0)
deinit();
return ret
}
}
Después de la verificación, el efecto es obvio. Puede intentar modificar los parámetros según sus propias necesidades.