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"
24 #include "play_core.h"
26 #define one_subpixel one_subpixel_gamma_clamp_oldpix
27 //#define one_subpixel one_subpixel_clamp
30 do_one_pixel(sparrow_play_t
*player
, guint8
*outpix
, guint8
*inpix
, guint8
*jpegpix
,
32 outpix
[0] = one_subpixel(player
, inpix
[0], jpegpix
[0], oldframe
[0]);
33 outpix
[1] = one_subpixel(player
, inpix
[1], jpegpix
[1], oldframe
[1]);
34 outpix
[2] = one_subpixel(player
, inpix
[2], jpegpix
[2], oldframe
[2]);
35 outpix
[3] = one_subpixel(player
, inpix
[3], jpegpix
[3], oldframe
[3]);
39 select_jpeg_adaptive(GstSparrow
*sparrow
, sparrow_play_t
*player
){
41 GST_DEBUG("in select_jpeg_adaptive, starting at %d", player->jpeg_index);
42 GstBuffer *oldbuf = player->old_frames[player->old_frames_tail];
44 GST_DEBUG("old buffer is not there! using random jump: %d to %d",
45 player->jpeg_index, player->jpeg_index);
46 return RANDINT(sparrow, 0, sparrow->shared->image_count);
48 guint8 *old_frame = (guint8 *)GST_BUFFER_DATA(oldbuf);
50 cvResize( const CvArr* src, CvArr* dst, CV_INTER_LINEAR)
53 guint32 summary[6 * 8 * PIXSIZE] = {0};
54 int xdiv = sparrow->out.width / 8;
55 int ydiv = sparrow->out.height / 6;
58 for (y2 = 0; y2 < 6; y2++){
59 for (y = y2 * ydiv; y < (y2 + 1) * ydiv; y += 4){
60 for (x2 = 0; x2 < 8; x2++){
61 for (x = x2 * xdiv; x < (x2 + 1) * xdiv; x++){
63 int i = y * sparrow->out.width + x;
65 summary[i2 + ] += old_frame[];
70 for (x = 0; x < sparrow->out.width; x++){
75 GST_DEBUG("in select_jpeg_adaptive");
77 return RANDINT(sparrow
, 0, sparrow
->shared
->image_count
);
82 set_up_jpeg(GstSparrow
*sparrow
, sparrow_play_t
*player
){
83 /*XXX pick a jpeg, somehow*/
84 /*first, chance of random jump anywhere. */
85 if (rng_uniform(sparrow
) < 1.0 / 500){
86 player
->jpeg_index
= RANDINT(sparrow
, 0, sparrow
->shared
->image_count
);
87 GST_DEBUG("CHANGE_SHOT: random jump: %d to %d", player
->jpeg_index
, player
->jpeg_index
);
90 sparrow_frame_t
*old_frame
= &sparrow
->shared
->index
[player
->jpeg_index
];
91 int next
= old_frame
->successors
[0];
93 int i
= RANDINT(sparrow
, 1, 8);
95 next
= old_frame
->successors
[i
];
96 GST_DEBUG("CHANGE_SHOT: %d to %d (option %d)", player
->jpeg_index
, next
, i
);
99 next
= select_jpeg_adaptive(sparrow
, player
);
102 player
->jpeg_index
= next
;
105 sparrow_frame_t
*frame
= &sparrow
->shared
->index
[player
->jpeg_index
];
106 guint8
*src
= sparrow
->shared
->jpeg_blob
+ frame
->offset
;
107 guint size
= frame
->jpeg_size
;
108 GST_DEBUG("blob is %p, offset %d, src %p, size %d\n",
109 sparrow
->shared
->jpeg_blob
, frame
->offset
, src
, size
);
111 begin_reading_jpeg(sparrow
, src
, size
);
115 play_from_full_lut(GstSparrow
*sparrow
, guint8
*in
, guint8
*out
){
116 sparrow_play_t
*player
= sparrow
->helper_struct
;
119 guint32
*out32
= (guint32
*)out
;
120 guint32
*in32
= (guint32
*)in
;
121 GstBuffer
*oldbuf
= player
->old_frames
[player
->old_frames_tail
];
122 guint8
*old_frame
= (oldbuf
) ? (guint8
*)GST_BUFFER_DATA(oldbuf
) : out
;
124 set_up_jpeg(sparrow
, player
);
126 guint8
*jpeg_row
= player
->image_row
;
128 for (oy
= 0; oy
< sparrow
->out
.height
; oy
++){
129 read_one_line(sparrow
, jpeg_row
);
130 for (ox
= 0; ox
< sparrow
->out
.width
; ox
++, i
++){
131 guint inpos
= sparrow
->map_lut
[i
];
135 (guint8
*)&in32
[inpos
],
136 &jpeg_row
[ox
* PIXSIZE
],
137 &old_frame
[i
* PIXSIZE
]
145 finish_reading_jpeg(sparrow
);
147 if (DEBUG_PLAY
&& sparrow
->debug
){
148 debug_frame(sparrow
, out
, sparrow
->out
.width
, sparrow
->out
.height
, PIXSIZE
);
153 store_old_frame(GstSparrow
*sparrow
, GstBuffer
*outbuf
){
154 sparrow_play_t
*player
= sparrow
->helper_struct
;
155 player
->old_frames
[player
->old_frames_head
] = outbuf
;
156 gst_buffer_ref(outbuf
);
157 player
->old_frames_head
++;
158 player
->old_frames_head
%= OLD_FRAMES
;
162 drop_old_frame(GstSparrow
*sparrow
, GstBuffer
*outbuf
){
163 sparrow_play_t
*player
= sparrow
->helper_struct
;
164 GstBuffer
*tail
= player
->old_frames
[player
->old_frames_tail
];
166 gst_buffer_unref(tail
);
168 player
->old_frames_tail
++;
169 player
->old_frames_tail
%= OLD_FRAMES
;
173 INVISIBLE sparrow_state
174 mode_play(GstSparrow
*sparrow
, GstBuffer
*inbuf
, GstBuffer
*outbuf
){
175 guint8
*in
= GST_BUFFER_DATA(inbuf
);
176 guint8
*out
= GST_BUFFER_DATA(outbuf
);
177 store_old_frame(sparrow
, outbuf
);
178 play_from_full_lut(sparrow
, in
, out
);
179 drop_old_frame(sparrow
, outbuf
);
180 return SPARROW_STATUS_QUO
;
185 init_gamma_lut(sparrow_play_t
*player
){
187 1. perform inverse gamma calculation (-> linear colour space)
191 for (int i
= 0; i
< 256; i
++){
194 x
= pow(x
, GAMMA
) * (GAMMA_UNIT_LIMIT
- 1);
195 if (x
>= GAMMA_UNIT_LIMIT
){
196 x
= GAMMA_UNIT_LIMIT
- 1;
198 player
->lut_f
[i
] = (guint16
)x
;
200 for (int i
= GAMMA_FLOOR
; i
< GAMMA_UNIT_LIMIT
; i
++){
202 x
= (double)i
/ (GAMMA_UNIT_LIMIT
- GAMMA_FLOOR
- 1);
203 x
= pow(x
, INV_GAMMA
) * 255 + 0.5;
207 player
->lut_b
[i
] = (guint8
)x
;
209 /*add some extra on the table to catch overflow -- should perhaps ramp
210 toward 255, if the top is not that high
211 XXX current implemetation doesn't use this*/
212 for (int i
= GAMMA_UNIT_LIMIT
; i
< GAMMA_TABLE_TOP
; i
++){
213 player
->lut_b
[i
] = 255;
217 INVISIBLE
void init_play(GstSparrow
*sparrow
){
218 GST_DEBUG("starting play mode\n");
219 init_jpeg_src(sparrow
);
220 sparrow_play_t
*player
= zalloc_aligned_or_die(sizeof(sparrow_play_t
));
221 player
->image_row
= zalloc_aligned_or_die(sparrow
->out
.width
* PIXSIZE
);
222 player
->old_frames_head
= MIN(sparrow
->lag
, OLD_FRAMES
- 1) || 1;
223 GST_INFO("using old frame lag of %d\n", player
->old_frames_head
);
224 sparrow
->helper_struct
= player
;
225 init_gamma_lut(player
);
226 GST_DEBUG("finished init_play\n");
229 INVISIBLE
void finalise_play(GstSparrow
*sparrow
){
230 GST_DEBUG("leaving play mode\n");