Browse Source

deps/media-playback: Fix bug where inverted media would crash

When media returns frames with negative linesizes, it means they're
inverted RGB formats and start from the last line of the image and move
back to the top via the negative linesize number.  This would cause a
crash because this wasn't being taken in to account, and it would
traverse in to invalid memory.
jp9000 8 years ago
parent
commit
4217f273a6
1 changed files with 11 additions and 3 deletions
  1. 11 3
      deps/media-playback/media-playback/media.c

+ 11 - 3
deps/media-playback/media-playback/media.c

@@ -289,6 +289,7 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
 		return;
 		return;
 	}
 	}
 
 
+	bool flip = false;
 	if (m->swscale) {
 	if (m->swscale) {
 		int ret = sws_scale(m->swscale,
 		int ret = sws_scale(m->swscale,
 				(const uint8_t *const *)f->data, f->linesize,
 				(const uint8_t *const *)f->data, f->linesize,
@@ -297,17 +298,24 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
 		if (ret < 0)
 		if (ret < 0)
 			return;
 			return;
 
 
+		flip = m->scale_linesizes[0] < 0 && m->scale_linesizes[1] == 0;
 		for (size_t i = 0; i < 4; i++) {
 		for (size_t i = 0; i < 4; i++) {
 			frame->data[i] = m->scale_pic[i];
 			frame->data[i] = m->scale_pic[i];
-			frame->linesize[i] = m->scale_linesizes[i];
+			frame->linesize[i] = abs(m->scale_linesizes[i]);
 		}
 		}
+
 	} else {
 	} else {
+		flip = f->linesize[0] < 0 && f->linesize[1] == 0;
+
 		for (size_t i = 0; i < MAX_AV_PLANES; i++) {
 		for (size_t i = 0; i < MAX_AV_PLANES; i++) {
 			frame->data[i] = f->data[i];
 			frame->data[i] = f->data[i];
-			frame->linesize[i] = f->linesize[i];
+			frame->linesize[i] = abs(f->linesize[i]);
 		}
 		}
 	}
 	}
 
 
+	if (flip)
+		frame->data[0] -= frame->linesize[0] * (f->height - 1);
+
 	new_format = convert_pixel_format(m->scale_format);
 	new_format = convert_pixel_format(m->scale_format);
 	new_space  = convert_color_space(f->colorspace);
 	new_space  = convert_color_space(f->colorspace);
 	new_range  = m->force_range == VIDEO_RANGE_DEFAULT
 	new_range  = m->force_range == VIDEO_RANGE_DEFAULT
@@ -346,7 +354,7 @@ static void mp_media_next_video(mp_media_t *m, bool preload)
 		m->play_sys_ts - base_sys_ts;
 		m->play_sys_ts - base_sys_ts;
 	frame->width = f->width;
 	frame->width = f->width;
 	frame->height = f->height;
 	frame->height = f->height;
-	frame->flip = false;
+	frame->flip = flip;
 
 
 	if (preload)
 	if (preload)
 		m->v_preload_cb(m->opaque, frame);
 		m->v_preload_cb(m->opaque, frame);