1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
From b2975883315542cc9beead18a6bfe3bf1dab06b7 Mon Sep 17 00:00:00 2001
From: Kazunori Kobayashi <kkobayas@igel.co.jp>
Date: Tue, 16 Oct 2012 16:42:17 +0900
Subject: [PATCH 21/31] videocrop: support cropping interlaced images
This patch supports it by adjusting the subbuffer offset and
chroma_byte_offset in caps.
---
gst/videocrop/gstvideocrop.c | 43 ++++++++++++++++++++++++++++++++++++------
gst/videocrop/gstvideocrop.h | 2 ++
2 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
index dbebcfa..4d2a027 100644
--- a/gst/videocrop/gstvideocrop.c
+++ b/gst/videocrop/gstvideocrop.c
@@ -679,20 +679,44 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
guint ratio_y_c;
GstStructure *structure;
gint tile_height;
+ gboolean interlaced;
+ const gchar *layout;
+
+ structure = gst_caps_get_structure (caps, 0);
+ if (gst_structure_get_boolean (structure, "interlaced", &interlaced) &&
+ (interlaced == TRUE) &&
+ ((layout =
+ gst_structure_get_string (structure, "field-layout")) != NULL)
+ && (strcmp (layout, "sequential") == 0))
+ vcrop->interlaced = TRUE;
+ else
+ vcrop->interlaced = FALSE;
rowstride = img_details.stride;
/* Y plane / UV plane */
ratio_y_c = img_details.uv_off / (img_details.size - img_details.uv_off);
- delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c;
+ if (vcrop->interlaced)
+ delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c / 2;
+ else
+ delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c;
/* set tile boudary for T/L addressing */
- structure = gst_caps_get_structure (caps, 0);
if (gst_structure_get_int (structure, "tile-height", &tile_height)) {
+ gint tile_y_offs, tile_c_offs;
+
+ if (vcrop->interlaced) {
+ tile_y_offs = vcrop->crop_top / 2 % tile_height;
+ tile_c_offs = vcrop->crop_top / ratio_y_c / 2 % tile_height;
+ } else {
+ tile_y_offs = vcrop->crop_top % tile_height;
+ tile_c_offs = vcrop->crop_top / ratio_y_c % tile_height;
+ }
+
gst_structure_set (new_structure, "tile_boundary_y_offset",
- G_TYPE_INT, vcrop->crop_top % tile_height, NULL);
+ G_TYPE_INT, tile_y_offs, NULL);
gst_structure_set (new_structure, "tile_boundary_c_offset",
- G_TYPE_INT, vcrop->crop_top / ratio_y_c % tile_height, NULL);
+ G_TYPE_INT, tile_c_offs, NULL);
}
} else {
rowstride = 0;
@@ -830,8 +854,15 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
sub_offset = (vcrop->crop_top * vcrop->in.stride) +
(ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel);
} else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
- ROUND_DOWN_2 (vcrop->crop_left);
+ GstStructure *structure;
+
+ structure = gst_caps_get_structure (caps, 0);
+ if (vcrop->interlaced)
+ sub_offset = (vcrop->crop_top / 2 * vcrop->in.stride) +
+ ROUND_DOWN_2 (vcrop->crop_left);
+ else
+ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+ ROUND_DOWN_2 (vcrop->crop_left);
} else {
GST_LOG_OBJECT (vcrop,
"can't do zero-copy cropping except for packed format");
diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
index 1534b3d..a72cacb 100644
--- a/gst/videocrop/gstvideocrop.h
+++ b/gst/videocrop/gstvideocrop.h
@@ -83,6 +83,8 @@ struct _GstVideoCrop
/* query for rowstride */
GstQueryType query_type_stride;
+
+ gboolean interlaced;
};
struct _GstVideoCropClass
--
1.7.9.5
|