summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-01 23:53:18 +0200
committerwm4 <wm4@nowhere>2014-05-02 01:09:58 +0200
commiteb9d2039460e413fe2f4f191ad0ddafde3be27df (patch)
tree7e6458cad5655d209c5b6c5a3de53e3f302ad160 /video
parent346daec4038b74f8b2136e9950e34cec50e3d2ec (diff)
downloadmpv-eb9d2039460e413fe2f4f191ad0ddafde3be27df.tar.bz2
mpv-eb9d2039460e413fe2f4f191ad0ddafde3be27df.tar.xz
video: change everything
Change how the video decoding loop works. The structure should now be a bit easier to follow. The interactions on format changes are (probably) simpler. This also aligns the decoding loop with future planned changes, such as moving various things to separate threads.
Diffstat (limited to 'video')
-rw-r--r--video/decode/dec_video.c2
-rw-r--r--video/decode/dec_video.h6
-rw-r--r--video/out/vo.c58
-rw-r--r--video/out/vo.h7
4 files changed, 33 insertions, 40 deletions
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index b59ded7ac3..f092e82a2e 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -436,8 +436,6 @@ int video_reconfig_filters(struct dec_video *d_video,
return -1;
}
- d_video->vf_input = *params;
-
return 0;
}
diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h
index 7805d89c48..58ec99a86b 100644
--- a/video/decode/dec_video.h
+++ b/video/decode/dec_video.h
@@ -40,11 +40,9 @@ struct dec_video {
char *decoder_desc;
- struct mp_image_params decoder_output; // last output of the decoder
- struct mp_image_params vf_input; // video filter input params
-
- // Used temporarily during format changes
+ // Used temporarily during decoding (important for format changes)
struct mp_image *waiting_decoded_mpi;
+ struct mp_image_params decoder_output; // last output of the decoder
void *priv; // for free use by vd_driver
diff --git a/video/out/vo.c b/video/out/vo.c
index 2372ce36b0..a13922534e 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -174,8 +174,6 @@ static struct vo *vo_create(struct mpv_global *global,
.event_fd = -1,
.monitor_par = 1,
.max_video_queue = 1,
- .next_pts = MP_NOPTS_VALUE,
- .next_pts2 = MP_NOPTS_VALUE,
};
talloc_steal(vo, log);
if (vo->driver->encode != !!vo->encode_lavc_ctx)
@@ -358,27 +356,11 @@ int vo_control(struct vo *vo, uint32_t request, void *data)
return vo->driver->control(vo, request, data);
}
-static void update_video_queue_state(struct vo *vo, bool eof)
-{
- int num = vo->num_video_queue;
- // Normally, buffer 1 image ahead, except if the queue is limited to less
- // than 2 entries, or if EOF is reached and there aren't enough images left.
- int min = 2;
- if (vo->max_video_queue < 2 || (vo->num_video_queue < 2 && eof))
- min = 1;
- vo->frame_loaded = num >= min;
- if (!vo->frame_loaded)
- num = -1;
- vo->next_pts = num > 0 ? vo->video_queue[0]->pts : MP_NOPTS_VALUE;
- vo->next_pts2 = num > 1 ? vo->video_queue[1]->pts : MP_NOPTS_VALUE;
-}
-
static void forget_frames(struct vo *vo)
{
for (int n = 0; n < vo->num_video_queue; n++)
talloc_free(vo->video_queue[n]);
vo->num_video_queue = 0;
- update_video_queue_state(vo, false);
}
void vo_queue_image(struct vo *vo, struct mp_image *mpi)
@@ -397,7 +379,34 @@ void vo_queue_image(struct vo *vo, struct mp_image *mpi)
assert(vo->max_video_queue <= VO_MAX_QUEUE);
assert(vo->num_video_queue < vo->max_video_queue);
vo->video_queue[vo->num_video_queue++] = mpi;
- update_video_queue_state(vo, false);
+}
+
+// Return whether vo_queue_image() should be called.
+bool vo_needs_new_image(struct vo *vo)
+{
+ if (!vo->config_ok)
+ return false;
+ return vo->num_video_queue < vo->max_video_queue;
+}
+
+// Return whether a frame can be displayed.
+// eof==true: return true if at least one frame is queued
+// eof==false: return true if "enough" frames are queued
+bool vo_has_next_frame(struct vo *vo, bool eof)
+{
+ if (!vo->config_ok)
+ return false;
+ // Normally, buffer 1 image ahead, except if the queue is limited to less
+ // than 2 entries, or if EOF is reached and there aren't enough images left.
+ return eof ? vo->num_video_queue : vo->num_video_queue == vo->max_video_queue;
+}
+
+// Return the PTS of a future frame (where index==0 is the next frame)
+double vo_get_next_pts(struct vo *vo, int index)
+{
+ if (index < 0 || index >= vo->num_video_queue)
+ return MP_NOPTS_VALUE;
+ return vo->video_queue[index]->pts;
}
int vo_redraw_frame(struct vo *vo)
@@ -418,14 +427,6 @@ bool vo_get_want_redraw(struct vo *vo)
return vo->want_redraw;
}
-int vo_get_buffered_frame(struct vo *vo, bool eof)
-{
- if (!vo->config_ok)
- return -1;
- update_video_queue_state(vo, eof);
- return vo->frame_loaded ? 0 : -1;
-}
-
// Remove vo->video_queue[0]
static void shift_queue(struct vo *vo)
{
@@ -440,12 +441,10 @@ static void shift_queue(struct vo *vo)
void vo_skip_frame(struct vo *vo)
{
shift_queue(vo);
- vo->frame_loaded = false;
}
void vo_new_frame_imminent(struct vo *vo)
{
- assert(vo->frame_loaded);
assert(vo->num_video_queue > 0);
vo->driver->draw_image(vo, vo->video_queue[0]);
shift_queue(vo);
@@ -467,7 +466,6 @@ void vo_flip_page(struct vo *vo, int64_t pts_us, int duration)
else
vo->driver->flip_page(vo);
vo->hasframe = true;
- update_video_queue_state(vo, false);
}
void vo_check_events(struct vo *vo)
diff --git a/video/out/vo.h b/video/out/vo.h
index e3ab562839..77382d9f38 100644
--- a/video/out/vo.h
+++ b/video/out/vo.h
@@ -237,9 +237,6 @@ struct vo {
bool untimed; // non-interactive, don't do sleep calls in playloop
- bool frame_loaded; // Is there a next frame the VO could flip to?
- double next_pts; // pts value of the next frame if any
- double next_pts2; // optional pts of frame after that
bool want_redraw; // visible frame wrong (window resize), needs refresh
bool hasframe; // >= 1 frame has been drawn, so redraw is possible
double wakeup_period; // if > 0, this sets the maximum wakeup period for event polling
@@ -288,7 +285,9 @@ int vo_control(struct vo *vo, uint32_t request, void *data);
void vo_queue_image(struct vo *vo, struct mp_image *mpi);
int vo_redraw_frame(struct vo *vo);
bool vo_get_want_redraw(struct vo *vo);
-int vo_get_buffered_frame(struct vo *vo, bool eof);
+bool vo_has_next_frame(struct vo *vo, bool eof);
+double vo_get_next_pts(struct vo *vo, int index);
+bool vo_needs_new_image(struct vo *vo);
void vo_skip_frame(struct vo *vo);
void vo_new_frame_imminent(struct vo *vo);
void vo_draw_osd(struct vo *vo, struct osd_state *osd);