目的:调整视频的亮度和对比度。

    可参考ffmpeg的源码:

    \examples\filtering_video.c,视频滤波例子

    \libavfilter\vf_eq.c,亮度对比度调整的具体实现

    ffmpeg.exe -i record.mp4 -vf eq=contrast=1:brightness=-0.2 output.mp4 处理后图片
    ffmpeg.exe -i record.mp4 -vf eq=contrast=1:brightness=0.2 output.mp4 处理后图片

    效果还可以.

    写好了,贴代码,主要是参考这个文件\examples\filtering_video.c,C代码改C#遇到了几个坑花了大半天时间

    Init函数的contrast和brightness参数分别对应对比度和亮度,取值1-9,5为原始图像。

    1. public unsafe class VideoFiltering
    2. {
    3. #region 类成员变量
    4. AVFilterGraph* m_filter_graph = null;
    5. AVFilterContext* m_buffersink_ctx = null;
    6. AVFilterContext* m_buffersrc_ctx = null;
    7. AVFrame* m_filt_frame = null;
    8. Object m_lock_record = new Object();
    9. #endregion
    10. public int Init(int width, int height, int contrast, int brightness)
    11. {
    12. lock (m_lock_record)
    13. {
    14. // Critical code section
    15. if (m_filter_graph != null)
    16. return -1;
    17. contrast = contrast < 1 ? 1 : contrast;
    18. contrast = contrast > 9 ? 9 : contrast;
    19. brightness = brightness < 1 ? 1 : brightness;
    20. brightness = brightness > 9 ? 9 : brightness;
    21. float contrast_f = 1 + ((float)(contrast - 5)) / 10;
    22. float brightness_f = 0 + ((float)(brightness - 5)) / 10;
    23. string filters_descr = string.Format("eq=contrast=" + contrast_f.ToString() + ":brightness=" + brightness_f.ToString());
    24. return init_filters(width, height, filters_descr);
    25. }
    26. }
    27. public int Reset(int width, int height, int contrast, int brightness)
    28. {
    29. Deinit();
    30. return Init(width, height, contrast, brightness);
    31. }
    32. public int Filter(AVFrame * frame_src, AVFrame **frame_dst)
    33. {
    34. lock (m_lock_record)
    35. {
    36. *frame_dst = frame_src;
    37. if (m_filter_graph == null)
    38. {
    39. return -1;
    40. }
    41. int ret;
    42. //AV_BUFFERSRC_FLAG_KEEP_REF = 8,
    43. ret = ffmpeg.av_buffersrc_add_frame_flags(m_buffersrc_ctx, frame_src, 8);
    44. if (ret < 0)
    45. return ret;
    46. ret = ffmpeg.av_buffersink_get_frame(m_buffersink_ctx, m_filt_frame);
    47. if (ret < 0)
    48. return ret;
    49. *frame_dst = m_filt_frame;
    50. return 0;
    51. }
    52. }
    53. public void UnrefFrame()
    54. {
    55. lock (m_lock_record)
    56. {
    57. if (m_filter_graph == null)
    58. return ;
    59. ffmpeg.av_frame_unref(m_filt_frame);
    60. }
    61. }
    62. public void Deinit()
    63. {
    64. if (m_filter_graph == null)
    65. return ;
    66. if(m_filter_graph != null)
    67. {
    68. fixed(AVFilterGraph** filter_graph = &m_filter_graph)
    69. ffmpeg.avfilter_graph_free(filter_graph);
    70. }
    71. if (m_filt_frame != null)
    72. {
    73. fixed (AVFrame** filt_frame = &m_filt_frame)
    74. ffmpeg.av_frame_free(filt_frame);
    75. }
    76. }
    77. private int init_filters(int width, int height, string filters_descr)
    78. {
    79. int ret = 0;
    80. ffmpeg.avfilter_register_all();
    81. //AVPixelFormat.AV_PIX_FMT_YUV420P = 0;
    82. string args = string.Format("video_size=" + width.ToString() + "x" + height.ToString() +
    83. ":pix_fmt=0:time_base=1/20");
    84. AVFilter* buffersrc = ffmpeg.avfilter_get_by_name("buffer");
    85. AVFilter* buffersink = ffmpeg.avfilter_get_by_name("buffersink");
    86. AVFilterInOut* outputs = ffmpeg.avfilter_inout_alloc();
    87. AVFilterInOut* inputs = ffmpeg.avfilter_inout_alloc();
    88. //AVRational time_base;
    89. int* pix_fmts = (int*)ffmpeg.av_malloc(8);
    90. pix_fmts[0] = (int)AVPixelFormat.AV_PIX_FMT_YUV420P;
    91. pix_fmts[1] = (int)AVPixelFormat.AV_PIX_FMT_NONE;
    92. //AVPixelFormat pix_fmts[] = { AVPixelFormat.AV_PIX_FMT_YUV420P, AVPixelFormat.AV_PIX_FMT_NONE };
    93. m_filter_graph = ffmpeg.avfilter_graph_alloc();
    94. if(outputs == null || inputs == null || m_filter_graph == null)
    95. {
    96. ret = -1;
    97. goto end;
    98. }
    99. fixed (AVFilterContext** buffersrc_ctx = &m_buffersrc_ctx)
    100. {
    101. ret = ffmpeg.avfilter_graph_create_filter(buffersrc_ctx, buffersrc, "in", args, null, m_filter_graph);
    102. if (ret < 0)
    103. {
    104. goto end;
    105. }
    106. }
    107. fixed (AVFilterContext** buffersink_ctx = &m_buffersink_ctx)
    108. {
    109. ret = ffmpeg.avfilter_graph_create_filter(buffersink_ctx, buffersink, "out", null, null, m_filter_graph);
    110. if (ret < 0)
    111. {
    112. goto end;
    113. }
    114. }
    115. int size = (int)ffmpeg.av_int_list_length_for_size(1, (void*)pix_fmts, unchecked((ulong)AVPixelFormat.AV_PIX_FMT_NONE));
    116. ret = ffmpeg.av_opt_set_bin(m_buffersink_ctx, "pix_fmts", (byte*)pix_fmts, size, ffmpeg.AV_OPT_SEARCH_CHILDREN);
    117. if(ret < 0)
    118. goto end;
    119. outputs->name = ffmpeg.av_strdup("in");
    120. outputs->filter_ctx = m_buffersrc_ctx;
    121. outputs->pad_idx = 0;
    122. outputs->next = null;
    123. inputs->name = ffmpeg.av_strdup("out");
    124. inputs->filter_ctx = m_buffersink_ctx;
    125. inputs->pad_idx = 0;
    126. inputs->next = null;
    127. ret = ffmpeg.avfilter_graph_parse_ptr(m_filter_graph, filters_descr, &inputs, &outputs, null);
    128. if (ret < 0)
    129. goto end;
    130. ret = ffmpeg.avfilter_graph_config(m_filter_graph, null);
    131. if (ret < 0)
    132. goto end;
    133. m_filt_frame = ffmpeg.av_frame_alloc();
    134. end:
    135. ffmpeg.avfilter_inout_free(&inputs);
    136. ffmpeg.avfilter_inout_free(&outputs);
    137. ffmpeg.av_free(pix_fmts);
    138. if (ret < 0)
    139. Deinit();
    140. return ret;
    141. }
    142. }