summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libvo/video_out.h5
-rw-r--r--libvo/vo_yuv4mpeg.c52
-rw-r--r--mplayer.c14
3 files changed, 67 insertions, 4 deletions
diff --git a/libvo/video_out.h b/libvo/video_out.h
index 118b14e65b..33cda1b1de 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -49,7 +49,10 @@
/* equalizer controls */
#define VOCTRL_SET_EQUALIZER 17
#define VOCTRL_GET_EQUALIZER 18
-// ... 20
+//#define VOCTRL_GUI_NOWINDOW 19
+/* Frame duplication */
+#define VOCTRL_DUPLICATE_FRAME 20
+// ... 21
#define VO_TRUE 1
diff --git a/libvo/vo_yuv4mpeg.c b/libvo/vo_yuv4mpeg.c
index 8d4f40227e..61116ba4ff 100644
--- a/libvo/vo_yuv4mpeg.c
+++ b/libvo/vo_yuv4mpeg.c
@@ -222,6 +222,56 @@ static void vo_y4m_write(const void *ptr, const size_t num_bytes)
perror("yuv4mpeg: Error writing image to output!");
}
+static int write_last_frame(void)
+{
+
+ uint8_t *upper_y, *upper_u, *upper_v, *rgb_buffer_lower;
+ int rgb_stride, uv_stride, field_height;
+ unsigned int i, low_ofs;
+
+ fprintf(yuv_out, "FRAME\n");
+
+ if (using_format != IMGFMT_YV12)
+ {
+ rgb_stride = image_width * 3;
+ uv_stride = image_width / 2;
+
+ if (Y4M_IS_INTERLACED)
+ {
+ field_height = image_height / 2;
+
+ upper_y = image;
+ upper_u = upper_y + image_width * field_height;
+ upper_v = upper_u + image_width * field_height / 4;
+ low_ofs = image_width * field_height * 3 / 2;
+ rgb_buffer_lower = rgb_buffer + rgb_stride * field_height;
+
+ /* Write Y plane */
+ for(i = 0; i < field_height; i++)
+ {
+ vo_y4m_write(upper_y + image_width * i, image_width);
+ vo_y4m_write(upper_y + image_width * i + low_ofs, image_width);
+ }
+
+ /* Write U and V plane */
+ for(i = 0; i < field_height / 2; i++)
+ {
+ vo_y4m_write(upper_u + uv_stride * i, uv_stride);
+ vo_y4m_write(upper_u + uv_stride * i + low_ofs, uv_stride);
+ }
+ for(i = 0; i < field_height / 2; i++)
+ {
+ vo_y4m_write(upper_v + uv_stride * i, uv_stride);
+ vo_y4m_write(upper_v + uv_stride * i + low_ofs, uv_stride);
+ }
+ return VO_TRUE; /* Image written; We have to stop here */
+ }
+ }
+ /* Write progressive frame */
+ vo_y4m_write(image, write_bytes);
+ return VO_TRUE;
+}
+
static void flip_page (void)
{
uint8_t *upper_y, *upper_u, *upper_v, *rgb_buffer_lower;
@@ -455,6 +505,8 @@ static uint32_t control(uint32_t request, void *data, ...)
switch (request) {
case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data));
+ case VOCTRL_DUPLICATE_FRAME:
+ return write_last_frame();
}
return VO_NOTIMPL;
}
diff --git a/mplayer.c b/mplayer.c
index 1b64639104..ba43f759b7 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -1725,7 +1725,8 @@ if(time_frame>0.001 && !(vo_flags&256)){
if(vo_config_count) video_out->check_events();
current_module="flip_page";
- if(blit_frame && !frame_time_remaining){
+ if (!frame_time_remaining) {
+ if(blit_frame){
unsigned int t2=GetTimer();
double tt;
float j;
@@ -1744,8 +1745,15 @@ if(time_frame>0.001 && !(vo_flags&256)){
t2=GetTimer()-t2;
tt = t2*0.000001f;
vout_time_usage+=tt;
- }
-
+ } else {
+ /*
+ Well, no blitting is needed, but some devices (such as yuv4mpeg) must output frame
+ otherwise A/V desync will occur. -- Alvieboy
+ */
+ if (vo_config_count)
+ video_out->control(VOCTRL_DUPLICATE_FRAME, NULL);
+ }
+ }
//====================== A-V TIMESTAMP CORRECTION: =========================
current_module="av_sync";