+#if !defined(TIZEN_MULTIMEDIA_PIXMAP_SUPPORT)
+void TizenVideoDecodeAccelerator::Impl::OnSinkCapChanged(
+ GstPad* sink_pad, GParamSpec* gparamspec, void* user_data) {
+ content::TizenVideoDecodeAccelerator::Impl* impl =
+ static_cast<TizenVideoDecodeAccelerator::Impl*>(user_data);
+ int width = 0, height = 0;
+#if GST_VERSION_MAJOR == 1
+ GstCaps* caps = gst_pad_get_current_caps(GST_PAD(sink_pad));
+ if (caps) {
+ GstVideoInfo info;
+ gst_video_info_init(&info);
+ if (gst_video_info_from_caps(&info, caps)) {
+ if ((impl->caps_width_ != width) || (impl->caps_height_ != height)) {
+ impl->caps_width_ = info.width;
+ impl->caps_height_ = info.height;
+ }
+ }
+ }
+#else
+ if (gst_video_get_size(sink_pad, &width, &height)) {
+ if ((impl->caps_width_ != width) || (impl->caps_height_ != height)) {
+ impl->caps_width_ = width;
+ impl->caps_height_ = height;
+ }
+ }
+#endif
+}
+
+GstFlowReturn TizenVideoDecodeAccelerator::Impl::OnDecoded(
+ GstAppSink* sink, gpointer app_data) {
+ GstBuffer* gst_output_buf = NULL;
+ content::TizenVideoDecodeAccelerator::Impl* self =
+ static_cast<TizenVideoDecodeAccelerator::Impl*>(app_data);
+ // FIXME: SONAL
+ // Once OnSinkCapChanged callback startes coming dont find height
+ // and width for all buffers, move this code under if block
+#if GST_VERSION_MAJOR == 1
+ GstSample* sample = gst_app_sink_pull_sample(GST_APP_SINK(sink));
+ gst_output_buf = gst_sample_get_buffer(sample);
+ GstMapInfo map;
+ if (!gst_buffer_map(gst_output_buf, &map, GST_MAP_READ))
+ LOG (ERROR) << "Decoded Buffer contains invalid or no info!";
+ GstCaps* caps = gst_sample_get_caps(sample);
+#else
+ gst_output_buf = gst_app_sink_pull_buffer(GST_APP_SINK(sink));
+ GstCaps* caps = gst_buffer_get_caps(GST_BUFFER(gst_output_buf));
+#endif
+ if (!self->caps_width_ || !self->caps_height_) {
+ if (!caps) {
+ LOG(ERROR) << __FUNCTION__ << "Could not fetch caps from buffer";
+ gst_buffer_unref(gst_output_buf);
+ return GST_FLOW_ERROR;
+ } else {
+ // No need to unref |GstStructure|
+ const GstStructure* str = gst_caps_get_structure(caps, 0);
+ if (!str) {
+ gst_buffer_unref(gst_output_buf);
+ gst_caps_unref(caps);
+ return GST_FLOW_ERROR;
+ }
+ if (!gst_structure_get_int(str, "width", &self->caps_width_) ||
+ !gst_structure_get_int(str, "height", &self->caps_height_)) {
+ LOG(ERROR) << "Buffer information could not be obtained";
+ gst_buffer_unref(gst_output_buf);
+ gst_caps_unref(caps);
+ return GST_FLOW_ERROR;
+ }
+ gst_caps_unref(caps);
+ }
+ }
+
+ if (gst_output_buf) {
+#if GST_VERSION_MAJOR == 1
+ if (map.data) {
+#else
+ if (gst_output_buf->data) {
+#endif
+ gfx::Rect frame_size =
+ gfx::Rect(self->caps_width_, self->caps_height_);
+ self->gst_thread_.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&TizenVideoDecodeAccelerator::Impl::DeliverVideoFrame,
+ base::Unretained(self),
+ gst_output_buf,
+ self->bitstream_buffer_id_,
+ frame_size));
+ self->bitstream_buffer_id_ = (self->bitstream_buffer_id_ + 1) & ID_LAST;
+ }
+ } else {
+ gst_buffer_unref(gst_output_buf);
+#if GST_VERSION_MAJOR == 1
+ gst_sample_unref(sample);
+#endif
+ LOG(ERROR) << __FUNCTION__
+ << " DECODING FRAME FAILED : frame_id"
+ << self->bitstream_buffer_id_;
+ }
+#if GST_VERSION_MAJOR == 1
+ gst_buffer_unmap(gst_output_buf, &map);
+#endif
+ return GST_FLOW_OK;
+}
+
+
+void TizenVideoDecodeAccelerator::Impl::CreateAppSinkElement() {
+ GstAppSinkCallbacks appsink_callbacks =
+ {NULL, NULL, &OnDecoded, NULL};
+
+ if (!(sink_ = gst_element_factory_make("appsink", "sink"))) {
+ LOG(ERROR) << __FUNCTION__ << "Appsink could not be created";
+ return;
+ }
+ gst_app_sink_set_callbacks(GST_APP_SINK(sink_),
+ &appsink_callbacks,
+ static_cast<gpointer>(this),
+ NULL);
+ gst_app_sink_set_max_buffers(GST_APP_SINK(sink_), 1);
+}
+
+void TizenVideoDecodeAccelerator::Impl::DeliverVideoFrame(
+ GstBuffer* buffer,
+ int32 bitstream_buffer_id,
+ gfx::Rect frame_size) {
+ base::SharedMemory shared_memory;
+ base::SharedMemoryHandle shared_memory_handle;
+
+#if GST_VERSION_MAJOR == 1
+ GstMapInfo map;
+ if (!gst_buffer_map(buffer, &map, GST_MAP_READ)) {
+ LOG (ERROR) << "Encoded Buffer contains invalid or no info.!";
+ return;
+ }
+ uint32 buffer_size = map.size;
+#else
+ uint32 buffer_size = buffer->size;
+#endif
+ if (!shared_memory.CreateAndMapAnonymous(buffer_size)) {
+ LOG (ERROR) << "Shared Memory creation failed.";
+ } else {
+ if (!shared_memory.ShareToProcess(base::GetCurrentProcessHandle(),
+ &shared_memory_handle)) {
+ LOG(ERROR) << __FUNCTION__ << "Could not get handle of Shared Memory";
+ } else {
+ memcpy(shared_memory.memory(),
+#if GST_VERSION_MAJOR == 1
+ map.data,
+#else
+ GST_BUFFER_DATA(buffer),
+#endif
+ buffer_size);
+ io_message_loop_proxy_->PostTask(
+ FROM_HERE,
+ base::Bind(&media::VideoDecodeAccelerator::Client::NotifyDecodeDone,
+ io_client_weak_factory_->GetWeakPtr(),
+ shared_memory_handle,
+ bitstream_buffer_id_,
+ buffer_size,
+ frame_size));
+ }
+ }
+#if GST_VERSION_MAJOR == 1
+ gst_buffer_unmap(buffer, &map);
+#endif
+ gst_buffer_unref(buffer);
+}
+#endif
+