static GstFlowReturn gst_mse_chain_ref (GstPad * pad, GstBuffer * buffer) { GstMSE *fs; fs = GST_MSE (gst_pad_get_parent (pad)); GST_DEBUG ("chain ref"); g_mutex_lock (fs->lock); while (fs->buffer_ref) { GST_DEBUG ("waiting for ref buffer clear"); g_cond_wait (fs->cond, fs->lock); if (fs->cancel) { g_mutex_unlock (fs->lock); gst_object_unref (fs); return GST_FLOW_WRONG_STATE; } } fs->buffer_ref = buffer; g_cond_signal (fs->cond); g_mutex_unlock (fs->lock); gst_object_unref (fs); return GST_FLOW_OK; }
static GstFlowReturn gst_mse_chain_test (GstPad * pad, GstBuffer * buffer) { GstMSE *fs; GstFlowReturn ret; GstBuffer *buffer_ref; fs = GST_MSE (gst_pad_get_parent (pad)); GST_DEBUG_OBJECT (fs, "chain test"); g_mutex_lock (fs->lock); while (fs->buffer_ref == NULL) { GST_DEBUG_OBJECT (fs, "waiting for ref buffer"); g_cond_wait (fs->cond, fs->lock); if (fs->cancel) { g_mutex_unlock (fs->lock); gst_object_unref (fs); return GST_FLOW_WRONG_STATE; } } buffer_ref = fs->buffer_ref; fs->buffer_ref = NULL; g_cond_signal (fs->cond); g_mutex_unlock (fs->lock); if (1) { CogFrame *frame_ref; CogFrame *frame_test; double mse[3]; frame_ref = gst_cog_buffer_wrap (gst_buffer_ref (buffer_ref), fs->format, fs->width, fs->height); frame_test = gst_cog_buffer_wrap (gst_buffer_ref (buffer), fs->format, fs->width, fs->height); cog_frame_mse (frame_ref, frame_test, mse); GST_INFO ("mse %g %g %g", mse_to_db (mse[0], FALSE), mse_to_db (mse[1], TRUE), mse_to_db (mse[2], TRUE)); fs->luma_mse_sum += mse[0]; fs->chroma_mse_sum += 0.5 * (mse[1] + mse[2]); fs->n_frames++; cog_frame_unref (frame_ref); cog_frame_unref (frame_test); } ret = gst_pad_push (fs->srcpad, buffer); gst_buffer_unref (buffer_ref); gst_object_unref (fs); return ret; }
static void gst_mse_finalize (GObject * object) { GstMSE *fs = GST_MSE (object); g_mutex_free (fs->lock); g_cond_free (fs->cond); }
static gboolean gst_mse_set_caps (GstPad * pad, GstCaps * caps) { GstMSE *fs; fs = GST_MSE (gst_pad_get_parent (pad)); gst_video_format_parse_caps (caps, &fs->format, &fs->width, &fs->height); gst_object_unref (fs); return TRUE; }
static void gst_mse_finalize (GObject * object) { GstMSE *fs = GST_MSE (object); gst_object_unref (fs->srcpad); gst_object_unref (fs->sinkpad_ref); gst_object_unref (fs->sinkpad_test); g_mutex_free (fs->lock); g_cond_free (fs->cond); gst_buffer_replace (&fs->buffer_ref, NULL); GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); }
static GstCaps * gst_mse_getcaps (GstPad * pad) { GstMSE *fs; GstCaps *caps; GstCaps *icaps; GstCaps *peercaps; fs = GST_MSE (gst_pad_get_parent (pad)); caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); if (pad != fs->srcpad) { peercaps = gst_pad_peer_get_caps (fs->srcpad); if (peercaps) { icaps = gst_caps_intersect (caps, peercaps); gst_caps_unref (caps); gst_caps_unref (peercaps); caps = icaps; } } if (pad != fs->sinkpad_ref) { peercaps = gst_pad_peer_get_caps (fs->sinkpad_ref); if (peercaps) { icaps = gst_caps_intersect (caps, peercaps); gst_caps_unref (caps); gst_caps_unref (peercaps); caps = icaps; } } if (pad != fs->sinkpad_test) { peercaps = gst_pad_peer_get_caps (fs->sinkpad_test); if (peercaps) { icaps = gst_caps_intersect (caps, peercaps); gst_caps_unref (caps); gst_caps_unref (peercaps); caps = icaps; } } gst_object_unref (fs); return caps; }
static gboolean gst_mse_sink_event (GstPad * pad, GstEvent * event) { GstMSE *fs; fs = GST_MSE (gst_pad_get_parent (pad)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NEWSEGMENT: { gboolean update; double rate; double applied_rate; GstFormat format; gint64 start, stop, position; gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate, &format, &start, &stop, &position); GST_DEBUG ("new_segment %d %g %g %d %" G_GINT64_FORMAT " %" G_GINT64_FORMAT " %" G_GINT64_FORMAT, update, rate, applied_rate, format, start, stop, position); } break; case GST_EVENT_FLUSH_START: GST_DEBUG ("flush start"); fs->cancel = TRUE; break; case GST_EVENT_FLUSH_STOP: GST_DEBUG ("flush stop"); fs->cancel = FALSE; break; default: break; } gst_pad_push_event (fs->srcpad, event); gst_object_unref (fs); return TRUE; }
static void gst_mse_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstMSE *fs = GST_MSE (object); switch (prop_id) { case LUMA_PSNR: g_value_set_double (value, mse_to_db (fs->luma_mse_sum / fs->n_frames, FALSE)); break; case CHROMA_PSNR: g_value_set_double (value, mse_to_db (fs->chroma_mse_sum / fs->n_frames, TRUE)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }