Rev 6133 | Rev 6136 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6133 | Rev 6135 | ||
---|---|---|---|
1 | #include |
1 | #include |
2 | #include |
2 | #include |
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | #include |
6 | #include |
7 | #include |
7 | #include |
8 | #include |
8 | #include |
9 | 9 | ||
10 | #include "winlib/winlib.h" |
10 | #include "winlib/winlib.h" |
11 | #include "fplay.h" |
11 | #include "fplay.h" |
12 | 12 | ||
13 | extern int res_pause_btn[]; |
13 | extern int res_pause_btn[]; |
14 | extern int res_pause_btn_pressed[]; |
14 | extern int res_pause_btn_pressed[]; |
15 | 15 | ||
16 | extern int res_play_btn[]; |
16 | extern int res_play_btn[]; |
17 | extern int res_play_btn_pressed[]; |
17 | extern int res_play_btn_pressed[]; |
18 | 18 | ||
19 | extern int64_t stream_duration; |
19 | extern int64_t stream_duration; |
20 | extern volatile int sound_level_0; |
20 | extern volatile int sound_level_0; |
21 | extern volatile int sound_level_1; |
21 | extern volatile int sound_level_1; |
22 | 22 | ||
23 | volatile int frames_count = 0; |
23 | volatile int frames_count = 0; |
24 | 24 | ||
25 | struct SwsContext *cvt_ctx = NULL; |
25 | struct SwsContext *cvt_ctx = NULL; |
26 | 26 | ||
27 | 27 | ||
28 | render_t *main_render; |
28 | render_t *main_render; |
29 | 29 | ||
30 | AVRational video_time_base; |
30 | AVRational video_time_base; |
31 | AVFrame *Frame; |
31 | AVFrame *Frame; |
32 | 32 | ||
33 | void get_client_rect(rect_t *rc); |
33 | void get_client_rect(rect_t *rc); |
34 | void run_render(window_t *win, void *render); |
34 | void run_render(window_t *win, void *render); |
35 | void window_update_layout(window_t *win); |
35 | void window_update_layout(window_t *win); |
36 | int fini_winlib(); |
36 | int fini_winlib(); |
37 | 37 | ||
38 | void flush_video(vst_t *vst) |
38 | void flush_video(vst_t *vst) |
39 | { |
39 | { |
40 | vframe_t *vframe, *tmp; |
40 | vframe_t *vframe, *tmp; |
41 | 41 | ||
42 | mutex_lock(&vst->output_lock); |
42 | mutex_lock(&vst->output_lock); |
43 | mutex_lock(&vst->input_lock); |
43 | mutex_lock(&vst->input_lock); |
44 | 44 | ||
45 | list_for_each_entry_safe(vframe, tmp, &vst->output_list, list) |
45 | list_for_each_entry_safe(vframe, tmp, &vst->output_list, list) |
46 | list_move_tail(&vframe->list, &vst->input_list); |
46 | list_move_tail(&vframe->list, &vst->input_list); |
47 | 47 | ||
48 | list_for_each_entry(vframe, &vst->output_list, list) |
48 | list_for_each_entry(vframe, &vst->output_list, list) |
49 | { |
49 | { |
50 | vframe->pts = 0; |
50 | vframe->pts = 0; |
51 | vframe->ready = 0; |
51 | vframe->ready = 0; |
52 | } |
52 | } |
53 | 53 | ||
54 | mutex_unlock(&vst->input_lock); |
54 | mutex_unlock(&vst->input_lock); |
55 | mutex_unlock(&vst->output_lock); |
55 | mutex_unlock(&vst->output_lock); |
56 | 56 | ||
57 | frames_count = 0; |
57 | frames_count = 0; |
58 | }; |
58 | }; |
59 | 59 | ||
60 | int init_video(vst_t *vst) |
60 | int init_video(vst_t *vst) |
61 | { |
61 | { |
62 | Frame = av_frame_alloc(); |
62 | Frame = av_frame_alloc(); |
63 | if ( Frame == NULL ) |
63 | if ( Frame == NULL ) |
64 | { |
64 | { |
65 | printf("Cannot alloc video frame\n\r"); |
65 | printf("Cannot alloc video frame\n\r"); |
66 | return 0; |
66 | return 0; |
67 | }; |
67 | }; |
68 | 68 | ||
69 | mutex_lock(&vst->decoder_lock); |
69 | mutex_lock(&vst->decoder_lock); |
70 | 70 | ||
71 | create_thread(video_thread, vst, 1024*1024); |
71 | create_thread(video_thread, vst, 1024*1024); |
72 | 72 | ||
73 | return 1; |
73 | return 1; |
74 | }; |
74 | }; |
75 | 75 | ||
76 | static double dts = 0.0; |
76 | static double dts = 0.0; |
77 | 77 | ||
78 | int decode_video(vst_t* vst) |
78 | static vframe_t *get_input_frame(vst_t *vst) |
79 | { |
79 | { |
80 | AVPacket pkt; |
- | |
81 | double pts; |
- | |
82 | int frameFinished; |
80 | vframe_t *vframe = NULL; |
83 | - | ||
84 | if(vst->decoder_frame == NULL) |
- | |
85 | { |
81 | |
86 | mutex_lock(&vst->input_lock); |
82 | mutex_lock(&vst->input_lock); |
87 | if(list_empty(&vst->input_list)) |
83 | if(!list_empty(&vst->input_list)) |
88 | { |
84 | { |
89 | mutex_unlock(&vst->input_lock); |
85 | vframe = list_first_entry(&vst->input_list, vframe_t, list); |
90 | return -1; |
86 | list_del(&vframe->list); |
91 | } |
- | |
92 | vst->decoder_frame = list_first_entry(&vst->input_list, vframe_t, list); |
- | |
93 | list_del(&vst->decoder_frame->list); |
87 | } |
- | 88 | mutex_unlock(&vst->input_lock); |
|
- | 89 | ||
- | 90 | return vframe; |
|
- | 91 | } |
|
- | 92 | ||
- | 93 | static void put_output_frame(vst_t *vst, vframe_t *vframe) |
|
- | 94 | { |
|
94 | mutex_unlock(&vst->input_lock); |
95 | mutex_lock(&vst->output_lock); |
- | 96 | if(list_empty(&vst->output_list)) |
|
- | 97 | list_add_tail(&vframe->list, &vst->output_list); |
|
- | 98 | else |
|
- | 99 | { |
|
- | 100 | vframe_t *cur; |
|
- | 101 | ||
- | 102 | cur = list_first_entry(&vst->output_list,vframe_t,list); |
|
- | 103 | if(vframe->pts < cur->pts) |
|
- | 104 | list_add_tail(&vframe->list, &vst->output_list); |
|
- | 105 | else |
|
- | 106 | { |
|
- | 107 | list_for_each_entry_reverse(cur,&vst->output_list,list) |
|
- | 108 | { |
|
- | 109 | if(vframe->pts > cur->pts) |
|
- | 110 | { |
|
- | 111 | list_add(&vframe->list, &cur->list); |
|
- | 112 | break; |
|
- | 113 | }; |
|
- | 114 | }; |
|
- | 115 | }; |
|
95 | 116 | }; |
|
96 | vframe_t *vframe = vst->decoder_frame; |
117 | mutex_unlock(&vst->output_lock); |
97 | }; |
118 | }; |
- | 119 | ||
- | 120 | int decode_video(vst_t* vst) |
|
- | 121 | { |
|
- | 122 | AVPacket pkt; |
|
- | 123 | double pts; |
|
- | 124 | int frameFinished; |
|
- | 125 | ||
- | 126 | if(vst->decoder_frame == NULL) |
|
- | 127 | vst->decoder_frame = get_input_frame(vst); |
|
- | 128 | ||
- | 129 | if(vst->decoder_frame == NULL) |
|
98 | 130 | return 0; |
|
99 | if( get_packet(&vst->q_video, &pkt) == 0 ) |
- | |
100 | { |
131 | |
101 | return 0; |
132 | if( get_packet(&vst->q_video, &pkt) == 0 ) |
102 | }; |
133 | return 0; |
103 | 134 | ||
104 | frameFinished = 0; |
135 | frameFinished = 0; |
105 | if(dts == 0) |
136 | if(dts == 0) |
106 | dts = pkt.pts; |
137 | dts = pkt.pts; |
107 | 138 | ||
108 | mutex_lock(&vst->gpu_lock); |
139 | mutex_lock(&vst->gpu_lock); |
109 | 140 | ||
110 | if(avcodec_decode_video2(vst->vCtx, Frame, &frameFinished, &pkt) <= 0) |
141 | if(avcodec_decode_video2(vst->vCtx, Frame, &frameFinished, &pkt) <= 0) |
111 | printf("video decoder error\n"); |
142 | printf("video decoder error\n"); |
112 | 143 | ||
113 | if(frameFinished) |
144 | if(frameFinished) |
114 | { |
145 | { |
115 | vframe_t *vframe; |
146 | vframe_t *vframe = vst->decoder_frame;; |
116 | AVPicture *dst_pic; |
147 | AVPicture *dst_pic; |
117 | 148 | ||
- | 149 | if(vst->hwdec) |
|
- | 150 | pts = pkt.pts; |
|
- | 151 | else |
|
118 | pts = av_frame_get_best_effort_timestamp(Frame); |
152 | pts = av_frame_get_best_effort_timestamp(Frame); |
- | 153 | ||
119 | pts *= av_q2d(video_time_base); |
154 | pts*= av_q2d(video_time_base); |
120 | - | ||
121 | vframe = vst->decoder_frame; |
155 | |
122 | dst_pic = &vframe->picture; |
156 | dst_pic = &vframe->picture; |
123 | 157 | ||
124 | if(vframe->is_hw_pic == 0) |
158 | if(vframe->is_hw_pic == 0) |
125 | av_image_copy(dst_pic->data, dst_pic->linesize, |
159 | av_image_copy(dst_pic->data, dst_pic->linesize, |
126 | (const uint8_t**)Frame->data, |
160 | (const uint8_t**)Frame->data, |
127 | Frame->linesize, vst->vCtx->pix_fmt, vst->vCtx->width, vst->vCtx->height); |
161 | Frame->linesize, vst->vCtx->pix_fmt, vst->vCtx->width, vst->vCtx->height); |
128 | else |
162 | else |
129 | va_create_planar(vst, vframe); |
163 | va_create_planar(vst, vframe); |
130 | 164 | ||
131 | vframe->pts = pts*1000.0; |
165 | vframe->pts = pts*1000.0; |
132 | vframe->pkt_pts = pkt.pts*av_q2d(video_time_base)*1000.0; |
166 | vframe->pkt_pts = pkt.pts*av_q2d(video_time_base)*1000.0; |
133 | vframe->pkt_dts = dts*av_q2d(video_time_base)*1000.0; |
167 | vframe->pkt_dts = dts*av_q2d(video_time_base)*1000.0; |
134 | vframe->ready = 1; |
168 | vframe->ready = 1; |
135 | 169 | ||
136 | - | ||
137 | mutex_lock(&vst->output_lock); |
170 | put_output_frame(vst, vframe); |
138 | - | ||
139 | if(list_empty(&vst->output_list)) |
- | |
140 | list_add_tail(&vframe->list, &vst->output_list); |
- | |
141 | else |
- | |
142 | { |
- | |
143 | vframe_t *cur; |
- | |
144 | - | ||
145 | cur = list_first_entry(&vst->output_list,vframe_t,list); |
- | |
146 | if(vframe->pkt_pts < cur->pkt_pts) |
- | |
147 | { |
- | |
148 | list_add_tail(&vframe->list, &vst->output_list); |
- | |
149 | } |
- | |
150 | else |
- | |
151 | { |
- | |
152 | list_for_each_entry_reverse(cur,&vst->output_list,list) |
- | |
153 | { |
- | |
154 | if(vframe->pkt_pts > cur->pkt_pts) |
- | |
155 | { |
- | |
156 | list_add(&vframe->list, &cur->list); |
- | |
157 | break; |
- | |
158 | }; |
- | |
159 | }; |
- | |
160 | }; |
- | |
161 | }; |
- | |
162 | mutex_unlock(&vst->output_lock); |
- | |
163 | - | ||
164 | 171 | ||
165 | // printf("decoded index: %d pts: %f pkt_pts %f pkt_dts %f\n", |
172 | // printf("decoded index: %d pts: %f pkt_pts %f pkt_dts %f\n", |
166 | // vst->dfx, vst->vframe[vst->dfx].pts, |
173 | // vst->dfx, vst->vframe[vst->dfx].pts, |
167 | // vst->vframe[vst->dfx].pkt_pts, vst->vframe[vst->dfx].pkt_dts); |
174 | // vst->vframe[vst->dfx].pkt_pts, vst->vframe[vst->dfx].pkt_dts); |
168 | 175 | ||
169 | vst->decoder_frame = NULL; |
176 | vst->decoder_frame = NULL; |
170 | frames_count++; |
177 | frames_count++; |
171 | dts = 0; |
178 | dts = 0; |
172 | }; |
179 | }; |
173 | av_frame_unref(Frame); |
180 | av_frame_unref(Frame); |
174 | mutex_unlock(&vst->gpu_lock); |
181 | mutex_unlock(&vst->gpu_lock); |
175 | 182 | ||
176 | av_free_packet(&pkt); |
183 | av_free_packet(&pkt); |
177 | 184 | ||
178 | return 1; |
185 | return 1; |
179 | } |
186 | } |
180 | 187 | ||
181 | extern volatile enum player_state player_state; |
188 | extern volatile enum player_state player_state; |
182 | extern volatile enum player_state decoder_state; |
189 | extern volatile enum player_state decoder_state; |
183 | extern volatile enum player_state sound_state; |
190 | extern volatile enum player_state sound_state; |
184 | 191 | ||
185 | extern int64_t rewind_pos; |
192 | extern int64_t rewind_pos; |
186 | 193 | ||
187 | static void player_stop() |
194 | static void player_stop() |
188 | { |
195 | { |
189 | window_t *win; |
196 | window_t *win; |
190 | 197 | ||
191 | win = main_render->win; |
198 | win = main_render->win; |
192 | 199 | ||
193 | rewind_pos = 0; |
200 | rewind_pos = 0; |
194 | 201 | ||
195 | win->panel.play_btn->img_default = res_play_btn; |
202 | win->panel.play_btn->img_default = res_play_btn; |
196 | win->panel.play_btn->img_hilite = res_play_btn; |
203 | win->panel.play_btn->img_hilite = res_play_btn; |
197 | win->panel.play_btn->img_pressed = res_play_btn_pressed; |
204 | win->panel.play_btn->img_pressed = res_play_btn_pressed; |
198 | win->panel.prg->current = rewind_pos; |
205 | win->panel.prg->current = rewind_pos; |
199 | 206 | ||
200 | send_message(&win->panel.ctrl, MSG_PAINT, 0, 0); |
207 | send_message(&win->panel.ctrl, MSG_PAINT, 0, 0); |
201 | player_state = STOP; |
208 | player_state = STOP; |
202 | decoder_state = PLAY_2_STOP; |
209 | decoder_state = PLAY_2_STOP; |
203 | sound_state = PLAY_2_STOP; |
210 | sound_state = PLAY_2_STOP; |
204 | render_draw_client(main_render); |
211 | render_draw_client(main_render); |
205 | }; |
212 | }; |
206 | 213 | ||
207 | int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2) |
214 | int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2) |
208 | { |
215 | { |
209 | window_t *win = (window_t*)ctrl; |
216 | window_t *win = (window_t*)ctrl; |
210 | static int spc_down = 0; |
217 | static int spc_down = 0; |
211 | static int ent_down = 0; |
218 | static int ent_down = 0; |
212 | 219 | ||
213 | switch(msg) |
220 | switch(msg) |
214 | { |
221 | { |
215 | case MSG_SIZE: |
222 | case MSG_SIZE: |
216 | if(main_render) |
223 | if(main_render) |
217 | { |
224 | { |
218 | render_adjust_size(main_render, win); |
225 | render_adjust_size(main_render, win); |
219 | render_draw_client(main_render); |
226 | render_draw_client(main_render); |
220 | }; |
227 | }; |
221 | break; |
228 | break; |
222 | 229 | ||
223 | case MSG_KEY: |
230 | case MSG_KEY: |
224 | switch((short)arg2) |
231 | switch((short)arg2) |
225 | { |
232 | { |
226 | case 0x39: |
233 | case 0x39: |
227 | if(spc_down == 0) |
234 | if(spc_down == 0) |
228 | { |
235 | { |
229 | spc_down = 1; |
236 | spc_down = 1; |
230 | send_message(win, MSG_LBTNDOWN, 0, 0); |
237 | send_message(win, MSG_LBTNDOWN, 0, 0); |
231 | } |
238 | } |
232 | break; |
239 | break; |
233 | 240 | ||
234 | case 0xB9: |
241 | case 0xB9: |
235 | spc_down = 0; |
242 | spc_down = 0; |
236 | break; |
243 | break; |
237 | 244 | ||
238 | case 0x1C: |
245 | case 0x1C: |
239 | if(ent_down == 0) |
246 | if(ent_down == 0) |
240 | { |
247 | { |
241 | int screensize; |
248 | int screensize; |
242 | if(win->win_state == NORMAL) |
249 | if(win->win_state == NORMAL) |
243 | { |
250 | { |
244 | win->saved = win->rc; |
251 | win->saved = win->rc; |
245 | win->saved_state = win->win_state; |
252 | win->saved_state = win->win_state; |
246 | 253 | ||
247 | screensize = GetScreenSize(); |
254 | screensize = GetScreenSize(); |
248 | __asm__ __volatile__( |
255 | __asm__ __volatile__( |
249 | "int $0x40" |
256 | "int $0x40" |
250 | ::"a"(67), "b"(0), "c"(0), |
257 | ::"a"(67), "b"(0), "c"(0), |
251 | "d"((screensize >> 16)-1),"S"((screensize & 0xFFFF)-1) ); |
258 | "d"((screensize >> 16)-1),"S"((screensize & 0xFFFF)-1) ); |
252 | win->win_state = FULLSCREEN; |
259 | win->win_state = FULLSCREEN; |
253 | window_update_layout(win); |
260 | window_update_layout(win); |
254 | } |
261 | } |
255 | else if(win->win_state == FULLSCREEN) |
262 | else if(win->win_state == FULLSCREEN) |
256 | { |
263 | { |
257 | __asm__ __volatile__( |
264 | __asm__ __volatile__( |
258 | "int $0x40" |
265 | "int $0x40" |
259 | ::"a"(67), "b"(win->saved.l), "c"(win->saved.t), |
266 | ::"a"(67), "b"(win->saved.l), "c"(win->saved.t), |
260 | "d"(win->saved.r-win->saved.l-1),"S"(win->saved.b-win->saved.t-1)); |
267 | "d"(win->saved.r-win->saved.l-1),"S"(win->saved.b-win->saved.t-1)); |
261 | win->win_state = win->saved_state; |
268 | win->win_state = win->saved_state; |
262 | window_update_layout(win); |
269 | window_update_layout(win); |
263 | // if(win->saved_state == MAXIMIZED) |
270 | // if(win->saved_state == MAXIMIZED) |
264 | // { |
271 | // { |
265 | // blit_caption(&win->caption); |
272 | // blit_caption(&win->caption); |
266 | // blit_panel(&win->panel); |
273 | // blit_panel(&win->panel); |
267 | // } |
274 | // } |
268 | } |
275 | } |
269 | ent_down = 1; |
276 | ent_down = 1; |
270 | }; |
277 | }; |
271 | break; |
278 | break; |
272 | 279 | ||
273 | case 0x9C: |
280 | case 0x9C: |
274 | ent_down = 0; |
281 | ent_down = 0; |
275 | break; |
282 | break; |
276 | }; |
283 | }; |
277 | 284 | ||
278 | case MSG_DRAW_CLIENT: |
285 | case MSG_DRAW_CLIENT: |
279 | if(main_render) |
286 | if(main_render) |
280 | { |
287 | { |
281 | render_draw_client(main_render); |
288 | render_draw_client(main_render); |
282 | }; |
289 | }; |
283 | break; |
290 | break; |
284 | 291 | ||
285 | case MSG_LBTNDOWN: |
292 | case MSG_LBTNDOWN: |
286 | 293 | ||
287 | if(player_state == PAUSE) |
294 | if(player_state == PAUSE) |
288 | { |
295 | { |
289 | win->panel.play_btn->img_default = res_pause_btn; |
296 | win->panel.play_btn->img_default = res_pause_btn; |
290 | win->panel.play_btn->img_hilite = res_pause_btn; |
297 | win->panel.play_btn->img_hilite = res_pause_btn; |
291 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
298 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
292 | send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0); |
299 | send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0); |
293 | player_state = PLAY; |
300 | player_state = PLAY; |
294 | sound_state = PAUSE_2_PLAY; |
301 | sound_state = PAUSE_2_PLAY; |
295 | 302 | ||
296 | } |
303 | } |
297 | else if(player_state == PLAY) |
304 | else if(player_state == PLAY) |
298 | { |
305 | { |
299 | win->panel.play_btn->img_default = res_play_btn; |
306 | win->panel.play_btn->img_default = res_play_btn; |
300 | win->panel.play_btn->img_hilite = res_play_btn; |
307 | win->panel.play_btn->img_hilite = res_play_btn; |
301 | win->panel.play_btn->img_pressed = res_play_btn_pressed; |
308 | win->panel.play_btn->img_pressed = res_play_btn_pressed; |
302 | send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0); |
309 | send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0); |
303 | player_state = PAUSE; |
310 | player_state = PAUSE; |
304 | sound_state = PLAY_2_PAUSE; |
311 | sound_state = PLAY_2_PAUSE; |
305 | } |
312 | } |
306 | break; |
313 | break; |
307 | 314 | ||
308 | case MSG_COMMAND: |
315 | case MSG_COMMAND: |
309 | switch((short)arg1) |
316 | switch((short)arg1) |
310 | { |
317 | { |
311 | case ID_PLAY: |
318 | case ID_PLAY: |
312 | if(player_state == PAUSE) |
319 | if(player_state == PAUSE) |
313 | { |
320 | { |
314 | win->panel.play_btn->img_default = res_pause_btn; |
321 | win->panel.play_btn->img_default = res_pause_btn; |
315 | win->panel.play_btn->img_hilite = res_pause_btn; |
322 | win->panel.play_btn->img_hilite = res_pause_btn; |
316 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
323 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
317 | player_state = PLAY; |
324 | player_state = PLAY; |
318 | sound_state = PAUSE_2_PLAY; |
325 | sound_state = PAUSE_2_PLAY; |
319 | } |
326 | } |
320 | else if(player_state == PLAY) |
327 | else if(player_state == PLAY) |
321 | { |
328 | { |
322 | win->panel.play_btn->img_default = res_play_btn; |
329 | win->panel.play_btn->img_default = res_play_btn; |
323 | win->panel.play_btn->img_hilite = res_play_btn; |
330 | win->panel.play_btn->img_hilite = res_play_btn; |
324 | win->panel.play_btn->img_pressed = res_play_btn_pressed; |
331 | win->panel.play_btn->img_pressed = res_play_btn_pressed; |
325 | player_state = PAUSE; |
332 | player_state = PAUSE; |
326 | sound_state = PLAY_2_PAUSE; |
333 | sound_state = PLAY_2_PAUSE; |
327 | } |
334 | } |
328 | else if(player_state == STOP) |
335 | else if(player_state == STOP) |
329 | { |
336 | { |
330 | win->panel.play_btn->img_default = res_pause_btn; |
337 | win->panel.play_btn->img_default = res_pause_btn; |
331 | win->panel.play_btn->img_hilite = res_pause_btn; |
338 | win->panel.play_btn->img_hilite = res_pause_btn; |
332 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
339 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
333 | rewind_pos = 0; |
340 | rewind_pos = 0; |
334 | send_message(&win->panel.ctrl, MSG_PAINT, 0, 0); |
341 | send_message(&win->panel.ctrl, MSG_PAINT, 0, 0); |
335 | player_state = PLAY; |
342 | player_state = PLAY; |
336 | decoder_state = PREPARE; |
343 | decoder_state = PREPARE; |
337 | } |
344 | } |
338 | break; |
345 | break; |
339 | 346 | ||
340 | case ID_STOP: |
347 | case ID_STOP: |
341 | player_stop(); |
348 | player_stop(); |
342 | break; |
349 | break; |
343 | 350 | ||
344 | case ID_PROGRESS: |
351 | case ID_PROGRESS: |
345 | if(player_state != REWIND) |
352 | if(player_state != REWIND) |
346 | { |
353 | { |
347 | progress_t *prg = (progress_t*)arg2; |
354 | progress_t *prg = (progress_t*)arg2; |
348 | 355 | ||
349 | rewind_pos = (prg->max - prg->min)*prg->pos/prg->ctrl.w; |
356 | rewind_pos = (prg->max - prg->min)*prg->pos/prg->ctrl.w; |
350 | 357 | ||
351 | player_state = REWIND; |
358 | player_state = REWIND; |
352 | decoder_state = REWIND; |
359 | decoder_state = REWIND; |
353 | sound_state = PLAY_2_STOP; |
360 | sound_state = PLAY_2_STOP; |
354 | if(rewind_pos < prg->current) |
361 | if(rewind_pos < prg->current) |
355 | { |
362 | { |
356 | prg->current = rewind_pos; |
363 | prg->current = rewind_pos; |
357 | rewind_pos = -rewind_pos; |
364 | rewind_pos = -rewind_pos; |
358 | } |
365 | } |
359 | else |
366 | else |
360 | prg->current = rewind_pos; |
367 | prg->current = rewind_pos; |
361 | 368 | ||
362 | win->panel.play_btn->img_default = res_pause_btn; |
369 | win->panel.play_btn->img_default = res_pause_btn; |
363 | win->panel.play_btn->img_hilite = res_pause_btn; |
370 | win->panel.play_btn->img_hilite = res_pause_btn; |
364 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
371 | win->panel.play_btn->img_pressed = res_pause_btn_pressed; |
365 | send_message(&prg->ctrl, MSG_PAINT, 0, 0); |
372 | send_message(&prg->ctrl, MSG_PAINT, 0, 0); |
366 | }; |
373 | }; |
367 | break; |
374 | break; |
368 | 375 | ||
369 | case ID_VOL_CTRL: |
376 | case ID_VOL_CTRL: |
370 | { |
377 | { |
371 | slider_t *sld = (slider_t*)arg2; |
378 | slider_t *sld = (slider_t*)arg2; |
372 | int peak; |
379 | int peak; |
373 | int level; |
380 | int level; |
374 | 381 | ||
375 | peak = sld->min + sld->pos * (sld->max - sld->min)/(96); |
382 | peak = sld->min + sld->pos * (sld->max - sld->min)/(96); |
376 | level = peak; |
383 | level = peak; |
377 | 384 | ||
378 | set_audio_volume(level, level); |
385 | set_audio_volume(level, level); |
379 | send_message(&sld->ctrl, MSG_PAINT, 0, 0); |
386 | send_message(&sld->ctrl, MSG_PAINT, 0, 0); |
380 | win->panel.lvl->vol = level; |
387 | win->panel.lvl->vol = level; |
381 | } |
388 | } |
382 | 389 | ||
383 | default: |
390 | default: |
384 | break; |
391 | break; |
385 | } |
392 | } |
386 | break; |
393 | break; |
387 | 394 | ||
388 | default: |
395 | default: |
389 | def_window_proc(ctrl,msg,arg1,arg2); |
396 | def_window_proc(ctrl,msg,arg1,arg2); |
390 | }; |
397 | }; |
391 | return 0; |
398 | return 0; |
392 | }; |
399 | }; |
393 | 400 | ||
394 | void render_time(render_t *render) |
401 | void render_time(render_t *render) |
395 | { |
402 | { |
396 | progress_t *prg = main_render->win->panel.prg; |
403 | progress_t *prg = main_render->win->panel.prg; |
397 | level_t *lvl = main_render->win->panel.lvl; |
404 | level_t *lvl = main_render->win->panel.lvl; |
398 | vst_t *vst = main_render->vst; |
405 | vst_t *vst = main_render->vst; |
399 | double ctime; /* milliseconds */ |
406 | double ctime; /* milliseconds */ |
400 | double fdelay; /* milliseconds */ |
407 | double fdelay; /* milliseconds */ |
401 | 408 | ||
402 | if(player_state == CLOSED) |
409 | if(player_state == CLOSED) |
403 | { |
410 | { |
404 | render->win->win_command = WIN_CLOSED; |
411 | render->win->win_command = WIN_CLOSED; |
405 | return; |
412 | return; |
406 | } |
413 | } |
407 | else if((player_state == PAUSE) || (player_state == REWIND)) |
414 | else if((player_state == PAUSE) || (player_state == REWIND)) |
408 | { |
415 | { |
409 | delay(1); |
416 | delay(1); |
410 | return; |
417 | return; |
411 | } |
418 | } |
412 | else if (decoder_state == STOP && frames_count == 0 && |
419 | else if (decoder_state == STOP && frames_count == 0 && |
413 | player_state != STOP) |
420 | player_state != STOP) |
414 | { |
421 | { |
415 | player_stop(); |
422 | player_stop(); |
416 | } |
423 | } |
417 | else if(player_state != PLAY) |
424 | else if(player_state != PLAY) |
418 | { |
425 | { |
419 | delay(1); |
426 | delay(1); |
420 | return; |
427 | return; |
421 | }; |
428 | }; |
422 | 429 | ||
423 | mutex_lock(&vst->output_lock); |
430 | mutex_lock(&vst->output_lock); |
424 | if(list_empty(&vst->output_list)) |
431 | if(list_empty(&vst->output_list)) |
425 | { |
432 | { |
426 | mutex_unlock(&vst->output_lock); |
433 | mutex_unlock(&vst->output_lock); |
427 | delay(1); |
434 | delay(1); |
428 | } |
435 | } |
429 | else |
436 | else |
430 | { |
437 | { |
431 | vframe_t *vframe; |
438 | vframe_t *vframe; |
432 | int sys_time; |
439 | int sys_time; |
433 | 440 | ||
434 | vframe = list_first_entry(&vst->output_list, vframe_t, list); |
441 | vframe = list_first_entry(&vst->output_list, vframe_t, list); |
435 | list_del(&vframe->list); |
442 | list_del(&vframe->list); |
436 | mutex_unlock(&vst->output_lock); |
443 | mutex_unlock(&vst->output_lock); |
437 | 444 | ||
438 | ctime = get_master_clock(); |
445 | ctime = get_master_clock(); |
439 | fdelay = (vframe->pkt_pts - ctime); |
446 | fdelay = (vframe->pkt_pts - ctime); |
440 | 447 | ||
441 | if(fdelay > 15.0) |
448 | if(fdelay > 15.0) |
442 | { |
449 | { |
443 | delay((int)fdelay/10); |
450 | delay((int)fdelay/10); |
444 | }; |
451 | }; |
445 | 452 | ||
446 | // printf("output index: %d pts: %f pkt_pts %f pkt_dts %f\n", |
453 | // printf("output index: %d pts: %f pkt_pts %f pkt_dts %f\n", |
447 | // vframe->index,vframe->pts,vframe->pkt_pts,vframe->pkt_dts); |
454 | // vframe->index,vframe->pts,vframe->pkt_pts,vframe->pkt_dts); |
448 | 455 | ||
449 | main_render->draw(main_render, vframe); |
456 | main_render->draw(main_render, vframe); |
450 | 457 | ||
451 | if(main_render->win->win_state != FULLSCREEN) |
458 | if(main_render->win->win_state != FULLSCREEN) |
452 | { |
459 | { |
453 | prg->current = vframe->pkt_pts * 1000; |
460 | prg->current = vframe->pkt_pts * 1000; |
454 | lvl->current = vframe->index & 1 ? sound_level_1 : sound_level_0; |
461 | lvl->current = vframe->index & 1 ? sound_level_1 : sound_level_0; |
455 | 462 | ||
456 | send_message(&prg->ctrl, PRG_PROGRESS, 0, 0); |
463 | send_message(&prg->ctrl, PRG_PROGRESS, 0, 0); |
457 | 464 | ||
458 | if(main_render->win->panel.layout) |
465 | if(main_render->win->panel.layout) |
459 | send_message(&lvl->ctrl, MSG_PAINT, 0, 0); |
466 | send_message(&lvl->ctrl, MSG_PAINT, 0, 0); |
460 | } |
467 | } |
461 | 468 | ||
462 | frames_count--; |
469 | frames_count--; |
463 | vframe->ready = 0; |
470 | vframe->ready = 0; |
464 | 471 | ||
465 | mutex_lock(&vst->input_lock); |
472 | mutex_lock(&vst->input_lock); |
466 | list_add_tail(&vframe->list, &vst->input_list); |
473 | list_add_tail(&vframe->list, &vst->input_list); |
467 | mutex_unlock(&vst->input_lock); |
474 | mutex_unlock(&vst->input_lock); |
468 | } |
475 | } |
469 | } |
476 | } |
470 | 477 | ||
471 | 478 | ||
472 | extern char *movie_file; |
479 | extern char *movie_file; |
473 | 480 | ||
474 | int video_thread(void *param) |
481 | int video_thread(void *param) |
475 | { |
482 | { |
476 | vst_t *vst = param; |
483 | vst_t *vst = param; |
477 | window_t *MainWindow; |
484 | window_t *MainWindow; |
478 | 485 | ||
479 | init_winlib(); |
486 | init_winlib(); |
480 | 487 | ||
481 | MainWindow = create_window(movie_file,0, |
488 | MainWindow = create_window(movie_file,0, |
482 | 10,10,vst->vCtx->width,vst->vCtx->height+CAPTION_HEIGHT+PANEL_HEIGHT,MainWindowProc); |
489 | 10,10,vst->vCtx->width,vst->vCtx->height+CAPTION_HEIGHT+PANEL_HEIGHT,MainWindowProc); |
483 | 490 | ||
484 | MainWindow->panel.prg->max = stream_duration; |
491 | MainWindow->panel.prg->max = stream_duration; |
485 | 492 | ||
486 | show_window(MainWindow, NORMAL); |
493 | show_window(MainWindow, NORMAL); |
487 | 494 | ||
488 | main_render = create_render(vst, MainWindow, HW_TEX_BLIT|HW_BIT_BLIT); |
495 | main_render = create_render(vst, MainWindow, HW_TEX_BLIT|HW_BIT_BLIT); |
489 | if( main_render == NULL) |
496 | if( main_render == NULL) |
490 | { |
497 | { |
491 | mutex_unlock(&vst->decoder_lock); |
498 | mutex_unlock(&vst->decoder_lock); |
492 | printf("Cannot create render\n\r"); |
499 | printf("Cannot create render\n\r"); |
493 | return 0; |
500 | return 0; |
494 | }; |
501 | }; |
495 | 502 | ||
496 | __sync_or_and_fetch(&threads_running,VIDEO_THREAD); |
503 | __sync_or_and_fetch(&threads_running,VIDEO_THREAD); |
497 | 504 | ||
498 | render_draw_client(main_render); |
505 | render_draw_client(main_render); |
499 | player_state = PLAY; |
506 | player_state = PLAY; |
500 | 507 | ||
501 | mutex_unlock(&vst->decoder_lock); |
508 | mutex_unlock(&vst->decoder_lock); |
502 | 509 | ||
503 | run_render(MainWindow, main_render); |
510 | run_render(MainWindow, main_render); |
504 | 511 | ||
505 | __sync_and_and_fetch(&threads_running,~VIDEO_THREAD); |
512 | __sync_and_and_fetch(&threads_running,~VIDEO_THREAD); |
506 | 513 | ||
507 | destroy_render(main_render); |
514 | destroy_render(main_render); |
508 | fini_winlib(); |
515 | fini_winlib(); |
509 | player_state = CLOSED; |
516 | player_state = CLOSED; |
510 | return 0; |
517 | return 0; |
511 | }; |
518 | }; |
512 | 519 | ||
513 | 520 | ||
514 | void draw_hw_picture(render_t *render, vframe_t *vframe); |
521 | void draw_hw_picture(render_t *render, vframe_t *vframe); |
515 | void draw_sw_picture(render_t *render, vframe_t *vframe); |
522 | void draw_sw_picture(render_t *render, vframe_t *vframe); |
516 | 523 | ||
517 | render_t *create_render(vst_t *vst, window_t *win, uint32_t flags) |
524 | render_t *create_render(vst_t *vst, window_t *win, uint32_t flags) |
518 | { |
525 | { |
519 | render_t *render; |
526 | render_t *render; |
520 | 527 | ||
521 | uint32_t right, bottom, draw_w, draw_h; |
528 | uint32_t right, bottom, draw_w, draw_h; |
522 | uint32_t s, sw, sh; |
529 | uint32_t s, sw, sh; |
523 | uint8_t state; |
530 | uint8_t state; |
524 | 531 | ||
525 | // __asm__ __volatile__("int3"); |
532 | // __asm__ __volatile__("int3"); |
526 | 533 | ||
527 | render = (render_t*)malloc(sizeof(render_t)); |
534 | render = (render_t*)malloc(sizeof(render_t)); |
528 | memset(render, 0, sizeof(render_t)); |
535 | memset(render, 0, sizeof(render_t)); |
529 | 536 | ||
530 | render->vst = vst; |
537 | render->vst = vst; |
531 | render->win = win; |
538 | render->win = win; |
532 | 539 | ||
533 | render->ctx_width = vst->vCtx->width; |
540 | render->ctx_width = vst->vCtx->width; |
534 | render->ctx_height = vst->vCtx->height; |
541 | render->ctx_height = vst->vCtx->height; |
535 | render->ctx_format = vst->vCtx->pix_fmt; |
542 | render->ctx_format = vst->vCtx->pix_fmt; |
536 | 543 | ||
537 | render->caps = pxInit(1); |
544 | render->caps = pxInit(1); |
538 | 545 | ||
539 | right = win->w; |
546 | right = win->w; |
540 | bottom = win->h-CAPTION_HEIGHT-PANEL_HEIGHT; |
547 | bottom = win->h-CAPTION_HEIGHT-PANEL_HEIGHT; |
541 | 548 | ||
542 | printf("window width %d height %d\n", |
549 | printf("window width %d height %d\n", |
543 | right, bottom); |
550 | right, bottom); |
544 | 551 | ||
545 | render->win_state = win->win_state; |
552 | render->win_state = win->win_state; |
546 | 553 | ||
547 | draw_w = bottom*render->ctx_width/render->ctx_height; |
554 | draw_w = bottom*render->ctx_width/render->ctx_height; |
548 | draw_h = right*render->ctx_height/render->ctx_width; |
555 | draw_h = right*render->ctx_height/render->ctx_width; |
549 | 556 | ||
550 | if(draw_w > right) |
557 | if(draw_w > right) |
551 | { |
558 | { |
552 | draw_w = right; |
559 | draw_w = right; |
553 | draw_h = right*render->ctx_height/render->ctx_width; |
560 | draw_h = right*render->ctx_height/render->ctx_width; |
554 | }; |
561 | }; |
555 | 562 | ||
556 | if(draw_h > bottom) |
563 | if(draw_h > bottom) |
557 | { |
564 | { |
558 | draw_h = bottom; |
565 | draw_h = bottom; |
559 | draw_w = bottom*render->ctx_width/render->ctx_height; |
566 | draw_w = bottom*render->ctx_width/render->ctx_height; |
560 | }; |
567 | }; |
561 | 568 | ||
562 | render->win_width = win->w; |
569 | render->win_width = win->w; |
563 | render->win_height = win->h-CAPTION_HEIGHT-PANEL_HEIGHT; |
570 | render->win_height = win->h-CAPTION_HEIGHT-PANEL_HEIGHT; |
564 | 571 | ||
565 | render_set_size(render, draw_w, draw_h); |
572 | render_set_size(render, draw_w, draw_h); |
566 | 573 | ||
567 | pxCreateClient(0, CAPTION_HEIGHT, right, bottom); |
574 | pxCreateClient(0, CAPTION_HEIGHT, right, bottom); |
568 | 575 | ||
569 | if(render->caps==0) |
576 | if(render->caps==0) |
570 | { |
577 | { |
571 | render->bitmap[0] = pxCreateBitmap(draw_w, draw_h); |
578 | render->bitmap[0] = pxCreateBitmap(draw_w, draw_h); |
572 | if(render->bitmap[0] == NULL) |
579 | if(render->bitmap[0] == NULL) |
573 | { |
580 | { |
574 | free(render); |
581 | free(render); |
575 | return NULL; |
582 | return NULL; |
576 | } |
583 | } |
577 | render->draw = draw_sw_picture; |
584 | render->draw = draw_sw_picture; |
578 | } |
585 | } |
579 | else |
586 | else |
580 | { |
587 | { |
581 | int width, height; |
588 | int width, height; |
582 | int i; |
589 | int i; |
583 | 590 | ||
584 | if(render->caps & HW_TEX_BLIT) |
591 | if(render->caps & HW_TEX_BLIT) |
585 | { |
592 | { |
586 | width = render->ctx_width; |
593 | width = render->ctx_width; |
587 | height = render->ctx_height; |
594 | height = render->ctx_height; |
588 | } |
595 | } |
589 | else |
596 | else |
590 | { |
597 | { |
591 | width = draw_w; |
598 | width = draw_w; |
592 | height = draw_h;; |
599 | height = draw_h;; |
593 | } |
600 | } |
594 | 601 | ||
595 | for( i=0; i < 2; i++) |
602 | for( i=0; i < 2; i++) |
596 | { |
603 | { |
597 | render->bitmap[i] = pxCreateBitmap(width, height); |
604 | render->bitmap[i] = pxCreateBitmap(width, height); |
598 | if( render->bitmap[i] == NULL ) |
605 | if( render->bitmap[i] == NULL ) |
599 | { |
606 | { |
600 | player_state = CLOSED; |
607 | player_state = CLOSED; |
601 | free(render); |
608 | free(render); |
602 | return NULL; |
609 | return NULL; |
603 | }; |
610 | }; |
604 | } |
611 | } |
605 | 612 | ||
606 | render->state = INIT; |
613 | render->state = INIT; |
607 | render->target = 0; |
614 | render->target = 0; |
608 | render->draw = draw_hw_picture; |
615 | render->draw = draw_hw_picture; |
609 | }; |
616 | }; |
610 | 617 | ||
611 | printf("FPlay %s render engine: context %dx%d picture %dx%d\n", |
618 | printf("FPlay %s render engine: context %dx%d picture %dx%d\n", |
612 | render->caps & HW_TEX_BLIT ? "hw_tex_blit": |
619 | render->caps & HW_TEX_BLIT ? "hw_tex_blit": |
613 | render->caps & HW_BIT_BLIT ? "hw_bit_blit":"software", |
620 | render->caps & HW_BIT_BLIT ? "hw_bit_blit":"software", |
614 | render->ctx_width, render->ctx_height, |
621 | render->ctx_width, render->ctx_height, |
615 | draw_w, draw_h); |
622 | draw_w, draw_h); |
616 | 623 | ||
617 | return render; |
624 | return render; |
618 | }; |
625 | }; |
619 | 626 | ||
620 | void destroy_render(render_t *render) |
627 | void destroy_render(render_t *render) |
621 | { |
628 | { |
622 | 629 | ||
623 | pxDestroyBitmap(render->bitmap[0]); |
630 | pxDestroyBitmap(render->bitmap[0]); |
624 | 631 | ||
625 | if(render->caps & (HW_BIT_BLIT|HW_TEX_BLIT)) /* hw blitter */ |
632 | if(render->caps & (HW_BIT_BLIT|HW_TEX_BLIT)) /* hw blitter */ |
626 | pxDestroyBitmap(render->bitmap[1]); |
633 | pxDestroyBitmap(render->bitmap[1]); |
627 | 634 | ||
628 | pxFini(); |
635 | pxFini(); |
629 | }; |
636 | }; |
630 | 637 | ||
631 | void render_set_size(render_t *render, int width, int height) |
638 | void render_set_size(render_t *render, int width, int height) |
632 | { |
639 | { |
633 | int i; |
640 | int i; |
634 | 641 | ||
635 | render->layout = 0; |
642 | render->layout = 0; |
636 | render->rcvideo.l = 0; |
643 | render->rcvideo.l = 0; |
637 | render->rcvideo.t = 0; |
644 | render->rcvideo.t = 0; |
638 | render->rcvideo.r = width; |
645 | render->rcvideo.r = width; |
639 | render->rcvideo.b = height; |
646 | render->rcvideo.b = height; |
640 | 647 | ||
641 | // printf("render width %d height %d\n",width, height); |
648 | // printf("render width %d height %d\n",width, height); |
642 | 649 | ||
643 | if( render->win_height > height ) |
650 | if( render->win_height > height ) |
644 | { |
651 | { |
645 | int yoffs; |
652 | int yoffs; |
646 | yoffs = (render->win_height-height)/2; |
653 | yoffs = (render->win_height-height)/2; |
647 | if(yoffs) |
654 | if(yoffs) |
648 | { |
655 | { |
649 | render->rctop.t = 0; |
656 | render->rctop.t = 0; |
650 | render->rctop.b = yoffs; |
657 | render->rctop.b = yoffs; |
651 | render->rcvideo.t = yoffs; |
658 | render->rcvideo.t = yoffs; |
652 | render->layout |= HAS_TOP; |
659 | render->layout |= HAS_TOP; |
653 | } |
660 | } |
654 | 661 | ||
655 | yoffs = render->win_height-(render->rcvideo.t+render->rcvideo.b); |
662 | yoffs = render->win_height-(render->rcvideo.t+render->rcvideo.b); |
656 | if(yoffs) |
663 | if(yoffs) |
657 | { |
664 | { |
658 | render->rcbottom.t = render->rcvideo.t+render->rcvideo.b; |
665 | render->rcbottom.t = render->rcvideo.t+render->rcvideo.b; |
659 | render->rcbottom.b = yoffs; |
666 | render->rcbottom.b = yoffs; |
660 | render->layout |= HAS_BOTTOM; |
667 | render->layout |= HAS_BOTTOM; |
661 | } |
668 | } |
662 | } |
669 | } |
663 | 670 | ||
664 | if( render->win_width > width ) |
671 | if( render->win_width > width ) |
665 | { |
672 | { |
666 | int xoffs; |
673 | int xoffs; |
667 | xoffs = (render->win_width-width)/2; |
674 | xoffs = (render->win_width-width)/2; |
668 | if(xoffs) |
675 | if(xoffs) |
669 | { |
676 | { |
670 | render->rcleft.r = xoffs; |
677 | render->rcleft.r = xoffs; |
671 | render->rcvideo.l = xoffs; |
678 | render->rcvideo.l = xoffs; |
672 | render->layout |= HAS_LEFT; |
679 | render->layout |= HAS_LEFT; |
673 | } |
680 | } |
674 | xoffs = render->win_width-(render->rcvideo.l+render->rcvideo.r); |
681 | xoffs = render->win_width-(render->rcvideo.l+render->rcvideo.r); |
675 | if(xoffs) |
682 | if(xoffs) |
676 | { |
683 | { |
677 | render->rcright.l = render->rcvideo.l+render->rcvideo.r; |
684 | render->rcright.l = render->rcvideo.l+render->rcvideo.r; |
678 | render->rcright.r = xoffs; |
685 | render->rcright.r = xoffs; |
679 | render->layout |= HAS_RIGHT; |
686 | render->layout |= HAS_RIGHT; |
680 | } |
687 | } |
681 | }; |
688 | }; |
682 | }; |
689 | }; |
683 | 690 | ||
684 | void render_adjust_size(render_t *render, window_t *win) |
691 | void render_adjust_size(render_t *render, window_t *win) |
685 | { |
692 | { |
686 | uint32_t right, bottom, new_w, new_h; |
693 | uint32_t right, bottom, new_w, new_h; |
687 | uint32_t s, sw, sh; |
694 | uint32_t s, sw, sh; |
688 | uint8_t state; |
695 | uint8_t state; |
689 | 696 | ||
690 | right = win->w; |
697 | right = win->w; |
691 | bottom = win->h; |
698 | bottom = win->h; |
692 | 699 | ||
693 | if(win->win_state != FULLSCREEN) |
700 | if(win->win_state != FULLSCREEN) |
694 | bottom-= CAPTION_HEIGHT+PANEL_HEIGHT; |
701 | bottom-= CAPTION_HEIGHT+PANEL_HEIGHT; |
695 | 702 | ||
696 | // printf("window width %d height %d\n", |
703 | // printf("window width %d height %d\n", |
697 | // right, bottom); |
704 | // right, bottom); |
698 | 705 | ||
699 | render->win_state = win->win_state; |
706 | render->win_state = win->win_state; |
700 | 707 | ||
701 | if(render->win_state == MINIMIZED) |
708 | if(render->win_state == MINIMIZED) |
702 | return; |
709 | return; |
703 | 710 | ||
704 | if(render->win_state == ROLLED) |
711 | if(render->win_state == ROLLED) |
705 | return; |
712 | return; |
706 | 713 | ||
707 | if( right == render->win_width && |
714 | if( right == render->win_width && |
708 | bottom == render->win_height) |
715 | bottom == render->win_height) |
709 | return; |
716 | return; |
710 | 717 | ||
711 | // printf("%s r: %d b: %d\n", __FUNCTION__, right, bottom); |
718 | // printf("%s r: %d b: %d\n", __FUNCTION__, right, bottom); |
712 | 719 | ||
713 | new_w = bottom*render->ctx_width/render->ctx_height; |
720 | new_w = bottom*render->ctx_width/render->ctx_height; |
714 | new_h = right*render->ctx_height/render->ctx_width; |
721 | new_h = right*render->ctx_height/render->ctx_width; |
715 | 722 | ||
716 | if(new_w > right) |
723 | if(new_w > right) |
717 | { |
724 | { |
718 | new_w = right; |
725 | new_w = right; |
719 | new_h = right*render->ctx_height/render->ctx_width; |
726 | new_h = right*render->ctx_height/render->ctx_width; |
720 | }; |
727 | }; |
721 | if(new_h > bottom) |
728 | if(new_h > bottom) |
722 | { |
729 | { |
723 | new_h = bottom; |
730 | new_h = bottom; |
724 | new_w = bottom*render->ctx_width/render->ctx_height; |
731 | new_w = bottom*render->ctx_width/render->ctx_height; |
725 | }; |
732 | }; |
726 | 733 | ||
727 | render->win_width = right; |
734 | render->win_width = right; |
728 | render->win_height = bottom; |
735 | render->win_height = bottom; |
729 | render_set_size(render, new_w, new_h); |
736 | render_set_size(render, new_w, new_h); |
730 | 737 | ||
731 | if(render->caps & HW_TEX_BLIT) /* hw scaler */ |
738 | if(render->caps & HW_TEX_BLIT) /* hw scaler */ |
732 | { |
739 | { |
733 | if(render->win->win_state == FULLSCREEN) |
740 | if(render->win->win_state == FULLSCREEN) |
734 | pxResizeClient(render->rcvideo.l, render->rcvideo.t, new_w, new_h); |
741 | pxResizeClient(render->rcvideo.l, render->rcvideo.t, new_w, new_h); |
735 | else |
742 | else |
736 | pxResizeClient(render->rcvideo.l, render->rcvideo.t+CAPTION_HEIGHT, new_w, new_h); |
743 | pxResizeClient(render->rcvideo.l, render->rcvideo.t+CAPTION_HEIGHT, new_w, new_h); |
737 | 744 | ||
738 | return; |
745 | return; |
739 | }; |
746 | }; |
740 | 747 | ||
741 | pxResizeBitmap(render->bitmap[0], new_w, new_h); |
748 | pxResizeBitmap(render->bitmap[0], new_w, new_h); |
742 | 749 | ||
743 | if(render->caps & HW_BIT_BLIT) /* hw blitter */ |
750 | if(render->caps & HW_BIT_BLIT) /* hw blitter */ |
744 | pxResizeBitmap(render->bitmap[1], new_w, new_h); |
751 | pxResizeBitmap(render->bitmap[1], new_w, new_h); |
745 | 752 | ||
746 | return; |
753 | return; |
747 | }; |
754 | }; |
748 | 755 | ||
749 | static void render_hw_planar(render_t *render, vframe_t *vframe) |
756 | static void render_hw_planar(render_t *render, vframe_t *vframe) |
750 | { |
757 | { |
751 | vst_t *vst = render->vst; |
758 | vst_t *vst = render->vst; |
752 | planar_t *planar = vframe->planar; |
759 | planar_t *planar = vframe->planar; |
753 | 760 | ||
754 | if(vframe->is_hw_pic != 0 && vframe->format != AV_PIX_FMT_NONE) |
761 | if(vframe->is_hw_pic != 0 && vframe->format != AV_PIX_FMT_NONE) |
755 | { |
762 | { |
756 | mutex_lock(&render->vst->gpu_lock); |
763 | mutex_lock(&render->vst->gpu_lock); |
757 | 764 | ||
758 | pxBlitPlanar(planar, render->rcvideo.l, |
765 | pxBlitPlanar(planar, render->rcvideo.l, |
759 | CAPTION_HEIGHT+render->rcvideo.t, |
766 | CAPTION_HEIGHT+render->rcvideo.t, |
760 | render->rcvideo.r, render->rcvideo.b,0,0); |
767 | render->rcvideo.r, render->rcvideo.b,0,0); |
761 | mutex_unlock(&render->vst->gpu_lock); |
768 | mutex_unlock(&render->vst->gpu_lock); |
762 | 769 | ||
763 | } |
770 | } |
764 | }; |
771 | }; |
765 | 772 | ||
766 | void draw_hw_picture(render_t *render, vframe_t *vframe) |
773 | void draw_hw_picture(render_t *render, vframe_t *vframe) |
767 | { |
774 | { |
768 | AVPicture *picture; |
775 | AVPicture *picture; |
769 | int dst_width; |
776 | int dst_width; |
770 | int dst_height; |
777 | int dst_height; |
771 | bitmap_t *bitmap; |
778 | bitmap_t *bitmap; |
772 | uint8_t *bitmap_data; |
779 | uint8_t *bitmap_data; |
773 | uint32_t bitmap_pitch; |
780 | uint32_t bitmap_pitch; |
774 | uint8_t *data[4]; |
781 | uint8_t *data[4]; |
775 | int linesize[4]; |
782 | int linesize[4]; |
776 | enum AVPixelFormat format; |
783 | enum AVPixelFormat format; |
777 | 784 | ||
778 | vst_t *vst = render->vst; |
785 | vst_t *vst = render->vst; |
779 | 786 | ||
780 | if(render->win->win_state == MINIMIZED || |
787 | if(render->win->win_state == MINIMIZED || |
781 | render->win->win_state == ROLLED) |
788 | render->win->win_state == ROLLED) |
782 | return; |
789 | return; |
783 | 790 | ||
784 | if(render->caps & HW_TEX_BLIT) |
791 | if(render->caps & HW_TEX_BLIT) |
785 | { |
792 | { |
786 | dst_width = render->ctx_width; |
793 | dst_width = render->ctx_width; |
787 | dst_height = render->ctx_height; |
794 | dst_height = render->ctx_height; |
788 | } |
795 | } |
789 | else |
796 | else |
790 | { |
797 | { |
791 | dst_width = render->rcvideo.r; |
798 | dst_width = render->rcvideo.r; |
792 | dst_height = render->rcvideo.b; |
799 | dst_height = render->rcvideo.b; |
793 | }; |
800 | }; |
794 | 801 | ||
795 | if(vst->hwdec) |
802 | if(vst->hwdec) |
796 | { |
803 | { |
797 | render_hw_planar(render, vframe); |
804 | render_hw_planar(render, vframe); |
798 | return; |
805 | return; |
799 | }; |
806 | }; |
800 | 807 | ||
801 | picture = &vframe->picture; |
808 | picture = &vframe->picture; |
802 | 809 | ||
803 | format = render->vst->hwdec == 0 ? render->ctx_format : AV_PIX_FMT_BGRA; |
810 | format = render->vst->hwdec == 0 ? render->ctx_format : AV_PIX_FMT_BGRA; |
804 | cvt_ctx = sws_getCachedContext(cvt_ctx, render->ctx_width, render->ctx_height, format, |
811 | cvt_ctx = sws_getCachedContext(cvt_ctx, render->ctx_width, render->ctx_height, format, |
805 | dst_width, dst_height, AV_PIX_FMT_BGRA, |
812 | dst_width, dst_height, AV_PIX_FMT_BGRA, |
806 | SWS_FAST_BILINEAR, NULL, NULL, NULL); |
813 | SWS_FAST_BILINEAR, NULL, NULL, NULL); |
807 | if(cvt_ctx == NULL) |
814 | if(cvt_ctx == NULL) |
808 | { |
815 | { |
809 | printf("Cannot initialize the conversion context!\n"); |
816 | printf("Cannot initialize the conversion context!\n"); |
810 | return ; |
817 | return ; |
811 | }; |
818 | }; |
812 | 819 | ||
813 | bitmap = render->bitmap[render->target]; |
820 | bitmap = render->bitmap[render->target]; |
814 | 821 | ||
815 | bitmap_data = pxLockBitmap(bitmap, &bitmap_pitch); |
822 | bitmap_data = pxLockBitmap(bitmap, &bitmap_pitch); |
816 | if( bitmap_data == NULL) |
823 | if( bitmap_data == NULL) |
817 | { |
824 | { |
818 | printf("Cannot lock bitmap!\n"); |
825 | printf("Cannot lock bitmap!\n"); |
819 | return ; |
826 | return ; |
820 | } |
827 | } |
821 | 828 | ||
822 | data[0] = bitmap_data; |
829 | data[0] = bitmap_data; |
823 | data[1] = bitmap_data+1; |
830 | data[1] = bitmap_data+1; |
824 | data[2] = bitmap_data+2; |
831 | data[2] = bitmap_data+2; |
825 | data[3] = bitmap_data+3; |
832 | data[3] = bitmap_data+3; |
826 | 833 | ||
827 | linesize[0] = bitmap_pitch; |
834 | linesize[0] = bitmap_pitch; |
828 | linesize[1] = bitmap_pitch; |
835 | linesize[1] = bitmap_pitch; |
829 | linesize[2] = bitmap_pitch; |
836 | linesize[2] = bitmap_pitch; |
830 | linesize[3] = bitmap_pitch; |
837 | linesize[3] = bitmap_pitch; |
831 | 838 | ||
832 | sws_scale(cvt_ctx, (const uint8_t* const *)picture->data, |
839 | sws_scale(cvt_ctx, (const uint8_t* const *)picture->data, |
833 | picture->linesize, 0, render->ctx_height, data, linesize); |
840 | picture->linesize, 0, render->ctx_height, data, linesize); |
834 | // printf("sws_scale\n"); |
841 | // printf("sws_scale\n"); |
835 | 842 | ||
836 | mutex_lock(&render->vst->gpu_lock); |
843 | mutex_lock(&render->vst->gpu_lock); |
837 | 844 | ||
838 | if(render->caps & HW_TEX_BLIT) |
845 | if(render->caps & HW_TEX_BLIT) |
839 | { |
846 | { |
840 | 847 | ||
841 | if(render->win->win_state == FULLSCREEN) |
848 | if(render->win->win_state == FULLSCREEN) |
842 | pxBlitBitmap(bitmap,render->rcvideo.l,render->rcvideo.t, |
849 | pxBlitBitmap(bitmap,render->rcvideo.l,render->rcvideo.t, |
843 | render->rcvideo.r, render->rcvideo.b,0,0); |
850 | render->rcvideo.r, render->rcvideo.b,0,0); |
844 | else |
851 | else |
845 | pxBlitBitmap(bitmap, render->rcvideo.l, |
852 | pxBlitBitmap(bitmap, render->rcvideo.l, |
846 | CAPTION_HEIGHT+render->rcvideo.t, |
853 | CAPTION_HEIGHT+render->rcvideo.t, |
847 | render->rcvideo.r, render->rcvideo.b,0,0); |
854 | render->rcvideo.r, render->rcvideo.b,0,0); |
848 | } |
855 | } |
849 | else |
856 | else |
850 | { |
857 | { |
851 | if(render->win->win_state == FULLSCREEN) |
858 | if(render->win->win_state == FULLSCREEN) |
852 | pxBlitBitmap(bitmap,render->rcvideo.l,render->rcvideo.t, |
859 | pxBlitBitmap(bitmap,render->rcvideo.l,render->rcvideo.t, |
853 | render->rcvideo.r, render->rcvideo.b, 0,0); |
860 | render->rcvideo.r, render->rcvideo.b, 0,0); |
854 | else |
861 | else |
855 | pxBlitBitmap(bitmap, render->rcvideo.l, |
862 | pxBlitBitmap(bitmap, render->rcvideo.l, |
856 | CAPTION_HEIGHT+render->rcvideo.t, |
863 | CAPTION_HEIGHT+render->rcvideo.t, |
857 | render->rcvideo.r, render->rcvideo.b, 0, 0); |
864 | render->rcvideo.r, render->rcvideo.b, 0, 0); |
858 | }; |
865 | }; |
859 | mutex_unlock(&render->vst->gpu_lock); |
866 | mutex_unlock(&render->vst->gpu_lock); |
860 | 867 | ||
861 | render->last_bitmap = bitmap; |
868 | render->last_bitmap = bitmap; |
862 | render->target++; |
869 | render->target++; |
863 | render->target&= 1; |
870 | render->target&= 1; |
864 | } |
871 | } |
865 | 872 | ||
866 | void draw_sw_picture(render_t *render, vframe_t *vframe) |
873 | void draw_sw_picture(render_t *render, vframe_t *vframe) |
867 | { |
874 | { |
868 | AVPicture *picture; |
875 | AVPicture *picture; |
869 | uint8_t *bitmap_data; |
876 | uint8_t *bitmap_data; |
870 | uint32_t bitmap_pitch; |
877 | uint32_t bitmap_pitch; |
871 | uint8_t *data[4]; |
878 | uint8_t *data[4]; |
872 | int linesize[4]; |
879 | int linesize[4]; |
873 | 880 | ||
874 | if(render->win->win_state == MINIMIZED || |
881 | if(render->win->win_state == MINIMIZED || |
875 | render->win->win_state == ROLLED) |
882 | render->win->win_state == ROLLED) |
876 | return; |
883 | return; |
877 | 884 | ||
878 | picture = &vframe->picture; |
885 | picture = &vframe->picture; |
879 | 886 | ||
880 | cvt_ctx = sws_getCachedContext(cvt_ctx, |
887 | cvt_ctx = sws_getCachedContext(cvt_ctx, |
881 | render->ctx_width, render->ctx_height, |
888 | render->ctx_width, render->ctx_height, |
882 | render->ctx_format, |
889 | render->ctx_format, |
883 | render->rcvideo.r, render->rcvideo.b, |
890 | render->rcvideo.r, render->rcvideo.b, |
884 | AV_PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL); |
891 | AV_PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL); |
885 | if(cvt_ctx == NULL) |
892 | if(cvt_ctx == NULL) |
886 | { |
893 | { |
887 | printf("Cannot initialize the conversion context!\n"); |
894 | printf("Cannot initialize the conversion context!\n"); |
888 | return ; |
895 | return ; |
889 | } |
896 | } |
890 | 897 | ||
891 | bitmap_data = pxLockBitmap(render->bitmap[0],&bitmap_pitch); |
898 | bitmap_data = pxLockBitmap(render->bitmap[0],&bitmap_pitch); |
892 | 899 | ||
893 | data[0] = bitmap_data; |
900 | data[0] = bitmap_data; |
894 | data[1] = bitmap_data+1; |
901 | data[1] = bitmap_data+1; |
895 | data[2] = bitmap_data+2; |
902 | data[2] = bitmap_data+2; |
896 | data[3] = bitmap_data+3; |
903 | data[3] = bitmap_data+3; |
897 | 904 | ||
898 | linesize[0] = bitmap_pitch; |
905 | linesize[0] = bitmap_pitch; |
899 | linesize[1] = bitmap_pitch; |
906 | linesize[1] = bitmap_pitch; |
900 | linesize[2] = bitmap_pitch; |
907 | linesize[2] = bitmap_pitch; |
901 | linesize[3] = bitmap_pitch; |
908 | linesize[3] = bitmap_pitch; |
902 | 909 | ||
903 | sws_scale(cvt_ctx, (const uint8_t* const *)picture->data, |
910 | sws_scale(cvt_ctx, (const uint8_t* const *)picture->data, |
904 | picture->linesize, 0, render->ctx_height, data, linesize); |
911 | picture->linesize, 0, render->ctx_height, data, linesize); |
905 | 912 | ||
906 | if(render->win->win_state == FULLSCREEN) |
913 | if(render->win->win_state == FULLSCREEN) |
907 | pxBlitBitmap(render->bitmap[0],render->rcvideo.l,render->rcvideo.t, |
914 | pxBlitBitmap(render->bitmap[0],render->rcvideo.l,render->rcvideo.t, |
908 | render->rcvideo.r, render->rcvideo.b,0,0); |
915 | render->rcvideo.r, render->rcvideo.b,0,0); |
909 | else |
916 | else |
910 | pxBlitBitmap(render->bitmap[0], render->rcvideo.l, |
917 | pxBlitBitmap(render->bitmap[0], render->rcvideo.l, |
911 | CAPTION_HEIGHT+render->rcvideo.t, |
918 | CAPTION_HEIGHT+render->rcvideo.t, |
912 | render->rcvideo.r, render->rcvideo.b,0,0); |
919 | render->rcvideo.r, render->rcvideo.b,0,0); |
913 | 920 | ||
914 | render->last_bitmap = render->bitmap[0]; |
921 | render->last_bitmap = render->bitmap[0]; |
915 | } |
922 | } |
916 | 923 | ||
917 | void render_draw_client(render_t *render) |
924 | void render_draw_client(render_t *render) |
918 | { |
925 | { |
919 | vst_t *vst = render->vst; |
926 | vst_t *vst = render->vst; |
920 | int y; |
927 | int y; |
921 | 928 | ||
922 | if(render->win_state == MINIMIZED || |
929 | if(render->win_state == MINIMIZED || |
923 | render->win_state == ROLLED ) |
930 | render->win_state == ROLLED ) |
924 | return; |
931 | return; |
925 | if(render->win_state == FULLSCREEN) |
932 | if(render->win_state == FULLSCREEN) |
926 | y = 0; |
933 | y = 0; |
927 | else |
934 | else |
928 | y = CAPTION_HEIGHT; |
935 | y = CAPTION_HEIGHT; |
929 | 936 | ||
930 | if(player_state == PAUSE) |
937 | if(player_state == PAUSE) |
931 | { |
938 | { |
932 | // if(vst->vframe[vst->vfx].ready == 1 ) |
939 | // if(vst->vframe[vst->vfx].ready == 1 ) |
933 | // main_render->draw(main_render, &vst->vframe[vst->vfx].picture); |
940 | // main_render->draw(main_render, &vst->vframe[vst->vfx].picture); |
934 | // else |
941 | // else |
935 | draw_bar(0, y, render->win_width, |
942 | draw_bar(0, y, render->win_width, |
936 | render->rcvideo.b, 0); |
943 | render->rcvideo.b, 0); |
937 | } |
944 | } |
938 | else if( player_state == STOP ) |
945 | else if( player_state == STOP ) |
939 | { |
946 | { |
940 | draw_bar(0,y, render->win_width, |
947 | draw_bar(0,y, render->win_width, |
941 | render->rcvideo.b, 0); |
948 | render->rcvideo.b, 0); |
942 | }; |
949 | }; |
943 | 950 | ||
944 | if(render->layout & HAS_TOP) |
951 | if(render->layout & HAS_TOP) |
945 | draw_bar(0, y, render->win_width, |
952 | draw_bar(0, y, render->win_width, |
946 | render->rctop.b, 0); |
953 | render->rctop.b, 0); |
947 | if(render->layout & HAS_LEFT) |
954 | if(render->layout & HAS_LEFT) |
948 | draw_bar(0, render->rcvideo.t+y, render->rcleft.r, |
955 | draw_bar(0, render->rcvideo.t+y, render->rcleft.r, |
949 | render->rcvideo.b, 0); |
956 | render->rcvideo.b, 0); |
950 | if(render->layout & HAS_RIGHT) |
957 | if(render->layout & HAS_RIGHT) |
951 | draw_bar(render->rcright.l, render->rcvideo.t+y, |
958 | draw_bar(render->rcright.l, render->rcvideo.t+y, |
952 | render->rcright.r, render->rcvideo.b, 0); |
959 | render->rcright.r, render->rcvideo.b, 0); |
953 | if(render->layout & HAS_BOTTOM) |
960 | if(render->layout & HAS_BOTTOM) |
954 | draw_bar(0, render->rcbottom.t+y, |
961 | draw_bar(0, render->rcbottom.t+y, |
955 | render->win_width, render->rcbottom.b, 0); |
962 | render->win_width, render->rcbottom.b, 0); |
956 | }>>>=> |
963 | }>>=>> |