Browse Source

Merge pull request #2071 from jpark37/mjpeg-default-range

win-dshow: Fix color range when using FFmpeg decode
Jim 6 years ago
parent
commit
888a7ad3fb

+ 12 - 10
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,
 bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
 			 size_t size, long long *ts,
 			 size_t size, long long *ts,
+			 enum video_range_type range,
 			 struct obs_source_frame2 *frame, bool *got_output)
 			 struct obs_source_frame2 *frame, bool *got_output)
 {
 {
 	AVPacket packet = {0};
 	AVPacket packet = {0};
 	int got_frame = false;
 	int got_frame = false;
-	enum video_format new_format;
 	AVFrame *out_frame;
 	AVFrame *out_frame;
 	int ret;
 	int ret;
 
 
@@ -337,17 +337,17 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
 		frame->linesize[i] = decode->frame->linesize[i];
 		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);
 			frame->color_range_min, frame->color_range_max);
 		if (!success) {
 		if (!success) {
 			blog(LOG_ERROR,
 			blog(LOG_ERROR,
@@ -356,6 +356,8 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
 			     VIDEO_CS_601);
 			     VIDEO_CS_601);
 			return false;
 			return false;
 		}
 		}
+
+		frame->range = range;
 	}
 	}
 
 
 	*ts = decode->frame->pkt_pts;
 	*ts = decode->frame->pkt_pts;

+ 1 - 0
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,
 extern bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
 				size_t size, long long *ts,
 				size_t size, long long *ts,
+				enum video_range_type range,
 				struct obs_source_frame2 *frame,
 				struct obs_source_frame2 *frame,
 				bool *got_output);
 				bool *got_output);
 
 

+ 7 - 5
plugins/win-dshow/win-dshow.cpp

@@ -178,6 +178,7 @@ struct DShowInput {
 	VideoConfig videoConfig;
 	VideoConfig videoConfig;
 	AudioConfig audioConfig;
 	AudioConfig audioConfig;
 
 
+	video_range_type range;
 	obs_source_frame2 frame;
 	obs_source_frame2 frame;
 	obs_source_audio audio;
 	obs_source_audio audio;
 
 
@@ -481,7 +482,7 @@ void DShowInput::OnEncodedVideoData(enum AVCodecID id, unsigned char *data,
 
 
 	bool got_output;
 	bool got_output;
 	bool success = ffmpeg_decode_video(video_decoder, data, size, &ts,
 	bool success = ffmpeg_decode_video(video_decoder, data, size, &ts,
-					   &frame, &got_output);
+					   range, &frame, &got_output);
 	if (!success) {
 	if (!success) {
 		blog(LOG_WARNING, "Error decoding video");
 		blog(LOG_WARNING, "Error decoding video");
 		return;
 		return;
@@ -1079,13 +1080,14 @@ inline bool DShowInput::Activate(obs_data_t *settings)
 	if (!device.ConnectFilters())
 	if (!device.ConnectFilters())
 		return false;
 		return false;
 
 
-	enum video_colorspace cs = GetColorSpace(settings);
-	frame.range = GetColorRange(settings);
-
 	if (device.Start() != Result::Success)
 	if (device.Start() != Result::Success)
 		return false;
 		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_matrix,
 						   frame.color_range_min,
 						   frame.color_range_min,
 						   frame.color_range_max);
 						   frame.color_range_max);