From: Sebastian Dröge Date: Mon, 31 Dec 2012 10:56:51 +0000 (+0100) Subject: mfc: Recreate fimc context if settings change X-Git-Tag: 1.19.3~507^2~14290 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9739f58a7fbf64ea2d08796a7257006ceef46505;p=platform%2Fupstream%2Fgstreamer.git mfc: Recreate fimc context if settings change --- diff --git a/sys/mfc/gstmfcdec.c b/sys/mfc/gstmfcdec.c index c466170..84a5562 100644 --- a/sys/mfc/gstmfcdec.c +++ b/sys/mfc/gstmfcdec.c @@ -123,7 +123,6 @@ static gboolean gst_mfc_dec_start (GstVideoDecoder * decoder) { GstMFCDec *self = GST_MFC_DEC (decoder); - Fimc *fimc; GST_DEBUG_OBJECT (self, "Starting"); @@ -153,15 +152,6 @@ gst_mfc_dec_start (GstVideoDecoder * decoder) return FALSE; } - fimc = fimc_new (); - - if (!fimc) { - GST_ELEMENT_ERROR (self, LIBRARY, INIT, - ("Failed to initialize FIMC context"), (NULL)); - return FALSE; - } - self->fimc = fimc; - return TRUE; } @@ -381,29 +371,20 @@ enqueue_error: } static gboolean -gst_mfc_dec_negotiate (GstVideoDecoder * decoder) +gst_mfc_dec_create_fimc (GstMFCDec * self, GstVideoCodecState * state) { - GstMFCDec *self = GST_MFC_DEC (decoder); - Fimc *fimc = self->fimc; - GstVideoCodecState *state; - GstCaps *allowed_caps; - GstVideoFormat format = GST_VIDEO_FORMAT_I420; + Fimc *fimc; FimcColorFormat fimc_format; - allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self)); - allowed_caps = gst_caps_truncate (allowed_caps); - allowed_caps = gst_caps_fixate (allowed_caps); - if (!gst_caps_is_empty (allowed_caps)) { - const gchar *format_str; - GstStructure *s = gst_caps_get_structure (allowed_caps, 0); - - format_str = gst_structure_get_string (s, "format"); - if (format_str) - format = gst_video_format_from_string (format_str); + fimc = self->fimc; + if (fimc) { + fimc_free (fimc); + self->fimc = fimc = NULL; } - gst_caps_unref (allowed_caps); - switch (format) { + fimc = fimc_new (); + + switch (state->info.finfo->format) { case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: fimc_format = FIMC_COLOR_FORMAT_YUV420P; @@ -416,8 +397,6 @@ gst_mfc_dec_negotiate (GstVideoDecoder * decoder) break; } - fimc_release_src_buffers (fimc); - if (fimc_set_src_format (fimc, FIMC_COLOR_FORMAT_YUV420SPT, self->width, self->height, self->src_stride, self->crop_left, self->crop_top, self->crop_width, self->crop_height) < 0) @@ -426,7 +405,7 @@ gst_mfc_dec_negotiate (GstVideoDecoder * decoder) if (fimc_request_src_buffers (fimc) < 0) goto fimc_src_requestbuffers_error; - fimc_release_dst_buffers (fimc); + self->fimc = fimc; self->dst[0] = NULL; self->dst[1] = NULL; self->dst[2] = NULL; @@ -436,24 +415,13 @@ gst_mfc_dec_negotiate (GstVideoDecoder * decoder) self->fimc_format = fimc_format; - state = - gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self), - format, self->crop_width, self->crop_height, self->input_state); - - gst_video_codec_state_unref (state); - - return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder); - - - GST_DEBUG_OBJECT (self, - "Got direct output buffer: %p [%d], %p [%d], %p [%d]", self->dst[0], - self->dst_stride[0], self->dst[1], self->dst_stride[1], self->dst[2], - self->dst_stride[2]); + return TRUE; fimc_src_error: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, ("Failed to set FIMC source parameters"), (NULL)); + fimc_free (fimc); return FALSE; } @@ -461,10 +429,41 @@ fimc_src_requestbuffers_error: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, ("Failed to request FIMC source buffers"), (NULL)); + fimc_free (fimc); return FALSE; } } +static gboolean +gst_mfc_dec_negotiate (GstVideoDecoder * decoder) +{ + GstMFCDec *self = GST_MFC_DEC (decoder); + GstVideoCodecState *state; + GstCaps *allowed_caps; + GstVideoFormat format = GST_VIDEO_FORMAT_I420; + + allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self)); + allowed_caps = gst_caps_truncate (allowed_caps); + allowed_caps = gst_caps_fixate (allowed_caps); + if (!gst_caps_is_empty (allowed_caps)) { + const gchar *format_str; + GstStructure *s = gst_caps_get_structure (allowed_caps, 0); + + format_str = gst_structure_get_string (s, "format"); + if (format_str) + format = gst_video_format_from_string (format_str); + } + gst_caps_unref (allowed_caps); + + state = + gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self), + format, self->crop_width, self->crop_height, self->input_state); + + gst_video_codec_state_unref (state); + + return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder); +} + static GstFlowReturn gst_mfc_dec_fill_outbuf (GstMFCDec * self, GstBuffer * outbuf, struct mfc_buffer *mfc_outbuf, GstVideoCodecState * state) @@ -490,8 +489,11 @@ gst_mfc_dec_fill_outbuf (GstMFCDec * self, GstBuffer * outbuf, && strcmp (mem->allocator->mem_type, "GstEGLImage") == 0) { void *dst[3]; - if (self->mmap) { - fimc_release_dst_buffers (fimc); + if (self->mmap || !self->fimc) { + if (!gst_mfc_dec_create_fimc (self, state)) + goto fimc_create_error; + + fimc = self->fimc; if (self->format == GST_VIDEO_FORMAT_NV12) { self->dst_stride[0] = GST_ROUND_UP_4 (self->width); @@ -526,13 +528,15 @@ gst_mfc_dec_fill_outbuf (GstMFCDec * self, GstBuffer * outbuf, if (fimc_convert (fimc, (void **) mfc_outbuf_comps, (void **) dst) < 0) goto fimc_convert_error; } else { - if (!self->mmap) { - fimc_release_dst_buffers (fimc); + if (!self->mmap || !self->fimc) { + if (!gst_mfc_dec_create_fimc (self, state)) + goto fimc_create_error; self->dst_stride[0] = 0; self->dst_stride[1] = 0; self->dst_stride[2] = 0; self->mmap = TRUE; + fimc = self->fimc; } if (!self->dst[0]) { @@ -601,6 +605,11 @@ frame_map_error: goto done; } +fimc_create_error: + { + ret = GST_FLOW_ERROR; + goto done; + } fimc_dst_error: {