From f60b820feed76666cb045e234ab83d58f562c2a1 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Sat, 14 Sep 2019 17:04:22 -0700 Subject: [PATCH] win-dshow: Fix color range when using FFmpeg decode Full color range seems to be active when decoding video with FFMmpeg even when partial is explicitly selected. This should keep the range synchronized. --- plugins/win-dshow/ffmpeg-decode.c | 22 ++++++++++++---------- plugins/win-dshow/ffmpeg-decode.h | 1 + plugins/win-dshow/win-dshow.cpp | 12 +++++++----- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/plugins/win-dshow/ffmpeg-decode.c b/plugins/win-dshow/ffmpeg-decode.c index 48ea5d1c9..4960a6c4b 100644 --- a/plugins/win-dshow/ffmpeg-decode.c +++ b/plugins/win-dshow/ffmpeg-decode.c @@ -273,11 +273,11 @@ bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data, bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data, size_t size, long long *ts, + enum video_range_type range, struct obs_source_frame2 *frame, bool *got_output) { AVPacket packet = {0}; int got_frame = false; - enum video_format new_format; AVFrame *out_frame; int ret; @@ -337,17 +337,17 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data, frame->linesize[i] = decode->frame->linesize[i]; } - new_format = convert_pixel_format(decode->frame->format); - if (new_format != frame->format) { - bool success; + frame->format = convert_pixel_format(decode->frame->format); - frame->format = new_format; - frame->range = decode->frame->color_range == AVCOL_RANGE_JPEG - ? VIDEO_RANGE_FULL - : VIDEO_RANGE_DEFAULT; + if (range == VIDEO_RANGE_DEFAULT) { + range = (decode->frame->color_range == AVCOL_RANGE_JPEG) + ? VIDEO_RANGE_FULL + : VIDEO_RANGE_PARTIAL; + } - success = video_format_get_parameters( - VIDEO_CS_601, frame->range, frame->color_matrix, + if (range != frame->range) { + const bool success = video_format_get_parameters( + VIDEO_CS_601, range, frame->color_matrix, frame->color_range_min, frame->color_range_max); if (!success) { blog(LOG_ERROR, @@ -356,6 +356,8 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data, VIDEO_CS_601); return false; } + + frame->range = range; } *ts = decode->frame->pkt_pts; diff --git a/plugins/win-dshow/ffmpeg-decode.h b/plugins/win-dshow/ffmpeg-decode.h index 2f86b7f1e..f06c01b09 100644 --- a/plugins/win-dshow/ffmpeg-decode.h +++ b/plugins/win-dshow/ffmpeg-decode.h @@ -58,6 +58,7 @@ extern bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data, extern bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data, size_t size, long long *ts, + enum video_range_type range, struct obs_source_frame2 *frame, bool *got_output); diff --git a/plugins/win-dshow/win-dshow.cpp b/plugins/win-dshow/win-dshow.cpp index 34f5678d4..625093bd0 100644 --- a/plugins/win-dshow/win-dshow.cpp +++ b/plugins/win-dshow/win-dshow.cpp @@ -178,6 +178,7 @@ struct DShowInput { VideoConfig videoConfig; AudioConfig audioConfig; + video_range_type range; obs_source_frame2 frame; obs_source_audio audio; @@ -481,7 +482,7 @@ void DShowInput::OnEncodedVideoData(enum AVCodecID id, unsigned char *data, bool got_output; bool success = ffmpeg_decode_video(video_decoder, data, size, &ts, - &frame, &got_output); + range, &frame, &got_output); if (!success) { blog(LOG_WARNING, "Error decoding video"); return; @@ -1079,13 +1080,14 @@ inline bool DShowInput::Activate(obs_data_t *settings) if (!device.ConnectFilters()) return false; - enum video_colorspace cs = GetColorSpace(settings); - frame.range = GetColorRange(settings); - if (device.Start() != Result::Success) return false; - bool success = video_format_get_parameters(cs, frame.range, + enum video_colorspace cs = GetColorSpace(settings); + range = GetColorRange(settings); + frame.range = range; + + bool success = video_format_get_parameters(cs, range, frame.color_matrix, frame.color_range_min, frame.color_range_max);