QT RLE encoder
[libav.git] / ffplay.c
1 /*
2 * FFplay : Simple Media Player based on the ffmpeg libraries
3 * Copyright (c) 2003 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "avformat.h"
23 #include "swscale.h"
24 #include "avstring.h"
25
26 #include "version.h"
27 #include "cmdutils.h"
28
29 #include <SDL.h>
30 #include <SDL_thread.h>
31
32 #ifdef __MINGW32__
33 #undef main /* We don't want SDL to override our main() */
34 #endif
35
36 #ifdef CONFIG_OS2
37 #define INCL_DOS
38 #include <os2.h>
39 #include <stdio.h>
40
41 void MorphToPM()
42 {
43 PPIB pib;
44 PTIB tib;
45
46 DosGetInfoBlocks(&tib, &pib);
47
48 // Change flag from VIO to PM:
49 if (pib->pib_ultype==2) pib->pib_ultype = 3;
50 }
51 #endif
52
53 #undef exit
54
55 //#define DEBUG_SYNC
56
57 #define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
58 #define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
59 #define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
60
61 /* SDL audio buffer size, in samples. Should be small to have precise
62 A/V sync as SDL does not have hardware buffer fullness info. */
63 #define SDL_AUDIO_BUFFER_SIZE 1024
64
65 /* no AV sync correction is done if below the AV sync threshold */
66 #define AV_SYNC_THRESHOLD 0.01
67 /* no AV correction is done if too big error */
68 #define AV_NOSYNC_THRESHOLD 10.0
69
70 /* maximum audio speed change to get correct sync */
71 #define SAMPLE_CORRECTION_PERCENT_MAX 10
72
73 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
74 #define AUDIO_DIFF_AVG_NB 20
75
76 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
77 #define SAMPLE_ARRAY_SIZE (2*65536)
78
79 static int sws_flags = SWS_BICUBIC;
80
81 typedef struct PacketQueue {
82 AVPacketList *first_pkt, *last_pkt;
83 int nb_packets;
84 int size;
85 int abort_request;
86 SDL_mutex *mutex;
87 SDL_cond *cond;
88 } PacketQueue;
89
90 #define VIDEO_PICTURE_QUEUE_SIZE 1
91 #define SUBPICTURE_QUEUE_SIZE 4
92
93 typedef struct VideoPicture {
94 double pts; ///<presentation time stamp for this picture
95 SDL_Overlay *bmp;
96 int width, height; /* source height & width */
97 int allocated;
98 } VideoPicture;
99
100 typedef struct SubPicture {
101 double pts; /* presentation time stamp for this picture */
102 AVSubtitle sub;
103 } SubPicture;
104
105 enum {
106 AV_SYNC_AUDIO_MASTER, /* default choice */
107 AV_SYNC_VIDEO_MASTER,
108 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
109 };
110
111 typedef struct VideoState {
112 SDL_Thread *parse_tid;
113 SDL_Thread *video_tid;
114 AVInputFormat *iformat;
115 int no_background;
116 int abort_request;
117 int paused;
118 int last_paused;
119 int seek_req;
120 int seek_flags;
121 int64_t seek_pos;
122 AVFormatContext *ic;
123 int dtg_active_format;
124
125 int audio_stream;
126
127 int av_sync_type;
128 double external_clock; /* external clock base */
129 int64_t external_clock_time;
130
131 double audio_clock;
132 double audio_diff_cum; /* used for AV difference average computation */
133 double audio_diff_avg_coef;
134 double audio_diff_threshold;
135 int audio_diff_avg_count;
136 AVStream *audio_st;
137 PacketQueue audioq;
138 int audio_hw_buf_size;
139 /* samples output by the codec. we reserve more space for avsync
140 compensation */
141 DECLARE_ALIGNED(16,uint8_t,audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]);
142 unsigned int audio_buf_size; /* in bytes */
143 int audio_buf_index; /* in bytes */
144 AVPacket audio_pkt;
145 uint8_t *audio_pkt_data;
146 int audio_pkt_size;
147
148 int show_audio; /* if true, display audio samples */
149 int16_t sample_array[SAMPLE_ARRAY_SIZE];
150 int sample_array_index;
151 int last_i_start;
152
153 SDL_Thread *subtitle_tid;
154 int subtitle_stream;
155 int subtitle_stream_changed;
156 AVStream *subtitle_st;
157 PacketQueue subtitleq;
158 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
159 int subpq_size, subpq_rindex, subpq_windex;
160 SDL_mutex *subpq_mutex;
161 SDL_cond *subpq_cond;
162
163 double frame_timer;
164 double frame_last_pts;
165 double frame_last_delay;
166 double video_clock; ///<pts of last decoded frame / predicted pts of next decoded frame
167 int video_stream;
168 AVStream *video_st;
169 PacketQueue videoq;
170 double video_current_pts; ///<current displayed pts (different from video_clock if frame fifos are used)
171 int64_t video_current_pts_time; ///<time (av_gettime) at which we updated video_current_pts - used to have running video pts
172 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
173 int pictq_size, pictq_rindex, pictq_windex;
174 SDL_mutex *pictq_mutex;
175 SDL_cond *pictq_cond;
176
177 // QETimer *video_timer;
178 char filename[1024];
179 int width, height, xleft, ytop;
180 } VideoState;
181
182 void show_help(void);
183 static int audio_write_get_buf_size(VideoState *is);
184
185 /* options specified by the user */
186 static AVInputFormat *file_iformat;
187 static const char *input_filename;
188 static int fs_screen_width;
189 static int fs_screen_height;
190 static int screen_width = 0;
191 static int screen_height = 0;
192 static int frame_width = 0;
193 static int frame_height = 0;
194 static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
195 static int audio_disable;
196 static int video_disable;
197 static int wanted_audio_stream= 0;
198 static int seek_by_bytes;
199 static int display_disable;
200 static int show_status;
201 static int av_sync_type = AV_SYNC_AUDIO_MASTER;
202 static int64_t start_time = AV_NOPTS_VALUE;
203 static int debug = 0;
204 static int debug_mv = 0;
205 static int step = 0;
206 static int thread_count = 1;
207 static int workaround_bugs = 1;
208 static int fast = 0;
209 static int genpts = 0;
210 static int lowres = 0;
211 static int idct = FF_IDCT_AUTO;
212 static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
213 static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
214 static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
215 static int error_resilience = FF_ER_CAREFUL;
216 static int error_concealment = 3;
217 static int decoder_reorder_pts= 0;
218
219 /* current context */
220 static int is_full_screen;
221 static VideoState *cur_stream;
222 static int64_t audio_callback_time;
223
224 AVPacket flush_pkt;
225
226 #define FF_ALLOC_EVENT (SDL_USEREVENT)
227 #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
228 #define FF_QUIT_EVENT (SDL_USEREVENT + 2)
229
230 SDL_Surface *screen;
231
232 /* packet queue handling */
233 static void packet_queue_init(PacketQueue *q)
234 {
235 memset(q, 0, sizeof(PacketQueue));
236 q->mutex = SDL_CreateMutex();
237 q->cond = SDL_CreateCond();
238 }
239
240 static void packet_queue_flush(PacketQueue *q)
241 {
242 AVPacketList *pkt, *pkt1;
243
244 SDL_LockMutex(q->mutex);
245 for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
246 pkt1 = pkt->next;
247 av_free_packet(&pkt->pkt);
248 av_freep(&pkt);
249 }
250 q->last_pkt = NULL;
251 q->first_pkt = NULL;
252 q->nb_packets = 0;
253 q->size = 0;
254 SDL_UnlockMutex(q->mutex);
255 }
256
257 static void packet_queue_end(PacketQueue *q)
258 {
259 packet_queue_flush(q);
260 SDL_DestroyMutex(q->mutex);
261 SDL_DestroyCond(q->cond);
262 }
263
264 static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
265 {
266 AVPacketList *pkt1;
267
268 /* duplicate the packet */
269 if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
270 return -1;
271
272 pkt1 = av_malloc(sizeof(AVPacketList));
273 if (!pkt1)
274 return -1;
275 pkt1->pkt = *pkt;
276 pkt1->next = NULL;
277
278
279 SDL_LockMutex(q->mutex);
280
281 if (!q->last_pkt)
282
283 q->first_pkt = pkt1;
284 else
285 q->last_pkt->next = pkt1;
286 q->last_pkt = pkt1;
287 q->nb_packets++;
288 q->size += pkt1->pkt.size;
289 /* XXX: should duplicate packet data in DV case */
290 SDL_CondSignal(q->cond);
291
292 SDL_UnlockMutex(q->mutex);
293 return 0;
294 }
295
296 static void packet_queue_abort(PacketQueue *q)
297 {
298 SDL_LockMutex(q->mutex);
299
300 q->abort_request = 1;
301
302 SDL_CondSignal(q->cond);
303
304 SDL_UnlockMutex(q->mutex);
305 }
306
307 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
308 static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
309 {
310 AVPacketList *pkt1;
311 int ret;
312
313 SDL_LockMutex(q->mutex);
314
315 for(;;) {
316 if (q->abort_request) {
317 ret = -1;
318 break;
319 }
320
321 pkt1 = q->first_pkt;
322 if (pkt1) {
323 q->first_pkt = pkt1->next;
324 if (!q->first_pkt)
325 q->last_pkt = NULL;
326 q->nb_packets--;
327 q->size -= pkt1->pkt.size;
328 *pkt = pkt1->pkt;
329 av_free(pkt1);
330 ret = 1;
331 break;
332 } else if (!block) {
333 ret = 0;
334 break;
335 } else {
336 SDL_CondWait(q->cond, q->mutex);
337 }
338 }
339 SDL_UnlockMutex(q->mutex);
340 return ret;
341 }
342
343 static inline void fill_rectangle(SDL_Surface *screen,
344 int x, int y, int w, int h, int color)
345 {
346 SDL_Rect rect;
347 rect.x = x;
348 rect.y = y;
349 rect.w = w;
350 rect.h = h;
351 SDL_FillRect(screen, &rect, color);
352 }
353
354 #if 0
355 /* draw only the border of a rectangle */
356 void fill_border(VideoState *s, int x, int y, int w, int h, int color)
357 {
358 int w1, w2, h1, h2;
359
360 /* fill the background */
361 w1 = x;
362 if (w1 < 0)
363 w1 = 0;
364 w2 = s->width - (x + w);
365 if (w2 < 0)
366 w2 = 0;
367 h1 = y;
368 if (h1 < 0)
369 h1 = 0;
370 h2 = s->height - (y + h);
371 if (h2 < 0)
372 h2 = 0;
373 fill_rectangle(screen,
374 s->xleft, s->ytop,
375 w1, s->height,
376 color);
377 fill_rectangle(screen,
378 s->xleft + s->width - w2, s->ytop,
379 w2, s->height,
380 color);
381 fill_rectangle(screen,
382 s->xleft + w1, s->ytop,
383 s->width - w1 - w2, h1,
384 color);
385 fill_rectangle(screen,
386 s->xleft + w1, s->ytop + s->height - h2,
387 s->width - w1 - w2, h2,
388 color);
389 }
390 #endif
391
392
393
394 #define SCALEBITS 10
395 #define ONE_HALF (1 << (SCALEBITS - 1))
396 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
397
398 #define RGB_TO_Y_CCIR(r, g, b) \
399 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
400 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
401
402 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
403 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
404 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
405
406 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
407 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
408 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
409
410 #define ALPHA_BLEND(a, oldp, newp, s)\
411 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
412
413 #define RGBA_IN(r, g, b, a, s)\
414 {\
415 unsigned int v = ((const uint32_t *)(s))[0];\
416 a = (v >> 24) & 0xff;\
417 r = (v >> 16) & 0xff;\
418 g = (v >> 8) & 0xff;\
419 b = v & 0xff;\
420 }
421
422 #define YUVA_IN(y, u, v, a, s, pal)\
423 {\
424 unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)s];\
425 a = (val >> 24) & 0xff;\
426 y = (val >> 16) & 0xff;\
427 u = (val >> 8) & 0xff;\
428 v = val & 0xff;\
429 }
430
431 #define YUVA_OUT(d, y, u, v, a)\
432 {\
433 ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
434 }
435
436
437 #define BPP 1
438
439 static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
440 {
441 int wrap, wrap3, width2, skip2;
442 int y, u, v, a, u1, v1, a1, w, h;
443 uint8_t *lum, *cb, *cr;
444 const uint8_t *p;
445 const uint32_t *pal;
446
447 lum = dst->data[0] + rect->y * dst->linesize[0];
448 cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1];
449 cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2];
450
451 width2 = (rect->w + 1) >> 1;
452 skip2 = rect->x >> 1;
453 wrap = dst->linesize[0];
454 wrap3 = rect->linesize;
455 p = rect->bitmap;
456 pal = rect->rgba_palette; /* Now in YCrCb! */
457
458 if (rect->y & 1) {
459 lum += rect->x;
460 cb += skip2;
461 cr += skip2;
462
463 if (rect->x & 1) {
464 YUVA_IN(y, u, v, a, p, pal);
465 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
466 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
467 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
468 cb++;
469 cr++;
470 lum++;
471 p += BPP;
472 }
473 for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
474 YUVA_IN(y, u, v, a, p, pal);
475 u1 = u;
476 v1 = v;
477 a1 = a;
478 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
479
480 YUVA_IN(y, u, v, a, p + BPP, pal);
481 u1 += u;
482 v1 += v;
483 a1 += a;
484 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
485 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
486 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
487 cb++;
488 cr++;
489 p += 2 * BPP;
490 lum += 2;
491 }
492 if (w) {
493 YUVA_IN(y, u, v, a, p, pal);
494 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
495 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
496 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
497 }
498 p += wrap3 + (wrap3 - rect->w * BPP);
499 lum += wrap + (wrap - rect->w - rect->x);
500 cb += dst->linesize[1] - width2 - skip2;
501 cr += dst->linesize[2] - width2 - skip2;
502 }
503 for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) {
504 lum += rect->x;
505 cb += skip2;
506 cr += skip2;
507
508 if (rect->x & 1) {
509 YUVA_IN(y, u, v, a, p, pal);
510 u1 = u;
511 v1 = v;
512 a1 = a;
513 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
514 p += wrap3;
515 lum += wrap;
516 YUVA_IN(y, u, v, a, p, pal);
517 u1 += u;
518 v1 += v;
519 a1 += a;
520 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
521 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
522 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
523 cb++;
524 cr++;
525 p += -wrap3 + BPP;
526 lum += -wrap + 1;
527 }
528 for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
529 YUVA_IN(y, u, v, a, p, pal);
530 u1 = u;
531 v1 = v;
532 a1 = a;
533 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
534
535 YUVA_IN(y, u, v, a, p, pal);
536 u1 += u;
537 v1 += v;
538 a1 += a;
539 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
540 p += wrap3;
541 lum += wrap;
542
543 YUVA_IN(y, u, v, a, p, pal);
544 u1 += u;
545 v1 += v;
546 a1 += a;
547 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
548
549 YUVA_IN(y, u, v, a, p, pal);
550 u1 += u;
551 v1 += v;
552 a1 += a;
553 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
554
555 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
556 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
557
558 cb++;
559 cr++;
560 p += -wrap3 + 2 * BPP;
561 lum += -wrap + 2;
562 }
563 if (w) {
564 YUVA_IN(y, u, v, a, p, pal);
565 u1 = u;
566 v1 = v;
567 a1 = a;
568 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
569 p += wrap3;
570 lum += wrap;
571 YUVA_IN(y, u, v, a, p, pal);
572 u1 += u;
573 v1 += v;
574 a1 += a;
575 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
576 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
577 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
578 cb++;
579 cr++;
580 p += -wrap3 + BPP;
581 lum += -wrap + 1;
582 }
583 p += wrap3 + (wrap3 - rect->w * BPP);
584 lum += wrap + (wrap - rect->w - rect->x);
585 cb += dst->linesize[1] - width2 - skip2;
586 cr += dst->linesize[2] - width2 - skip2;
587 }
588 /* handle odd height */
589 if (h) {
590 lum += rect->x;
591 cb += skip2;
592 cr += skip2;
593
594 if (rect->x & 1) {
595 YUVA_IN(y, u, v, a, p, pal);
596 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
597 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
598 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
599 cb++;
600 cr++;
601 lum++;
602 p += BPP;
603 }
604 for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
605 YUVA_IN(y, u, v, a, p, pal);
606 u1 = u;
607 v1 = v;
608 a1 = a;
609 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
610
611 YUVA_IN(y, u, v, a, p + BPP, pal);
612 u1 += u;
613 v1 += v;
614 a1 += a;
615 lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
616 cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
617 cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
618 cb++;
619 cr++;
620 p += 2 * BPP;
621 lum += 2;
622 }
623 if (w) {
624 YUVA_IN(y, u, v, a, p, pal);
625 lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
626 cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
627 cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
628 }
629 }
630 }
631
632 static void free_subpicture(SubPicture *sp)
633 {
634 int i;
635
636 for (i = 0; i < sp->sub.num_rects; i++)
637 {
638 av_free(sp->sub.rects[i].bitmap);
639 av_free(sp->sub.rects[i].rgba_palette);
640 }
641
642 av_free(sp->sub.rects);
643
644 memset(&sp->sub, 0, sizeof(AVSubtitle));
645 }
646
647 static void video_image_display(VideoState *is)
648 {
649 VideoPicture *vp;
650 SubPicture *sp;
651 AVPicture pict;
652 float aspect_ratio;
653 int width, height, x, y;
654 SDL_Rect rect;
655 int i;
656
657 vp = &is->pictq[is->pictq_rindex];
658 if (vp->bmp) {
659 /* XXX: use variable in the frame */
660 if (is->video_st->codec->sample_aspect_ratio.num == 0)
661 aspect_ratio = 0;
662 else
663 aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio)
664 * is->video_st->codec->width / is->video_st->codec->height;;
665 if (aspect_ratio <= 0.0)
666 aspect_ratio = (float)is->video_st->codec->width /
667 (float)is->video_st->codec->height;
668 /* if an active format is indicated, then it overrides the
669 mpeg format */
670 #if 0
671 if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
672 is->dtg_active_format = is->video_st->codec->dtg_active_format;
673 printf("dtg_active_format=%d\n", is->dtg_active_format);
674 }
675 #endif
676 #if 0
677 switch(is->video_st->codec->dtg_active_format) {
678 case FF_DTG_AFD_SAME:
679 default:
680 /* nothing to do */
681 break;
682 case FF_DTG_AFD_4_3:
683 aspect_ratio = 4.0 / 3.0;
684 break;
685 case FF_DTG_AFD_16_9:
686 aspect_ratio = 16.0 / 9.0;
687 break;
688 case FF_DTG_AFD_14_9:
689 aspect_ratio = 14.0 / 9.0;
690 break;
691 case FF_DTG_AFD_4_3_SP_14_9:
692 aspect_ratio = 14.0 / 9.0;
693 break;
694 case FF_DTG_AFD_16_9_SP_14_9:
695 aspect_ratio = 14.0 / 9.0;
696 break;
697 case FF_DTG_AFD_SP_4_3:
698 aspect_ratio = 4.0 / 3.0;
699 break;
700 }
701 #endif
702
703 if (is->subtitle_st)
704 {
705 if (is->subpq_size > 0)
706 {
707 sp = &is->subpq[is->subpq_rindex];
708
709 if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
710 {
711 SDL_LockYUVOverlay (vp->bmp);
712
713 pict.data[0] = vp->bmp->pixels[0];
714 pict.data[1] = vp->bmp->pixels[2];
715 pict.data[2] = vp->bmp->pixels[1];
716
717 pict.linesize[0] = vp->bmp->pitches[0];
718 pict.linesize[1] = vp->bmp->pitches[2];
719 pict.linesize[2] = vp->bmp->pitches[1];
720
721 for (i = 0; i < sp->sub.num_rects; i++)
722 blend_subrect(&pict, &sp->sub.rects[i]);
723
724 SDL_UnlockYUVOverlay (vp->bmp);
725 }
726 }
727 }
728
729
730 /* XXX: we suppose the screen has a 1.0 pixel ratio */
731 height = is->height;
732 width = ((int)rint(height * aspect_ratio)) & -3;
733 if (width > is->width) {
734 width = is->width;
735 height = ((int)rint(width / aspect_ratio)) & -3;
736 }
737 x = (is->width - width) / 2;
738 y = (is->height - height) / 2;
739 if (!is->no_background) {
740 /* fill the background */
741 // fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
742 } else {
743 is->no_background = 0;
744 }
745 rect.x = is->xleft + x;
746 rect.y = is->ytop + y;
747 rect.w = width;
748 rect.h = height;
749 SDL_DisplayYUVOverlay(vp->bmp, &rect);
750 } else {
751 #if 0
752 fill_rectangle(screen,
753 is->xleft, is->ytop, is->width, is->height,
754 QERGB(0x00, 0x00, 0x00));
755 #endif
756 }
757 }
758
759 static inline int compute_mod(int a, int b)
760 {
761 a = a % b;
762 if (a >= 0)
763 return a;
764 else
765 return a + b;
766 }
767
768 static void video_audio_display(VideoState *s)
769 {
770 int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
771 int ch, channels, h, h2, bgcolor, fgcolor;
772 int16_t time_diff;
773
774 /* compute display index : center on currently output samples */
775 channels = s->audio_st->codec->channels;
776 nb_display_channels = channels;
777 if (!s->paused) {
778 n = 2 * channels;
779 delay = audio_write_get_buf_size(s);
780 delay /= n;
781
782 /* to be more precise, we take into account the time spent since
783 the last buffer computation */
784 if (audio_callback_time) {
785 time_diff = av_gettime() - audio_callback_time;
786 delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
787 }
788
789 delay -= s->width / 2;
790 if (delay < s->width)
791 delay = s->width;
792
793 i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
794
795 h= INT_MIN;
796 for(i=0; i<1000; i+=channels){
797 int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
798 int a= s->sample_array[idx];
799 int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
800 int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
801 int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
802 int score= a-d;
803 if(h<score && (b^c)<0){
804 h= score;
805 i_start= idx;
806 }
807 }
808
809 s->last_i_start = i_start;
810 } else {
811 i_start = s->last_i_start;
812 }
813
814 bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
815 fill_rectangle(screen,
816 s->xleft, s->ytop, s->width, s->height,
817 bgcolor);
818
819 fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
820
821 /* total height for one channel */
822 h = s->height / nb_display_channels;
823 /* graph height / 2 */
824 h2 = (h * 9) / 20;
825 for(ch = 0;ch < nb_display_channels; ch++) {
826 i = i_start + ch;
827 y1 = s->ytop + ch * h + (h / 2); /* position of center line */
828 for(x = 0; x < s->width; x++) {
829 y = (s->sample_array[i] * h2) >> 15;
830 if (y < 0) {
831 y = -y;
832 ys = y1 - y;
833 } else {
834 ys = y1;
835 }
836 fill_rectangle(screen,
837 s->xleft + x, ys, 1, y,
838 fgcolor);
839 i += channels;
840 if (i >= SAMPLE_ARRAY_SIZE)
841 i -= SAMPLE_ARRAY_SIZE;
842 }
843 }
844
845 fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
846
847 for(ch = 1;ch < nb_display_channels; ch++) {
848 y = s->ytop + ch * h;
849 fill_rectangle(screen,
850 s->xleft, y, s->width, 1,
851 fgcolor);
852 }
853 SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
854 }
855
856 static int video_open(VideoState *is){
857 int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
858 int w,h;
859
860 if(is_full_screen) flags |= SDL_FULLSCREEN;
861 else flags |= SDL_RESIZABLE;
862
863 if (is_full_screen && fs_screen_width) {
864 w = fs_screen_width;
865 h = fs_screen_height;
866 } else if(!is_full_screen && screen_width){
867 w = screen_width;
868 h = screen_height;
869 }else if (is->video_st && is->video_st->codec->width){
870 w = is->video_st->codec->width;
871 h = is->video_st->codec->height;
872 } else {
873 w = 640;
874 h = 480;
875 }
876 #ifndef CONFIG_DARWIN
877 screen = SDL_SetVideoMode(w, h, 0, flags);
878 #else
879 /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
880 screen = SDL_SetVideoMode(w, h, 24, flags);
881 #endif
882 if (!screen) {
883 fprintf(stderr, "SDL: could not set video mode - exiting\n");
884 return -1;
885 }
886 SDL_WM_SetCaption("FFplay", "FFplay");
887
888 is->width = screen->w;
889 is->height = screen->h;
890
891 return 0;
892 }
893
894 /* display the current picture, if any */
895 static void video_display(VideoState *is)
896 {
897 if(!screen)
898 video_open(cur_stream);
899 if (is->audio_st && is->show_audio)
900 video_audio_display(is);
901 else if (is->video_st)
902 video_image_display(is);
903 }
904
905 static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
906 {
907 SDL_Event event;
908 event.type = FF_REFRESH_EVENT;
909 event.user.data1 = opaque;
910 SDL_PushEvent(&event);
911 return 0; /* 0 means stop timer */
912 }
913
914 /* schedule a video refresh in 'delay' ms */
915 static void schedule_refresh(VideoState *is, int delay)
916 {
917 SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
918 }
919
920 /* get the current audio clock value */
921 static double get_audio_clock(VideoState *is)
922 {
923 double pts;
924 int hw_buf_size, bytes_per_sec;
925 pts = is->audio_clock;
926 hw_buf_size = audio_write_get_buf_size(is);
927 bytes_per_sec = 0;
928 if (is->audio_st) {
929 bytes_per_sec = is->audio_st->codec->sample_rate *
930 2 * is->audio_st->codec->channels;
931 }
932 if (bytes_per_sec)
933 pts -= (double)hw_buf_size / bytes_per_sec;
934 return pts;
935 }
936
937 /* get the current video clock value */
938 static double get_video_clock(VideoState *is)
939 {
940 double delta;
941 if (is->paused) {
942 delta = 0;
943 } else {
944 delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
945 }
946 return is->video_current_pts + delta;
947 }
948
949 /* get the current external clock value */
950 static double get_external_clock(VideoState *is)
951 {
952 int64_t ti;
953 ti = av_gettime();
954 return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
955 }
956
957 /* get the current master clock value */
958 static double get_master_clock(VideoState *is)
959 {
960 double val;
961
962 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
963 if (is->video_st)
964 val = get_video_clock(is);
965 else
966 val = get_audio_clock(is);
967 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
968 if (is->audio_st)
969 val = get_audio_clock(is);
970 else
971 val = get_video_clock(is);
972 } else {
973 val = get_external_clock(is);
974 }
975 return val;
976 }
977
978 /* seek in the stream */
979 static void stream_seek(VideoState *is, int64_t pos, int rel)
980 {
981 if (!is->seek_req) {
982 is->seek_pos = pos;
983 is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
984 if (seek_by_bytes)
985 is->seek_flags |= AVSEEK_FLAG_BYTE;
986 is->seek_req = 1;
987 }
988 }
989
990 /* pause or resume the video */
991 static void stream_pause(VideoState *is)
992 {
993 is->paused = !is->paused;
994 if (!is->paused) {
995 is->video_current_pts = get_video_clock(is);
996 is->frame_timer += (av_gettime() - is->video_current_pts_time) / 1000000.0;
997 }
998 }
999
1000 /* called to display each frame */
1001 static void video_refresh_timer(void *opaque)
1002 {
1003 VideoState *is = opaque;
1004 VideoPicture *vp;
1005 double actual_delay, delay, sync_threshold, ref_clock, diff;
1006
1007 SubPicture *sp, *sp2;
1008
1009 if (is->video_st) {
1010 if (is->pictq_size == 0) {
1011 /* if no picture, need to wait */
1012 schedule_refresh(is, 1);
1013 } else {
1014 /* dequeue the picture */
1015 vp = &is->pictq[is->pictq_rindex];
1016
1017 /* update current video pts */
1018 is->video_current_pts = vp->pts;
1019 is->video_current_pts_time = av_gettime();
1020
1021 /* compute nominal delay */
1022 delay = vp->pts - is->frame_last_pts;
1023 if (delay <= 0 || delay >= 1.0) {
1024 /* if incorrect delay, use previous one */
1025 delay = is->frame_last_delay;
1026 }
1027 is->frame_last_delay = delay;
1028 is->frame_last_pts = vp->pts;
1029
1030 /* update delay to follow master synchronisation source */
1031 if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1032 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1033 /* if video is slave, we try to correct big delays by
1034 duplicating or deleting a frame */
1035 ref_clock = get_master_clock(is);
1036 diff = vp->pts - ref_clock;
1037
1038 /* skip or repeat frame. We take into account the
1039 delay to compute the threshold. I still don't know
1040 if it is the best guess */
1041 sync_threshold = AV_SYNC_THRESHOLD;
1042 if (delay > sync_threshold)
1043 sync_threshold = delay;
1044 if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1045 if (diff <= -sync_threshold)
1046 delay = 0;
1047 else if (diff >= sync_threshold)
1048 delay = 2 * delay;
1049 }
1050 }
1051
1052 is->frame_timer += delay;
1053 /* compute the REAL delay (we need to do that to avoid
1054 long term errors */
1055 actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1056 if (actual_delay < 0.010) {
1057 /* XXX: should skip picture */
1058 actual_delay = 0.010;
1059 }
1060 /* launch timer for next picture */
1061 schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
1062
1063 #if defined(DEBUG_SYNC)
1064 printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1065 delay, actual_delay, vp->pts, -diff);
1066 #endif
1067
1068 if(is->subtitle_st) {
1069 if (is->subtitle_stream_changed) {
1070 SDL_LockMutex(is->subpq_mutex);
1071
1072 while (is->subpq_size) {
1073 free_subpicture(&is->subpq[is->subpq_rindex]);
1074
1075 /* update queue size and signal for next picture */
1076 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1077 is->subpq_rindex = 0;
1078
1079 is->subpq_size--;
1080 }
1081 is->subtitle_stream_changed = 0;
1082
1083 SDL_CondSignal(is->subpq_cond);
1084 SDL_UnlockMutex(is->subpq_mutex);
1085 } else {
1086 if (is->subpq_size > 0) {
1087 sp = &is->subpq[is->subpq_rindex];
1088
1089 if (is->subpq_size > 1)
1090 sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1091 else
1092 sp2 = NULL;
1093
1094 if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1095 || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1096 {
1097 free_subpicture(sp);
1098
1099 /* update queue size and signal for next picture */
1100 if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1101 is->subpq_rindex = 0;
1102
1103 SDL_LockMutex(is->subpq_mutex);
1104 is->subpq_size--;
1105 SDL_CondSignal(is->subpq_cond);
1106 SDL_UnlockMutex(is->subpq_mutex);
1107 }
1108 }
1109 }
1110 }
1111
1112 /* display picture */
1113 video_display(is);
1114
1115 /* update queue size and signal for next picture */
1116 if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1117 is->pictq_rindex = 0;
1118
1119 SDL_LockMutex(is->pictq_mutex);
1120 is->pictq_size--;
1121 SDL_CondSignal(is->pictq_cond);
1122 SDL_UnlockMutex(is->pictq_mutex);
1123 }
1124 } else if (is->audio_st) {
1125 /* draw the next audio frame */
1126
1127 schedule_refresh(is, 40);
1128
1129 /* if only audio stream, then display the audio bars (better
1130 than nothing, just to test the implementation */
1131
1132 /* display picture */
1133 video_display(is);
1134 } else {
1135 schedule_refresh(is, 100);
1136 }
1137 if (show_status) {
1138 static int64_t last_time;
1139 int64_t cur_time;
1140 int aqsize, vqsize, sqsize;
1141 double av_diff;
1142
1143 cur_time = av_gettime();
1144 if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1145 aqsize = 0;
1146 vqsize = 0;
1147 sqsize = 0;
1148 if (is->audio_st)
1149 aqsize = is->audioq.size;
1150 if (is->video_st)
1151 vqsize = is->videoq.size;
1152 if (is->subtitle_st)
1153 sqsize = is->subtitleq.size;
1154 av_diff = 0;
1155 if (is->audio_st && is->video_st)
1156 av_diff = get_audio_clock(is) - get_video_clock(is);
1157 printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB \r",
1158 get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1159 fflush(stdout);
1160 last_time = cur_time;
1161 }
1162 }
1163 }
1164
1165 /* allocate a picture (needs to do that in main thread to avoid
1166 potential locking problems */
1167 static void alloc_picture(void *opaque)
1168 {
1169 VideoState *is = opaque;
1170 VideoPicture *vp;
1171
1172 vp = &is->pictq[is->pictq_windex];
1173
1174 if (vp->bmp)
1175 SDL_FreeYUVOverlay(vp->bmp);
1176
1177 #if 0
1178 /* XXX: use generic function */
1179 /* XXX: disable overlay if no hardware acceleration or if RGB format */
1180 switch(is->video_st->codec->pix_fmt) {
1181 case PIX_FMT_YUV420P:
1182 case PIX_FMT_YUV422P:
1183 case PIX_FMT_YUV444P:
1184 case PIX_FMT_YUYV422:
1185 case PIX_FMT_YUV410P:
1186 case PIX_FMT_YUV411P:
1187 is_yuv = 1;
1188 break;
1189 default:
1190 is_yuv = 0;
1191 break;
1192 }
1193 #endif
1194 vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1195 is->video_st->codec->height,
1196 SDL_YV12_OVERLAY,
1197 screen);
1198 vp->width = is->video_st->codec->width;
1199 vp->height = is->video_st->codec->height;
1200
1201 SDL_LockMutex(is->pictq_mutex);
1202 vp->allocated = 1;
1203 SDL_CondSignal(is->pictq_cond);
1204 SDL_UnlockMutex(is->pictq_mutex);
1205 }
1206
1207 /**
1208 *
1209 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1210 */
1211 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1212 {
1213 VideoPicture *vp;
1214 int dst_pix_fmt;
1215 AVPicture pict;
1216 static struct SwsContext *img_convert_ctx;
1217
1218 /* wait until we have space to put a new picture */
1219 SDL_LockMutex(is->pictq_mutex);
1220 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1221 !is->videoq.abort_request) {
1222 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1223 }
1224 SDL_UnlockMutex(is->pictq_mutex);
1225
1226 if (is->videoq.abort_request)
1227 return -1;
1228
1229 vp = &is->pictq[is->pictq_windex];
1230
1231 /* alloc or resize hardware picture buffer */
1232 if (!vp->bmp ||
1233 vp->width != is->video_st->codec->width ||
1234 vp->height != is->video_st->codec->height) {
1235 SDL_Event event;
1236
1237 vp->allocated = 0;
1238
1239 /* the allocation must be done in the main thread to avoid
1240 locking problems */
1241 event.type = FF_ALLOC_EVENT;
1242 event.user.data1 = is;
1243 SDL_PushEvent(&event);
1244
1245 /* wait until the picture is allocated */
1246 SDL_LockMutex(is->pictq_mutex);
1247 while (!vp->allocated && !is->videoq.abort_request) {
1248 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1249 }
1250 SDL_UnlockMutex(is->pictq_mutex);
1251
1252 if (is->videoq.abort_request)
1253 return -1;
1254 }
1255
1256 /* if the frame is not skipped, then display it */
1257 if (vp->bmp) {
1258 /* get a pointer on the bitmap */
1259 SDL_LockYUVOverlay (vp->bmp);
1260
1261 dst_pix_fmt = PIX_FMT_YUV420P;
1262 pict.data[0] = vp->bmp->pixels[0];
1263 pict.data[1] = vp->bmp->pixels[2];
1264 pict.data[2] = vp->bmp->pixels[1];
1265
1266 pict.linesize[0] = vp->bmp->pitches[0];
1267 pict.linesize[1] = vp->bmp->pitches[2];
1268 pict.linesize[2] = vp->bmp->pitches[1];
1269 if (img_convert_ctx == NULL) {
1270 img_convert_ctx = sws_getContext(is->video_st->codec->width,
1271 is->video_st->codec->height, is->video_st->codec->pix_fmt,
1272 is->video_st->codec->width, is->video_st->codec->height,
1273 dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1274 if (img_convert_ctx == NULL) {
1275 fprintf(stderr, "Cannot initialize the conversion context\n");
1276 exit(1);
1277 }
1278 }
1279 sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
1280 0, is->video_st->codec->height, pict.data, pict.linesize);
1281 /* update the bitmap content */
1282 SDL_UnlockYUVOverlay(vp->bmp);
1283
1284 vp->pts = pts;
1285
1286 /* now we can update the picture count */
1287 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1288 is->pictq_windex = 0;
1289 SDL_LockMutex(is->pictq_mutex);
1290 is->pictq_size++;
1291 SDL_UnlockMutex(is->pictq_mutex);
1292 }
1293 return 0;
1294 }
1295
1296 /**
1297 * compute the exact PTS for the picture if it is omitted in the stream
1298 * @param pts1 the dts of the pkt / pts of the frame
1299 */
1300 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1301 {
1302 double frame_delay, pts;
1303
1304 pts = pts1;
1305
1306 if (pts != 0) {
1307 /* update video clock with pts, if present */
1308 is->video_clock = pts;
1309 } else {
1310 pts = is->video_clock;
1311 }
1312 /* update video clock for next frame */
1313 frame_delay = av_q2d(is->video_st->codec->time_base);
1314 /* for MPEG2, the frame can be repeated, so we update the
1315 clock accordingly */
1316 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1317 is->video_clock += frame_delay;
1318
1319 #if defined(DEBUG_SYNC) && 0
1320 {
1321 int ftype;
1322 if (src_frame->pict_type == FF_B_TYPE)
1323 ftype = 'B';
1324 else if (src_frame->pict_type == FF_I_TYPE)
1325 ftype = 'I';
1326 else
1327 ftype = 'P';
1328 printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1329 ftype, pts, pts1);
1330 }
1331 #endif
1332 return queue_picture(is, src_frame, pts);
1333 }
1334
1335 static uint64_t global_video_pkt_pts= AV_NOPTS_VALUE;
1336
1337 static int my_get_buffer(struct AVCodecContext *c, AVFrame *pic){
1338 int ret= avcodec_default_get_buffer(c, pic);
1339 uint64_t *pts= av_malloc(sizeof(uint64_t));
1340 *pts= global_video_pkt_pts;
1341 pic->opaque= pts;
1342 return ret;
1343 }
1344
1345 static void my_release_buffer(struct AVCodecContext *c, AVFrame *pic){
1346 if(pic) av_freep(&pic->opaque);
1347 avcodec_default_release_buffer(c, pic);
1348 }
1349
1350 static int video_thread(void *arg)
1351 {
1352 VideoState *is = arg;
1353 AVPacket pkt1, *pkt = &pkt1;
1354 int len1, got_picture;
1355 AVFrame *frame= avcodec_alloc_frame();
1356 double pts;
1357
1358 for(;;) {
1359 while (is->paused && !is->videoq.abort_request) {
1360 SDL_Delay(10);
1361 }
1362 if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1363 break;
1364
1365 if(pkt->data == flush_pkt.data){
1366 avcodec_flush_buffers(is->video_st->codec);
1367 continue;
1368 }
1369
1370 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1371 this packet, if any */
1372 global_video_pkt_pts= pkt->pts;
1373 len1 = avcodec_decode_video(is->video_st->codec,
1374 frame, &got_picture,
1375 pkt->data, pkt->size);
1376
1377 if( (decoder_reorder_pts || pkt->dts == AV_NOPTS_VALUE)
1378 && frame->opaque && *(uint64_t*)frame->opaque != AV_NOPTS_VALUE)
1379 pts= *(uint64_t*)frame->opaque;
1380 else if(pkt->dts != AV_NOPTS_VALUE)
1381 pts= pkt->dts;
1382 else
1383 pts= 0;
1384 pts *= av_q2d(is->video_st->time_base);
1385
1386 // if (len1 < 0)
1387 // break;
1388 if (got_picture) {
1389 if (output_picture2(is, frame, pts) < 0)
1390 goto the_end;
1391 }
1392 av_free_packet(pkt);
1393 if (step)
1394 if (cur_stream)
1395 stream_pause(cur_stream);
1396 }
1397 the_end:
1398 av_free(frame);
1399 return 0;
1400 }
1401
1402 static int subtitle_thread(void *arg)
1403 {
1404 VideoState *is = arg;
1405 SubPicture *sp;
1406 AVPacket pkt1, *pkt = &pkt1;
1407 int len1, got_subtitle;
1408 double pts;
1409 int i, j;
1410 int r, g, b, y, u, v, a;
1411
1412 for(;;) {
1413 while (is->paused && !is->subtitleq.abort_request) {
1414 SDL_Delay(10);
1415 }
1416 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1417 break;
1418
1419 if(pkt->data == flush_pkt.data){
1420 avcodec_flush_buffers(is->subtitle_st->codec);
1421 continue;
1422 }
1423 SDL_LockMutex(is->subpq_mutex);
1424 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1425 !is->subtitleq.abort_request) {
1426 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1427 }
1428 SDL_UnlockMutex(is->subpq_mutex);
1429
1430 if (is->subtitleq.abort_request)
1431 goto the_end;
1432
1433 sp = &is->subpq[is->subpq_windex];
1434
1435 /* NOTE: ipts is the PTS of the _first_ picture beginning in
1436 this packet, if any */
1437 pts = 0;
1438 if (pkt->pts != AV_NOPTS_VALUE)
1439 pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1440
1441 len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
1442 &sp->sub, &got_subtitle,
1443 pkt->data, pkt->size);
1444 // if (len1 < 0)
1445 // break;
1446 if (got_subtitle && sp->sub.format == 0) {
1447 sp->pts = pts;
1448
1449 for (i = 0; i < sp->sub.num_rects; i++)
1450 {
1451 for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
1452 {
1453 RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
1454 y = RGB_TO_Y_CCIR(r, g, b);
1455 u = RGB_TO_U_CCIR(r, g, b, 0);
1456 v = RGB_TO_V_CCIR(r, g, b, 0);
1457 YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
1458 }
1459 }
1460
1461 /* now we can update the picture count */
1462 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1463 is->subpq_windex = 0;
1464 SDL_LockMutex(is->subpq_mutex);
1465 is->subpq_size++;
1466 SDL_UnlockMutex(is->subpq_mutex);
1467 }
1468 av_free_packet(pkt);
1469 // if (step)
1470 // if (cur_stream)
1471 // stream_pause(cur_stream);
1472 }
1473 the_end:
1474 return 0;
1475 }
1476
1477 /* copy samples for viewing in editor window */
1478 static void update_sample_display(VideoState *is, short *samples, int samples_size)
1479 {
1480 int size, len, channels;
1481
1482 channels = is->audio_st->codec->channels;
1483
1484 size = samples_size / sizeof(short);
1485 while (size > 0) {
1486 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1487 if (len > size)
1488 len = size;
1489 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1490 samples += len;
1491 is->sample_array_index += len;
1492 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1493 is->sample_array_index = 0;
1494 size -= len;
1495 }
1496 }
1497
1498 /* return the new audio buffer size (samples can be added or deleted
1499 to get better sync if video or external master clock) */
1500 static int synchronize_audio(VideoState *is, short *samples,
1501 int samples_size1, double pts)
1502 {
1503 int n, samples_size;
1504 double ref_clock;
1505
1506 n = 2 * is->audio_st->codec->channels;
1507 samples_size = samples_size1;
1508
1509 /* if not master, then we try to remove or add samples to correct the clock */
1510 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1511 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1512 double diff, avg_diff;
1513 int wanted_size, min_size, max_size, nb_samples;
1514
1515 ref_clock = get_master_clock(is);
1516 diff = get_audio_clock(is) - ref_clock;
1517
1518 if (diff < AV_NOSYNC_THRESHOLD) {
1519 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1520 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1521 /* not enough measures to have a correct estimate */
1522 is->audio_diff_avg_count++;
1523 } else {
1524 /* estimate the A-V difference */
1525 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1526
1527 if (fabs(avg_diff) >= is->audio_diff_threshold) {
1528 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1529 nb_samples = samples_size / n;
1530
1531 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1532 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1533 if (wanted_size < min_size)
1534 wanted_size = min_size;
1535 else if (wanted_size > max_size)
1536 wanted_size = max_size;
1537
1538 /* add or remove samples to correction the synchro */
1539 if (wanted_size < samples_size) {
1540 /* remove samples */
1541 samples_size = wanted_size;
1542 } else if (wanted_size > samples_size) {
1543 uint8_t *samples_end, *q;
1544 int nb;
1545
1546 /* add samples */
1547 nb = (samples_size - wanted_size);
1548 samples_end = (uint8_t *)samples + samples_size - n;
1549 q = samples_end + n;
1550 while (nb > 0) {
1551 memcpy(q, samples_end, n);
1552 q += n;
1553 nb -= n;
1554 }
1555 samples_size = wanted_size;
1556 }
1557 }
1558 #if 0
1559 printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1560 diff, avg_diff, samples_size - samples_size1,
1561 is->audio_clock, is->video_clock, is->audio_diff_threshold);
1562 #endif
1563 }
1564 } else {
1565 /* too big difference : may be initial PTS errors, so
1566 reset A-V filter */
1567 is->audio_diff_avg_count = 0;
1568 is->audio_diff_cum = 0;
1569 }
1570 }
1571
1572 return samples_size;
1573 }
1574
1575 /* decode one audio frame and returns its uncompressed size */
1576 static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size, double *pts_ptr)
1577 {
1578 AVPacket *pkt = &is->audio_pkt;
1579 int n, len1, data_size;
1580 double pts;
1581
1582 for(;;) {
1583 /* NOTE: the audio packet can contain several frames */
1584 while (is->audio_pkt_size > 0) {
1585 data_size = buf_size;
1586 len1 = avcodec_decode_audio2(is->audio_st->codec,
1587 (int16_t *)audio_buf, &data_size,
1588 is->audio_pkt_data, is->audio_pkt_size);
1589 if (len1 < 0) {
1590 /* if error, we skip the frame */
1591 is->audio_pkt_size = 0;
1592 break;
1593 }
1594
1595 is->audio_pkt_data += len1;
1596 is->audio_pkt_size -= len1;
1597 if (data_size <= 0)
1598 continue;
1599 /* if no pts, then compute it */
1600 pts = is->audio_clock;
1601 *pts_ptr = pts;
1602 n = 2 * is->audio_st->codec->channels;
1603 is->audio_clock += (double)data_size /
1604 (double)(n * is->audio_st->codec->sample_rate);
1605 #if defined(DEBUG_SYNC)
1606 {
1607 static double last_clock;
1608 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1609 is->audio_clock - last_clock,
1610 is->audio_clock, pts);
1611 last_clock = is->audio_clock;
1612 }
1613 #endif
1614 return data_size;
1615 }
1616
1617 /* free the current packet */
1618 if (pkt->data)
1619 av_free_packet(pkt);
1620
1621 if (is->paused || is->audioq.abort_request) {
1622 return -1;
1623 }
1624
1625 /* read next packet */
1626 if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1627 return -1;
1628 if(pkt->data == flush_pkt.data){
1629 avcodec_flush_buffers(is->audio_st->codec);
1630 continue;
1631 }
1632
1633 is->audio_pkt_data = pkt->data;
1634 is->audio_pkt_size = pkt->size;
1635
1636 /* if update the audio clock with the pts */
1637 if (pkt->pts != AV_NOPTS_VALUE) {
1638 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1639 }
1640 }
1641 }
1642
1643 /* get the current audio output buffer size, in samples. With SDL, we
1644 cannot have a precise information */
1645 static int audio_write_get_buf_size(VideoState *is)
1646 {
1647 return is->audio_buf_size - is->audio_buf_index;
1648 }
1649
1650
1651 /* prepare a new audio buffer */
1652 void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1653 {
1654 VideoState *is = opaque;
1655 int audio_size, len1;
1656 double pts;
1657
1658 audio_callback_time = av_gettime();
1659
1660 while (len > 0) {
1661 if (is->audio_buf_index >= is->audio_buf_size) {
1662 audio_size = audio_decode_frame(is, is->audio_buf, sizeof(is->audio_buf), &pts);
1663 if (audio_size < 0) {
1664 /* if error, just output silence */
1665 is->audio_buf_size = 1024;
1666 memset(is->audio_buf, 0, is->audio_buf_size);
1667 } else {
1668 if (is->show_audio)
1669 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1670 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1671 pts);
1672 is->audio_buf_size = audio_size;
1673 }
1674 is->audio_buf_index = 0;
1675 }
1676 len1 = is->audio_buf_size - is->audio_buf_index;
1677 if (len1 > len)
1678 len1 = len;
1679 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1680 len -= len1;
1681 stream += len1;
1682 is->audio_buf_index += len1;
1683 }
1684 }
1685
1686 /* open a given stream. Return 0 if OK */
1687 static int stream_component_open(VideoState *is, int stream_index)
1688 {
1689 AVFormatContext *ic = is->ic;
1690 AVCodecContext *enc;
1691 AVCodec *codec;
1692 SDL_AudioSpec wanted_spec, spec;
1693
1694 if (stream_index < 0 || stream_index >= ic->nb_streams)
1695 return -1;
1696 enc = ic->streams[stream_index]->codec;
1697
1698 /* prepare audio output */
1699 if (enc->codec_type == CODEC_TYPE_AUDIO) {
1700 wanted_spec.freq = enc->sample_rate;
1701 wanted_spec.format = AUDIO_S16SYS;
1702 /* hack for AC3. XXX: suppress that */
1703 if (enc->channels > 2)
1704 enc->channels = 2;
1705 wanted_spec.channels = enc->channels;
1706 wanted_spec.silence = 0;
1707 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1708 wanted_spec.callback = sdl_audio_callback;
1709 wanted_spec.userdata = is;
1710 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1711 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1712 return -1;
1713 }
1714 is->audio_hw_buf_size = spec.size;
1715 }
1716
1717 codec = avcodec_find_decoder(enc->codec_id);
1718 enc->debug_mv = debug_mv;
1719 enc->debug = debug;
1720 enc->workaround_bugs = workaround_bugs;
1721 enc->lowres = lowres;
1722 if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1723 enc->idct_algo= idct;
1724 if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1725 enc->skip_frame= skip_frame;
1726 enc->skip_idct= skip_idct;
1727 enc->skip_loop_filter= skip_loop_filter;
1728 enc->error_resilience= error_resilience;
1729 enc->error_concealment= error_concealment;
1730 if (!codec ||
1731 avcodec_open(enc, codec) < 0)
1732 return -1;
1733 if(thread_count>1)
1734 avcodec_thread_init(enc, thread_count);
1735 enc->thread_count= thread_count;
1736 switch(enc->codec_type) {
1737 case CODEC_TYPE_AUDIO:
1738 is->audio_stream = stream_index;
1739 is->audio_st = ic->streams[stream_index];
1740 is->audio_buf_size = 0;
1741 is->audio_buf_index = 0;
1742
1743 /* init averaging filter */
1744 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1745 is->audio_diff_avg_count = 0;
1746 /* since we do not have a precise anough audio fifo fullness,
1747 we correct audio sync only if larger than this threshold */
1748 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1749
1750 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1751 packet_queue_init(&is->audioq);
1752 SDL_PauseAudio(0);
1753 break;
1754 case CODEC_TYPE_VIDEO:
1755 is->video_stream = stream_index;
1756 is->video_st = ic->streams[stream_index];
1757
1758 is->frame_last_delay = 40e-3;
1759 is->frame_timer = (double)av_gettime() / 1000000.0;
1760 is->video_current_pts_time = av_gettime();
1761
1762 packet_queue_init(&is->videoq);
1763 is->video_tid = SDL_CreateThread(video_thread, is);
1764
1765 enc-> get_buffer= my_get_buffer;
1766 enc->release_buffer= my_release_buffer;
1767 break;
1768 case CODEC_TYPE_SUBTITLE:
1769 is->subtitle_stream = stream_index;
1770 is->subtitle_st = ic->streams[stream_index];
1771 packet_queue_init(&is->subtitleq);
1772
1773 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1774 break;
1775 default:
1776 break;
1777 }
1778 return 0;
1779 }
1780
1781 static void stream_component_close(VideoState *is, int stream_index)
1782 {
1783 AVFormatContext *ic = is->ic;
1784 AVCodecContext *enc;
1785
1786 if (stream_index < 0 || stream_index >= ic->nb_streams)
1787 return;
1788 enc = ic->streams[stream_index]->codec;
1789
1790 switch(enc->codec_type) {
1791 case CODEC_TYPE_AUDIO:
1792 packet_queue_abort(&is->audioq);
1793
1794 SDL_CloseAudio();
1795
1796 packet_queue_end(&is->audioq);
1797 break;
1798 case CODEC_TYPE_VIDEO:
1799 packet_queue_abort(&is->videoq);
1800
1801 /* note: we also signal this mutex to make sure we deblock the
1802 video thread in all cases */
1803 SDL_LockMutex(is->pictq_mutex);
1804 SDL_CondSignal(is->pictq_cond);
1805 SDL_UnlockMutex(is->pictq_mutex);
1806
1807 SDL_WaitThread(is->video_tid, NULL);
1808
1809 packet_queue_end(&is->videoq);
1810 break;
1811 case CODEC_TYPE_SUBTITLE:
1812 packet_queue_abort(&is->subtitleq);
1813
1814 /* note: we also signal this mutex to make sure we deblock the
1815 video thread in all cases */
1816 SDL_LockMutex(is->subpq_mutex);
1817 is->subtitle_stream_changed = 1;
1818
1819 SDL_CondSignal(is->subpq_cond);
1820 SDL_UnlockMutex(is->subpq_mutex);
1821
1822 SDL_WaitThread(is->subtitle_tid, NULL);
1823
1824 packet_queue_end(&is->subtitleq);
1825 break;
1826 default:
1827 break;
1828 }
1829
1830 avcodec_close(enc);
1831 switch(enc->codec_type) {
1832 case CODEC_TYPE_AUDIO:
1833 is->audio_st = NULL;
1834 is->audio_stream = -1;
1835 break;
1836 case CODEC_TYPE_VIDEO:
1837 is->video_st = NULL;
1838 is->video_stream = -1;
1839 break;
1840 case CODEC_TYPE_SUBTITLE:
1841 is->subtitle_st = NULL;
1842 is->subtitle_stream = -1;
1843 break;
1844 default:
1845 break;
1846 }
1847 }
1848
1849 static void dump_stream_info(const AVFormatContext *s)
1850 {
1851 if (s->track != 0)
1852 fprintf(stderr, "Track: %d\n", s->track);
1853 if (s->title[0] != '\0')
1854 fprintf(stderr, "Title: %s\n", s->title);
1855 if (s->author[0] != '\0')
1856 fprintf(stderr, "Author: %s\n", s->author);
1857 if (s->copyright[0] != '\0')
1858 fprintf(stderr, "Copyright: %s\n", s->copyright);
1859 if (s->comment[0] != '\0')
1860 fprintf(stderr, "Comment: %s\n", s->comment);
1861 if (s->album[0] != '\0')
1862 fprintf(stderr, "Album: %s\n", s->album);
1863 if (s->year != 0)
1864 fprintf(stderr, "Year: %d\n", s->year);
1865 if (s->genre[0] != '\0')
1866 fprintf(stderr, "Genre: %s\n", s->genre);
1867 }
1868
1869 /* since we have only one decoding thread, we can use a global
1870 variable instead of a thread local variable */
1871 static VideoState *global_video_state;
1872
1873 static int decode_interrupt_cb(void)
1874 {
1875 return (global_video_state && global_video_state->abort_request);
1876 }
1877
1878 /* this thread gets the stream from the disk or the network */
1879 static int decode_thread(void *arg)
1880 {
1881 VideoState *is = arg;
1882 AVFormatContext *ic;
1883 int err, i, ret, video_index, audio_index, use_play;
1884 AVPacket pkt1, *pkt = &pkt1;
1885 AVFormatParameters params, *ap = &params;
1886
1887 video_index = -1;
1888 audio_index = -1;
1889 is->video_stream = -1;
1890 is->audio_stream = -1;
1891 is->subtitle_stream = -1;
1892
1893 global_video_state = is;
1894 url_set_interrupt_cb(decode_interrupt_cb);
1895
1896 memset(ap, 0, sizeof(*ap));
1897 ap->initial_pause = 1; /* we force a pause when starting an RTSP
1898 stream */
1899
1900 ap->width = frame_width;
1901 ap->height= frame_height;
1902 ap->time_base= (AVRational){1, 25};
1903 ap->pix_fmt = frame_pix_fmt;
1904
1905 err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1906 if (err < 0) {
1907 print_error(is->filename, err);
1908 ret = -1;
1909 goto fail;
1910 }
1911 is->ic = ic;
1912 #ifdef CONFIG_RTSP_DEMUXER
1913 use_play = (ic->iformat == &rtsp_demuxer);
1914 #else
1915 use_play = 0;
1916 #endif
1917
1918 if(genpts)
1919 ic->flags |= AVFMT_FLAG_GENPTS;
1920
1921 if (!use_play) {
1922 err = av_find_stream_info(ic);
1923 if (err < 0) {
1924 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1925 ret = -1;
1926 goto fail;
1927 }
1928 ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1929 }
1930
1931 /* if seeking requested, we execute it */
1932 if (start_time != AV_NOPTS_VALUE) {
1933 int64_t timestamp;
1934
1935 timestamp = start_time;
1936 /* add the stream start time */
1937 if (ic->start_time != AV_NOPTS_VALUE)
1938 timestamp += ic->start_time;
1939 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1940 if (ret < 0) {
1941 fprintf(stderr, "%s: could not seek to position %0.3f\n",
1942 is->filename, (double)timestamp / AV_TIME_BASE);
1943 }
1944 }
1945
1946 /* now we can begin to play (RTSP stream only) */
1947 av_read_play(ic);
1948
1949 if (use_play) {
1950 err = av_find_stream_info(ic);
1951 if (err < 0) {
1952 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1953 ret = -1;
1954 goto fail;
1955 }
1956 }
1957
1958 for(i = 0; i < ic->nb_streams; i++) {
1959 AVCodecContext *enc = ic->streams[i]->codec;
1960 switch(enc->codec_type) {
1961 case CODEC_TYPE_AUDIO:
1962 if ((audio_index < 0 || wanted_audio_stream-- > 0) && !audio_disable)
1963 audio_index = i;
1964 break;
1965 case CODEC_TYPE_VIDEO:
1966 if (video_index < 0 && !video_disable)
1967 video_index = i;
1968 break;
1969 default:
1970 break;
1971 }
1972 }
1973 if (show_status) {
1974 dump_format(ic, 0, is->filename, 0);
1975 dump_stream_info(ic);
1976 }
1977
1978 /* open the streams */
1979 if (audio_index >= 0) {
1980 stream_component_open(is, audio_index);
1981 }
1982
1983 if (video_index >= 0) {
1984 stream_component_open(is, video_index);
1985 } else {
1986 if (!display_disable)
1987 is->show_audio = 1;
1988 }
1989
1990 if (is->video_stream < 0 && is->audio_stream < 0) {
1991 fprintf(stderr, "%s: could not open codecs\n", is->filename);
1992 ret = -1;
1993 goto fail;
1994 }
1995
1996 for(;;) {
1997 if (is->abort_request)
1998 break;
1999 if (is->paused != is->last_paused) {
2000 is->last_paused = is->paused;
2001 if (is->paused)
2002 av_read_pause(ic);
2003 else
2004 av_read_play(ic);
2005 }
2006 #ifdef CONFIG_RTSP_DEMUXER
2007 if (is->paused && ic->iformat == &rtsp_demuxer) {
2008 /* wait 10 ms to avoid trying to get another packet */
2009 /* XXX: horrible */
2010 SDL_Delay(10);
2011 continue;
2012 }
2013 #endif
2014 if (is->seek_req) {
2015 int stream_index= -1;
2016 int64_t seek_target= is->seek_pos;
2017
2018 if (is-> video_stream >= 0) stream_index= is-> video_stream;
2019 else if(is-> audio_stream >= 0) stream_index= is-> audio_stream;
2020 else if(is->subtitle_stream >= 0) stream_index= is->subtitle_stream;
2021
2022 if(stream_index>=0){
2023 seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, ic->streams[stream_index]->time_base);
2024 }
2025
2026 ret = av_seek_frame(is->ic, stream_index, seek_target, is->seek_flags);
2027 if (ret < 0) {
2028 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2029 }else{
2030 if (is->audio_stream >= 0) {
2031 packet_queue_flush(&is->audioq);
2032 packet_queue_put(&is->audioq, &flush_pkt);
2033 }
2034 if (is->subtitle_stream >= 0) {
2035 packet_queue_flush(&is->subtitleq);
2036 packet_queue_put(&is->subtitleq, &flush_pkt);
2037 }
2038 if (is->video_stream >= 0) {
2039 packet_queue_flush(&is->videoq);
2040 packet_queue_put(&is->videoq, &flush_pkt);
2041 }
2042 }
2043 is->seek_req = 0;
2044 }
2045
2046 /* if the queue are full, no need to read more */
2047 if (is->audioq.size > MAX_AUDIOQ_SIZE ||
2048 is->videoq.size > MAX_VIDEOQ_SIZE ||
2049 is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
2050 url_feof(&ic->pb)) {
2051 /* wait 10 ms */
2052 SDL_Delay(10);
2053 continue;
2054 }
2055 ret = av_read_frame(ic, pkt);
2056 if (ret < 0) {
2057 if (url_ferror(&ic->pb) == 0) {
2058 SDL_Delay(100); /* wait for user event */
2059 continue;
2060 } else
2061 break;
2062 }
2063 if (pkt->stream_index == is->audio_stream) {
2064 packet_queue_put(&is->audioq, pkt);
2065 } else if (pkt->stream_index == is->video_stream) {
2066 packet_queue_put(&is->videoq, pkt);
2067 } else if (pkt->stream_index == is->subtitle_stream) {
2068 packet_queue_put(&is->subtitleq, pkt);
2069 } else {
2070 av_free_packet(pkt);
2071 }
2072 }
2073 /* wait until the end */
2074 while (!is->abort_request) {
2075 SDL_Delay(100);
2076 }
2077
2078 ret = 0;
2079 fail:
2080 /* disable interrupting */
2081 global_video_state = NULL;
2082
2083 /* close each stream */
2084 if (is->audio_stream >= 0)
2085 stream_component_close(is, is->audio_stream);
2086 if (is->video_stream >= 0)
2087 stream_component_close(is, is->video_stream);
2088 if (is->subtitle_stream >= 0)
2089 stream_component_close(is, is->subtitle_stream);
2090 if (is->ic) {
2091 av_close_input_file(is->ic);
2092 is->ic = NULL; /* safety */
2093 }
2094 url_set_interrupt_cb(NULL);
2095
2096 if (ret != 0) {
2097 SDL_Event event;
2098
2099 event.type = FF_QUIT_EVENT;
2100 event.user.data1 = is;
2101 SDL_PushEvent(&event);
2102 }
2103 return 0;
2104 }
2105
2106 static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2107 {
2108 VideoState *is;
2109
2110 is = av_mallocz(sizeof(VideoState));
2111 if (!is)
2112 return NULL;
2113 av_strlcpy(is->filename, filename, sizeof(is->filename));
2114 is->iformat = iformat;
2115 is->ytop = 0;
2116 is->xleft = 0;
2117
2118 /* start video display */
2119 is->pictq_mutex = SDL_CreateMutex();
2120 is->pictq_cond = SDL_CreateCond();
2121
2122 is->subpq_mutex = SDL_CreateMutex();
2123 is->subpq_cond = SDL_CreateCond();
2124
2125 /* add the refresh timer to draw the picture */
2126 schedule_refresh(is, 40);
2127
2128 is->av_sync_type = av_sync_type;
2129 is->parse_tid = SDL_CreateThread(decode_thread, is);
2130 if (!is->parse_tid) {
2131 av_free(is);
2132 return NULL;
2133 }
2134 return is;
2135 }
2136
2137 static void stream_close(VideoState *is)
2138 {
2139 VideoPicture *vp;
2140 int i;
2141 /* XXX: use a special url_shutdown call to abort parse cleanly */
2142 is->abort_request = 1;
2143 SDL_WaitThread(is->parse_tid, NULL);
2144
2145 /* free all pictures */
2146 for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2147 vp = &is->pictq[i];
2148 if (vp->bmp) {
2149 SDL_FreeYUVOverlay(vp->bmp);
2150 vp->bmp = NULL;
2151 }
2152 }
2153 SDL_DestroyMutex(is->pictq_mutex);
2154 SDL_DestroyCond(is->pictq_cond);
2155 SDL_DestroyMutex(is->subpq_mutex);
2156 SDL_DestroyCond(is->subpq_cond);
2157 }
2158
2159 static void stream_cycle_channel(VideoState *is, int codec_type)
2160 {
2161 AVFormatContext *ic = is->ic;
2162 int start_index, stream_index;
2163 AVStream *st;
2164
2165 if (codec_type == CODEC_TYPE_VIDEO)
2166 start_index = is->video_stream;
2167 else if (codec_type == CODEC_TYPE_AUDIO)
2168 start_index = is->audio_stream;
2169 else
2170 start_index = is->subtitle_stream;
2171 if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2172 return;
2173 stream_index = start_index;
2174 for(;;) {
2175 if (++stream_index >= is->ic->nb_streams)
2176 {
2177 if (codec_type == CODEC_TYPE_SUBTITLE)
2178 {
2179 stream_index = -1;
2180 goto the_end;
2181 } else
2182 stream_index = 0;
2183 }
2184 if (stream_index == start_index)
2185 return;
2186 st = ic->streams[stream_index];
2187 if (st->codec->codec_type == codec_type) {
2188 /* check that parameters are OK */
2189 switch(codec_type) {
2190 case CODEC_TYPE_AUDIO:
2191 if (st->codec->sample_rate != 0 &&
2192 st->codec->channels != 0)
2193 goto the_end;
2194 break;
2195 case CODEC_TYPE_VIDEO:
2196 case CODEC_TYPE_SUBTITLE:
2197 goto the_end;
2198 default:
2199 break;
2200 }
2201 }
2202 }
2203 the_end:
2204 stream_component_close(is, start_index);
2205 stream_component_open(is, stream_index);
2206 }
2207
2208
2209 static void toggle_full_screen(void)
2210 {
2211 is_full_screen = !is_full_screen;
2212 if (!fs_screen_width) {
2213 /* use default SDL method */
2214 // SDL_WM_ToggleFullScreen(screen);
2215 }
2216 video_open(cur_stream);
2217 }
2218
2219 static void toggle_pause(void)
2220 {
2221 if (cur_stream)
2222 stream_pause(cur_stream);
2223 step = 0;
2224 }
2225
2226 static void step_to_next_frame(void)
2227 {
2228 if (cur_stream) {
2229 if (cur_stream->paused)
2230 cur_stream->paused=0;
2231 cur_stream->video_current_pts = get_video_clock(cur_stream);
2232 }
2233 step = 1;
2234 }
2235
2236 static void do_exit(void)
2237 {
2238 if (cur_stream) {
2239 stream_close(cur_stream);
2240 cur_stream = NULL;
2241 }
2242 if (show_status)
2243 printf("\n");
2244 SDL_Quit();
2245 exit(0);
2246 }
2247
2248 static void toggle_audio_display(void)
2249 {
2250 if (cur_stream) {
2251 cur_stream->show_audio = !cur_stream->show_audio;
2252 }
2253 }
2254
2255 /* handle an event sent by the GUI */
2256 static void event_loop(void)
2257 {
2258 SDL_Event event;
2259 double incr, pos, frac;
2260
2261 for(;;) {
2262 SDL_WaitEvent(&event);
2263 switch(event.type) {
2264 case SDL_KEYDOWN:
2265 switch(event.key.keysym.sym) {
2266 case SDLK_ESCAPE:
2267 case SDLK_q:
2268 do_exit();
2269 break;
2270 case SDLK_f:
2271 toggle_full_screen();
2272 break;
2273 case SDLK_p:
2274 case SDLK_SPACE:
2275 toggle_pause();
2276 break;
2277 case SDLK_s: //S: Step to next frame
2278 step_to_next_frame();
2279 break;
2280 case SDLK_a:
2281 if (cur_stream)
2282 stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2283 break;
2284 case SDLK_v:
2285 if (cur_stream)
2286 stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2287 break;
2288 case SDLK_t:
2289 if (cur_stream)
2290 stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2291 break;
2292 case SDLK_w:
2293 toggle_audio_display();
2294 break;
2295 case SDLK_LEFT:
2296 incr = -10.0;
2297 goto do_seek;
2298 case SDLK_RIGHT:
2299 incr = 10.0;
2300 goto do_seek;
2301 case SDLK_UP:
2302 incr = 60.0;
2303 goto do_seek;
2304 case SDLK_DOWN:
2305 incr = -60.0;
2306 do_seek:
2307 if (cur_stream) {
2308 if (seek_by_bytes) {
2309 pos = url_ftell(&cur_stream->ic->pb);
2310 if (cur_stream->ic->bit_rate)
2311 incr *= cur_stream->ic->bit_rate / 60.0;
2312 else
2313 incr *= 180000.0;
2314 pos += incr;
2315 stream_seek(cur_stream, pos, incr);
2316 } else {
2317 pos = get_master_clock(cur_stream);
2318 pos += incr;
2319 stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
2320 }
2321 }
2322 break;
2323 default:
2324 break;
2325 }
2326 break;
2327 case SDL_MOUSEBUTTONDOWN:
2328 if (cur_stream) {
2329 int ns, hh, mm, ss;
2330 int tns, thh, tmm, tss;
2331 tns = cur_stream->ic->duration/1000000LL;
2332 thh = tns/3600;
2333 tmm = (tns%3600)/60;
2334 tss = (tns%60);
2335 frac = (double)event.button.x/(double)cur_stream->width;
2336 ns = frac*tns;
2337 hh = ns/3600;
2338 mm = (ns%3600)/60;
2339 ss = (ns%60);
2340 fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
2341 hh, mm, ss, thh, tmm, tss);
2342 stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
2343 }
2344 break;
2345 case SDL_VIDEORESIZE:
2346 if (cur_stream) {
2347 screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2348 SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2349 screen_width = cur_stream->width = event.resize.w;
2350 screen_height= cur_stream->height= event.resize.h;
2351 }
2352 break;
2353 case SDL_QUIT:
2354 case FF_QUIT_EVENT:
2355 do_exit();
2356 break;
2357 case FF_ALLOC_EVENT:
2358 video_open(event.user.data1);
2359 alloc_picture(event.user.data1);
2360 break;
2361 case FF_REFRESH_EVENT:
2362 video_refresh_timer(event.user.data1);
2363 break;
2364 default:
2365 break;
2366 }
2367 }
2368 }
2369
2370 static void opt_frame_size(const char *arg)
2371 {
2372 if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2373 fprintf(stderr, "Incorrect frame size\n");
2374 exit(1);
2375 }
2376 if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2377 fprintf(stderr, "Frame size must be a multiple of 2\n");
2378 exit(1);
2379 }
2380 }
2381
2382 static void opt_width(const char *arg)
2383 {
2384 screen_width = atoi(arg);
2385 if(screen_width<=0){
2386 fprintf(stderr, "invalid width\n");
2387 exit(1);
2388 }
2389 }
2390
2391 static void opt_height(const char *arg)
2392 {
2393 screen_height = atoi(arg);
2394 if(screen_height<=0){
2395 fprintf(stderr, "invalid height\n");
2396 exit(1);
2397 }
2398 }
2399
2400 static void opt_format(const char *arg)
2401 {
2402 file_iformat = av_find_input_format(arg);
2403 if (!file_iformat) {
2404 fprintf(stderr, "Unknown input format: %s\n", arg);
2405 exit(1);
2406 }
2407 }
2408
2409 static void opt_frame_pix_fmt(const char *arg)
2410 {
2411 frame_pix_fmt = avcodec_get_pix_fmt(arg);
2412 }
2413
2414 #ifdef CONFIG_RTSP_DEMUXER
2415 static void opt_rtp_tcp(void)
2416 {
2417 /* only tcp protocol */
2418 rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
2419 }
2420 #endif
2421
2422 static void opt_sync(const char *arg)
2423 {
2424 if (!strcmp(arg, "audio"))
2425 av_sync_type = AV_SYNC_AUDIO_MASTER;
2426 else if (!strcmp(arg, "video"))
2427 av_sync_type = AV_SYNC_VIDEO_MASTER;
2428 else if (!strcmp(arg, "ext"))
2429 av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2430 else
2431 show_help();
2432 }
2433
2434 static void opt_seek(const char *arg)
2435 {
2436 start_time = parse_date(arg, 1);
2437 }
2438
2439 static void opt_debug(const char *arg)
2440 {
2441 av_log_level = 99;
2442 debug = atoi(arg);
2443 }
2444
2445 static void opt_vismv(const char *arg)
2446 {
2447 debug_mv = atoi(arg);
2448 }
2449
2450 static void opt_thread_count(const char *arg)
2451 {
2452 thread_count= atoi(arg);
2453 #if !defined(HAVE_THREADS)
2454 fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2455 #endif
2456 }
2457
2458 const OptionDef options[] = {
2459 { "h", 0, {(void*)show_help}, "show help" },
2460 { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2461 { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
2462 { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2463 { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2464 { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2465 { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2466 { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "", "" },
2467 { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2468 { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2469 { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2470 { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2471 { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2472 { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2473 { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2474 { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2475 { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2476 { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2477 { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2478 { "drp", OPT_BOOL |OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts", ""},
2479 { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2480 { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2481 { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2482 { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2483 { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" },
2484 { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)", "threshold" },
2485 { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
2486 #ifdef CONFIG_RTSP_DEMUXER
2487 { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
2488 #endif
2489 { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2490 { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2491 { NULL, },
2492 };
2493
2494 void show_help(void)
2495 {
2496 printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard, et al.\n"
2497 "usage: ffplay [options] input_file\n"
2498 "Simple media player\n");
2499 printf("\n");
2500 show_help_options(options, "Main options:\n",
2501 OPT_EXPERT, 0);
2502 show_help_options(options, "\nAdvanced options:\n",
2503 OPT_EXPERT, OPT_EXPERT);
2504 printf("\nWhile playing:\n"
2505 "q, ESC quit\n"
2506 "f toggle full screen\n"
2507 "p, SPC pause\n"
2508 "a cycle audio channel\n"
2509 "v cycle video channel\n"
2510 "t cycle subtitle channel\n"
2511 "w show audio waves\n"
2512 "left/right seek backward/forward 10 seconds\n"
2513 "down/up seek backward/forward 1 minute\n"
2514 "mouse click seek to percentage in file corresponding to fraction of width\n"
2515 );
2516 exit(1);
2517 }
2518
2519 void parse_arg_file(const char *filename)
2520 {
2521 if (!strcmp(filename, "-"))
2522 filename = "pipe:";
2523 input_filename = filename;
2524 }
2525
2526 /* Called from the main */
2527 int main(int argc, char **argv)
2528 {
2529 int flags;
2530
2531 /* register all codecs, demux and protocols */
2532 av_register_all();
2533
2534 #ifdef CONFIG_OS2
2535 MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
2536
2537 // Make stdout and stderr unbuffered
2538 setbuf( stdout, NULL );
2539 setbuf( stderr, NULL );
2540 #endif
2541
2542 parse_options(argc, argv, options);
2543
2544 if (!input_filename)
2545 show_help();
2546
2547 if (display_disable) {
2548 video_disable = 1;
2549 }
2550 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2551 #if !defined(__MINGW32__) && !defined(CONFIG_DARWIN)
2552 flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 or darwin */
2553 #endif
2554 if (SDL_Init (flags)) {
2555 fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2556 exit(1);
2557 }
2558
2559 if (!display_disable) {
2560 #ifdef HAVE_SDL_VIDEO_SIZE
2561 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2562 fs_screen_width = vi->current_w;
2563 fs_screen_height = vi->current_h;
2564 #endif
2565 }
2566
2567 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2568 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2569 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2570 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2571
2572 av_init_packet(&flush_pkt);
2573 flush_pkt.data= "FLUSH";
2574
2575 cur_stream = stream_open(input_filename, file_iformat);
2576
2577 event_loop();
2578
2579 /* never returns */
2580
2581 return 0;
2582 }