amlvideosink: CF1 sync vr360 feature to amlvideosink [1/1]
PD#SWPL-164853
Problem:
sync vr360 feature to amlvideosink
Solution:
sync vr360 feature to amlvideosink
Verify:
ah212
Change-Id: I1855a65808d8e07d9aecc4a87339d1995c5518bc
Signed-off-by: hanghang.luo <hanghang.luo@amlogic.com>
diff --git a/src/gstamlvideosink.c b/src/gstamlvideosink.c
index c2392c6..34a2531 100644
--- a/src/gstamlvideosink.c
+++ b/src/gstamlvideosink.c
@@ -89,6 +89,7 @@
{
SIGNAL_FIRSTFRAME,
SIGNAL_UNDERFLOW,
+ SIGNAL_DECODEDBUFFER,
LAST_SIGNAL
};
@@ -106,6 +107,7 @@
PROP_DISPLAY_OUTPUT,
PROP_SHOW_FIRST_FRAME_ASAP,
PROP_KEEP_LAST_FRAME_ON_FLUSH,
+ PROP_ENABLE_USER_RENDERING,
#if GST_IMPORT_LGE_PROP
PROP_LGE_RESOURCE_INFO,
PROP_LGE_CURRENT_PTS,
@@ -133,7 +135,8 @@
#define DRMBP_EXTRA_BUF_SZIE_FOR_DISPLAY 1
#define DRMBP_LIMIT_MAX_BUFSIZE_TO_BUFSIZE 1
#define DRMBP_UNLIMIT_MAX_BUFSIZE 0
-#define GST_AML_WAIT_TIME 5000
+#define GST_AML_WAIT_TIME 5000
+#define FORMAT_NV21 0x3231564e // this value is used to be same as cobalt
typedef struct _GstAmlVideoSinkWindowSet
{
@@ -190,6 +193,12 @@
#endif
};
+typedef struct bufferInfo
+{
+ GstAmlVideoSink *sink;
+ GstBuffer *buf;
+} bufferInfo;
+
static guint g_signals[LAST_SIGNAL]= {0};
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE(
@@ -332,6 +341,12 @@
g_param_spec_boolean("show-first-frame-asap", "show first video frame asap",
"Whether showing first video frame asap, default is disable",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (
+ G_OBJECT_CLASS(klass), PROP_ENABLE_USER_RENDERING,
+ g_param_spec_boolean ("enable-user-rendering",
+ "enable signal decoded buffer to user to rendering",
+ "0: disable; 1: enable",
+ FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_signals[SIGNAL_FIRSTFRAME]= g_signal_new( "first-video-frame-callback",
G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)),
@@ -356,6 +371,16 @@
2,
G_TYPE_UINT,
G_TYPE_POINTER );
+ g_signals[SIGNAL_DECODEDBUFFER]= g_signal_new ("decoded-buffer-callback",
+ G_TYPE_FROM_CLASS(GST_ELEMENT_CLASS(klass)),
+ (GSignalFlags) (G_SIGNAL_RUN_FIRST),
+ 0, /* class offset */
+ NULL, /* accumulator */
+ NULL, /* accu data */
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ GST_TYPE_BUFFER);
#if GST_IMPORT_LGE_PROP
g_object_class_install_property(
G_OBJECT_CLASS(klass), PROP_LGE_RESOURCE_INFO,
@@ -430,6 +455,7 @@
sink->pixel_aspect_ratio_changed = FALSE;
sink->pixel_aspect_ratio = 1.0;
sink->keep_last_frame_on_flush = TRUE;
+ //sink->enable_decoded_buffer_signal = FALSE;
g_mutex_init(&sink->eos_lock);
g_cond_init(&sink->eos_cond);
@@ -490,6 +516,14 @@
GST_OBJECT_UNLOCK(sink);
break;
}
+ case PROP_ENABLE_USER_RENDERING:
+ {
+ GST_OBJECT_LOCK(sink);
+ g_value_set_boolean(value, sink->enable_decoded_buffer_signal);
+ GST_OBJECT_UNLOCK(sink);
+ break;
+ }
+
#if GST_IMPORT_LGE_PROP
case PROP_LGE_CURRENT_PTS:
{
@@ -633,6 +667,11 @@
GST_OBJECT_UNLOCK(sink);
break;
}
+ case PROP_ENABLE_USER_RENDERING:
+ {
+ sink->enable_decoded_buffer_signal = g_value_get_boolean(value);
+ GST_DEBUG("set enable decoded buffer signal %d", sink->enable_decoded_buffer_signal);
+ }
#if GST_IMPORT_LGE_PROP
case PROP_LGE_RESOURCE_INFO:
{
@@ -864,9 +903,9 @@
{
if ( sink->eos_detect_thread_handle )
{
- sink->quit_eos_detect_thread= TRUE;
+ sink->quit_eos_detect_thread = TRUE;
g_thread_join(sink->eos_detect_thread_handle);
- sink->eos_detect_thread_handle= NULL;
+ sink->eos_detect_thread_handle = NULL;
}
GST_DEBUG_OBJECT(sink, "before disconnect rlib");
render_disconnect(sink_priv->render_device_handle);
@@ -1036,6 +1075,117 @@
return ret;
}
+
+static void gst_show_vr_cb(gpointer data)
+{
+ bufferInfo *binfo = (bufferInfo*)data;
+ GstAmlVideoSink *sink = binfo->sink;
+ GST_DEBUG("unref vr360 buffer %p ",binfo->buf);
+ sink->rendered++;
+ if (binfo->buf)
+ gst_buffer_unref(binfo->buf);
+ free(binfo);
+}
+
+static gboolean gst_aml_video_sink_show_vr_frame(GstAmlVideoSink *sink, GstBuffer *buffer)
+{
+ bufferInfo *binfo;
+ GstStructure *s;
+ GstBuffer *buf;
+ gint fd0 = -1, fd1 = -1, fd2 = -1;
+ gint stride0, stride1, stride2;
+ GstVideoMeta *vmeta = NULL;
+ GST_DEBUG("pts: %lld %p", GST_BUFFER_PTS (buffer),buffer);
+
+ binfo= (bufferInfo*)malloc( sizeof(bufferInfo) );
+ if (binfo)
+ {
+ int offset1= 0, offset2 = 0;
+ guint n_mem = 0;
+ GstMemory *dma_mem0 = NULL;
+ GstMemory *dma_mem1 = NULL;
+ GstMemory *dma_mem2 = NULL;
+ gst_buffer_ref(buffer);
+ binfo->sink= sink;
+ binfo->buf = buffer;
+ n_mem = gst_buffer_n_memory(buffer);
+ vmeta = gst_buffer_get_video_meta(buffer);
+ if (vmeta == NULL)
+ {
+ GST_ERROR_OBJECT(sink, "not found video meta info");
+ gst_buffer_unref(binfo->buf);
+ free(binfo);
+ return FALSE;
+ }
+ GST_DEBUG("height:%d,width:%d,n_mem:%d",vmeta->height,vmeta->width,n_mem);
+
+ if (n_mem > 1)
+ {
+ dma_mem0 = gst_buffer_peek_memory(buffer, 0);
+ dma_mem1 = gst_buffer_peek_memory(buffer, 1);
+ fd0 = gst_dmabuf_memory_get_fd(dma_mem0);
+ fd1 = gst_dmabuf_memory_get_fd(dma_mem1);
+ GST_DEBUG("fd0:%d,fd1:%d,fd2:%d",fd0,fd1,fd2);
+ stride0 = vmeta->stride[0];
+ stride1 = vmeta->stride[1];
+ stride2 = 0;
+ if ( fd1 < 0 )
+ {
+ stride1= stride0;
+ offset1= stride0*vmeta->height;
+ }
+ if ( fd2 < 0 )
+ {
+ offset2= offset1+(vmeta->width*vmeta->height)/2;
+ stride2= stride0;
+ }
+ GST_DEBUG("stride0:%d,stride1:%d,stride2:%d",stride0,stride1,stride2);
+ GST_DEBUG("offset0:%d,offset1:%d,offset2:%d",offset2,offset2,offset2);
+
+ }
+ else
+ {
+ GST_DEBUG("single plane");
+ dma_mem0 = gst_buffer_peek_memory(buffer, 0);
+ fd0 = gst_dmabuf_memory_get_fd(dma_mem0);
+ stride0 = vmeta->stride[0];
+ offset1= stride0*vmeta->height;
+ }
+ }
+ s = gst_structure_new ("drmbuffer_info",
+ "fd0", G_TYPE_INT, fd0,
+ "fd1", G_TYPE_INT, fd1,
+ "fd2", G_TYPE_INT, fd2,
+ "stride0", G_TYPE_INT, stride0,
+ "stride1", G_TYPE_INT, stride1,
+ "stride2", G_TYPE_INT, stride2,
+ "width", G_TYPE_INT, vmeta->width,
+ "height", G_TYPE_INT, vmeta->height,
+ "format", G_TYPE_INT, FORMAT_NV21,
+ NULL);
+ GST_DEBUG("structure: %" GST_PTR_FORMAT,s);
+
+ buf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
+ (gpointer) binfo, sizeof(bufferInfo), 0, sizeof(bufferInfo),
+ (gpointer) binfo, gst_show_vr_cb);
+ if (!buf)
+ {
+ GST_ERROR_OBJECT(sink, "new buffer fail!");
+ gst_buffer_unref(buf);
+ gst_buffer_unref(binfo->buf);
+ free(binfo);
+ return FALSE;;
+ }
+ gst_buffer_add_protection_meta(buf, s);
+ GST_BUFFER_PTS (buf) = GST_BUFFER_PTS(buffer);
+ GST_DEBUG("pts: %lld, %p", GST_BUFFER_PTS (buf),buf);
+ g_signal_emit (G_OBJECT(sink),g_signals[SIGNAL_DECODEDBUFFER],0,buf);
+ gst_buffer_unref(buf);
+ return TRUE;
+
+}
+
+
static GstFlowReturn gst_aml_video_sink_show_frame(GstVideoSink *vsink, GstBuffer *buffer)
{
GstAmlVideoSink *sink = GST_AML_VIDEO_SINK(vsink);
@@ -1068,6 +1218,37 @@
GST_LOG_OBJECT(sink, "get preroll buffer 1st time, buf:%p", buffer);
sink_priv->preroll_buffer = buffer;
}
+ GST_INFO_OBJECT(sink, "sink->enable_decoded_buffer_signal:%d",
+ sink->enable_decoded_buffer_signal);
+
+ if (sink->enable_decoded_buffer_signal)
+ {
+ if (!gst_aml_video_sink_check_buf(sink, buffer))
+ {
+ GST_ERROR_OBJECT(sink, "buf out of segment return");
+ goto ret;
+ }
+
+ if (!gst_aml_video_sink_show_vr_frame(sink,buffer))
+ {
+ GST_ERROR_OBJECT(sink, "can't play vr360 file!");
+ goto ret;
+ }
+ sink->queued++;
+ sink->quit_eos_detect_thread = FALSE;
+ if (sink->eos_detect_thread_handle == NULL )
+ {
+ GST_DEBUG_OBJECT(sink, "start eos detect thread");
+ sink->eos_detect_thread_handle = g_thread_new("video_sink_eos", eos_detection_thread, sink);
+ }
+ goto ret;
+ }
+
+ if (!gst_aml_video_sink_check_buf(sink, buffer))
+ {
+ GST_ERROR_OBJECT(sink, "buf out of segment return");
+ goto ret;
+ }
if (sink_priv->window_set.window_change)
{
@@ -1110,11 +1291,7 @@
render_set_value(sink_priv->render_device_handle, KEY_PIXEL_ASPECT_RATIO, &sink->pixel_aspect_ratio);
}
- if (!gst_aml_video_sink_check_buf(sink, buffer))
- {
- GST_ERROR_OBJECT(sink, "buf out of segment return");
- goto ret;
- }
+
tunnel_lib_buf_wrap = render_allocate_render_buffer_wrap(sink_priv->render_device_handle, BUFFER_FLAG_DMA_BUFFER);
if (!tunnel_lib_buf_wrap)
diff --git a/src/gstamlvideosink.h b/src/gstamlvideosink.h
index 865e893..6ced153 100644
--- a/src/gstamlvideosink.h
+++ b/src/gstamlvideosink.h
@@ -74,6 +74,7 @@
gboolean pixel_aspect_ratio_changed;
double pixel_aspect_ratio;
gboolean keep_last_frame_on_flush;
+ gboolean enable_decoded_buffer_signal;
GstAmlVideoSinkPrivate *priv;
};