[vlc-devel] [PATCH 3/3] snapshot: fix copy of opaque pictures
Thomas Guillem
thomas at gllm.fr
Mon Jun 5 16:22:06 CEST 2017
Call picture_Copy() only for CPU pictures (planes_count > 0). Otherwise,
convert the opaque picture to a cpu picture.
---
src/video_output/snapshot.c | 67 ++++++++++++++++++++++++++++++++++++++---
src/video_output/snapshot.h | 3 +-
src/video_output/video_output.c | 2 +-
3 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/src/video_output/snapshot.c b/src/video_output/snapshot.c
index 3f48541f56..c5fd7134dd 100644
--- a/src/video_output/snapshot.c
+++ b/src/video_output/snapshot.c
@@ -37,6 +37,7 @@
#include <vlc_strings.h>
#include <vlc_block.h>
#include <vlc_vout.h>
+#include <vlc_filter.h>
#include "snapshot.h"
#include "vout_internal.h"
@@ -110,17 +111,73 @@ bool vout_snapshot_IsRequested(vout_snapshot_t *snap)
}
return has_request;
}
-void vout_snapshot_Set(vout_snapshot_t *snap,
- const picture_t *picture)
+
+static picture_t *filter_chain_buffer_new_cb(filter_t *filter)
+{
+ return picture_NewFromFormat(&filter->fmt_out.video);
+}
+
+static picture_t *snapshot_Copy(vlc_object_t *obj, picture_t *picture)
+{
+ const video_format_t *fmt = &picture->format;
+ const vlc_chroma_description_t *desc =
+ vlc_fourcc_GetChromaDescription(fmt->i_chroma);
+ assert(desc);
+
+ if (desc->plane_count != 0)
+ {
+ /* CPU picture case */
+ picture_t *dup = picture_NewFromFormat(fmt);
+ if (!dup)
+ return NULL;
+ picture_Copy(dup, picture);
+ return dup;
+ }
+
+ /* Create a CPU picture from an Opaque one using a video converter */
+ static const filter_owner_t owner = {
+ .video = {
+ .buffer_new = filter_chain_buffer_new_cb,
+ },
+ };
+ filter_chain_t *chain = filter_chain_NewVideo(obj, true, &owner);
+ if (unlikely(chain == NULL))
+ return NULL;
+
+ es_format_t fmt_in;
+ es_format_InitFromVideo(&fmt_in, fmt);
+
+ /* Set chroma to 0: the video chain converter will find the best available
+ * chroma */
+ es_format_t fmt_out = fmt_in;
+ fmt_out.video.i_chroma = fmt_out.i_codec = 0;
+
+ filter_chain_Reset(chain, &fmt_in, &fmt_out);
+ es_format_Clean(&fmt_in);
+
+ if (filter_chain_AppendConverter(chain, NULL, NULL) != 0)
+ {
+ filter_chain_Delete(chain);
+ return NULL;
+ }
+
+ /* Hold current picture since the filter will release it */
+ picture_Hold(picture);
+ picture_t *dup = filter_chain_VideoFilter(chain, picture);
+ filter_chain_Delete(chain);
+ return dup;
+
+}
+
+void vout_snapshot_Set(vout_snapshot_t *snap, vlc_object_t *obj,
+ picture_t *picture)
{
vlc_mutex_lock(&snap->lock);
while (snap->request_count > 0) {
- picture_t *dup = picture_NewFromFormat(&picture->format);
+ picture_t *dup = snapshot_Copy(obj, picture);
if (!dup)
break;
- picture_Copy(dup, picture);
-
dup->p_next = snap->picture;
snap->picture = dup;
snap->request_count--;
diff --git a/src/video_output/snapshot.h b/src/video_output/snapshot.h
index 1b361beec2..8254de2576 100644
--- a/src/video_output/snapshot.h
+++ b/src/video_output/snapshot.h
@@ -33,7 +33,6 @@ typedef struct {
bool is_available;
int request_count;
picture_t *picture;
-
} vout_snapshot_t;
/* */
@@ -55,7 +54,7 @@ bool vout_snapshot_IsRequested(vout_snapshot_t *);
*
* The given picture is only copied and not released.
*/
-void vout_snapshot_Set(vout_snapshot_t *, const picture_t *);
+void vout_snapshot_Set(vout_snapshot_t *, vlc_object_t *, picture_t *);
/**
* This function will return the directory used for snapshots
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index bbd25b631e..fe05beb64c 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -1087,7 +1087,7 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
* Take a snapshot if requested
*/
if (do_snapshot)
- vout_snapshot_Set(&vout->p->snapshot, todisplay);
+ vout_snapshot_Set(&vout->p->snapshot, VLC_OBJECT(vout), todisplay);
/* Render the direct buffer */
vout_UpdateDisplaySourceProperties(vd, &todisplay->format);
--
2.11.0
More information about the vlc-devel
mailing list