summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2012-10-09 10:13:32 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-10-15 16:28:42 +0200
commita870e6a5c30dd85240fe75c7409cc1cf1b86541d (patch)
treef037d2b82facbcedf7f4843dd80eb8154eee8f9d /sys
parent7341ed62fa2034ebfb9a8a7d7c8a1026dc603b91 (diff)
Check output format metadata some more
And implement workaround for NVidia Tegra 3 not setting the slice_height. Thanks to Josep Torra for debugging this issue.
Diffstat (limited to 'sys')
-rw-r--r--sys/androidmedia/gstamcvideodec.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/sys/androidmedia/gstamcvideodec.c b/sys/androidmedia/gstamcvideodec.c
index 7eace20fc..4e6a33ca3 100644
--- a/sys/androidmedia/gstamcvideodec.c
+++ b/sys/androidmedia/gstamcvideodec.c
@@ -675,6 +675,11 @@ gst_amc_video_dec_set_src_caps (GstAmcVideoDec * self, GstAmcFormat * format)
return FALSE;
}
+ if (width == 0 || height == 0) {
+ GST_ERROR_OBJECT (self, "Height or width not set");
+ return FALSE;
+ }
+
if (crop_bottom)
height = height - (height - crop_bottom - 1);
if (crop_top)
@@ -718,6 +723,7 @@ static gboolean
gst_amc_video_dec_fill_buffer (GstAmcVideoDec * self, gint idx,
const GstAmcBufferInfo * buffer_info, GstBuffer * outbuf)
{
+ GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
GstAmcBuffer *buf = &self->output_buffers[idx];
GstVideoCodecState *state =
gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self));
@@ -748,32 +754,50 @@ gst_amc_video_dec_fill_buffer (GstAmcVideoDec * self, gint idx,
case COLOR_FormatYUV420Planar:{
gint i, j, height;
guint8 *src, *dest;
+ gint stride, slice_height;
gint src_stride, dest_stride;
gint row_length;
+ stride = self->stride;
+ if (stride == 0) {
+ GST_ERROR_OBJECT (self, "Stride not set");
+ goto done;
+ }
+
+ slice_height = self->slice_height;
+ if (slice_height == 0) {
+ /* NVidia Tegra 3 on Nexus 7 does not set this */
+ if (g_str_has_prefix (klass->codec_info->name, "OMX.Nvidia.")) {
+ slice_height = GST_ROUND_UP_32 (self->height);
+ } else {
+ GST_ERROR_OBJECT (self, "Slice height not set");
+ goto done;
+ }
+ }
+
for (i = 0; i < 3; i++) {
if (i == 0) {
- src_stride = self->stride;
+ src_stride = stride;
dest_stride = GST_VIDEO_INFO_COMP_STRIDE (info, i);
} else {
- src_stride = (self->stride + 1) / 2;
+ src_stride = (stride + 1) / 2;
dest_stride = GST_VIDEO_INFO_COMP_STRIDE (info, i);
}
src = buf->data + buffer_info->offset;
if (i == 0) {
- src += self->crop_top * self->stride;
+ src += self->crop_top * stride;
src += self->crop_left;
row_length = self->width;
} else if (i > 0) {
- src += self->slice_height * self->stride;
+ src += slice_height * stride;
src += self->crop_top * src_stride;
src += self->crop_left / 2;
row_length = (self->width + 1) / 2;
}
if (i == 2)
- src += ((self->slice_height + 1) / 2) * ((self->stride + 1) / 2);
+ src += ((slice_height + 1) / 2) * ((stride + 1) / 2);
dest = GST_BUFFER_DATA (outbuf) + GST_VIDEO_INFO_COMP_OFFSET (info, i);
height = GST_VIDEO_INFO_COMP_HEIGHT (info, i);
@@ -794,6 +818,12 @@ gst_amc_video_dec_fill_buffer (GstAmcVideoDec * self, gint idx,
gint src_stride, dest_stride;
gint row_length;
+ /* This should always be set */
+ if (self->stride == 0 || self->slice_height == 0) {
+ GST_ERROR_OBJECT (self, "Stride or slice height not set");
+ goto done;
+ }
+
/* FIXME: This does not work for odd widths or heights
* but might as well be a bug in the codec */
for (i = 0; i < 2; i++) {
@@ -832,6 +862,12 @@ gst_amc_video_dec_fill_buffer (GstAmcVideoDec * self, gint idx,
gint src_stride, dest_stride;
gint row_length;
+ /* This should always be set */
+ if (self->stride == 0 || self->slice_height == 0) {
+ GST_ERROR_OBJECT (self, "Stride or slice height not set");
+ goto done;
+ }
+
/* FIXME: This is untested! */
for (i = 0; i < 2; i++) {