17
17
* along with this program; if not, write to the Free Software
18
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20
* $Id: video_out.c,v 1.214.2.1 2005/04/20 17:21:17 mroi Exp $
20
* $Id: video_out.c,v 1.222 2005/11/14 23:48:19 miguelfreitas Exp $
22
22
* frame allocation / queuing / scheduling / output functions
59
59
#define FIRST_FRAME_POLL_DELAY 3000
60
60
#define FIRST_FRAME_MAX_POLL 10 /* poll n times at most */
62
/* experimental optimization: try to allocate frames from free queue
63
* in the same format as requested (avoid unnecessary free/alloc in
64
* vo driver). up to 25% less cpu load using deinterlace with film mode.
66
#define EXPERIMENTAL_FRAME_QUEUE_OPTIMIZATION 1
62
68
static vo_frame_t * crop_frame( xine_video_port_t *this_gen, vo_frame_t *img );
174
180
pthread_mutex_unlock (&queue->mutex);
177
static vo_frame_t *vo_remove_from_img_buf_queue_int (img_buf_fifo_t *queue, int blocking) {
180
while (!queue->first || queue->locked_for_read) {
182
pthread_cond_wait (&queue->not_empty, &queue->mutex);
186
gettimeofday(&tv, NULL);
187
ts.tv_sec = tv.tv_sec + 1;
188
ts.tv_nsec = tv.tv_usec * 1000;
189
if (pthread_cond_timedwait (&queue->not_empty, &queue->mutex, &ts) != 0)
183
static vo_frame_t *vo_remove_from_img_buf_queue_int (img_buf_fifo_t *queue, int blocking,
184
uint32_t width, uint32_t height,
185
double ratio, int format,
187
vo_frame_t *img = NULL;
188
vo_frame_t *previous = NULL;
190
while (!img || queue->locked_for_read) {
192
img = (queue->locked_for_read) ? NULL : queue->first;
194
#if EXPERIMENTAL_FRAME_QUEUE_OPTIMIZATION
196
/* try to obtain a frame with the same format first.
197
* doing so may avoid unnecessary alloc/free's at the vo
198
* driver, specially when using post plugins that change
199
* format like the tvtime deinterlacer does.
202
while( img && width && height &&
203
(img->width != width || img->height != height ||
204
img->ratio != ratio || img->format != format) ) {
210
if( width && height ) {
212
if( queue->num_buffers == 1 && !blocking) {
213
/* non-blocking and only a single frame on fifo with different
214
* format -> ignore it (give another chance of a frame format hit)
216
lprintf("frame format mismatch - will wait another frame\n");
218
/* we have at least 2 frames on fifo but they don't match ->
219
* give up. return whatever we got.
222
lprintf("frame format miss (%d/%d)\n", i, queue->num_buffers);
225
/* good: format match! */
226
lprintf("frame format hit (%d/%d)\n", i, queue->num_buffers);
234
pthread_cond_wait (&queue->not_empty, &queue->mutex);
238
gettimeofday(&tv, NULL);
239
ts.tv_sec = tv.tv_sec + 1;
240
ts.tv_nsec = tv.tv_usec * 1000;
241
if (pthread_cond_timedwait (&queue->not_empty, &queue->mutex, &ts) != 0)
197
queue->first = img->next;
249
if( img == queue->first ) {
250
queue->first = img->next;
252
previous->next = img->next;
253
if( img == queue->last )
254
queue->last = previous;
198
257
img->next = NULL;
199
258
if (!queue->first) {
200
259
queue->last = NULL;
201
260
queue->num_buffers = 0;
204
262
queue->num_buffers--;
214
272
pthread_mutex_lock (&queue->mutex);
215
img = vo_remove_from_img_buf_queue_int(queue, 1);
273
img = vo_remove_from_img_buf_queue_int(queue, 1, 0, 0, 0, 0, 0);
216
274
pthread_mutex_unlock (&queue->mutex);
221
static vo_frame_t *vo_remove_from_img_buf_queue_nonblock (img_buf_fifo_t *queue) {
279
static vo_frame_t *vo_remove_from_img_buf_queue_nonblock (img_buf_fifo_t *queue,
280
uint32_t width, uint32_t height,
281
double ratio, int format,
224
285
pthread_mutex_lock (&queue->mutex);
225
img = vo_remove_from_img_buf_queue_int(queue, 0);
286
img = vo_remove_from_img_buf_queue_int(queue, 0, width, height, ratio, format, flags);
226
287
pthread_mutex_unlock (&queue->mutex);
313
374
lprintf ("get_frame (%d x %d)\n", width, height);
315
while (!(img = vo_remove_from_img_buf_queue_nonblock (this->free_img_buf_queue)))
376
while (!(img = vo_remove_from_img_buf_queue_nonblock (this->free_img_buf_queue,
377
width, height, ratio, format, flags)))
316
378
if (this->xine->port_ticket->ticket_revoked)
317
379
this->xine->port_ticket->renew(this->xine->port_ticket, 1);
626
692
dupl->crop_right = img->crop_right;
627
693
dupl->crop_top = img->crop_top;
628
694
dupl->crop_bottom = img->crop_bottom;
695
dupl->overlay_offset_x = img->overlay_offset_x;
696
dupl->overlay_offset_y = img->overlay_offset_y;
630
698
this->driver->update_frame_format (this->driver, dupl, dupl->width, dupl->height,
631
699
dupl->ratio, dupl->format, dupl->flags);
741
809
this->num_frames_discarded++;
744
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
812
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
746
814
if (img->stream) {
747
815
pthread_mutex_lock( &img->stream->current_extra_info_lock );
889
957
* remove frame from display queue and show it
892
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
960
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
893
961
pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
1155
1223
img = this->display_img_buf_queue->first;
1158
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
1226
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
1159
1227
vo_frame_dec_lock( img );
1161
1229
img = this->display_img_buf_queue->first;
1213
1281
* remove frame from display queue and show it
1216
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
1284
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
1217
1285
pthread_mutex_unlock(&this->display_img_buf_queue->mutex);
1219
1287
frame->vpts = img->vpts;
1383
1451
lprintf ("flushing out frame\n");
1385
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1);
1453
img = vo_remove_from_img_buf_queue_int (this->display_img_buf_queue, 1, 0, 0, 0, 0, 0);
1387
1455
vo_frame_dec_lock (img);