From: Wim Taymans Date: Fri, 2 Mar 2012 10:01:44 +0000 (+0100) Subject: theoradec: move negotiation code around X-Git-Tag: 1.19.3~511^2~6727 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f9bdf436f90c92d1783554715903a92d7534e500;p=platform%2Fupstream%2Fgstreamer.git theoradec: move negotiation code around Move the format negotiation to the bufferpool negotiation. --- diff --git a/ext/theora/gsttheoradec.c b/ext/theora/gsttheoradec.c index c747370..7c7cd24 100644 --- a/ext/theora/gsttheoradec.c +++ b/ext/theora/gsttheoradec.c @@ -768,20 +768,107 @@ theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet) } static GstFlowReturn -theora_negotiate_pool (GstTheoraDec * dec) +theora_negotiate (GstTheoraDec * dec) { + GstVideoFormat format; GstQuery *query; GstBufferPool *pool; guint size, min, max, prefix, alignment; GstStructure *config; GstCaps *caps; - GstVideoInfo info; + GstVideoInfo info, cinfo; + + /* theora has: + * + * frame_width/frame_height : dimension of the encoded frame + * pic_width/pic_height : dimension of the visible part + * pic_x/pic_y : offset in encoded frame where visible part starts + */ + GST_DEBUG_OBJECT (dec, "frame dimension %dx%d, PAR %d/%d, fps %d/%d", + dec->info.frame_width, dec->info.frame_height, + dec->info.aspect_numerator, dec->info.aspect_denominator, + dec->info.fps_numerator, dec->info.fps_denominator); + GST_DEBUG_OBJECT (dec, "picture dimension %dx%d, offset %d:%d", + dec->info.pic_width, dec->info.pic_height, dec->info.pic_x, + dec->info.pic_y); + + switch (dec->info.pixel_fmt) { + case TH_PF_444: + dec->output_bpp = 24; + format = GST_VIDEO_FORMAT_Y444; + break; + case TH_PF_420: + dec->output_bpp = 12; /* Average bits per pixel. */ + format = GST_VIDEO_FORMAT_I420; + break; + case TH_PF_422: + dec->output_bpp = 16; + format = GST_VIDEO_FORMAT_Y42B; + break; + default: + goto invalid_format; + } + + if (dec->info.pic_width != dec->info.frame_width || + dec->info.pic_height != dec->info.frame_height || + dec->info.pic_x != 0 || dec->info.pic_y != 0) { + GST_DEBUG_OBJECT (dec, "we need to crop"); + dec->need_cropping = TRUE; + } else { + GST_DEBUG_OBJECT (dec, "no cropping needed"); + dec->need_cropping = FALSE; + } + + /* info contains the dimensions for the coded picture before cropping */ + gst_video_info_set_format (&info, format, dec->info.frame_width, + dec->info.frame_height); + info.fps_n = dec->info.fps_numerator; + info.fps_d = dec->info.fps_denominator; + /* calculate par + * the info.aspect_* values reflect PAR; + * 0:x and x:0 are allowed and can be interpreted as 1:1. + */ + if (dec->have_par) { + /* we had a par on the sink caps, override the encoded par */ + GST_DEBUG_OBJECT (dec, "overriding with input PAR %dx%d", dec->par_num, + dec->par_den); + info.par_n = dec->par_num; + info.par_d = dec->par_den; + } else { + /* take encoded par */ + info.par_n = dec->info.aspect_numerator; + info.par_d = dec->info.aspect_denominator; + } + if (info.par_n == 0 || info.par_d == 0) { + info.par_n = info.par_d = 1; + } + + /* these values are for all versions of the colorspace specified in the + * theora info */ + info.chroma_site = GST_VIDEO_CHROMA_SITE_JPEG; + info.colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235; + info.colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601; + info.colorimetry.transfer = GST_VIDEO_TRANSFER_BT709; + switch (dec->info.colorspace) { + case TH_CS_ITU_REC_470M: + info.colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M; + break; + case TH_CS_ITU_REC_470BG: + info.colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG; + break; + default: + info.colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN; + break; + } + + /* remove reconfigure flag now */ + gst_pad_check_reconfigure (dec->srcpad); /* for the output caps we always take the cropped dimensions */ - info = dec->vinfo; - gst_video_info_set_format (&info, GST_VIDEO_INFO_FORMAT (&info), + cinfo = info; + gst_video_info_set_format (&cinfo, GST_VIDEO_INFO_FORMAT (&info), dec->info.pic_width, dec->info.pic_height); - caps = gst_video_info_to_caps (&info); + caps = gst_video_info_to_caps (&cinfo); gst_pad_set_caps (dec->srcpad, caps); /* find a pool for the negotiated caps now */ @@ -805,6 +892,7 @@ theora_negotiate_pool (GstTheoraDec * dec) pool = NULL; dec->has_cropping = FALSE; } + GST_DEBUG_OBJECT (dec, "downstream cropping %d", dec->has_cropping); if (pool == NULL) { /* we did not get a pool, make one ourselves then */ @@ -816,16 +904,16 @@ theora_negotiate_pool (GstTheoraDec * dec) dec->pool = pool; if (dec->has_cropping) { - dec->outinfo = dec->vinfo; + dec->vinfo = info; /* we can crop, configure the pool with buffers of caps and size of the * decoded picture size and then crop them with metadata */ gst_caps_unref (caps); - caps = gst_video_info_to_caps (&dec->vinfo); + caps = gst_video_info_to_caps (&info); } else { /* no cropping, use cropped videoinfo */ - dec->outinfo = info; + dec->vinfo = cinfo; } - size = MAX (size, GST_VIDEO_INFO_SIZE (&dec->outinfo)); + size = MAX (size, GST_VIDEO_INFO_SIZE (&dec->vinfo)); config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set (config, caps, size, min, max, prefix, alignment); @@ -836,8 +924,6 @@ theora_negotiate_pool (GstTheoraDec * dec) * option and only activate it then. */ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - GST_DEBUG_OBJECT (dec, "downstream cropping %d", dec->has_cropping); - gst_buffer_pool_set_config (pool, config); /* and activate */ gst_buffer_pool_set_active (pool, TRUE); @@ -845,106 +931,23 @@ theora_negotiate_pool (GstTheoraDec * dec) gst_query_unref (query); return GST_FLOW_OK; + + /* ERRORS */ +invalid_format: + { + GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt); + return GST_FLOW_ERROR; + } } static GstFlowReturn theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet) { - GstVideoFormat format; - gint par_num, par_den; GstFlowReturn ret = GST_FLOW_OK; GList *walk; - GST_DEBUG_OBJECT (dec, "fps %d/%d, PAR %d/%d", - dec->info.fps_numerator, dec->info.fps_denominator, - dec->info.aspect_numerator, dec->info.aspect_denominator); - - /* calculate par - * the info.aspect_* values reflect PAR; - * 0:x and x:0 are allowed and can be interpreted as 1:1. - */ - if (dec->have_par) { - /* we had a par on the sink caps, override the encoded par */ - GST_DEBUG_OBJECT (dec, "overriding with input PAR"); - par_num = dec->par_num; - par_den = dec->par_den; - } else { - /* take encoded par */ - par_num = dec->info.aspect_numerator; - par_den = dec->info.aspect_denominator; - } - if (par_num == 0 || par_den == 0) { - par_num = par_den = 1; - } - /* theora has: - * - * frame_width/frame_height : dimension of the encoded frame - * pic_width/pic_height : dimension of the visible part - * pic_x/pic_y : offset in encoded frame where visible part starts - */ - GST_DEBUG_OBJECT (dec, "frame dimension %dx%d, PAR %d/%d", - dec->info.frame_width, dec->info.frame_height, par_num, par_den); - GST_DEBUG_OBJECT (dec, "picture dimension %dx%d, offset %d:%d", - dec->info.pic_width, dec->info.pic_height, dec->info.pic_x, - dec->info.pic_y); - - switch (dec->info.pixel_fmt) { - case TH_PF_444: - dec->output_bpp = 24; - format = GST_VIDEO_FORMAT_Y444; - break; - case TH_PF_420: - dec->output_bpp = 12; /* Average bits per pixel. */ - format = GST_VIDEO_FORMAT_I420; - break; - case TH_PF_422: - dec->output_bpp = 16; - format = GST_VIDEO_FORMAT_Y42B; - break; - default: - goto invalid_format; - } - - if (dec->info.pic_width != dec->info.frame_width || - dec->info.pic_height != dec->info.frame_height || - dec->info.pic_x != 0 || dec->info.pic_y != 0) { - GST_DEBUG_OBJECT (dec, "we need to crop"); - dec->need_cropping = TRUE; - } else { - GST_DEBUG_OBJECT (dec, "no cropping needed"); - dec->need_cropping = FALSE; - } - - /* our info contains the dimensions for the coded picture before cropping */ - gst_video_info_set_format (&dec->vinfo, format, dec->info.frame_width, - dec->info.frame_height); - dec->vinfo.fps_n = dec->info.fps_numerator; - dec->vinfo.fps_d = dec->info.fps_denominator; - dec->vinfo.par_n = par_num; - dec->vinfo.par_d = par_den; - - /* these values are for all versions of the colorspace specified in the - * theora info */ - dec->vinfo.chroma_site = GST_VIDEO_CHROMA_SITE_JPEG; - dec->vinfo.colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235; - dec->vinfo.colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601; - dec->vinfo.colorimetry.transfer = GST_VIDEO_TRANSFER_BT709; - switch (dec->info.colorspace) { - case TH_CS_ITU_REC_470M: - dec->vinfo.colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470M; - break; - case TH_CS_ITU_REC_470BG: - dec->vinfo.colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG; - break; - default: - dec->vinfo.colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN; - break; - } - - /* remove reconfigure flag now */ - gst_pad_check_reconfigure (dec->srcpad); - - theora_negotiate_pool (dec); + if ((ret = theora_negotiate (dec)) != GST_FLOW_OK) + goto negotiate_failed; /* done */ dec->decoder = th_decode_alloc (&dec->info, dec->setup); @@ -983,10 +986,10 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet) return ret; /* ERRORS */ -invalid_format: +negotiate_failed: { - GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt); - return GST_FLOW_ERROR; + GST_ERROR_OBJECT (dec, "failed to negotiate"); + return ret; } } @@ -1114,15 +1117,19 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out) GstVideoCropMeta *crop; gint offset_x, offset_y; - if (gst_pad_check_reconfigure (dec->srcpad)) - theora_negotiate_pool (dec); + if G_UNLIKELY + (gst_pad_check_reconfigure (dec->srcpad)) + if G_UNLIKELY + ((result = theora_negotiate (dec)) != GST_FLOW_OK) + goto negotiate_failed; result = gst_buffer_pool_acquire_buffer (dec->pool, out, NULL); if (G_UNLIKELY (result != GST_FLOW_OK)) goto no_buffer; - if (!gst_video_frame_map (&frame, &dec->outinfo, *out, GST_MAP_WRITE)) - goto invalid_frame; + if G_UNLIKELY + (!gst_video_frame_map (&frame, &dec->vinfo, *out, GST_MAP_WRITE)) + goto invalid_frame; if (!dec->has_cropping) { /* we need to crop the hard way */ @@ -1180,6 +1187,12 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out) return GST_FLOW_OK; /* ERRORS */ +negotiate_failed: + { + GST_DEBUG_OBJECT (dec, "could not negotiate, reason: %s", + gst_flow_get_name (result)); + return result; + } no_buffer: { GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s", diff --git a/ext/theora/gsttheoradec.h b/ext/theora/gsttheoradec.h index 6c671e1..e9fe1a8 100644 --- a/ext/theora/gsttheoradec.h +++ b/ext/theora/gsttheoradec.h @@ -70,7 +70,6 @@ struct _GstTheoraDec guint64 frame_nr; gboolean need_keyframe; GstVideoInfo vinfo; - GstVideoInfo outinfo; gint output_bpp; GstBufferPool *pool;