1 /* Copyright (C) <2010> Douglas Bagnall <douglas@halo.gen.nz>
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Library General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 02111-1307, USA.
20 #include "gstsparrow.h"
25 /* static functions (via `make cproto`) */
28 /* set up whatever debugging methods are enabled */
30 init_debug(GstSparrow
*sparrow
){
31 if (!sparrow
->debug_frame
){
32 sparrow
->debug_frame
= malloc_aligned_or_die(MAX(sparrow
->in
.size
, sparrow
->out
.size
));
37 /*seed with -1 for automatic seed choice */
38 static void rng_init(GstSparrow
*sparrow
, guint32 seed
){
39 GST_DEBUG("in RNG init\n");
40 if (seed
== (guint32
)-1){
41 /* XXX should really use /dev/urandom */
43 GST_DEBUG("Real seed %u\n", seed
);
48 dsfmt_init_gen_rand(sparrow
->dsfmt
, seed
);
49 dsfmt_gen_rand_all(sparrow
->dsfmt
);
50 GST_DEBUG("RNG seeded with %u\n", seed
);
53 /** debugging: write frames out somewhere. **/
55 /*spit out the frame as a ppm image */
57 ppm_dump(sparrow_format
*rgb
, guint8
*data
, guint32 width
, guint32 height
, char *name
)
60 FILE *fh
= fopen(name
, "w");
61 guint32 size
= width
* height
;
62 fprintf(fh
, "P6\n%u %u\n255\n", width
, height
);
63 /* 4 cases: xBGR xRGB BGRx RGBx
64 need to convert to 24bit R G B
65 XX maybe could optimise some cases?
67 guint32
*p
= (guint32
*)data
;
68 for (i
= 0; i
< size
; i
++){
69 putc((*p
>> rgb
->rshift
) & 255, fh
);
70 putc((*p
>> rgb
->gshift
) & 255, fh
);
71 putc((*p
>> rgb
->bshift
) & 255, fh
);
79 #define PPM_FILENAME_TEMPLATE "/tmp/sparrow_%05d.ppm"
80 #define PPM_FILENAME_LENGTH (sizeof(PPM_FILENAME_TEMPLATE) + 10)
83 debug_frame(GstSparrow
*sparrow
, guint8
*data
, guint32 width
, guint32 height
){
85 char name
[PPM_FILENAME_LENGTH
];
86 int res
= snprintf(name
, PPM_FILENAME_LENGTH
, PPM_FILENAME_TEMPLATE
, sparrow
->frame_count
);
88 ppm_dump(&(sparrow
->in
), data
, width
, height
, name
);
93 /** interpret gst attributes **/
95 /* Extract a colour (R,G,B) bitmask from gobject */
96 static guint32
get_mask(GstStructure
*s
, char *mask_name
){
98 int res
= gst_structure_get_int(s
, mask_name
, &mask
);
100 GST_WARNING("No mask for '%s' !\n", mask_name
);
102 return (guint32
)mask
;
106 extract_caps(sparrow_format
*im
, GstCaps
*caps
)
108 GstStructure
*s
= gst_caps_get_structure (caps
, 0);
109 gst_structure_get_int(s
, "width", &(im
->width
));
110 gst_structure_get_int(s
, "height", &(im
->height
));
111 im
->rmask
= get_mask(s
, "red_mask");
112 im
->rshift
= mask_to_shift(im
->rmask
);
113 im
->gmask
= get_mask(s
, "green_mask");
114 im
->gshift
= mask_to_shift(im
->gmask
);
115 im
->bmask
= get_mask(s
, "blue_mask");
116 im
->bshift
= mask_to_shift(im
->bmask
);
118 im
->pixcount
= im
->width
* im
->height
;
119 im
->size
= im
->pixcount
* PIXSIZE
;
121 GST_DEBUG("\ncaps:\n%" GST_PTR_FORMAT
, caps
);
122 GST_DEBUG("shifts: r %u g %u b %u\n", im
->rshift
, im
->gshift
, im
->bshift
);
123 GST_DEBUG("dimensions: w %u h %u pix %u size %u\n", im
->width
, im
->height
,
124 im
->pixcount
, im
->size
);
129 /*Functions below here are called from gstsparrow.c and are NOT static */
132 sparrow_rotate_history(GstSparrow
*sparrow
, GstBuffer
*inbuf
){
133 if (sparrow
->in_buffer
){
134 gst_buffer_unref(sparrow
->prev_buffer
);
135 sparrow
->prev_buffer
= sparrow
->in_buffer
;
136 sparrow
->prev_frame
= sparrow
->in_frame
;
138 gst_buffer_ref(inbuf
);
139 sparrow
->in_buffer
= inbuf
;
141 sparrow
->in_frame
= GST_BUFFER_DATA(inbuf
);
144 /* called by gst_sparrow_init() */
146 sparrow_pre_init(GstSparrow
*sparrow
){
149 /* called by gst_sparrow_set_caps() */
151 sparrow_init(GstSparrow
*sparrow
, GstCaps
*incaps
, GstCaps
*outcaps
){
152 extract_caps(&(sparrow
->in
), incaps
);
153 extract_caps(&(sparrow
->out
), outcaps
);
154 sparrow_format
*in
= &(sparrow
->in
);
156 GST_DEBUG("allocating %u * %u for lag_table\n", in
->pixcount
, sizeof(lag_times_t
));
157 sparrow
->lag_table
= zalloc_aligned_or_die(in
->pixcount
* sizeof(lag_times_t
));
158 sparrow
->work_frame
= zalloc_aligned_or_die(in
->size
);
159 sparrow
->dsfmt
= zalloc_aligned_or_die(sizeof(dsfmt_t
));
161 sparrow
->prev_buffer
= gst_buffer_new_and_alloc(in
->size
);
162 sparrow
->prev_frame
= GST_BUFFER_DATA(sparrow
->prev_buffer
);
163 memset(sparrow
->prev_frame
, 0, in
->size
);
165 /*initialise IPL structs for openCV */
166 for (int i
= 0; i
< 3; i
++){
167 sparrow
->in_ipl
[i
] = init_ipl_image(&(sparrow
->in
));
170 rng_init(sparrow
, sparrow
->rng_seed
);
176 change_state(sparrow
, SPARROW_FIND_SELF
);
182 sparrow_finalise(GstSparrow
*sparrow
)
186 //cvReleaseImageHeader(IplImage** image)
190 /*when a state is done, it calls back here and names its preferred
193 change_state(GstSparrow
*sparrow
, sparrow_state state
)
196 case SPARROW_FIND_SELF
:
197 reset_find_self(sparrow
, 1);
199 case SPARROW_FIND_EDGES
:
200 init_find_edges(sparrow
);
202 case SPARROW_WAIT_FOR_GRID
:
204 case SPARROW_FIND_GRID
:
205 calibrate_init_grid(sparrow
);
211 sparrow
->state
= state
;
216 /*called by gst_sparrow_transform_ip */
218 sparrow_transform(GstSparrow
*sparrow
, guint8
*in
, guint8
*out
)
220 switch(sparrow
->state
){
221 case SPARROW_FIND_SELF
:
222 find_self(sparrow
, in
, out
);
224 case SPARROW_WAIT_FOR_GRID
:
225 if (wait_for_blank(sparrow
, in
, out
)){
226 change_state(sparrow
, SPARROW_FIND_EDGES
);
229 case SPARROW_FIND_EDGES
:
230 find_edges(sparrow
, in
, out
);
233 gamma_negation(sparrow
, in
, out
);
235 sparrow
->frame_count
++;