Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tim-Philipp Müller
gst-plugins-good
Commits
a0fd92df
Commit
a0fd92df
authored
Apr 07, 2010
by
Sebastian Dröge
Browse files
videobox: Add support for direct RGB<->AYUV conversion
parent
84ce6f2a
Changes
1
Hide whitespace changes
Inline
Side-by-side
gst/videobox/gstvideobox.c
View file @
a0fd92df
...
...
@@ -900,6 +900,196 @@ copy_rgb32 (guint i_alpha, GstVideoFormat dest_format, guint8 * dest,
}
}
static
void
copy_rgb32_ayuv
(
guint
i_alpha
,
GstVideoFormat
dest_format
,
guint8
*
dest
,
gboolean
dest_sdtv
,
gint
dest_width
,
gint
dest_height
,
gint
dest_x
,
gint
dest_y
,
GstVideoFormat
src_format
,
const
guint8
*
src
,
gboolean
src_sdtv
,
gint
src_width
,
gint
src_height
,
gint
src_x
,
gint
src_y
,
gint
w
,
gint
h
)
{
gint
i
,
j
;
gint
src_stride
,
dest_stride
;
gboolean
in_alpha
;
gint
in_bpp
;
gint
p_in
[
4
];
gboolean
packed_in
=
(
src_format
==
GST_VIDEO_FORMAT_RGB
||
src_format
==
GST_VIDEO_FORMAT_BGR
);
gint
matrix
[
12
];
gint
a
;
gint
y
,
u
,
v
;
gint
r
,
g
,
b
;
src_stride
=
(
packed_in
)
?
GST_ROUND_UP_4
(
3
*
src_width
)
:
4
*
src_width
;
dest_stride
=
4
*
dest_width
;
in_bpp
=
(
packed_in
)
?
3
:
4
;
_argb_order
(
src_format
,
p_in
,
&
in_alpha
);
memcpy
(
matrix
,
(
dest_sdtv
)
?
cog_rgb_to_ycbcr_matrix_8bit_sdtv
:
cog_rgb_to_ycbcr_matrix_8bit_hdtv
,
12
*
sizeof
(
gint
));
dest
=
dest
+
dest_y
*
dest_stride
+
dest_x
*
4
;
src
=
src
+
src_y
*
src_stride
+
src_x
*
in_bpp
;
if
(
in_alpha
)
{
w
*=
4
;
for
(
i
=
0
;
i
<
h
;
i
++
)
{
for
(
j
=
0
;
j
<
w
;
j
+=
4
)
{
a
=
(
src
[
j
+
p_in
[
0
]]
*
i_alpha
)
>>
8
;
r
=
src
[
j
+
p_in
[
1
]];
g
=
src
[
j
+
p_in
[
2
]];
b
=
src
[
j
+
p_in
[
3
]];
y
=
APPLY_MATRIX
(
matrix
,
0
,
r
,
g
,
b
);
u
=
APPLY_MATRIX
(
matrix
,
1
,
r
,
g
,
b
);
v
=
APPLY_MATRIX
(
matrix
,
2
,
r
,
g
,
b
);
dest
[
j
+
0
]
=
a
;
dest
[
j
+
1
]
=
CLAMP
(
y
,
0
,
255
);
dest
[
j
+
2
]
=
CLAMP
(
u
,
0
,
255
);
dest
[
j
+
3
]
=
CLAMP
(
v
,
0
,
255
);
}
dest
+=
dest_stride
;
src
+=
src_stride
;
}
}
else
if
(
!
packed_in
)
{
w
*=
4
;
for
(
i
=
0
;
i
<
h
;
i
++
)
{
for
(
j
=
0
;
j
<
w
;
j
+=
4
)
{
a
=
i_alpha
&
0xff
;
r
=
src
[
j
+
p_in
[
1
]];
g
=
src
[
j
+
p_in
[
2
]];
b
=
src
[
j
+
p_in
[
3
]];
y
=
APPLY_MATRIX
(
matrix
,
0
,
r
,
g
,
b
);
u
=
APPLY_MATRIX
(
matrix
,
1
,
r
,
g
,
b
);
v
=
APPLY_MATRIX
(
matrix
,
2
,
r
,
g
,
b
);
dest
[
j
+
0
]
=
a
;
dest
[
j
+
1
]
=
CLAMP
(
y
,
0
,
255
);
dest
[
j
+
2
]
=
CLAMP
(
u
,
0
,
255
);
dest
[
j
+
3
]
=
CLAMP
(
v
,
0
,
255
);
}
dest
+=
dest_stride
;
src
+=
src_stride
;
}
}
else
{
for
(
i
=
0
;
i
<
h
;
i
++
)
{
for
(
j
=
0
;
j
<
w
;
j
++
)
{
a
=
i_alpha
&
0xff
;
r
=
src
[
in_bpp
*
j
+
p_in
[
1
]];
g
=
src
[
in_bpp
*
j
+
p_in
[
2
]];
b
=
src
[
in_bpp
*
j
+
p_in
[
3
]];
y
=
APPLY_MATRIX
(
matrix
,
0
,
r
,
g
,
b
);
u
=
APPLY_MATRIX
(
matrix
,
1
,
r
,
g
,
b
);
v
=
APPLY_MATRIX
(
matrix
,
2
,
r
,
g
,
b
);
dest
[
4
*
j
+
0
]
=
a
;
dest
[
4
*
j
+
1
]
=
CLAMP
(
y
,
0
,
255
);
dest
[
4
*
j
+
2
]
=
CLAMP
(
u
,
0
,
255
);
dest
[
4
*
j
+
3
]
=
CLAMP
(
v
,
0
,
255
);
}
dest
+=
dest_stride
;
src
+=
src_stride
;
}
}
}
static
void
copy_ayuv_rgb32
(
guint
i_alpha
,
GstVideoFormat
dest_format
,
guint8
*
dest
,
gboolean
dest_sdtv
,
gint
dest_width
,
gint
dest_height
,
gint
dest_x
,
gint
dest_y
,
GstVideoFormat
src_format
,
const
guint8
*
src
,
gboolean
src_sdtv
,
gint
src_width
,
gint
src_height
,
gint
src_x
,
gint
src_y
,
gint
w
,
gint
h
)
{
gint
i
,
j
;
gint
src_stride
,
dest_stride
;
gboolean
out_alpha
;
gint
out_bpp
;
gint
p_out
[
4
];
gboolean
packed_out
=
(
dest_format
==
GST_VIDEO_FORMAT_RGB
||
dest_format
==
GST_VIDEO_FORMAT_BGR
);
gint
matrix
[
12
];
gint
a
;
gint
y
,
u
,
v
;
gint
r
,
g
,
b
;
dest_stride
=
(
packed_out
)
?
GST_ROUND_UP_4
(
3
*
dest_width
)
:
4
*
dest_width
;
src_stride
=
4
*
src_width
;
out_bpp
=
(
packed_out
)
?
3
:
4
;
_argb_order
(
dest_format
,
p_out
,
&
out_alpha
);
memcpy
(
matrix
,
(
src_sdtv
)
?
cog_ycbcr_to_rgb_matrix_8bit_sdtv
:
cog_ycbcr_to_rgb_matrix_8bit_hdtv
,
12
*
sizeof
(
gint
));
dest
=
dest
+
dest_y
*
dest_stride
+
dest_x
*
out_bpp
;
src
=
src
+
src_y
*
src_stride
+
src_x
*
4
;
if
(
out_alpha
)
{
w
*=
4
;
for
(
i
=
0
;
i
<
h
;
i
++
)
{
for
(
j
=
0
;
j
<
w
;
j
+=
4
)
{
a
=
(
src
[
j
+
0
]
*
i_alpha
)
>>
8
;
y
=
src
[
j
+
1
];
u
=
src
[
j
+
2
];
v
=
src
[
j
+
3
];
r
=
APPLY_MATRIX
(
matrix
,
0
,
y
,
u
,
v
);
g
=
APPLY_MATRIX
(
matrix
,
1
,
y
,
u
,
v
);
b
=
APPLY_MATRIX
(
matrix
,
2
,
y
,
u
,
v
);
dest
[
j
+
p_out
[
0
]]
=
a
;
dest
[
j
+
p_out
[
1
]]
=
CLAMP
(
r
,
0
,
255
);
dest
[
j
+
p_out
[
2
]]
=
CLAMP
(
g
,
0
,
255
);
dest
[
j
+
p_out
[
3
]]
=
CLAMP
(
b
,
0
,
255
);
}
dest
+=
dest_stride
;
src
+=
src_stride
;
}
}
else
if
(
!
packed_out
)
{
w
*=
4
;
for
(
i
=
0
;
i
<
h
;
i
++
)
{
for
(
j
=
0
;
j
<
w
;
j
+=
4
)
{
y
=
src
[
j
+
1
];
u
=
src
[
j
+
2
];
v
=
src
[
j
+
3
];
r
=
APPLY_MATRIX
(
matrix
,
0
,
y
,
u
,
v
);
g
=
APPLY_MATRIX
(
matrix
,
1
,
y
,
u
,
v
);
b
=
APPLY_MATRIX
(
matrix
,
2
,
y
,
u
,
v
);
dest
[
j
+
p_out
[
1
]]
=
CLAMP
(
r
,
0
,
255
);
dest
[
j
+
p_out
[
2
]]
=
CLAMP
(
g
,
0
,
255
);
dest
[
j
+
p_out
[
3
]]
=
CLAMP
(
b
,
0
,
255
);
}
dest
+=
dest_stride
;
src
+=
src_stride
;
}
}
else
{
for
(
i
=
0
;
i
<
h
;
i
++
)
{
for
(
j
=
0
;
j
<
w
;
j
++
)
{
y
=
src
[
4
*
j
+
1
];
u
=
src
[
4
*
j
+
2
];
v
=
src
[
4
*
j
+
3
];
r
=
APPLY_MATRIX
(
matrix
,
0
,
y
,
u
,
v
);
g
=
APPLY_MATRIX
(
matrix
,
1
,
y
,
u
,
v
);
b
=
APPLY_MATRIX
(
matrix
,
2
,
y
,
u
,
v
);
dest
[
out_bpp
*
j
+
p_out
[
1
]]
=
CLAMP
(
r
,
0
,
255
);
dest
[
out_bpp
*
j
+
p_out
[
2
]]
=
CLAMP
(
g
,
0
,
255
);
dest
[
out_bpp
*
j
+
p_out
[
3
]]
=
CLAMP
(
b
,
0
,
255
);
}
dest
+=
dest_stride
;
src
+=
src_stride
;
}
}
}
#define DEFAULT_LEFT 0
#define DEFAULT_RIGHT 0
#define DEFAULT_TOP 0
...
...
@@ -1275,11 +1465,56 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
gint
width
,
height
;
to
=
gst_caps_copy
(
from
);
/* Just to be sure... */
gst_caps_truncate
(
to
);
structure
=
gst_caps_get_structure
(
to
,
0
);
/* For I420/AYUV we support conversion, for all
* 24/32bpp RGBs we support conversion and for
* everything else we only support passthrough
/* Transform width/height */
if
(
video_box
->
autocrop
)
{
gst_structure_remove_field
(
structure
,
"width"
);
gst_structure_remove_field
(
structure
,
"height"
);
}
else
{
/* calculate width and height */
if
(
gst_structure_get_int
(
structure
,
"width"
,
&
width
))
{
if
(
direction
==
GST_PAD_SINK
)
{
width
-=
video_box
->
box_left
;
width
-=
video_box
->
box_right
;
}
else
{
width
+=
video_box
->
box_left
;
width
+=
video_box
->
box_right
;
}
if
(
width
<=
0
)
width
=
1
;
GST_DEBUG_OBJECT
(
trans
,
"New caps width: %d"
,
width
);
gst_structure_set
(
structure
,
"width"
,
G_TYPE_INT
,
width
,
NULL
);
}
if
(
gst_structure_get_int
(
structure
,
"height"
,
&
height
))
{
if
(
direction
==
GST_PAD_SINK
)
{
height
-=
video_box
->
box_top
;
height
-=
video_box
->
box_bottom
;
}
else
{
height
+=
video_box
->
box_top
;
height
+=
video_box
->
box_bottom
;
}
if
(
height
<=
0
)
height
=
1
;
GST_DEBUG_OBJECT
(
trans
,
"New caps height: %d"
,
height
);
gst_structure_set
(
structure
,
"height"
,
G_TYPE_INT
,
height
,
NULL
);
}
}
/* Supported conversions:
* I420->AYUV
* AYUV->I420
* AYUV->xRGB (24bpp, 32bpp, incl. alpha)
* xRGB->xRGB (24bpp, 32bpp, from/to all variants, incl. alpha)
* xRGB->AYUV (24bpp, 32bpp, incl. alpha)
*
* Passthrough only for everything else.
*/
name
=
gst_structure_get_name
(
structure
);
if
(
g_str_equal
(
name
,
"video/x-raw-yuv"
))
{
...
...
@@ -1290,12 +1525,15 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
fourcc
==
GST_STR_FOURCC
(
"I420"
)))
{
GValue
list
=
{
0
,
};
GValue
val
=
{
0
,
};
GstStructure
*
s2
;
/* get rid of format */
gst_structure_remove_field
(
structure
,
"format"
);
gst_structure_remove_field
(
structure
,
"color-matrix"
);
gst_structure_remove_field
(
structure
,
"chroma-site"
);
s2
=
gst_structure_copy
(
structure
);
g_value_init
(
&
list
,
GST_TYPE_LIST
);
g_value_init
(
&
val
,
GST_TYPE_FOURCC
);
gst_value_set_fourcc
(
&
val
,
GST_STR_FOURCC
(
"AYUV"
));
...
...
@@ -1303,9 +1541,23 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
g_value_reset
(
&
val
);
gst_value_set_fourcc
(
&
val
,
GST_STR_FOURCC
(
"I420"
));
gst_value_list_append_value
(
&
list
,
&
val
);
g_value_
re
set
(
&
val
);
g_value_
un
set
(
&
val
);
gst_structure_set_value
(
structure
,
"format"
,
&
list
);
g_value_unset
(
&
list
);
gst_structure_set_name
(
s2
,
"video/x-raw-rgb"
);
g_value_init
(
&
list
,
GST_TYPE_LIST
);
g_value_init
(
&
val
,
G_TYPE_INT
);
g_value_set_int
(
&
val
,
32
);
gst_value_list_append_value
(
&
list
,
&
val
);
g_value_reset
(
&
val
);
g_value_set_int
(
&
val
,
24
);
gst_value_list_append_value
(
&
list
,
&
val
);
g_value_unset
(
&
val
);
gst_structure_set_value
(
s2
,
"depth"
,
&
list
);
gst_structure_set_value
(
s2
,
"bpp"
,
&
list
);
g_value_unset
(
&
list
);
gst_caps_append_structure
(
to
,
s2
);
}
}
else
if
(
g_str_equal
(
name
,
"video/x-raw-rgb"
))
{
gint
bpp
;
...
...
@@ -1314,6 +1566,7 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
(
bpp
==
32
||
bpp
==
24
))
{
GValue
list
=
{
0
,
};
GValue
val
=
{
0
,
};
GstStructure
*
s2
;
/* get rid of format */
gst_structure_remove_field
(
structure
,
"depth"
);
...
...
@@ -1323,6 +1576,8 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
gst_structure_remove_field
(
structure
,
"blue_mask"
);
gst_structure_remove_field
(
structure
,
"alpha_mask"
);
s2
=
gst_structure_copy
(
structure
);
g_value_init
(
&
list
,
GST_TYPE_LIST
);
g_value_init
(
&
val
,
G_TYPE_INT
);
g_value_set_int
(
&
val
,
32
);
...
...
@@ -1330,48 +1585,15 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
g_value_reset
(
&
val
);
g_value_set_int
(
&
val
,
24
);
gst_value_list_append_value
(
&
list
,
&
val
);
g_value_
re
set
(
&
val
);
g_value_
un
set
(
&
val
);
gst_structure_set_value
(
structure
,
"depth"
,
&
list
);
gst_structure_set_value
(
structure
,
"bpp"
,
&
list
);
g_value_unset
(
&
list
);
}
}
/* otherwise caps nego will fail: */
if
(
video_box
->
autocrop
)
{
gst_structure_remove_field
(
structure
,
"width"
);
gst_structure_remove_field
(
structure
,
"height"
);
}
else
{
/* calculate width and height */
if
(
gst_structure_get_int
(
structure
,
"width"
,
&
width
))
{
if
(
direction
==
GST_PAD_SINK
)
{
width
-=
video_box
->
box_left
;
width
-=
video_box
->
box_right
;
}
else
{
width
+=
video_box
->
box_left
;
width
+=
video_box
->
box_right
;
}
if
(
width
<=
0
)
width
=
1
;
GST_DEBUG_OBJECT
(
trans
,
"New caps width: %d"
,
width
);
gst_structure_set
(
structure
,
"width"
,
G_TYPE_INT
,
width
,
NULL
);
}
if
(
gst_structure_get_int
(
structure
,
"height"
,
&
height
))
{
if
(
direction
==
GST_PAD_SINK
)
{
height
-=
video_box
->
box_top
;
height
-=
video_box
->
box_bottom
;
}
else
{
height
+=
video_box
->
box_top
;
height
+=
video_box
->
box_bottom
;
}
if
(
height
<=
0
)
height
=
1
;
GST_DEBUG_OBJECT
(
trans
,
"New caps height: %d"
,
height
);
gst_structure_set
(
structure
,
"height"
,
G_TYPE_INT
,
height
,
NULL
);
gst_structure_set_name
(
s2
,
"video/x-raw-yuv"
);
gst_structure_set
(
s2
,
"format"
,
GST_TYPE_FOURCC
,
GST_STR_FOURCC
(
"AYUV"
),
NULL
);
gst_caps_append_structure
(
to
,
s2
);
}
}
...
...
@@ -1424,6 +1646,18 @@ gst_video_box_select_processing_functions (GstVideoBox * video_box)
case
GST_VIDEO_FORMAT_I420
:
video_box
->
copy
=
copy_i420_ayuv
;
break
;
case
GST_VIDEO_FORMAT_ARGB
:
case
GST_VIDEO_FORMAT_ABGR
:
case
GST_VIDEO_FORMAT_RGBA
:
case
GST_VIDEO_FORMAT_BGRA
:
case
GST_VIDEO_FORMAT_xRGB
:
case
GST_VIDEO_FORMAT_xBGR
:
case
GST_VIDEO_FORMAT_RGBx
:
case
GST_VIDEO_FORMAT_BGRx
:
case
GST_VIDEO_FORMAT_RGB
:
case
GST_VIDEO_FORMAT_BGR
:
video_box
->
copy
=
copy_rgb32_ayuv
;
break
;
default:
break
;
}
...
...
@@ -1466,6 +1700,9 @@ gst_video_box_select_processing_functions (GstVideoBox * video_box)
case
GST_VIDEO_FORMAT_RGB
:
case
GST_VIDEO_FORMAT_BGR
:
video_box
->
copy
=
copy_rgb32
;
break
;
case
GST_VIDEO_FORMAT_AYUV
:
video_box
->
copy
=
copy_ayuv_rgb32
;
default:
break
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment