From 1be4f26ad8f13698671d63f203ec0433cf4cf4aa Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 1 Jun 2020 10:25:52 +0200 Subject: [PATCH] Suppress repeated chroma location warnings from FFmpeg. It's no good getting one of these for every frame. This works around an FFmpeg bug where HEVC doesn't get the right chroma location set. --- nageru/ffmpeg_capture.cpp | 22 +++++++++++++++------- nageru/ffmpeg_capture.h | 5 +++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/nageru/ffmpeg_capture.cpp b/nageru/ffmpeg_capture.cpp index 87d1c00..c682406 100644 --- a/nageru/ffmpeg_capture.cpp +++ b/nageru/ffmpeg_capture.cpp @@ -143,7 +143,7 @@ AVPixelFormat decide_dst_format(AVPixelFormat src_format, bmusb::PixelFormat dst return av_get_pix_fmt(best_format); } -YCbCrFormat decode_ycbcr_format(const AVPixFmtDescriptor *desc, const AVFrame *frame, bool is_mjpeg) +YCbCrFormat decode_ycbcr_format(const AVPixFmtDescriptor *desc, const AVFrame *frame, bool is_mjpeg, AVColorSpace *last_colorspace, AVChromaLocation *last_chroma_location) { YCbCrFormat format; AVColorSpace colorspace = frame->colorspace; @@ -163,11 +163,14 @@ YCbCrFormat decode_ycbcr_format(const AVPixFmtDescriptor *desc, const AVFrame *f format.luma_coefficients = (frame->height >= 720 ? YCBCR_REC_709 : YCBCR_REC_601); break; default: - fprintf(stderr, "Unknown Y'CbCr coefficient enum %d from FFmpeg; choosing Rec. 709.\n", - colorspace); + if (colorspace != *last_colorspace) { + fprintf(stderr, "Unknown Y'CbCr coefficient enum %d from FFmpeg; choosing Rec. 709.\n", + colorspace); + } format.luma_coefficients = YCBCR_REC_709; break; } + *last_colorspace = colorspace; format.full_range = is_full_range(desc); format.num_levels = 1 << desc->comp[0].depth; @@ -200,12 +203,15 @@ YCbCrFormat decode_ycbcr_format(const AVPixFmtDescriptor *desc, const AVFrame *f format.cb_y_position = 1.0; break; default: - fprintf(stderr, "Unknown chroma location coefficient enum %d from FFmpeg; choosing center.\n", - frame->chroma_location); + if (frame->chroma_location != *last_chroma_location) { + fprintf(stderr, "Unknown chroma location coefficient enum %d from FFmpeg; choosing center.\n", + frame->chroma_location); + } format.cb_x_position = 0.5; format.cb_y_position = 0.5; break; } + *last_chroma_location = frame->chroma_location; if (is_mjpeg && !format.full_range) { // Limited-range MJPEG is only detected by FFmpeg whenever a special @@ -459,6 +465,8 @@ bool FFmpegCapture::play_video(const string &pathname) } else { last_modified = buf.st_mtim; } + last_colorspace = static_cast(-1); + last_chroma_location = static_cast(-1); AVFormatContextWithCloser format_ctx; if (srt_sock == -1) { @@ -1002,7 +1010,7 @@ UniqueFrame FFmpegCapture::make_video_frame(const AVFrame *frame, const string & video_frame->len = (frame_width(frame) * 2) * frame_height(frame); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(sws_dst_format); - current_frame_ycbcr_format = decode_ycbcr_format(desc, frame, is_mjpeg); + current_frame_ycbcr_format = decode_ycbcr_format(desc, frame, is_mjpeg, &last_colorspace, &last_chroma_location); } else { assert(pixel_format == bmusb::PixelFormat_8BitYCbCrPlanar); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(sws_dst_format); @@ -1021,7 +1029,7 @@ UniqueFrame FFmpegCapture::make_video_frame(const AVFrame *frame, const string & video_frame->len = frame_width(frame) * frame_height(frame) + 2 * chroma_width * chroma_height; - current_frame_ycbcr_format = decode_ycbcr_format(desc, frame, is_mjpeg); + current_frame_ycbcr_format = decode_ycbcr_format(desc, frame, is_mjpeg, &last_colorspace, &last_chroma_location); } sws_scale(sws_ctx.get(), frame->data, frame->linesize, 0, frame->height, pic_data, linesizes); diff --git a/nageru/ffmpeg_capture.h b/nageru/ffmpeg_capture.h index 4cddbfd..1fc8f71 100644 --- a/nageru/ffmpeg_capture.h +++ b/nageru/ffmpeg_capture.h @@ -329,6 +329,11 @@ private: std::string last_subtitle; movit::RGBTriplet last_neutral_color{1.0f, 1.0f, 1.0f}; + + // Used for suppressing repeated warnings. Reset when a video starts playing. + // -1 is strictly speaking outside the range of the enum, but hopefully, it will be alright. + AVColorSpace last_colorspace = static_cast(-1); + AVChromaLocation last_chroma_location = static_cast(-1); }; #endif // !defined(_FFMPEG_CAPTURE_H) -- 2.39.2