mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 15:27:07 +00:00
- reimplemented using organic masks, rendered with gouraud shaded triangles
Original commit message from CVS: - reimplemented using organic masks, rendered with gouraud shaded triangles - implemented more masks - implemented adjustable border
This commit is contained in:
parent
9b067365c9
commit
e5c5f6be80
8 changed files with 771 additions and 220 deletions
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit fa2e4df50fd965b1dbd3b35b87d914ff87362815
|
||||
Subproject commit 2f0e1ecbfe7d27cf1b2215204958c95516db173d
|
|
@ -20,122 +20,455 @@
|
|||
#include "paint.h"
|
||||
#include "gstmask.h"
|
||||
|
||||
static void
|
||||
gst_bar_wipe_lr_update (GstMask *mask,
|
||||
GstClockTime position,
|
||||
GstClockTime duration)
|
||||
enum
|
||||
{
|
||||
gint width = mask->width;
|
||||
gint height = mask->height;
|
||||
gint split = (position * width) / duration;
|
||||
BOX_VERTICAL = 1,
|
||||
BOX_HORIZONTAL = 2,
|
||||
TRIGANLE_LINEAR = 3,
|
||||
};
|
||||
|
||||
gst_smpte_paint_rect (mask->data, width, split, 0, width - split, height, 0);
|
||||
gst_smpte_paint_rect (mask->data, width, 0, 0, split, height, 255);
|
||||
}
|
||||
static gint boxes_1b[][7] =
|
||||
{
|
||||
#define WIPE_B1_1 0
|
||||
{ BOX_VERTICAL, 0, 0, 0, 1, 1, 1 },
|
||||
#define WIPE_B1_2 1
|
||||
{ BOX_HORIZONTAL, 0, 0, 0, 1, 1, 1 }
|
||||
};
|
||||
|
||||
static gint boxes_2b[][7*2] =
|
||||
{
|
||||
#define WIPE_B2_21 0
|
||||
{ BOX_VERTICAL, 0, 0, 1, 1, 2, 0,
|
||||
BOX_VERTICAL, 1, 0, 0, 2, 2, 1 },
|
||||
#define WIPE_B2_22 1
|
||||
{ BOX_HORIZONTAL, 0, 0, 1, 2, 1, 0,
|
||||
BOX_HORIZONTAL, 0, 1, 0, 2, 2, 1 },
|
||||
};
|
||||
|
||||
static gint triangles_2t[][2*9] =
|
||||
{
|
||||
/* 3 -> 6 */
|
||||
#define WIPE_T2_3 0
|
||||
{ 0, 0, 0, 0, 1, 1, 1, 1, 1,
|
||||
1, 0, 1, 0, 0, 0, 1, 1, 1 },
|
||||
#define WIPE_T2_4 WIPE_T2_3+1
|
||||
{ 0, 0, 1, 1, 0, 0, 0, 1, 1,
|
||||
1, 0, 0, 0, 1, 1, 1, 1, 1 },
|
||||
#define WIPE_T2_5 WIPE_T2_4+1
|
||||
{ 0, 0, 1, 0, 1, 1, 1, 1, 0,
|
||||
1, 0, 1, 0, 0, 1, 1, 1, 0 },
|
||||
#define WIPE_T2_6 WIPE_T2_5+1
|
||||
{ 0, 0, 1, 1, 0, 1, 0, 1, 0,
|
||||
1, 0, 1, 0, 1, 0, 1, 1, 1 },
|
||||
#define WIPE_T2_41 WIPE_T2_6+1
|
||||
{ 0, 0, 0, 1, 0, 1, 0, 1, 1,
|
||||
1, 0, 1, 0, 1, 1, 1, 1, 2 },
|
||||
#define WIPE_T2_42 WIPE_T2_41+1
|
||||
{ 0, 0, 1, 1, 0, 0, 1, 1, 1,
|
||||
0, 0, 1, 0, 1, 2, 1, 1, 1 },
|
||||
#define WIPE_T2_45 WIPE_T2_42+1
|
||||
{ 0, 0, 1, 1, 0, 0, 0, 1, 0,
|
||||
1, 0, 0, 0, 1, 0, 1, 1, 1 },
|
||||
#define WIPE_T2_46 WIPE_T2_45+1
|
||||
{ 0, 0, 0, 1, 0, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 0 },
|
||||
};
|
||||
|
||||
static gint triangles_3t[][3*9] =
|
||||
{
|
||||
/* 23 -> 26 */
|
||||
#define WIPE_T3_23 0
|
||||
{ 0, 0, 1, 1, 0, 0, 0, 2, 1,
|
||||
1, 0, 0, 0, 2, 1, 2, 2, 1,
|
||||
1, 0, 0, 2, 0, 1, 2, 2, 1 },
|
||||
#define WIPE_T3_24 1
|
||||
{ 0, 0, 1, 2, 0, 1, 2, 1, 0,
|
||||
0, 0, 1, 2, 1, 0, 0, 2, 1,
|
||||
2, 1, 0, 0, 2, 1, 2, 2, 1 },
|
||||
#define WIPE_T3_25 2
|
||||
{ 0, 0, 1, 0, 2, 1, 1, 2, 0,
|
||||
0, 0, 1, 2, 0, 1, 1, 2, 0,
|
||||
2, 0, 1, 1, 2, 0, 2, 2, 1 },
|
||||
#define WIPE_T3_26 3
|
||||
{ 0, 0, 1, 2, 0, 1, 0, 1, 0,
|
||||
2, 0, 1, 0, 1, 0, 2, 2, 1,
|
||||
0, 1, 0, 0, 2, 1, 2, 2, 1 }
|
||||
};
|
||||
|
||||
static gint triangles_4t[][4*9] =
|
||||
{
|
||||
#define WIPE_T4_61 0
|
||||
{ 0, 0, 1, 1, 0, 0, 1, 2, 1,
|
||||
0, 0, 1, 0, 2, 2, 1, 2, 1,
|
||||
1, 0, 0, 2, 0, 1, 1, 2, 1,
|
||||
2, 0, 1, 1, 2, 1, 2, 2, 2 },
|
||||
#define WIPE_T4_62 1
|
||||
{ 0, 0, 2, 2, 0, 1, 0, 1, 1,
|
||||
2, 0, 1, 0, 1, 1, 2, 1, 0,
|
||||
0, 1, 1, 2, 1, 0, 2, 2, 1,
|
||||
0, 1, 1, 0, 2, 2, 2, 2, 1 },
|
||||
#define WIPE_T4_63 2
|
||||
{ 0, 0, 2, 1, 0, 1, 0, 2, 1,
|
||||
1, 0, 1, 0, 2, 1, 1, 2, 0,
|
||||
1, 0, 1, 1, 2, 0, 2, 2, 1,
|
||||
1, 0, 1, 2, 0, 2, 2, 2, 1 },
|
||||
#define WIPE_T4_64 3
|
||||
{ 0, 0, 1, 2, 0, 2, 2, 1, 1,
|
||||
0, 0, 1, 0, 1, 0, 2, 1, 1,
|
||||
0, 1, 0, 2, 1, 1, 0, 2, 1,
|
||||
2, 1, 1, 0, 2, 1, 2, 2, 2 },
|
||||
#define WIPE_T4_65 4
|
||||
{ 0, 0, 0, 1, 0, 1, 1, 2, 0,
|
||||
0, 0, 0, 0, 2, 1, 1, 2, 0,
|
||||
1, 0, 1, 2, 0, 0, 1, 2, 0,
|
||||
2, 0, 0, 1, 2, 0, 2, 2, 1 },
|
||||
#define WIPE_T4_66 5
|
||||
{ 0, 0, 1, 2, 0, 0, 0, 1, 0,
|
||||
2, 0, 0, 0, 1, 0, 2, 1, 1,
|
||||
0, 1, 0, 2, 1, 1, 2, 2, 0,
|
||||
0, 1, 0, 0, 2, 1, 2, 2, 0 },
|
||||
#define WIPE_T4_67 6
|
||||
{ 0, 0, 1, 1, 0, 0, 0, 2, 0,
|
||||
1, 0, 0, 0, 2, 0, 1, 2, 1,
|
||||
1, 0, 0, 1, 2, 1, 2, 2, 0,
|
||||
1, 0, 0, 2, 0, 1, 2, 2, 0 },
|
||||
#define WIPE_T4_68 7
|
||||
{ 0, 0, 0, 2, 0, 1, 2, 1, 0,
|
||||
0, 0, 0, 0, 1, 1, 2, 1, 0,
|
||||
0, 1, 1, 2, 1, 0, 0, 2, 0,
|
||||
2, 1, 0, 0, 2, 0, 2, 2, 1 },
|
||||
#define WIPE_T4_101 8
|
||||
{ 0, 0, 1, 2, 0, 1, 1, 1, 0,
|
||||
0, 0, 1, 1, 1, 0, 0, 2, 1,
|
||||
1, 1, 0, 0, 2, 1, 2, 2, 1,
|
||||
2, 0, 1, 1, 1, 0, 2, 2, 1 }
|
||||
};
|
||||
|
||||
static gint triangles_8t[][8*9] =
|
||||
{
|
||||
/* 7 */
|
||||
#define WIPE_T8_7 0
|
||||
{ 0, 0, 0, 1, 0, 1, 1, 1, 1,
|
||||
1, 0, 1, 2, 0, 0, 1, 1, 1,
|
||||
2, 0, 0, 1, 1, 1, 2, 1, 1,
|
||||
1, 1, 1, 2, 1, 1, 2, 2, 0,
|
||||
1, 1, 1, 1, 2, 1, 2, 2, 0,
|
||||
1, 1, 1, 0, 2, 0, 1, 2, 1,
|
||||
0, 1, 1, 1, 1, 1, 0, 2, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 1 },
|
||||
#define WIPE_T8_43 1
|
||||
{ 0, 0, 1, 1, 0, 0, 1, 1, 1,
|
||||
1, 0, 0, 2, 0, 1, 1, 1, 1,
|
||||
2, 0, 1, 1, 1, 1, 2, 1, 2,
|
||||
1, 1, 1, 2, 1, 2, 2, 2, 1,
|
||||
1, 1, 1, 1, 2, 0, 2, 2, 1,
|
||||
1, 1, 1, 0, 2, 1, 1, 2, 0,
|
||||
0, 1, 2, 1, 1, 1, 0, 2, 1,
|
||||
0, 0, 1, 0, 1, 2, 1, 1, 1 },
|
||||
#define WIPE_T8_44 2
|
||||
{ 0, 0, 1, 1, 0, 2, 1, 1, 1,
|
||||
1, 0, 2, 2, 0, 1, 1, 1, 1,
|
||||
2, 0, 1, 1, 1, 1, 2, 1, 0,
|
||||
1, 1, 1, 2, 1, 0, 2, 2, 1,
|
||||
1, 1, 1, 1, 2, 2, 2, 2, 1,
|
||||
1, 1, 1, 0, 2, 1, 1, 2, 2,
|
||||
0, 1, 0, 1, 1, 1, 0, 2, 1,
|
||||
0, 0, 1, 0, 1, 0, 1, 1, 1 },
|
||||
#define WIPE_T8_47 3
|
||||
{ 0, 0, 0, 1, 0, 1, 1, 1, 0,
|
||||
1, 0, 1, 2, 0, 0, 1, 1, 0,
|
||||
2, 0, 0, 1, 1, 0, 2, 1, 1,
|
||||
1, 1, 0, 2, 1, 1, 2, 2, 0,
|
||||
1, 1, 0, 1, 2, 1, 2, 2, 0,
|
||||
1, 1, 0, 0, 2, 0, 1, 2, 1,
|
||||
0, 1, 1, 1, 1, 0, 0, 2, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 0 },
|
||||
#define WIPE_T8_48 4
|
||||
{ 0, 0, 1, 1, 0, 0, 0, 1, 0,
|
||||
1, 0, 0, 0, 1, 0, 1, 1, 1,
|
||||
1, 0, 0, 2, 0, 1, 2, 1, 0,
|
||||
1, 0, 0, 1, 1, 1, 2, 1, 0,
|
||||
0, 1, 0, 1, 1, 1, 1, 2, 0,
|
||||
0, 1, 0, 0, 2, 1, 1, 2, 0,
|
||||
1, 1, 1, 2, 1, 0, 1, 2, 0,
|
||||
2, 1, 0, 1, 2, 0, 2, 2, 1 },
|
||||
};
|
||||
|
||||
static gint triangles_16t[][16*9] =
|
||||
{
|
||||
/* 8 */
|
||||
#define WIPE_T16_8 0
|
||||
{ 0, 0, 1, 2, 0, 1, 1, 1, 0,
|
||||
2, 0, 1, 1, 1, 0, 2, 2, 1,
|
||||
1, 1, 0, 0, 2, 1, 2, 2, 1,
|
||||
0, 0, 1, 1, 1, 0, 0, 2, 1,
|
||||
2, 0, 1, 4, 0, 1, 3, 1, 0,
|
||||
4, 0, 1, 3, 1, 0, 4, 2, 1,
|
||||
3, 1, 0, 2, 2, 1, 4, 2, 1,
|
||||
2, 0, 1, 3, 1, 0, 2, 2, 1,
|
||||
0, 2, 1, 2, 2, 1, 1, 3, 0,
|
||||
2, 2, 1, 1, 3, 0, 2, 4, 1,
|
||||
1, 3, 0, 0, 4, 1, 2, 4, 1,
|
||||
0, 2, 1, 1, 3, 0, 0, 4, 1,
|
||||
2, 2, 1, 4, 2, 1, 3, 3, 0,
|
||||
4, 2, 1, 3, 3, 0, 4, 4, 1,
|
||||
3, 3, 0, 2, 4, 1, 4, 4, 1,
|
||||
2, 2, 1, 3, 3, 0, 2, 4, 1 }
|
||||
};
|
||||
|
||||
typedef struct _GstWipeConfig GstWipeConfig;
|
||||
|
||||
struct _GstWipeConfig {
|
||||
gint *objects;
|
||||
gint nobjects;
|
||||
gint xscale;
|
||||
gint yscale;
|
||||
gint cscale;
|
||||
};
|
||||
|
||||
static GstWipeConfig wipe_config[] =
|
||||
{
|
||||
#define WIPE_CONFIG_1 0
|
||||
{ boxes_1b[WIPE_B1_1], 1, 0, 0, 0 }, /* 1 */
|
||||
#define WIPE_CONFIG_2 WIPE_CONFIG_1+1
|
||||
{ boxes_1b[WIPE_B1_2], 1, 0, 0, 0 }, /* 2 */
|
||||
#define WIPE_CONFIG_3 WIPE_CONFIG_2+1
|
||||
{ triangles_2t[WIPE_T2_3], 2, 0, 0, 0 }, /* 3 */
|
||||
#define WIPE_CONFIG_4 WIPE_CONFIG_3+1
|
||||
{ triangles_2t[WIPE_T2_4], 2, 0, 0, 0 }, /* 4 */
|
||||
#define WIPE_CONFIG_5 WIPE_CONFIG_4+1
|
||||
{ triangles_2t[WIPE_T2_5], 2, 0, 0, 0 }, /* 5 */
|
||||
#define WIPE_CONFIG_6 WIPE_CONFIG_5+1
|
||||
{ triangles_2t[WIPE_T2_6], 2, 0, 0, 0 }, /* 6 */
|
||||
#define WIPE_CONFIG_7 WIPE_CONFIG_6+1
|
||||
{ triangles_8t[WIPE_T8_7], 8, 1, 1, 0 }, /* 7 */
|
||||
#define WIPE_CONFIG_8 WIPE_CONFIG_7+1
|
||||
{ triangles_16t[WIPE_T16_8], 16, 2, 2, 0 }, /* 8 */
|
||||
|
||||
#define WIPE_CONFIG_21 WIPE_CONFIG_8+1
|
||||
{ boxes_2b[WIPE_B2_21], 2, 1, 1, 0 }, /* 21 */
|
||||
#define WIPE_CONFIG_22 WIPE_CONFIG_21+1
|
||||
{ boxes_2b[WIPE_B2_22], 2, 1, 1, 0 }, /* 22 */
|
||||
|
||||
#define WIPE_CONFIG_23 WIPE_CONFIG_22+1
|
||||
{ triangles_3t[WIPE_T3_23], 3, 1, 1, 0 }, /* 23 */
|
||||
#define WIPE_CONFIG_24 WIPE_CONFIG_23+1
|
||||
{ triangles_3t[WIPE_T3_24], 3, 1, 1, 0 }, /* 24 */
|
||||
#define WIPE_CONFIG_25 WIPE_CONFIG_24+1
|
||||
{ triangles_3t[WIPE_T3_23], 3, 1, 1, 0 }, /* 25 */
|
||||
#define WIPE_CONFIG_26 WIPE_CONFIG_25+1
|
||||
{ triangles_3t[WIPE_T3_26], 3, 1, 1, 0 }, /* 26 */
|
||||
#define WIPE_CONFIG_41 WIPE_CONFIG_26+1
|
||||
{ triangles_2t[WIPE_T2_41], 2, 0, 0, 1 }, /* 41 */
|
||||
#define WIPE_CONFIG_42 WIPE_CONFIG_41+1
|
||||
{ triangles_2t[WIPE_T2_42], 2, 0, 0, 1 }, /* 42 */
|
||||
#define WIPE_CONFIG_43 WIPE_CONFIG_42+1
|
||||
{ triangles_8t[WIPE_T8_43], 8, 1, 1, 1 }, /* 43 */
|
||||
#define WIPE_CONFIG_44 WIPE_CONFIG_43+1
|
||||
{ triangles_8t[WIPE_T8_44], 8, 1, 1, 1 }, /* 44 */
|
||||
#define WIPE_CONFIG_45 WIPE_CONFIG_44+1
|
||||
{ triangles_2t[WIPE_T2_45], 2, 0, 0, 0 }, /* 45 */
|
||||
#define WIPE_CONFIG_46 WIPE_CONFIG_45+1
|
||||
{ triangles_2t[WIPE_T2_46], 2, 0, 0, 0 }, /* 46 */
|
||||
#define WIPE_CONFIG_47 WIPE_CONFIG_46+1
|
||||
{ triangles_8t[WIPE_T8_47], 8, 1, 1, 0 }, /* 47 */
|
||||
#define WIPE_CONFIG_48 WIPE_CONFIG_47+1
|
||||
{ triangles_8t[WIPE_T8_48], 8, 1, 1, 0 }, /* 48 */
|
||||
#define WIPE_CONFIG_61 WIPE_CONFIG_48+1
|
||||
{ triangles_4t[WIPE_T4_61], 4, 1, 1, 1 }, /* 61 */
|
||||
#define WIPE_CONFIG_62 WIPE_CONFIG_61+1
|
||||
{ triangles_4t[WIPE_T4_62], 4, 1, 1, 1 }, /* 62 */
|
||||
#define WIPE_CONFIG_63 WIPE_CONFIG_62+1
|
||||
{ triangles_4t[WIPE_T4_63], 4, 1, 1, 1 }, /* 63 */
|
||||
#define WIPE_CONFIG_64 WIPE_CONFIG_63+1
|
||||
{ triangles_4t[WIPE_T4_64], 4, 1, 1, 1 }, /* 64 */
|
||||
#define WIPE_CONFIG_65 WIPE_CONFIG_64+1
|
||||
{ triangles_4t[WIPE_T4_65], 4, 1, 1, 0 }, /* 65 */
|
||||
#define WIPE_CONFIG_66 WIPE_CONFIG_65+1
|
||||
{ triangles_4t[WIPE_T4_66], 4, 1, 1, 0 }, /* 66 */
|
||||
#define WIPE_CONFIG_67 WIPE_CONFIG_66+1
|
||||
{ triangles_4t[WIPE_T4_67], 4, 1, 1, 0 }, /* 67 */
|
||||
#define WIPE_CONFIG_68 WIPE_CONFIG_67+1
|
||||
{ triangles_4t[WIPE_T4_68], 4, 1, 1, 0 }, /* 68 */
|
||||
#define WIPE_CONFIG_101 WIPE_CONFIG_68+1
|
||||
{ triangles_4t[WIPE_T4_101], 4, 1, 1, 0 }, /* 101 */
|
||||
};
|
||||
|
||||
static void
|
||||
gst_bar_wipe_tb_update (GstMask *mask,
|
||||
GstClockTime position,
|
||||
GstClockTime duration)
|
||||
gst_wipe_boxes_draw (GstMask *mask)
|
||||
{
|
||||
gint width = mask->width;
|
||||
gint height = mask->height;
|
||||
gint split = (position * height) / duration;
|
||||
GstWipeConfig *config = mask->user_data;
|
||||
gint *impacts = config->objects;
|
||||
gint width = (mask->width >> config->xscale) - 1;
|
||||
gint height = (mask->height >> config->yscale) - 1;
|
||||
gint depth = (1 << mask->bpp) >> config->cscale;
|
||||
|
||||
gst_smpte_paint_rect (mask->data, width, 0, 0, width, split, 255);
|
||||
gst_smpte_paint_rect (mask->data, width, 0, split, width, height - split, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_box_wipe_update (GstMask *mask,
|
||||
GstClockTime position,
|
||||
GstClockTime duration)
|
||||
{
|
||||
static gint box_wipe_impacts[8][4] =
|
||||
{
|
||||
/* 3 -> 6 */
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 2, 2, 0, 0 },
|
||||
{ 2, 2, 2, 2 },
|
||||
{ 0, 0, 2, 2 },
|
||||
/* 23 -> 26 */
|
||||
{ 1, 1, 0, 0 },
|
||||
{ 2, 2, 1, 1 },
|
||||
{ 1, 1, 2, 2 },
|
||||
{ 0, 0, 1, 1 },
|
||||
};
|
||||
gint *impacts = box_wipe_impacts[(mask->type & 0x0F) - 3];
|
||||
gint width = mask->width;
|
||||
gint height = mask->height;
|
||||
gint splitx = (position * width) / duration;
|
||||
gint splity = (position * height) / duration;
|
||||
|
||||
gst_smpte_paint_rect (mask->data, width, 0, 0, width, height, 0);
|
||||
gst_smpte_paint_rect (mask->data, width,
|
||||
(impacts[0] * width)/2 - (impacts[1] * splitx)/2,
|
||||
(impacts[2] * height)/2 - (impacts[3] * splity)/2,
|
||||
splitx, splity, 255);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fourc_box_wipe_update (GstMask *mask,
|
||||
GstClockTime position,
|
||||
GstClockTime duration)
|
||||
{
|
||||
static gint box_wipe_impacts[8][4] =
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 1, 1, 1, 1 },
|
||||
{ 4, 2, 0, 0 },
|
||||
{ 3, 1, 1, 1 },
|
||||
{ 4, 2, 4, 2 },
|
||||
{ 1, 1, 3, 1 },
|
||||
{ 0, 0, 4, 2 },
|
||||
{ 3, 1, 3, 1 },
|
||||
};
|
||||
gint *impacts;
|
||||
gint width = mask->width;
|
||||
gint height = mask->height;
|
||||
gint splitx = (position * width/2) / duration;
|
||||
gint splity = (position * height/2) / duration;
|
||||
gint i;
|
||||
|
||||
gst_smpte_paint_rect (mask->data, width, 0, 0, width, height, 0);
|
||||
for (i = 0; i < config->nobjects; i++) {
|
||||
switch (impacts[0]) {
|
||||
case BOX_VERTICAL:
|
||||
gst_smpte_paint_vbox (mask->data, mask->width,
|
||||
impacts[1] * width, impacts[2] * height, impacts[3] * depth,
|
||||
impacts[4] * width, impacts[5] * height, impacts[6] * depth);
|
||||
impacts += 7;
|
||||
break;
|
||||
case BOX_HORIZONTAL:
|
||||
gst_smpte_paint_hbox (mask->data, mask->width,
|
||||
impacts[1] * width, impacts[2] * height, impacts[3] * depth,
|
||||
impacts[4] * width, impacts[5] * height, impacts[6] * depth);
|
||||
impacts += 7;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 7; i > 0; i -= 2) {
|
||||
impacts = box_wipe_impacts[mask->type - i];
|
||||
gst_smpte_paint_rect (mask->data, width,
|
||||
(impacts[0] * width)/4 - (impacts[1] * splitx)/2,
|
||||
(impacts[2] * height)/4 - (impacts[3] * splity)/2,
|
||||
splitx, splity, 255);
|
||||
static void
|
||||
gst_wipe_triangles_draw (GstMask *mask)
|
||||
{
|
||||
GstWipeConfig *config = mask->user_data;
|
||||
gint *impacts = config->objects;
|
||||
gint width = (mask->width >> config->xscale) - 1;
|
||||
gint height = (mask->height >> config->yscale) - 1;
|
||||
gint depth = (1 << mask->bpp) >> config->cscale;
|
||||
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < config->nobjects; i++) {
|
||||
gst_smpte_paint_triangle_linear (mask->data, mask->width,
|
||||
impacts[0] * width, impacts[1] * height, impacts[2] * depth,
|
||||
impacts[3] * width, impacts[4] * height, impacts[5] * depth,
|
||||
impacts[6] * width, impacts[7] * height, impacts[8] * depth);
|
||||
impacts += 9;
|
||||
}
|
||||
}
|
||||
|
||||
static GstMaskDefinition definitions[] = {
|
||||
{ 1, "bar_wipe_lr", "A bar moves from left to right",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_bar_wipe_lr_update },
|
||||
{ 2, "bar_wipe_tb", "A bar moves from top to bottom",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_bar_wipe_tb_update },
|
||||
{ 3, "box_wipe_tl", "A box expands from the upper-left corner to the lower-right corner",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 4, "box_wipe_tr", "A box expands from the upper-right corner to the lower-left corner",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 5, "box_wipe_br", "A box expands from the lower-right corner to the upper-left corner",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 6, "box_wipe_bl", "A box expands from the lower-left corner to the upper-right corner",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 23, "box_wipe_tc", "A box expands from the top edge's midpoint to the bottom corners",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 24, "box_wipe_rc", "A box expands from the right edge's midpoint to the left corners",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 25, "box_wipe_bc", "A box expands from the bottom edge's midpoint to the top corners",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 26, "box_wipe_lc", "A box expands from the left edge's midpoint to the right corners",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update },
|
||||
{ 7 , "four_box_wipe_ci", "A box shape expands from each of the four corners toward the center",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_fourc_box_wipe_update },
|
||||
{ 8 , "four_box_wipe_co", "A box shape expands from the center of each quadrant toward the corners of each quadrant",
|
||||
_gst_mask_default_new, _gst_mask_default_destroy, gst_fourc_box_wipe_update },
|
||||
{ 1, "bar_wipe_lr",
|
||||
"A bar moves from left to right",
|
||||
gst_wipe_boxes_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_1] },
|
||||
{ 2, "bar_wipe_tb",
|
||||
"A bar moves from top to bottom",
|
||||
gst_wipe_boxes_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_2] },
|
||||
{ 3, "box_wipe_tl",
|
||||
"A box expands from the upper-left corner to the lower-right corner",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_3] },
|
||||
{ 4, "box_wipe_tr",
|
||||
"A box expands from the upper-right corner to the lower-left corner",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_4] },
|
||||
{ 5, "box_wipe_br",
|
||||
"A box expands from the lower-right corner to the upper-left corner",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_5] },
|
||||
{ 6, "box_wipe_bl",
|
||||
"A box expands from the lower-left corner to the upper-right corner",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_6] },
|
||||
{ 7 , "four_box_wipe_ci",
|
||||
"A box shape expands from each of the four corners toward the center",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_7] },
|
||||
{ 8 , "four_box_wipe_co",
|
||||
"A box shape expands from the center of each quadrant toward the corners of each quadrant",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_8] },
|
||||
{ 21, "barndoor_v",
|
||||
"A central, vertical line splits and expands toward the left and right edges",
|
||||
gst_wipe_boxes_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_21] },
|
||||
{ 22, "barndoor_h",
|
||||
"A central, horizontal line splits and expands toward the top and bottom edges",
|
||||
gst_wipe_boxes_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_22] },
|
||||
{ 23, "box_wipe_tc",
|
||||
"A box expands from the top edge's midpoint to the bottom corners",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_23] },
|
||||
{ 24, "box_wipe_rc",
|
||||
"A box expands from the right edge's midpoint to the left corners",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_24] },
|
||||
{ 25, "box_wipe_bc",
|
||||
"A box expands from the bottom edge's midpoint to the top corners",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_25] },
|
||||
{ 26, "box_wipe_lc",
|
||||
"A box expands from the left edge's midpoint to the right corners",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_26] },
|
||||
{ 41, "diagonal_tl",
|
||||
"A diagonal line moves from the upper-left corner to the lower-right corner",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_41] },
|
||||
{ 42, "diagonal_tr",
|
||||
"A diagonal line moves from the upper right corner to the lower-left corner",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_42] },
|
||||
{ 43, "bowtie_v",
|
||||
"Two wedge shapes slide in from the top and bottom edges toward the center",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_43] },
|
||||
{ 44, "bowtie_h",
|
||||
"Two wedge shapes slide in from the left and right edges toward the center",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_44] },
|
||||
{ 45, "barndoor_dbl",
|
||||
"A diagonal line from the lower-left to upper-right corners splits and expands toward the opposite corners",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_45] },
|
||||
{ 46, "barndoor_dtl",
|
||||
"A diagonal line from upper-left to lower-right corners splits and expands toward the opposite corners",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_46] },
|
||||
{ 47, "misc_diagonal_dbd",
|
||||
"Four wedge shapes split from the center and retract toward the four edges",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_47] },
|
||||
{ 48, "misc_diagonal_dd",
|
||||
"A diamond connecting the four edge midpoints simultaneously contracts toward the center and expands toward the edges",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_48] },
|
||||
{ 61, "vee_d",
|
||||
"A wedge shape moves from top to bottom",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_61] },
|
||||
{ 62, "vee_l",
|
||||
"A wedge shape moves from right to left",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_62] },
|
||||
{ 63, "vee_u",
|
||||
"A wedge shape moves from bottom to top",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_63] },
|
||||
{ 64, "vee_r",
|
||||
"A wedge shape moves from left to right",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_64] },
|
||||
{ 65, "barnvee_d",
|
||||
"A 'V' shape extending from the bottom edge's midpoint to the opposite corners contracts toward the center and expands toward the edges",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_65] },
|
||||
{ 66, "barnvee_l",
|
||||
"A 'V' shape extending from the left edge's midpoint to the opposite corners contracts toward the center and expands toward the edges",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_66] },
|
||||
{ 67, "barnvee_u",
|
||||
"A 'V' shape extending from the top edge's midpoint to the opposite corners contracts toward the center and expands toward the edges",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_67] },
|
||||
{ 68, "barnvee_r",
|
||||
"A 'V' shape extending from the right edge's midpoint to the opposite corners contracts toward the center and expands toward the edges",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_68] },
|
||||
{ 101, "iris_rect",
|
||||
"A rectangle expands from the center.",
|
||||
gst_wipe_triangles_draw, _gst_mask_default_destroy,
|
||||
&wipe_config[WIPE_CONFIG_101] },
|
||||
{ 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
|
||||
#include "gstmask.h"
|
||||
#include "paint.h"
|
||||
|
||||
extern void _gst_barboxwipes_register (void);
|
||||
|
||||
|
@ -73,31 +74,23 @@ gst_mask_factory_new (gint type, gint bpp, gint width, gint height)
|
|||
|
||||
definition = gst_mask_find_definition (type);
|
||||
if (definition) {
|
||||
mask = definition->new_func (definition, bpp, width, height);
|
||||
mask = g_new0 (GstMask, 1);
|
||||
|
||||
mask->type = definition->type;
|
||||
mask->bpp = bpp;
|
||||
mask->width = width;
|
||||
mask->height = height;
|
||||
mask->destroy_func = definition->destroy_func;
|
||||
mask->user_data = definition->user_data;
|
||||
mask->data = g_malloc (width * height * sizeof (guint32));
|
||||
|
||||
if (definition->draw_func)
|
||||
definition->draw_func (mask);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
GstMask*
|
||||
_gst_mask_default_new (GstMaskDefinition *definition,
|
||||
gint bpp, gint width, gint height)
|
||||
{
|
||||
GstMask *mask;
|
||||
|
||||
mask = g_new0 (GstMask, 1);
|
||||
|
||||
mask->type = definition->type;
|
||||
mask->bpp = bpp;
|
||||
mask->width = width;
|
||||
mask->height = height;
|
||||
mask->update_func = definition->update_func;
|
||||
mask->destroy_func = definition->destroy_func;
|
||||
mask->data = g_malloc (width * height * (bpp+7)>>3);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
void
|
||||
_gst_mask_default_destroy (GstMask *mask)
|
||||
{
|
||||
|
@ -119,6 +112,4 @@ gst_mask_update (GstMask *mask,
|
|||
{
|
||||
g_return_if_fail (mask != NULL);
|
||||
|
||||
if (mask->update_func)
|
||||
mask->update_func (mask, position, duration);
|
||||
}
|
||||
|
|
|
@ -27,47 +27,37 @@
|
|||
typedef struct _GstMask GstMask;
|
||||
typedef struct _GstMaskDefinition GstMaskDefinition;
|
||||
|
||||
typedef GstMask* (*GstMaskNewFunc) (GstMaskDefinition *definition,
|
||||
gint bpp, gint width, gint height);
|
||||
typedef void (*GstMaskDrawFunc) (GstMask *mask);
|
||||
typedef void (*GstMaskDestroyFunc) (GstMask *mask);
|
||||
typedef void (*GstMaskUpdateFunc) (GstMask *mask,
|
||||
GstClockTime position,
|
||||
GstClockTime duration);
|
||||
|
||||
struct _GstMaskDefinition {
|
||||
gint type;
|
||||
gchar *short_name;
|
||||
gchar *long_name;
|
||||
GstMaskNewFunc new_func;
|
||||
GstMaskDrawFunc draw_func;
|
||||
GstMaskDestroyFunc destroy_func;
|
||||
GstMaskUpdateFunc update_func;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
struct _GstMask {
|
||||
gint type;
|
||||
guint8 *data;
|
||||
guint32 *data;
|
||||
gpointer user_data;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
gint bpp;
|
||||
|
||||
GstMaskUpdateFunc update_func;
|
||||
GstMaskDestroyFunc destroy_func;
|
||||
};
|
||||
|
||||
void _gst_mask_init (void);
|
||||
void _gst_mask_register (GstMaskDefinition *definition);
|
||||
|
||||
GstMask* _gst_mask_default_new (GstMaskDefinition *definition,
|
||||
gint bpp, gint width, gint height);
|
||||
void _gst_mask_default_destroy (GstMask *mask);
|
||||
|
||||
const GList* gst_mask_get_definitions (void);
|
||||
GstMask* gst_mask_factory_new (gint type, gint bpp, gint width, gint height);
|
||||
void gst_mask_destroy (GstMask *mask);
|
||||
|
||||
void gst_mask_update (GstMask *mask,
|
||||
GstClockTime position,
|
||||
GstClockTime duration);
|
||||
|
||||
|
||||
#endif /* __GST_MASK_H__ */
|
||||
|
|
|
@ -79,6 +79,9 @@ enum {
|
|||
enum {
|
||||
ARG_0,
|
||||
ARG_TYPE,
|
||||
ARG_BORDER,
|
||||
ARG_DEPTH,
|
||||
ARG_FPS,
|
||||
};
|
||||
|
||||
#define GST_TYPE_SMPTE_TRANSITION_TYPE (gst_smpte_transition_type_get_type())
|
||||
|
@ -106,7 +109,8 @@ gst_smpte_transition_type_get_type (void)
|
|||
i++;
|
||||
}
|
||||
|
||||
smpte_transition_type = g_enum_register_static ("GstSMPTETransitionType", smpte_transitions);
|
||||
smpte_transition_type =
|
||||
g_enum_register_static ("GstSMPTETransitionType", smpte_transitions);
|
||||
}
|
||||
return smpte_transition_type;
|
||||
}
|
||||
|
@ -166,7 +170,15 @@ gst_smpte_class_init (GstSMPTEClass *klass)
|
|||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TYPE,
|
||||
g_param_spec_enum ("type", "Type", "The type of transition to use",
|
||||
GST_TYPE_SMPTE_TRANSITION_TYPE, 1, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FPS,
|
||||
g_param_spec_int ("fps", "FPS", "Frames per second if no input files are given",
|
||||
1, 255, 1, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BORDER,
|
||||
g_param_spec_int ("border", "Border", "The border width of the transition",
|
||||
0, G_MAXINT, 0, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEPTH,
|
||||
g_param_spec_int ("depth", "Depth", "Depth of the mask in bits",
|
||||
1, 24, 16, G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/* wht yel cya grn mag red blu blk -I Q */
|
||||
|
@ -177,13 +189,35 @@ static int v_colors[] = { 128, 155, 0, 21, 235, 255, 107, 128, 128, 255 };
|
|||
static void
|
||||
fill_i420 (guint8 *data, gint width, gint height, gint color)
|
||||
{
|
||||
gint size = width * height, size4 = size >> 2;
|
||||
guint8 *yp = data;
|
||||
guint8 *up = data + width * height;
|
||||
guint8 *vp = data + width * height + (width * height) / 4;
|
||||
guint8 *up = data + size;
|
||||
guint8 *vp = data + size + size4;
|
||||
|
||||
gst_smpte_paint_rect (yp, width, 0, 0, width, height, y_colors[color]);
|
||||
gst_smpte_paint_rect (up, width/2, 0, 0, width/2, height/2, u_colors[color]);
|
||||
gst_smpte_paint_rect (vp, width/2, 0, 0, width/2, height/2, v_colors[color]);
|
||||
memset (yp, y_colors[color], size);
|
||||
memset (up, u_colors[color], size4);
|
||||
memset (vp, v_colors[color], size4);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_smpte_update_mask (GstSMPTE *smpte, gint type, gint depth, gint width, gint height)
|
||||
{
|
||||
GstMask *newmask;
|
||||
|
||||
newmask = gst_mask_factory_new (type, depth, width, height);
|
||||
if (newmask) {
|
||||
if (smpte->mask) {
|
||||
gst_mask_destroy (smpte->mask);
|
||||
}
|
||||
smpte->mask = newmask;
|
||||
smpte->type = type;
|
||||
smpte->depth = depth;
|
||||
smpte->width = width;
|
||||
smpte->height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -199,7 +233,7 @@ gst_smpte_sinkconnect (GstPad *pad, GstCaps *caps)
|
|||
gst_caps_get_int (caps, "width", &smpte->width);
|
||||
gst_caps_get_int (caps, "height", &smpte->height);
|
||||
|
||||
smpte->mask = gst_mask_factory_new (smpte->type, 8, smpte->width, smpte->height);
|
||||
gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width, smpte->height);
|
||||
|
||||
/* forward to the next plugin */
|
||||
return gst_pad_try_set_caps(smpte->srcpad, gst_caps_copy_1(caps));
|
||||
|
@ -229,35 +263,43 @@ gst_smpte_init (GstSMPTE *smpte)
|
|||
smpte->duration = 64;
|
||||
smpte->position = 0;
|
||||
smpte->type = 1;
|
||||
smpte->mask = gst_mask_factory_new (smpte->type, 8, smpte->width, smpte->height);
|
||||
smpte->fps = 1;
|
||||
smpte->border = 0;
|
||||
smpte->depth = 16;
|
||||
gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width, smpte->height);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_smpte_blend_i420 (guint8 *in1, guint8 *in2, guint8 *out, GstMask *mask,
|
||||
gint width, gint height)
|
||||
gint width, gint height, gint border, gint pos)
|
||||
{
|
||||
gint i, j;
|
||||
guint8 *maskporig, *maskp;
|
||||
guint32 *maskp;
|
||||
gint value;
|
||||
gint i;
|
||||
gint min, max;
|
||||
guint8 *in1u, *in1v, *in2u, *in2v, *outu, *outv;
|
||||
guint8 value;
|
||||
gint chromsize = (width * height) >> 2;
|
||||
gint lumsize = width * height;
|
||||
gint chromsize = lumsize >> 2;
|
||||
|
||||
maskp = maskporig = mask->data;
|
||||
if (border == 0) border++;
|
||||
|
||||
min = pos - border;
|
||||
max = pos;
|
||||
|
||||
in1u = in1 + lumsize; in1v = in1 + chromsize;
|
||||
in2u = in2 + lumsize; in2v = in2 + chromsize;
|
||||
outu = out + lumsize; outv = out + chromsize;
|
||||
|
||||
for (i = width * height; i; i--) {
|
||||
value = *maskp++;
|
||||
*out++ = ((*in2++ * value) + (*in1++ * (255 - value))) >> 8;
|
||||
}
|
||||
in1u = in1; in1v = in1 + chromsize;
|
||||
in2u = in2; in2v = in2 + chromsize;
|
||||
outu = out; outv = out + chromsize;
|
||||
maskp = mask->data;
|
||||
|
||||
maskp = maskporig;
|
||||
for (i = height/2; i; i--, maskp += width) {
|
||||
for (j = width/2; j; j--, maskp += 2) {
|
||||
value = *maskp;
|
||||
*outu++ = ((*in2u++ * value) + (*in1u++ * (255 - value))) >> 8;
|
||||
*outv++ = ((*in2v++ * value) + (*in1v++ * (255 - value))) >> 8;
|
||||
for (i = lumsize; i; i--) {
|
||||
value = *maskp++;
|
||||
value = ((CLAMP (value, min, max) - min) << 8) / border;
|
||||
|
||||
*out++ = ((*in1++ * value) + (*in2++ * (255 - value))) >> 8;
|
||||
if (i % 4) {
|
||||
*outu++ = ((*in1u++ * value) + (*in2u++ * (255 - value))) >> 8;
|
||||
*outv++ = ((*in1v++ * value) + (*in2v++ * (255 - value))) >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +314,7 @@ gst_smpte_loop (GstElement *element)
|
|||
|
||||
smpte = GST_SMPTE (element);
|
||||
|
||||
ts = smpte->position * GST_SECOND;
|
||||
ts = smpte->position * GST_SECOND / smpte->fps;
|
||||
|
||||
if (GST_PAD_IS_USABLE (smpte->sinkpad1)) {
|
||||
in1 = gst_pad_pull (smpte->sinkpad1);
|
||||
|
@ -297,23 +339,26 @@ gst_smpte_loop (GstElement *element)
|
|||
|
||||
if (!GST_PAD_CAPS (smpte->srcpad)) {
|
||||
if (!gst_pad_try_set_caps (smpte->srcpad,
|
||||
GST_CAPS_NEW (
|
||||
"smpte_srccaps",
|
||||
"video/raw",
|
||||
"format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')),
|
||||
"width", GST_PROPS_INT (smpte->width),
|
||||
"height", GST_PROPS_INT (smpte->height)
|
||||
)))
|
||||
GST_CAPS_NEW (
|
||||
"smpte_srccaps",
|
||||
"video/raw",
|
||||
"format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')),
|
||||
"width", GST_PROPS_INT (smpte->width),
|
||||
"height", GST_PROPS_INT (smpte->height)
|
||||
)))
|
||||
{
|
||||
gst_element_error (element, "cannot set caps");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gst_mask_update (smpte->mask, smpte->position, smpte->duration);
|
||||
|
||||
gst_smpte_blend_i420 (GST_BUFFER_DATA (in1), GST_BUFFER_DATA (in2), GST_BUFFER_DATA (outbuf),
|
||||
smpte->mask, smpte->width, smpte->height);
|
||||
gst_smpte_blend_i420 (GST_BUFFER_DATA (in1),
|
||||
GST_BUFFER_DATA (in2),
|
||||
GST_BUFFER_DATA (outbuf),
|
||||
smpte->mask, smpte->width, smpte->height,
|
||||
smpte->border,
|
||||
((1 << smpte->depth) + smpte->border) *
|
||||
smpte->position / smpte->duration);
|
||||
}
|
||||
else {
|
||||
outbuf = in2;
|
||||
|
@ -342,17 +387,24 @@ gst_smpte_set_property (GObject *object, guint prop_id,
|
|||
switch (prop_id) {
|
||||
case ARG_TYPE:
|
||||
{
|
||||
GstMask *newmask;
|
||||
gint type = g_value_get_enum (value);
|
||||
|
||||
newmask = gst_mask_factory_new (type, 8, smpte->width, smpte->height);
|
||||
if (newmask) {
|
||||
if (smpte->mask) {
|
||||
gst_mask_destroy (smpte->mask);
|
||||
}
|
||||
smpte->mask = newmask;
|
||||
smpte->type = type;
|
||||
}
|
||||
gst_smpte_update_mask (smpte, type, smpte->depth,
|
||||
smpte->width, smpte->height);
|
||||
break;
|
||||
}
|
||||
case ARG_FPS:
|
||||
smpte->fps = g_value_get_int (value);
|
||||
break;
|
||||
case ARG_BORDER:
|
||||
smpte->border = g_value_get_int (value);
|
||||
break;
|
||||
case ARG_DEPTH:
|
||||
{
|
||||
gint depth = g_value_get_int (value);
|
||||
|
||||
gst_smpte_update_mask (smpte, smpte->type, depth,
|
||||
smpte->width, smpte->height);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -375,6 +427,15 @@ gst_smpte_get_property (GObject *object, guint prop_id,
|
|||
g_value_set_enum (value, smpte->mask->type);
|
||||
}
|
||||
break;
|
||||
case ARG_FPS:
|
||||
g_value_set_int (value, smpte->fps);
|
||||
break;
|
||||
case ARG_BORDER:
|
||||
g_value_set_int (value, smpte->border);
|
||||
break;
|
||||
case ARG_DEPTH:
|
||||
g_value_set_int (value, smpte->depth);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -391,9 +452,12 @@ plugin_init (GModule *module, GstPlugin *plugin)
|
|||
&smpte_details);
|
||||
g_return_val_if_fail(factory != NULL, FALSE);
|
||||
|
||||
gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (smpte_sink1_factory));
|
||||
gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (smpte_sink2_factory));
|
||||
gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (smpte_src_factory));
|
||||
gst_element_factory_add_pad_template (factory,
|
||||
GST_PAD_TEMPLATE_GET (smpte_sink1_factory));
|
||||
gst_element_factory_add_pad_template (factory,
|
||||
GST_PAD_TEMPLATE_GET (smpte_sink2_factory));
|
||||
gst_element_factory_add_pad_template (factory,
|
||||
GST_PAD_TEMPLATE_GET (smpte_src_factory));
|
||||
|
||||
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
|
||||
|
||||
|
|
|
@ -53,6 +53,9 @@ struct _GstSMPTE {
|
|||
*sinkpad2;
|
||||
|
||||
gint type;
|
||||
gint fps;
|
||||
gint border;
|
||||
gint depth;
|
||||
GstMask *mask;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,32 +20,196 @@
|
|||
#include "paint.h"
|
||||
|
||||
void
|
||||
gst_smpte_paint_rect (guint8 *dest, gint stride, gint x, gint y, gint w, gint h, guint8 color)
|
||||
{
|
||||
guint8 *d = dest + stride * y + x;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
memset (d, color, w);
|
||||
d += stride;
|
||||
gst_smpte_paint_vbox (guint32 *dest, gint stride,
|
||||
gint x0, gint y0, gint c0,
|
||||
gint x1, gint y1, gint c1)
|
||||
{
|
||||
gint i, j;
|
||||
gint width, height;
|
||||
|
||||
width = x1 - x0;
|
||||
height = y1 - y0;
|
||||
|
||||
g_assert (width > 0);
|
||||
g_assert (height > 0);
|
||||
|
||||
dest = dest + y0 * stride + x0;
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
dest[j] = (c1 * j + c0 * (width - j)) / width;
|
||||
}
|
||||
dest += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_smpte_paint_rect_s (guint8 *dest, gint stride, gint x, gint y, gint w, gint h, guint8 color)
|
||||
{
|
||||
guint8 *d = dest + stride * y + x;
|
||||
gst_smpte_paint_hbox (guint32 *dest, gint stride,
|
||||
gint x0, gint y0, gint c0,
|
||||
gint x1, gint y1, gint c1)
|
||||
{
|
||||
gint i, j;
|
||||
gint border = 100;
|
||||
gint width, height;
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
if (w - border > 0) {
|
||||
memset (d, color, w - border);
|
||||
width = x1 - x0;
|
||||
height = y1 - y0;
|
||||
|
||||
g_assert (width > 0);
|
||||
g_assert (height > 0);
|
||||
|
||||
g_print ("vbox: %d %d %d %d %d %d\n", x0, y0, c0, x1, y1, c1);
|
||||
|
||||
dest = dest + y0 * stride + x0;
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
guint32 value = (c1 * i + c0 * (height - i)) / height;
|
||||
for (j = 0; j < width; j++) {
|
||||
*dest++ = value;
|
||||
}
|
||||
|
||||
for (j = 0; j < border - w; j++) {
|
||||
*(d+w+j) = (color*(border-j)/border);
|
||||
}
|
||||
d += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_smpte_paint_rect16 (guint16 * dest, gint depth, gint w, gint h)
|
||||
{
|
||||
gint i, j;
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
*dest++ = (guint16) ((double) (1 << depth) * j / w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define STEP_3D_LINE(dxabs,dyabs,dzabs,sdx,sdy,sdz,xr,yr,zr,px,py,pz) \
|
||||
G_STMT_START { \
|
||||
if (dxabs >= dyabs && dxabs >= dzabs) { \
|
||||
yr += dyabs; \
|
||||
zr += dzabs; \
|
||||
if (yr >= dxabs) { \
|
||||
py += sdy; \
|
||||
yr -= dxabs; \
|
||||
} \
|
||||
if (zr >= dzabs) { \
|
||||
pz += sdz; \
|
||||
zr -= dxabs; \
|
||||
} \
|
||||
px += sdx; \
|
||||
} else if (dyabs >= dxabs && dyabs >= dzabs) { \
|
||||
xr += dxabs; \
|
||||
zr += dzabs; \
|
||||
if (xr >= dyabs) { \
|
||||
px += sdx; \
|
||||
xr -= dyabs; \
|
||||
} \
|
||||
if (zr >= dzabs) { \
|
||||
pz += sdz; \
|
||||
zr -= dyabs; \
|
||||
} \
|
||||
py += sdy; \
|
||||
} else { \
|
||||
yr += dyabs; \
|
||||
xr += dxabs; \
|
||||
if (yr >= dyabs) { \
|
||||
py += sdy; \
|
||||
yr -= dzabs; \
|
||||
} \
|
||||
if (xr >= dyabs) { \
|
||||
px += sdx; \
|
||||
xr -= dzabs; \
|
||||
} \
|
||||
pz += sdz; \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
#define SWAP(a,b) \
|
||||
G_STMT_START { \
|
||||
typeof (a) tmp; \
|
||||
tmp = (a); \
|
||||
(a) = (b); \
|
||||
(b) = (tmp); \
|
||||
} G_STMT_END
|
||||
|
||||
#define SIGN(a) ((a) < 0 ? -1 : 1)
|
||||
|
||||
#define PREPARE_3D_LINE(x0,y0,z0,x1,y1,z1,dxabs,dyabs,dzabs,sdx,sdy,sdz,xr,yr,zr,px,py,pz)\
|
||||
G_STMT_START { \
|
||||
typeof (x0) dx, dy, dz; \
|
||||
dx = x1 - x0; \
|
||||
dy = y1 - y0; \
|
||||
dz = z1 - z0; \
|
||||
dxabs = abs (dx); \
|
||||
dyabs = abs (dy); \
|
||||
dzabs = abs (dz); \
|
||||
sdx = SIGN (dx); \
|
||||
sdy = SIGN (dy); \
|
||||
sdz = SIGN (dz); \
|
||||
xr = dxabs >> 1; \
|
||||
yr = dyabs >> 1; \
|
||||
zr = dzabs >> 1; \
|
||||
px = x0; \
|
||||
py = y0; \
|
||||
pz = z0; \
|
||||
} G_STMT_END
|
||||
|
||||
void
|
||||
gst_smpte_paint_triangle_linear (guint32 *dest, gint stride,
|
||||
gint x0, gint y0, gint c0,
|
||||
gint x1, gint y1, gint c1, gint x2, gint y2, gint c2)
|
||||
{
|
||||
gint sdxl, sdyl, sdcl, dxlabs, dylabs, dclabs, xrl, yrl, crl, pxl, pyl, pcl;
|
||||
gint sdxr, sdyr, sdcr, dxrabs, dyrabs, dcrabs, xrr, yrr, crr, pxr, pyr, pcr;
|
||||
gint i, j, k, seg_start, seg_end;
|
||||
|
||||
if (y0 > y1) { SWAP (x0, x1); SWAP (y0, y1); SWAP (c0, c1); }
|
||||
if (y0 > y2) { SWAP (x0, x2); SWAP (y0, y2); SWAP (c0, c2); }
|
||||
if (y1 > y2) { SWAP (x1, x2); SWAP (y1, y2); SWAP (c1, c2); }
|
||||
|
||||
PREPARE_3D_LINE (x0,y0,c0,x2,y2,c2,
|
||||
dxlabs,dylabs,dclabs,
|
||||
sdxl, sdyl,sdcl,
|
||||
xrl,yrl,crl,
|
||||
pxl,pyl,pcl);
|
||||
|
||||
PREPARE_3D_LINE (x0,y0,c0,x1,y1,c1,
|
||||
dxrabs,dyrabs,dcrabs,
|
||||
sdxr, sdyr,sdcr,
|
||||
xrr,yrr,crr,
|
||||
pxr,pyr,pcr);
|
||||
|
||||
dest = dest + stride * y0;
|
||||
seg_start = y0;
|
||||
seg_end = y1;
|
||||
|
||||
/* do two passes */
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (i = seg_start; i < seg_end; i++) {
|
||||
gint s = pxl, e = pxr, sc = pcl, ec = pcr;
|
||||
gint sign = SIGN (e - s);
|
||||
|
||||
e += sign;
|
||||
|
||||
for (j = s; j != e; j+=sign) {
|
||||
dest[j] = (ec * (j - s) + sc * (e - j)) / (e - s);
|
||||
}
|
||||
while (pyr == i) {
|
||||
STEP_3D_LINE (dxrabs, dyrabs, dcrabs, sdxr, sdyr, sdcr,
|
||||
xrr, yrr, crr, pxr, pyr, pcr);
|
||||
}
|
||||
while (pyl == i) {
|
||||
STEP_3D_LINE (dxlabs, dylabs, dclabs, sdxl, sdyl, sdcl,
|
||||
xrl, yrl, crl, pxl, pyl, pcl);
|
||||
}
|
||||
dest += stride;
|
||||
}
|
||||
|
||||
PREPARE_3D_LINE (x1,y1,c1,x2,y2,c2,
|
||||
dxrabs,dyrabs,dcrabs,
|
||||
sdxr, sdyr,sdcr,
|
||||
xrr,yrr,crr,
|
||||
pxr,pyr,pcr);
|
||||
|
||||
seg_start = y1;
|
||||
seg_end = y2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,14 +22,20 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
void gst_smpte_paint_rect (guint8 *dest, gint stride,
|
||||
gint x, gint y, gint w, gint h,
|
||||
guint8 color);
|
||||
void gst_smpte_paint_vbox (guint32 *dest, gint stride,
|
||||
gint x0, gint y0, gint c0,
|
||||
gint x1, gint y1, gint c1);
|
||||
void gst_smpte_paint_hbox (guint32 *dest, gint stride,
|
||||
gint x0, gint y0, gint c0,
|
||||
gint x1, gint y1, gint c1);
|
||||
|
||||
void gst_smpte_paint_rect_s (guint8 *dest, gint stride,
|
||||
gint x, gint y, gint w, gint h,
|
||||
guint8 color);
|
||||
void gst_smpte_paint_rect16 (guint16 *dest, gint depth, gint width, gint height);
|
||||
|
||||
|
||||
void gst_smpte_paint_triangle_linear (guint32 *dest, gint stride,
|
||||
gint x0, gint y0, gint c0,
|
||||
gint x1, gint y1, gint c1,
|
||||
gint x2, gint y2, gint c2);
|
||||
|
||||
|
||||
#endif /* __GST_SMPTE_PAINT_H__ */
|
||||
|
|
Loading…
Reference in a new issue