static GstFlowReturn gst_zebra_stripe_transform_frame_ip (GstVideoFilter * filter, GstVideoFrame * frame) { GstZebraStripe *zebrastripe = GST_ZEBRA_STRIPE (filter); int width = frame->info.width; int height = frame->info.height; int i, j; int threshold = zebrastripe->y_threshold; int t = zebrastripe->t; int offset = 0; int pixel_stride = 0, y_position = 0; GST_DEBUG_OBJECT (zebrastripe, "transform_frame_ip"); zebrastripe->t++; pixel_stride = GST_VIDEO_FORMAT_INFO_PSTRIDE (frame->info.finfo, 0); switch (frame->info.finfo->format) { case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_Y41B: case GST_VIDEO_FORMAT_Y444: case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_YV12: break; case GST_VIDEO_FORMAT_UYVY: offset = 1; break; case GST_VIDEO_FORMAT_AYUV: y_position = 1; break; default: g_assert_not_reached (); } for (j = 0; j < height; j++) { guint8 *data = (guint8 *) frame->data[0] + frame->info.stride[0] * j + offset; for (i = 0; i < width; i++) { if (data[pixel_stride * i + y_position] >= threshold) { if ((i + j + t) & 0x4) data[pixel_stride * i + y_position] = 16; } } } return GST_FLOW_OK; }
/** * gst_video_info_align: * @info: a #GstVideoInfo * @align: alignment parameters * * Adjust the offset and stride fields in @info so that the padding and * stride alignment in @align is respected. * * Extra padding will be added to the right side when stride alignment padding * is required and @align will be updated with the new padding values. */ void gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align) { const GstVideoFormatInfo *vinfo = info->finfo; gint width, height; gint padded_width, padded_height; gint i, n_planes; gboolean aligned; width = GST_VIDEO_INFO_WIDTH (info); height = GST_VIDEO_INFO_HEIGHT (info); GST_LOG ("padding %u-%ux%u-%u", align->padding_top, align->padding_left, align->padding_right, align->padding_bottom); n_planes = GST_VIDEO_INFO_N_PLANES (info); if (GST_VIDEO_FORMAT_INFO_HAS_PALETTE (vinfo)) n_planes--; /* first make sure the left padding does not cause alignment problems later */ do { GST_LOG ("left padding %u", align->padding_left); aligned = TRUE; for (i = 0; i < n_planes; i++) { gint hedge; /* this is the amout of pixels to add as left padding */ hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, i, align->padding_left); hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, i); GST_LOG ("plane %d, padding %d, alignment %u", i, hedge, align->stride_align[i]); aligned &= (hedge & align->stride_align[i]) == 0; } if (aligned) break; GST_LOG ("unaligned padding, increasing padding"); /* increase padded_width */ align->padding_left += align->padding_left & ~(align->padding_left - 1); } while (!aligned); /* add the padding */ padded_width = width + align->padding_left + align->padding_right; padded_height = height + align->padding_top + align->padding_bottom; do { GST_LOG ("padded dimension %u-%u", padded_width, padded_height); info->width = padded_width; info->height = padded_height; fill_planes (info); /* check alignment */ aligned = TRUE; for (i = 0; i < n_planes; i++) { GST_LOG ("plane %d, stride %d, alignment %u", i, info->stride[i], align->stride_align[i]); aligned &= (info->stride[i] & align->stride_align[i]) == 0; } if (aligned) break; GST_LOG ("unaligned strides, increasing dimension"); /* increase padded_width */ padded_width += padded_width & ~(padded_width - 1); } while (!aligned); align->padding_right = padded_width - width - align->padding_left; info->width = width; info->height = height; for (i = 0; i < n_planes; i++) { gint vedge, hedge, comp; /* Find the component for this plane, FIXME, we assume the plane number and * component number is the same for now, for scaling the dimensions this is * currently true for all formats but it might not be when adding new * formats. We might need to add a plane subsamling in the format info to * make this more generic or maybe use a plane -> component mapping. */ comp = i; hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp, align->padding_left); vedge = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp, align->padding_top); GST_DEBUG ("plane %d: comp: %d, hedge %d vedge %d align %d stride %d", i, comp, hedge, vedge, align->stride_align[i], info->stride[i]); info->offset[i] += (vedge * info->stride[i]) + (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp)); } }
static bool gst_vlc_video_info_from_vout( GstVideoInfo *p_info, GstVideoAlignment *p_align, GstCaps *p_caps, decoder_t *p_dec, picture_t *p_pic_info ) { const GstVideoFormatInfo *p_vinfo = p_info->finfo; picture_t *p_pic = NULL; int i; /* Ensure the queue is empty */ gst_vlc_dec_ensure_empty_queue( p_dec ); gst_video_info_align( p_info, p_align ); if( !gst_vlc_set_vout_fmt( p_info, p_align, p_caps, p_dec )) { msg_Err( p_dec, "failed to set output format to vout" ); return false; } /* Acquire a picture and release it. This is to get the picture * stride/offsets info for the Gstreamer decoder looking to use * downstream bufferpool directly; Zero-Copy */ if( !decoder_UpdateVideoFormat( p_dec ) ) p_pic = decoder_NewPicture( p_dec ); if( !p_pic ) { msg_Err( p_dec, "failed to acquire picture from vout; for pic info" ); return false; } /* reject if strides don't match */ for( i = 0; i < p_pic->i_planes; i++ ) if( p_info->stride[i] != p_pic->p[i].i_pitch ) goto strides_mismatch; p_info->offset[0] = 0; for( i = 1; i < p_pic->i_planes; i++ ) { p_info->offset[i] = p_info->offset[i-1] + p_pic->p[i-1].i_pitch * p_pic->p[i-1].i_lines; } GST_VIDEO_INFO_SIZE( p_info ) = p_info->offset[i-1] + p_pic->p[i-1].i_pitch * p_pic->p[i-1].i_lines; for( i = 0; i < p_pic->i_planes; i++ ) { int i_v_edge, i_h_edge; i_h_edge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH( p_vinfo, i, p_align->padding_left); i_v_edge = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT( p_vinfo, i, p_align->padding_top); p_info->offset[i] += ( i_v_edge * p_info->stride[i] ) + ( i_h_edge * GST_VIDEO_FORMAT_INFO_PSTRIDE( p_vinfo, i )); } memcpy( p_pic_info, p_pic, sizeof( picture_t )); picture_Release( p_pic ); return true; strides_mismatch: msg_Err( p_dec, "strides mismatch" ); picture_Release( p_pic ); return false; }