Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 990c8438

History | View | Annotate | Download (73.7 KB)

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
#define HAVE_AV_CONFIG_H
22
#include "avformat.h"
23
#include "swscale.h"
24

    
25
#include "version.h"
26
#include "cmdutils.h"
27

    
28
#include <SDL.h>
29
#include <SDL_thread.h>
30

    
31
#ifdef __MINGW32__
32
#undef main /* We don't want SDL to override our main() */
33
#endif
34

    
35
#ifdef CONFIG_OS2
36
#define INCL_DOS
37
 #include <os2.h>
38
 #include <stdio.h>
39

    
40
 void MorphToPM()
41
 {
42
   PPIB pib;
43
   PTIB tib;
44

    
45
   DosGetInfoBlocks(&tib, &pib);
46

    
47
   // Change flag from VIO to PM:
48
   if (pib->pib_ultype==2) pib->pib_ultype = 3;
49
 }
50
#endif
51

    
52
//#define DEBUG_SYNC
53

    
54
#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
55
#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
56
#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
57

    
58
/* SDL audio buffer size, in samples. Should be small to have precise
59
   A/V sync as SDL does not have hardware buffer fullness info. */
60
#define SDL_AUDIO_BUFFER_SIZE 1024
61

    
62
/* no AV sync correction is done if below the AV sync threshold */
63
#define AV_SYNC_THRESHOLD 0.01
64
/* no AV correction is done if too big error */
65
#define AV_NOSYNC_THRESHOLD 10.0
66

    
67
/* maximum audio speed change to get correct sync */
68
#define SAMPLE_CORRECTION_PERCENT_MAX 10
69

    
70
/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
71
#define AUDIO_DIFF_AVG_NB   20
72

    
73
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
74
#define SAMPLE_ARRAY_SIZE (2*65536)
75

    
76
static int sws_flags = SWS_BICUBIC;
77

    
78
typedef struct PacketQueue {
79
    AVPacketList *first_pkt, *last_pkt;
80
    int nb_packets;
81
    int size;
82
    int abort_request;
83
    SDL_mutex *mutex;
84
    SDL_cond *cond;
85
} PacketQueue;
86

    
87
#define VIDEO_PICTURE_QUEUE_SIZE 1
88
#define SUBPICTURE_QUEUE_SIZE 4
89

    
90
typedef struct VideoPicture {
91
    double pts;                                  ///<presentation time stamp for this picture
92
    SDL_Overlay *bmp;
93
    int width, height; /* source height & width */
94
    int allocated;
95
} VideoPicture;
96

    
97
typedef struct SubPicture {
98
    double pts; /* presentation time stamp for this picture */
99
    AVSubtitle sub;
100
} SubPicture;
101

    
102
enum {
103
    AV_SYNC_AUDIO_MASTER, /* default choice */
104
    AV_SYNC_VIDEO_MASTER,
105
    AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
106
};
107

    
108
typedef struct VideoState {
109
    SDL_Thread *parse_tid;
110
    SDL_Thread *video_tid;
111
    AVInputFormat *iformat;
112
    int no_background;
113
    int abort_request;
114
    int paused;
115
    int last_paused;
116
    int seek_req;
117
    int seek_flags;
118
    int64_t seek_pos;
119
    AVFormatContext *ic;
120
    int dtg_active_format;
121

    
122
    int audio_stream;
123

    
124
    int av_sync_type;
125
    double external_clock; /* external clock base */
126
    int64_t external_clock_time;
127

    
128
    double audio_clock;
129
    double audio_diff_cum; /* used for AV difference average computation */
130
    double audio_diff_avg_coef;
131
    double audio_diff_threshold;
132
    int audio_diff_avg_count;
133
    AVStream *audio_st;
134
    PacketQueue audioq;
135
    int audio_hw_buf_size;
136
    /* samples output by the codec. we reserve more space for avsync
137
       compensation */
138
    DECLARE_ALIGNED(16,uint8_t,audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]);
139
    unsigned int audio_buf_size; /* in bytes */
140
    int audio_buf_index; /* in bytes */
141
    AVPacket audio_pkt;
142
    uint8_t *audio_pkt_data;
143
    int audio_pkt_size;
144

    
145
    int show_audio; /* if true, display audio samples */
146
    int16_t sample_array[SAMPLE_ARRAY_SIZE];
147
    int sample_array_index;
148
    int last_i_start;
149

    
150
    SDL_Thread *subtitle_tid;
151
    int subtitle_stream;
152
    int subtitle_stream_changed;
153
    AVStream *subtitle_st;
154
    PacketQueue subtitleq;
155
    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
156
    int subpq_size, subpq_rindex, subpq_windex;
157
    SDL_mutex *subpq_mutex;
158
    SDL_cond *subpq_cond;
159

    
160
    double frame_timer;
161
    double frame_last_pts;
162
    double frame_last_delay;
163
    double video_clock;                          ///<pts of last decoded frame / predicted pts of next decoded frame
164
    int video_stream;
165
    AVStream *video_st;
166
    PacketQueue videoq;
167
    double video_current_pts;                    ///<current displayed pts (different from video_clock if frame fifos are used)
168
    int64_t video_current_pts_time;              ///<time (av_gettime) at which we updated video_current_pts - used to have running video pts
169
    VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
170
    int pictq_size, pictq_rindex, pictq_windex;
171
    SDL_mutex *pictq_mutex;
172
    SDL_cond *pictq_cond;
173

    
174
    //    QETimer *video_timer;
175
    char filename[1024];
176
    int width, height, xleft, ytop;
177
} VideoState;
178

    
179
void show_help(void);
180
static int audio_write_get_buf_size(VideoState *is);
181

    
182
/* options specified by the user */
183
static AVInputFormat *file_iformat;
184
static const char *input_filename;
185
static int fs_screen_width;
186
static int fs_screen_height;
187
static int screen_width = 0;
188
static int screen_height = 0;
189
static int audio_disable;
190
static int video_disable;
191
static int seek_by_bytes;
192
static int display_disable;
193
static int show_status;
194
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
195
static int64_t start_time = AV_NOPTS_VALUE;
196
static int debug = 0;
197
static int debug_mv = 0;
198
static int step = 0;
199
static int thread_count = 1;
200
static int workaround_bugs = 1;
201
static int fast = 0;
202
static int genpts = 0;
203
static int lowres = 0;
204
static int idct = FF_IDCT_AUTO;
205
static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
206
static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
207
static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
208
static int error_resilience = FF_ER_CAREFUL;
209
static int error_concealment = 3;
210

    
211
/* current context */
212
static int is_full_screen;
213
static VideoState *cur_stream;
214
static int64_t audio_callback_time;
215

    
216
AVPacket flush_pkt;
217

    
218
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
219
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
220
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
221

    
222
SDL_Surface *screen;
223

    
224
/* packet queue handling */
225
static void packet_queue_init(PacketQueue *q)
226
{
227
    memset(q, 0, sizeof(PacketQueue));
228
    q->mutex = SDL_CreateMutex();
229
    q->cond = SDL_CreateCond();
230
}
231

    
232
static void packet_queue_flush(PacketQueue *q)
233
{
234
    AVPacketList *pkt, *pkt1;
235

    
236
    SDL_LockMutex(q->mutex);
237
    for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
238
        pkt1 = pkt->next;
239
        av_free_packet(&pkt->pkt);
240
        av_freep(&pkt);
241
    }
242
    q->last_pkt = NULL;
243
    q->first_pkt = NULL;
244
    q->nb_packets = 0;
245
    q->size = 0;
246
    SDL_UnlockMutex(q->mutex);
247
}
248

    
249
static void packet_queue_end(PacketQueue *q)
250
{
251
    packet_queue_flush(q);
252
    SDL_DestroyMutex(q->mutex);
253
    SDL_DestroyCond(q->cond);
254
}
255

    
256
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
257
{
258
    AVPacketList *pkt1;
259

    
260
    /* duplicate the packet */
261
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
262
        return -1;
263

    
264
    pkt1 = av_malloc(sizeof(AVPacketList));
265
    if (!pkt1)
266
        return -1;
267
    pkt1->pkt = *pkt;
268
    pkt1->next = NULL;
269

    
270

    
271
    SDL_LockMutex(q->mutex);
272

    
273
    if (!q->last_pkt)
274

    
275
        q->first_pkt = pkt1;
276
    else
277
        q->last_pkt->next = pkt1;
278
    q->last_pkt = pkt1;
279
    q->nb_packets++;
280
    q->size += pkt1->pkt.size;
281
    /* XXX: should duplicate packet data in DV case */
282
    SDL_CondSignal(q->cond);
283

    
284
    SDL_UnlockMutex(q->mutex);
285
    return 0;
286
}
287

    
288
static void packet_queue_abort(PacketQueue *q)
289
{
290
    SDL_LockMutex(q->mutex);
291

    
292
    q->abort_request = 1;
293

    
294
    SDL_CondSignal(q->cond);
295

    
296
    SDL_UnlockMutex(q->mutex);
297
}
298

    
299
/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
300
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
301
{
302
    AVPacketList *pkt1;
303
    int ret;
304

    
305
    SDL_LockMutex(q->mutex);
306

    
307
    for(;;) {
308
        if (q->abort_request) {
309
            ret = -1;
310
            break;
311
        }
312

    
313
        pkt1 = q->first_pkt;
314
        if (pkt1) {
315
            q->first_pkt = pkt1->next;
316
            if (!q->first_pkt)
317
                q->last_pkt = NULL;
318
            q->nb_packets--;
319
            q->size -= pkt1->pkt.size;
320
            *pkt = pkt1->pkt;
321
            av_free(pkt1);
322
            ret = 1;
323
            break;
324
        } else if (!block) {
325
            ret = 0;
326
            break;
327
        } else {
328
            SDL_CondWait(q->cond, q->mutex);
329
        }
330
    }
331
    SDL_UnlockMutex(q->mutex);
332
    return ret;
333
}
334

    
335
static inline void fill_rectangle(SDL_Surface *screen,
336
                                  int x, int y, int w, int h, int color)
337
{
338
    SDL_Rect rect;
339
    rect.x = x;
340
    rect.y = y;
341
    rect.w = w;
342
    rect.h = h;
343
    SDL_FillRect(screen, &rect, color);
344
}
345

    
346
#if 0
347
/* draw only the border of a rectangle */
348
void fill_border(VideoState *s, int x, int y, int w, int h, int color)
349
{
350
    int w1, w2, h1, h2;
351

352
    /* fill the background */
353
    w1 = x;
354
    if (w1 < 0)
355
        w1 = 0;
356
    w2 = s->width - (x + w);
357
    if (w2 < 0)
358
        w2 = 0;
359
    h1 = y;
360
    if (h1 < 0)
361
        h1 = 0;
362
    h2 = s->height - (y + h);
363
    if (h2 < 0)
364
        h2 = 0;
365
    fill_rectangle(screen,
366
                   s->xleft, s->ytop,
367
                   w1, s->height,
368
                   color);
369
    fill_rectangle(screen,
370
                   s->xleft + s->width - w2, s->ytop,
371
                   w2, s->height,
372
                   color);
373
    fill_rectangle(screen,
374
                   s->xleft + w1, s->ytop,
375
                   s->width - w1 - w2, h1,
376
                   color);
377
    fill_rectangle(screen,
378
                   s->xleft + w1, s->ytop + s->height - h2,
379
                   s->width - w1 - w2, h2,
380
                   color);
381
}
382
#endif
383

    
384

    
385

    
386
#define SCALEBITS 10
387
#define ONE_HALF  (1 << (SCALEBITS - 1))
388
#define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
389

    
390
#define RGB_TO_Y_CCIR(r, g, b) \
391
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
392
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
393

    
394
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
395
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
396
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
397

    
398
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
399
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
400
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
401

    
402
#define ALPHA_BLEND(a, oldp, newp, s)\
403
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
404

    
405
#define RGBA_IN(r, g, b, a, s)\
406
{\
407
    unsigned int v = ((const uint32_t *)(s))[0];\
408
    a = (v >> 24) & 0xff;\
409
    r = (v >> 16) & 0xff;\
410
    g = (v >> 8) & 0xff;\
411
    b = v & 0xff;\
412
}
413

    
414
#define YUVA_IN(y, u, v, a, s, pal)\
415
{\
416
    unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)s];\
417
    a = (val >> 24) & 0xff;\
418
    y = (val >> 16) & 0xff;\
419
    u = (val >> 8) & 0xff;\
420
    v = val & 0xff;\
421
}
422

    
423
#define YUVA_OUT(d, y, u, v, a)\
424
{\
425
    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
426
}
427

    
428

    
429
#define BPP 1
430

    
431
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
432
{
433
    int wrap, wrap3, width2, skip2;
434
    int y, u, v, a, u1, v1, a1, w, h;
435
    uint8_t *lum, *cb, *cr;
436
    const uint8_t *p;
437
    const uint32_t *pal;
438

    
439
    lum = dst->data[0] + rect->y * dst->linesize[0];
440
    cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1];
441
    cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2];
442

    
443
    width2 = (rect->w + 1) >> 1;
444
    skip2 = rect->x >> 1;
445
    wrap = dst->linesize[0];
446
    wrap3 = rect->linesize;
447
    p = rect->bitmap;
448
    pal = rect->rgba_palette;  /* Now in YCrCb! */
449

    
450
    if (rect->y & 1) {
451
        lum += rect->x;
452
        cb += skip2;
453
        cr += skip2;
454

    
455
        if (rect->x & 1) {
456
            YUVA_IN(y, u, v, a, p, pal);
457
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
458
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
459
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
460
            cb++;
461
            cr++;
462
            lum++;
463
            p += BPP;
464
        }
465
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
466
            YUVA_IN(y, u, v, a, p, pal);
467
            u1 = u;
468
            v1 = v;
469
            a1 = a;
470
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
471

    
472
            YUVA_IN(y, u, v, a, p + BPP, pal);
473
            u1 += u;
474
            v1 += v;
475
            a1 += a;
476
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
477
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
478
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
479
            cb++;
480
            cr++;
481
            p += 2 * BPP;
482
            lum += 2;
483
        }
484
        if (w) {
485
            YUVA_IN(y, u, v, a, p, pal);
486
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
487
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
488
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
489
        }
490
        p += wrap3 + (wrap3 - rect->w * BPP);
491
        lum += wrap + (wrap - rect->w - rect->x);
492
        cb += dst->linesize[1] - width2 - skip2;
493
        cr += dst->linesize[2] - width2 - skip2;
494
    }
495
    for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) {
496
        lum += rect->x;
497
        cb += skip2;
498
        cr += skip2;
499

    
500
        if (rect->x & 1) {
501
            YUVA_IN(y, u, v, a, p, pal);
502
            u1 = u;
503
            v1 = v;
504
            a1 = a;
505
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
506
            p += wrap3;
507
            lum += wrap;
508
            YUVA_IN(y, u, v, a, p, pal);
509
            u1 += u;
510
            v1 += v;
511
            a1 += a;
512
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
513
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
514
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
515
            cb++;
516
            cr++;
517
            p += -wrap3 + BPP;
518
            lum += -wrap + 1;
519
        }
520
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
521
            YUVA_IN(y, u, v, a, p, pal);
522
            u1 = u;
523
            v1 = v;
524
            a1 = a;
525
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
526

    
527
            YUVA_IN(y, u, v, a, p, pal);
528
            u1 += u;
529
            v1 += v;
530
            a1 += a;
531
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
532
            p += wrap3;
533
            lum += wrap;
534

    
535
            YUVA_IN(y, u, v, a, p, pal);
536
            u1 += u;
537
            v1 += v;
538
            a1 += a;
539
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
540

    
541
            YUVA_IN(y, u, v, a, p, pal);
542
            u1 += u;
543
            v1 += v;
544
            a1 += a;
545
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
546

    
547
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
548
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
549

    
550
            cb++;
551
            cr++;
552
            p += -wrap3 + 2 * BPP;
553
            lum += -wrap + 2;
554
        }
555
        if (w) {
556
            YUVA_IN(y, u, v, a, p, pal);
557
            u1 = u;
558
            v1 = v;
559
            a1 = a;
560
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
561
            p += wrap3;
562
            lum += wrap;
563
            YUVA_IN(y, u, v, a, p, pal);
564
            u1 += u;
565
            v1 += v;
566
            a1 += a;
567
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
568
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
569
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
570
            cb++;
571
            cr++;
572
            p += -wrap3 + BPP;
573
            lum += -wrap + 1;
574
        }
575
        p += wrap3 + (wrap3 - rect->w * BPP);
576
        lum += wrap + (wrap - rect->w - rect->x);
577
        cb += dst->linesize[1] - width2 - skip2;
578
        cr += dst->linesize[2] - width2 - skip2;
579
    }
580
    /* handle odd height */
581
    if (h) {
582
        lum += rect->x;
583
        cb += skip2;
584
        cr += skip2;
585

    
586
        if (rect->x & 1) {
587
            YUVA_IN(y, u, v, a, p, pal);
588
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
589
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
590
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
591
            cb++;
592
            cr++;
593
            lum++;
594
            p += BPP;
595
        }
596
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
597
            YUVA_IN(y, u, v, a, p, pal);
598
            u1 = u;
599
            v1 = v;
600
            a1 = a;
601
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
602

    
603
            YUVA_IN(y, u, v, a, p + BPP, pal);
604
            u1 += u;
605
            v1 += v;
606
            a1 += a;
607
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
608
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
609
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
610
            cb++;
611
            cr++;
612
            p += 2 * BPP;
613
            lum += 2;
614
        }
615
        if (w) {
616
            YUVA_IN(y, u, v, a, p, pal);
617
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
618
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
619
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
620
        }
621
    }
622
}
623

    
624
static void free_subpicture(SubPicture *sp)
625
{
626
    int i;
627

    
628
    for (i = 0; i < sp->sub.num_rects; i++)
629
    {
630
        av_free(sp->sub.rects[i].bitmap);
631
        av_free(sp->sub.rects[i].rgba_palette);
632
    }
633

    
634
    av_free(sp->sub.rects);
635

    
636
    memset(&sp->sub, 0, sizeof(AVSubtitle));
637
}
638

    
639
static void video_image_display(VideoState *is)
640
{
641
    VideoPicture *vp;
642
    SubPicture *sp;
643
    AVPicture pict;
644
    float aspect_ratio;
645
    int width, height, x, y;
646
    SDL_Rect rect;
647
    int i;
648

    
649
    vp = &is->pictq[is->pictq_rindex];
650
    if (vp->bmp) {
651
        /* XXX: use variable in the frame */
652
        if (is->video_st->codec->sample_aspect_ratio.num == 0)
653
            aspect_ratio = 0;
654
        else
655
            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio)
656
                * is->video_st->codec->width / is->video_st->codec->height;;
657
        if (aspect_ratio <= 0.0)
658
            aspect_ratio = (float)is->video_st->codec->width /
659
                (float)is->video_st->codec->height;
660
        /* if an active format is indicated, then it overrides the
661
           mpeg format */
662
#if 0
663
        if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
664
            is->dtg_active_format = is->video_st->codec->dtg_active_format;
665
            printf("dtg_active_format=%d\n", is->dtg_active_format);
666
        }
667
#endif
668
#if 0
669
        switch(is->video_st->codec->dtg_active_format) {
670
        case FF_DTG_AFD_SAME:
671
        default:
672
            /* nothing to do */
673
            break;
674
        case FF_DTG_AFD_4_3:
675
            aspect_ratio = 4.0 / 3.0;
676
            break;
677
        case FF_DTG_AFD_16_9:
678
            aspect_ratio = 16.0 / 9.0;
679
            break;
680
        case FF_DTG_AFD_14_9:
681
            aspect_ratio = 14.0 / 9.0;
682
            break;
683
        case FF_DTG_AFD_4_3_SP_14_9:
684
            aspect_ratio = 14.0 / 9.0;
685
            break;
686
        case FF_DTG_AFD_16_9_SP_14_9:
687
            aspect_ratio = 14.0 / 9.0;
688
            break;
689
        case FF_DTG_AFD_SP_4_3:
690
            aspect_ratio = 4.0 / 3.0;
691
            break;
692
        }
693
#endif
694

    
695
        if (is->subtitle_st)
696
        {
697
            if (is->subpq_size > 0)
698
            {
699
                sp = &is->subpq[is->subpq_rindex];
700

    
701
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
702
                {
703
                    SDL_LockYUVOverlay (vp->bmp);
704

    
705
                    pict.data[0] = vp->bmp->pixels[0];
706
                    pict.data[1] = vp->bmp->pixels[2];
707
                    pict.data[2] = vp->bmp->pixels[1];
708

    
709
                    pict.linesize[0] = vp->bmp->pitches[0];
710
                    pict.linesize[1] = vp->bmp->pitches[2];
711
                    pict.linesize[2] = vp->bmp->pitches[1];
712

    
713
                    for (i = 0; i < sp->sub.num_rects; i++)
714
                        blend_subrect(&pict, &sp->sub.rects[i]);
715

    
716
                    SDL_UnlockYUVOverlay (vp->bmp);
717
                }
718
            }
719
        }
720

    
721

    
722
        /* XXX: we suppose the screen has a 1.0 pixel ratio */
723
        height = is->height;
724
        width = ((int)rint(height * aspect_ratio)) & -3;
725
        if (width > is->width) {
726
            width = is->width;
727
            height = ((int)rint(width / aspect_ratio)) & -3;
728
        }
729
        x = (is->width - width) / 2;
730
        y = (is->height - height) / 2;
731
        if (!is->no_background) {
732
            /* fill the background */
733
            //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
734
        } else {
735
            is->no_background = 0;
736
        }
737
        rect.x = is->xleft + x;
738
        rect.y = is->xleft + y;
739
        rect.w = width;
740
        rect.h = height;
741
        SDL_DisplayYUVOverlay(vp->bmp, &rect);
742
    } else {
743
#if 0
744
        fill_rectangle(screen,
745
                       is->xleft, is->ytop, is->width, is->height,
746
                       QERGB(0x00, 0x00, 0x00));
747
#endif
748
    }
749
}
750

    
751
static inline int compute_mod(int a, int b)
752
{
753
    a = a % b;
754
    if (a >= 0)
755
        return a;
756
    else
757
        return a + b;
758
}
759

    
760
static void video_audio_display(VideoState *s)
761
{
762
    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
763
    int ch, channels, h, h2, bgcolor, fgcolor;
764
    int16_t time_diff;
765

    
766
    /* compute display index : center on currently output samples */
767
    channels = s->audio_st->codec->channels;
768
    nb_display_channels = channels;
769
    if (!s->paused) {
770
        n = 2 * channels;
771
        delay = audio_write_get_buf_size(s);
772
        delay /= n;
773

    
774
        /* to be more precise, we take into account the time spent since
775
           the last buffer computation */
776
        if (audio_callback_time) {
777
            time_diff = av_gettime() - audio_callback_time;
778
            delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
779
        }
780

    
781
        delay -= s->width / 2;
782
        if (delay < s->width)
783
            delay = s->width;
784
        i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
785
        s->last_i_start = i_start;
786
    } else {
787
        i_start = s->last_i_start;
788
    }
789

    
790
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
791
    fill_rectangle(screen,
792
                   s->xleft, s->ytop, s->width, s->height,
793
                   bgcolor);
794

    
795
    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
796

    
797
    /* total height for one channel */
798
    h = s->height / nb_display_channels;
799
    /* graph height / 2 */
800
    h2 = (h * 9) / 20;
801
    for(ch = 0;ch < nb_display_channels; ch++) {
802
        i = i_start + ch;
803
        y1 = s->ytop + ch * h + (h / 2); /* position of center line */
804
        for(x = 0; x < s->width; x++) {
805
            y = (s->sample_array[i] * h2) >> 15;
806
            if (y < 0) {
807
                y = -y;
808
                ys = y1 - y;
809
            } else {
810
                ys = y1;
811
            }
812
            fill_rectangle(screen,
813
                           s->xleft + x, ys, 1, y,
814
                           fgcolor);
815
            i += channels;
816
            if (i >= SAMPLE_ARRAY_SIZE)
817
                i -= SAMPLE_ARRAY_SIZE;
818
        }
819
    }
820

    
821
    fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
822

    
823
    for(ch = 1;ch < nb_display_channels; ch++) {
824
        y = s->ytop + ch * h;
825
        fill_rectangle(screen,
826
                       s->xleft, y, s->width, 1,
827
                       fgcolor);
828
    }
829
    SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
830
}
831

    
832
static int video_open(VideoState *is){
833
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
834
    int w,h;
835

    
836
    if (is_full_screen && fs_screen_width) {
837
        w = fs_screen_width;
838
        h = fs_screen_height;
839
        flags |= SDL_FULLSCREEN;
840
    } else {
841
        if(screen_width){
842
            w = screen_width;
843
            h = screen_height;
844
        }else if (is->video_st && is->video_st->codec->width){
845
            w = is->video_st->codec->width;
846
            h = is->video_st->codec->height;
847
        } else {
848
            w = 640;
849
            h = 480;
850
        }
851
        flags |= SDL_RESIZABLE;
852
    }
853
#ifndef CONFIG_DARWIN
854
    screen = SDL_SetVideoMode(w, h, 0, flags);
855
#else
856
    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
857
    screen = SDL_SetVideoMode(w, h, 24, flags);
858
#endif
859
    if (!screen) {
860
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
861
        return -1;
862
    }
863
    SDL_WM_SetCaption("FFplay", "FFplay");
864

    
865
    is->width = screen->w;
866
    is->height = screen->h;
867

    
868
    return 0;
869
}
870

    
871
/* display the current picture, if any */
872
static void video_display(VideoState *is)
873
{
874
    if(!screen)
875
        video_open(cur_stream);
876
    if (is->audio_st && is->show_audio)
877
        video_audio_display(is);
878
    else if (is->video_st)
879
        video_image_display(is);
880
}
881

    
882
static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
883
{
884
    SDL_Event event;
885
    event.type = FF_REFRESH_EVENT;
886
    event.user.data1 = opaque;
887
    SDL_PushEvent(&event);
888
    return 0; /* 0 means stop timer */
889
}
890

    
891
/* schedule a video refresh in 'delay' ms */
892
static void schedule_refresh(VideoState *is, int delay)
893
{
894
    SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
895
}
896

    
897
/* get the current audio clock value */
898
static double get_audio_clock(VideoState *is)
899
{
900
    double pts;
901
    int hw_buf_size, bytes_per_sec;
902
    pts = is->audio_clock;
903
    hw_buf_size = audio_write_get_buf_size(is);
904
    bytes_per_sec = 0;
905
    if (is->audio_st) {
906
        bytes_per_sec = is->audio_st->codec->sample_rate *
907
            2 * is->audio_st->codec->channels;
908
    }
909
    if (bytes_per_sec)
910
        pts -= (double)hw_buf_size / bytes_per_sec;
911
    return pts;
912
}
913

    
914
/* get the current video clock value */
915
static double get_video_clock(VideoState *is)
916
{
917
    double delta;
918
    if (is->paused) {
919
        delta = 0;
920
    } else {
921
        delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
922
    }
923
    return is->video_current_pts + delta;
924
}
925

    
926
/* get the current external clock value */
927
static double get_external_clock(VideoState *is)
928
{
929
    int64_t ti;
930
    ti = av_gettime();
931
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
932
}
933

    
934
/* get the current master clock value */
935
static double get_master_clock(VideoState *is)
936
{
937
    double val;
938

    
939
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
940
        if (is->video_st)
941
            val = get_video_clock(is);
942
        else
943
            val = get_audio_clock(is);
944
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
945
        if (is->audio_st)
946
            val = get_audio_clock(is);
947
        else
948
            val = get_video_clock(is);
949
    } else {
950
        val = get_external_clock(is);
951
    }
952
    return val;
953
}
954

    
955
/* seek in the stream */
956
static void stream_seek(VideoState *is, int64_t pos, int rel)
957
{
958
    if (!is->seek_req) {
959
        is->seek_pos = pos;
960
        is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
961
        if (seek_by_bytes)
962
            is->seek_flags |= AVSEEK_FLAG_BYTE;
963
        is->seek_req = 1;
964
    }
965
}
966

    
967
/* pause or resume the video */
968
static void stream_pause(VideoState *is)
969
{
970
    is->paused = !is->paused;
971
    if (is->paused) {
972
        is->video_current_pts = get_video_clock(is);
973
    }
974
}
975

    
976
/* called to display each frame */
977
static void video_refresh_timer(void *opaque)
978
{
979
    VideoState *is = opaque;
980
    VideoPicture *vp;
981
    double actual_delay, delay, sync_threshold, ref_clock, diff;
982

    
983
    SubPicture *sp, *sp2;
984

    
985
    if (is->video_st) {
986
        if (is->pictq_size == 0) {
987
            /* if no picture, need to wait */
988
            schedule_refresh(is, 1);
989
        } else {
990
            /* dequeue the picture */
991
            vp = &is->pictq[is->pictq_rindex];
992

    
993
            /* update current video pts */
994
            is->video_current_pts = vp->pts;
995
            is->video_current_pts_time = av_gettime();
996

    
997
            /* compute nominal delay */
998
            delay = vp->pts - is->frame_last_pts;
999
            if (delay <= 0 || delay >= 1.0) {
1000
                /* if incorrect delay, use previous one */
1001
                delay = is->frame_last_delay;
1002
            }
1003
            is->frame_last_delay = delay;
1004
            is->frame_last_pts = vp->pts;
1005

    
1006
            /* update delay to follow master synchronisation source */
1007
            if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1008
                 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1009
                /* if video is slave, we try to correct big delays by
1010
                   duplicating or deleting a frame */
1011
                ref_clock = get_master_clock(is);
1012
                diff = vp->pts - ref_clock;
1013

    
1014
                /* skip or repeat frame. We take into account the
1015
                   delay to compute the threshold. I still don't know
1016
                   if it is the best guess */
1017
                sync_threshold = AV_SYNC_THRESHOLD;
1018
                if (delay > sync_threshold)
1019
                    sync_threshold = delay;
1020
                if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1021
                    if (diff <= -sync_threshold)
1022
                        delay = 0;
1023
                    else if (diff >= sync_threshold)
1024
                        delay = 2 * delay;
1025
                }
1026
            }
1027

    
1028
            is->frame_timer += delay;
1029
            /* compute the REAL delay (we need to do that to avoid
1030
               long term errors */
1031
            actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1032
            if (actual_delay < 0.010) {
1033
                /* XXX: should skip picture */
1034
                actual_delay = 0.010;
1035
            }
1036
            /* launch timer for next picture */
1037
            schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
1038

    
1039
#if defined(DEBUG_SYNC)
1040
            printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1041
                   delay, actual_delay, vp->pts, -diff);
1042
#endif
1043

    
1044
            if(is->subtitle_st) {
1045
                if (is->subtitle_stream_changed) {
1046
                    SDL_LockMutex(is->subpq_mutex);
1047

    
1048
                    while (is->subpq_size) {
1049
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1050

    
1051
                        /* update queue size and signal for next picture */
1052
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1053
                            is->subpq_rindex = 0;
1054

    
1055
                        is->subpq_size--;
1056
                    }
1057
                    is->subtitle_stream_changed = 0;
1058

    
1059
                    SDL_CondSignal(is->subpq_cond);
1060
                    SDL_UnlockMutex(is->subpq_mutex);
1061
                } else {
1062
                    if (is->subpq_size > 0) {
1063
                        sp = &is->subpq[is->subpq_rindex];
1064

    
1065
                        if (is->subpq_size > 1)
1066
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1067
                        else
1068
                            sp2 = NULL;
1069

    
1070
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1071
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1072
                        {
1073
                            free_subpicture(sp);
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
                            SDL_LockMutex(is->subpq_mutex);
1080
                            is->subpq_size--;
1081
                            SDL_CondSignal(is->subpq_cond);
1082
                            SDL_UnlockMutex(is->subpq_mutex);
1083
                        }
1084
                    }
1085
                }
1086
            }
1087

    
1088
            /* display picture */
1089
            video_display(is);
1090

    
1091
            /* update queue size and signal for next picture */
1092
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1093
                is->pictq_rindex = 0;
1094

    
1095
            SDL_LockMutex(is->pictq_mutex);
1096
            is->pictq_size--;
1097
            SDL_CondSignal(is->pictq_cond);
1098
            SDL_UnlockMutex(is->pictq_mutex);
1099
        }
1100
    } else if (is->audio_st) {
1101
        /* draw the next audio frame */
1102

    
1103
        schedule_refresh(is, 40);
1104

    
1105
        /* if only audio stream, then display the audio bars (better
1106
           than nothing, just to test the implementation */
1107

    
1108
        /* display picture */
1109
        video_display(is);
1110
    } else {
1111
        schedule_refresh(is, 100);
1112
    }
1113
    if (show_status) {
1114
        static int64_t last_time;
1115
        int64_t cur_time;
1116
        int aqsize, vqsize, sqsize;
1117
        double av_diff;
1118

    
1119
        cur_time = av_gettime();
1120
        if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1121
            aqsize = 0;
1122
            vqsize = 0;
1123
            sqsize = 0;
1124
            if (is->audio_st)
1125
                aqsize = is->audioq.size;
1126
            if (is->video_st)
1127
                vqsize = is->videoq.size;
1128
            if (is->subtitle_st)
1129
                sqsize = is->subtitleq.size;
1130
            av_diff = 0;
1131
            if (is->audio_st && is->video_st)
1132
                av_diff = get_audio_clock(is) - get_video_clock(is);
1133
            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1134
                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1135
            fflush(stdout);
1136
            last_time = cur_time;
1137
        }
1138
    }
1139
}
1140

    
1141
/* allocate a picture (needs to do that in main thread to avoid
1142
   potential locking problems */
1143
static void alloc_picture(void *opaque)
1144
{
1145
    VideoState *is = opaque;
1146
    VideoPicture *vp;
1147

    
1148
    vp = &is->pictq[is->pictq_windex];
1149

    
1150
    if (vp->bmp)
1151
        SDL_FreeYUVOverlay(vp->bmp);
1152

    
1153
#if 0
1154
    /* XXX: use generic function */
1155
    /* XXX: disable overlay if no hardware acceleration or if RGB format */
1156
    switch(is->video_st->codec->pix_fmt) {
1157
    case PIX_FMT_YUV420P:
1158
    case PIX_FMT_YUV422P:
1159
    case PIX_FMT_YUV444P:
1160
    case PIX_FMT_YUV422:
1161
    case PIX_FMT_YUV410P:
1162
    case PIX_FMT_YUV411P:
1163
        is_yuv = 1;
1164
        break;
1165
    default:
1166
        is_yuv = 0;
1167
        break;
1168
    }
1169
#endif
1170
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1171
                                   is->video_st->codec->height,
1172
                                   SDL_YV12_OVERLAY,
1173
                                   screen);
1174
    vp->width = is->video_st->codec->width;
1175
    vp->height = is->video_st->codec->height;
1176

    
1177
    SDL_LockMutex(is->pictq_mutex);
1178
    vp->allocated = 1;
1179
    SDL_CondSignal(is->pictq_cond);
1180
    SDL_UnlockMutex(is->pictq_mutex);
1181
}
1182

    
1183
/**
1184
 *
1185
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1186
 */
1187
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1188
{
1189
    VideoPicture *vp;
1190
    int dst_pix_fmt;
1191
    AVPicture pict;
1192
    static struct SwsContext *img_convert_ctx;
1193

    
1194
    /* wait until we have space to put a new picture */
1195
    SDL_LockMutex(is->pictq_mutex);
1196
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1197
           !is->videoq.abort_request) {
1198
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1199
    }
1200
    SDL_UnlockMutex(is->pictq_mutex);
1201

    
1202
    if (is->videoq.abort_request)
1203
        return -1;
1204

    
1205
    vp = &is->pictq[is->pictq_windex];
1206

    
1207
    /* alloc or resize hardware picture buffer */
1208
    if (!vp->bmp ||
1209
        vp->width != is->video_st->codec->width ||
1210
        vp->height != is->video_st->codec->height) {
1211
        SDL_Event event;
1212

    
1213
        vp->allocated = 0;
1214

    
1215
        /* the allocation must be done in the main thread to avoid
1216
           locking problems */
1217
        event.type = FF_ALLOC_EVENT;
1218
        event.user.data1 = is;
1219
        SDL_PushEvent(&event);
1220

    
1221
        /* wait until the picture is allocated */
1222
        SDL_LockMutex(is->pictq_mutex);
1223
        while (!vp->allocated && !is->videoq.abort_request) {
1224
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1225
        }
1226
        SDL_UnlockMutex(is->pictq_mutex);
1227

    
1228
        if (is->videoq.abort_request)
1229
            return -1;
1230
    }
1231

    
1232
    /* if the frame is not skipped, then display it */
1233
    if (vp->bmp) {
1234
        /* get a pointer on the bitmap */
1235
        SDL_LockYUVOverlay (vp->bmp);
1236

    
1237
        dst_pix_fmt = PIX_FMT_YUV420P;
1238
        pict.data[0] = vp->bmp->pixels[0];
1239
        pict.data[1] = vp->bmp->pixels[2];
1240
        pict.data[2] = vp->bmp->pixels[1];
1241

    
1242
        pict.linesize[0] = vp->bmp->pitches[0];
1243
        pict.linesize[1] = vp->bmp->pitches[2];
1244
        pict.linesize[2] = vp->bmp->pitches[1];
1245
        if (img_convert_ctx == NULL) {
1246
            img_convert_ctx = sws_getContext(is->video_st->codec->width,
1247
                    is->video_st->codec->height, is->video_st->codec->pix_fmt,
1248
                    is->video_st->codec->width, is->video_st->codec->height,
1249
                    dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1250
            if (img_convert_ctx == NULL) {
1251
                fprintf(stderr, "Cannot initialize the conversion context\n");
1252
                exit(1);
1253
            }
1254
        }
1255
        sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
1256
                  0, is->video_st->codec->height, pict.data, pict.linesize);
1257
        /* update the bitmap content */
1258
        SDL_UnlockYUVOverlay(vp->bmp);
1259

    
1260
        vp->pts = pts;
1261

    
1262
        /* now we can update the picture count */
1263
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1264
            is->pictq_windex = 0;
1265
        SDL_LockMutex(is->pictq_mutex);
1266
        is->pictq_size++;
1267
        SDL_UnlockMutex(is->pictq_mutex);
1268
    }
1269
    return 0;
1270
}
1271

    
1272
/**
1273
 * compute the exact PTS for the picture if it is omitted in the stream
1274
 * @param pts1 the dts of the pkt / pts of the frame
1275
 */
1276
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1277
{
1278
    double frame_delay, pts;
1279

    
1280
    pts = pts1;
1281

    
1282
    if (pts != 0) {
1283
        /* update video clock with pts, if present */
1284
        is->video_clock = pts;
1285
    } else {
1286
        pts = is->video_clock;
1287
    }
1288
    /* update video clock for next frame */
1289
    frame_delay = av_q2d(is->video_st->codec->time_base);
1290
    /* for MPEG2, the frame can be repeated, so we update the
1291
       clock accordingly */
1292
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1293
    is->video_clock += frame_delay;
1294

    
1295
#if defined(DEBUG_SYNC) && 0
1296
    {
1297
        int ftype;
1298
        if (src_frame->pict_type == FF_B_TYPE)
1299
            ftype = 'B';
1300
        else if (src_frame->pict_type == FF_I_TYPE)
1301
            ftype = 'I';
1302
        else
1303
            ftype = 'P';
1304
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1305
               ftype, pts, pts1);
1306
    }
1307
#endif
1308
    return queue_picture(is, src_frame, pts);
1309
}
1310

    
1311
static int video_thread(void *arg)
1312
{
1313
    VideoState *is = arg;
1314
    AVPacket pkt1, *pkt = &pkt1;
1315
    int len1, got_picture;
1316
    AVFrame *frame= avcodec_alloc_frame();
1317
    double pts;
1318

    
1319
    for(;;) {
1320
        while (is->paused && !is->videoq.abort_request) {
1321
            SDL_Delay(10);
1322
        }
1323
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1324
            break;
1325

    
1326
        if(pkt->data == flush_pkt.data){
1327
            avcodec_flush_buffers(is->video_st->codec);
1328
            continue;
1329
        }
1330

    
1331
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1332
           this packet, if any */
1333
        pts = 0;
1334
        if (pkt->dts != AV_NOPTS_VALUE)
1335
            pts = av_q2d(is->video_st->time_base)*pkt->dts;
1336

    
1337
            len1 = avcodec_decode_video(is->video_st->codec,
1338
                                        frame, &got_picture,
1339
                                        pkt->data, pkt->size);
1340
//            if (len1 < 0)
1341
//                break;
1342
            if (got_picture) {
1343
                if (output_picture2(is, frame, pts) < 0)
1344
                    goto the_end;
1345
            }
1346
        av_free_packet(pkt);
1347
        if (step)
1348
            if (cur_stream)
1349
                stream_pause(cur_stream);
1350
    }
1351
 the_end:
1352
    av_free(frame);
1353
    return 0;
1354
}
1355

    
1356
static int subtitle_thread(void *arg)
1357
{
1358
    VideoState *is = arg;
1359
    SubPicture *sp;
1360
    AVPacket pkt1, *pkt = &pkt1;
1361
    int len1, got_subtitle;
1362
    double pts;
1363
    int i, j;
1364
    int r, g, b, y, u, v, a;
1365

    
1366
    for(;;) {
1367
        while (is->paused && !is->subtitleq.abort_request) {
1368
            SDL_Delay(10);
1369
        }
1370
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1371
            break;
1372

    
1373
        if(pkt->data == flush_pkt.data){
1374
            avcodec_flush_buffers(is->subtitle_st->codec);
1375
            continue;
1376
        }
1377
        SDL_LockMutex(is->subpq_mutex);
1378
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1379
               !is->subtitleq.abort_request) {
1380
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1381
        }
1382
        SDL_UnlockMutex(is->subpq_mutex);
1383

    
1384
        if (is->subtitleq.abort_request)
1385
            goto the_end;
1386

    
1387
        sp = &is->subpq[is->subpq_windex];
1388

    
1389
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1390
           this packet, if any */
1391
        pts = 0;
1392
        if (pkt->pts != AV_NOPTS_VALUE)
1393
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1394

    
1395
        len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
1396
                                    &sp->sub, &got_subtitle,
1397
                                    pkt->data, pkt->size);
1398
//            if (len1 < 0)
1399
//                break;
1400
        if (got_subtitle && sp->sub.format == 0) {
1401
            sp->pts = pts;
1402

    
1403
            for (i = 0; i < sp->sub.num_rects; i++)
1404
            {
1405
                for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
1406
                {
1407
                    RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
1408
                    y = RGB_TO_Y_CCIR(r, g, b);
1409
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1410
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1411
                    YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
1412
                }
1413
            }
1414

    
1415
            /* now we can update the picture count */
1416
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1417
                is->subpq_windex = 0;
1418
            SDL_LockMutex(is->subpq_mutex);
1419
            is->subpq_size++;
1420
            SDL_UnlockMutex(is->subpq_mutex);
1421
        }
1422
        av_free_packet(pkt);
1423
//        if (step)
1424
//            if (cur_stream)
1425
//                stream_pause(cur_stream);
1426
    }
1427
 the_end:
1428
    return 0;
1429
}
1430

    
1431
/* copy samples for viewing in editor window */
1432
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1433
{
1434
    int size, len, channels;
1435

    
1436
    channels = is->audio_st->codec->channels;
1437

    
1438
    size = samples_size / sizeof(short);
1439
    while (size > 0) {
1440
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1441
        if (len > size)
1442
            len = size;
1443
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1444
        samples += len;
1445
        is->sample_array_index += len;
1446
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1447
            is->sample_array_index = 0;
1448
        size -= len;
1449
    }
1450
}
1451

    
1452
/* return the new audio buffer size (samples can be added or deleted
1453
   to get better sync if video or external master clock) */
1454
static int synchronize_audio(VideoState *is, short *samples,
1455
                             int samples_size1, double pts)
1456
{
1457
    int n, samples_size;
1458
    double ref_clock;
1459

    
1460
    n = 2 * is->audio_st->codec->channels;
1461
    samples_size = samples_size1;
1462

    
1463
    /* if not master, then we try to remove or add samples to correct the clock */
1464
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1465
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1466
        double diff, avg_diff;
1467
        int wanted_size, min_size, max_size, nb_samples;
1468

    
1469
        ref_clock = get_master_clock(is);
1470
        diff = get_audio_clock(is) - ref_clock;
1471

    
1472
        if (diff < AV_NOSYNC_THRESHOLD) {
1473
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1474
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1475
                /* not enough measures to have a correct estimate */
1476
                is->audio_diff_avg_count++;
1477
            } else {
1478
                /* estimate the A-V difference */
1479
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1480

    
1481
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1482
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1483
                    nb_samples = samples_size / n;
1484

    
1485
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1486
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1487
                    if (wanted_size < min_size)
1488
                        wanted_size = min_size;
1489
                    else if (wanted_size > max_size)
1490
                        wanted_size = max_size;
1491

    
1492
                    /* add or remove samples to correction the synchro */
1493
                    if (wanted_size < samples_size) {
1494
                        /* remove samples */
1495
                        samples_size = wanted_size;
1496
                    } else if (wanted_size > samples_size) {
1497
                        uint8_t *samples_end, *q;
1498
                        int nb;
1499

    
1500
                        /* add samples */
1501
                        nb = (samples_size - wanted_size);
1502
                        samples_end = (uint8_t *)samples + samples_size - n;
1503
                        q = samples_end + n;
1504
                        while (nb > 0) {
1505
                            memcpy(q, samples_end, n);
1506
                            q += n;
1507
                            nb -= n;
1508
                        }
1509
                        samples_size = wanted_size;
1510
                    }
1511
                }
1512
#if 0
1513
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1514
                       diff, avg_diff, samples_size - samples_size1,
1515
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
1516
#endif
1517
            }
1518
        } else {
1519
            /* too big difference : may be initial PTS errors, so
1520
               reset A-V filter */
1521
            is->audio_diff_avg_count = 0;
1522
            is->audio_diff_cum = 0;
1523
        }
1524
    }
1525

    
1526
    return samples_size;
1527
}
1528

    
1529
/* decode one audio frame and returns its uncompressed size */
1530
static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
1531
{
1532
    AVPacket *pkt = &is->audio_pkt;
1533
    int n, len1, data_size;
1534
    double pts;
1535

    
1536
    for(;;) {
1537
        /* NOTE: the audio packet can contain several frames */
1538
        while (is->audio_pkt_size > 0) {
1539
            len1 = avcodec_decode_audio(is->audio_st->codec,
1540
                                        (int16_t *)audio_buf, &data_size,
1541
                                        is->audio_pkt_data, is->audio_pkt_size);
1542
            if (len1 < 0) {
1543
                /* if error, we skip the frame */
1544
                is->audio_pkt_size = 0;
1545
                break;
1546
            }
1547

    
1548
            is->audio_pkt_data += len1;
1549
            is->audio_pkt_size -= len1;
1550
            if (data_size <= 0)
1551
                continue;
1552
            /* if no pts, then compute it */
1553
            pts = is->audio_clock;
1554
            *pts_ptr = pts;
1555
            n = 2 * is->audio_st->codec->channels;
1556
            is->audio_clock += (double)data_size /
1557
                (double)(n * is->audio_st->codec->sample_rate);
1558
#if defined(DEBUG_SYNC)
1559
            {
1560
                static double last_clock;
1561
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1562
                       is->audio_clock - last_clock,
1563
                       is->audio_clock, pts);
1564
                last_clock = is->audio_clock;
1565
            }
1566
#endif
1567
            return data_size;
1568
        }
1569

    
1570
        /* free the current packet */
1571
        if (pkt->data)
1572
            av_free_packet(pkt);
1573

    
1574
        if (is->paused || is->audioq.abort_request) {
1575
            return -1;
1576
        }
1577

    
1578
        /* read next packet */
1579
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1580
            return -1;
1581
        if(pkt->data == flush_pkt.data){
1582
            avcodec_flush_buffers(is->audio_st->codec);
1583
            continue;
1584
        }
1585

    
1586
        is->audio_pkt_data = pkt->data;
1587
        is->audio_pkt_size = pkt->size;
1588

    
1589
        /* if update the audio clock with the pts */
1590
        if (pkt->pts != AV_NOPTS_VALUE) {
1591
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1592
        }
1593
    }
1594
}
1595

    
1596
/* get the current audio output buffer size, in samples. With SDL, we
1597
   cannot have a precise information */
1598
static int audio_write_get_buf_size(VideoState *is)
1599
{
1600
    return is->audio_hw_buf_size - is->audio_buf_index;
1601
}
1602

    
1603

    
1604
/* prepare a new audio buffer */
1605
void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1606
{
1607
    VideoState *is = opaque;
1608
    int audio_size, len1;
1609
    double pts;
1610

    
1611
    audio_callback_time = av_gettime();
1612

    
1613
    while (len > 0) {
1614
        if (is->audio_buf_index >= is->audio_buf_size) {
1615
           audio_size = audio_decode_frame(is, is->audio_buf, &pts);
1616
           if (audio_size < 0) {
1617
                /* if error, just output silence */
1618
               is->audio_buf_size = 1024;
1619
               memset(is->audio_buf, 0, is->audio_buf_size);
1620
           } else {
1621
               if (is->show_audio)
1622
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1623
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1624
                                              pts);
1625
               is->audio_buf_size = audio_size;
1626
           }
1627
           is->audio_buf_index = 0;
1628
        }
1629
        len1 = is->audio_buf_size - is->audio_buf_index;
1630
        if (len1 > len)
1631
            len1 = len;
1632
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1633
        len -= len1;
1634
        stream += len1;
1635
        is->audio_buf_index += len1;
1636
    }
1637
}
1638

    
1639
/* open a given stream. Return 0 if OK */
1640
static int stream_component_open(VideoState *is, int stream_index)
1641
{
1642
    AVFormatContext *ic = is->ic;
1643
    AVCodecContext *enc;
1644
    AVCodec *codec;
1645
    SDL_AudioSpec wanted_spec, spec;
1646

    
1647
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1648
        return -1;
1649
    enc = ic->streams[stream_index]->codec;
1650

    
1651
    /* prepare audio output */
1652
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1653
        wanted_spec.freq = enc->sample_rate;
1654
        wanted_spec.format = AUDIO_S16SYS;
1655
        /* hack for AC3. XXX: suppress that */
1656
        if (enc->channels > 2)
1657
            enc->channels = 2;
1658
        wanted_spec.channels = enc->channels;
1659
        wanted_spec.silence = 0;
1660
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1661
        wanted_spec.callback = sdl_audio_callback;
1662
        wanted_spec.userdata = is;
1663
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1664
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1665
            return -1;
1666
        }
1667
        is->audio_hw_buf_size = spec.size;
1668
    }
1669

    
1670
    codec = avcodec_find_decoder(enc->codec_id);
1671
    enc->debug_mv = debug_mv;
1672
    enc->debug = debug;
1673
    enc->workaround_bugs = workaround_bugs;
1674
    enc->lowres = lowres;
1675
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1676
    enc->idct_algo= idct;
1677
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1678
    enc->skip_frame= skip_frame;
1679
    enc->skip_idct= skip_idct;
1680
    enc->skip_loop_filter= skip_loop_filter;
1681
    enc->error_resilience= error_resilience;
1682
    enc->error_concealment= error_concealment;
1683
    if (!codec ||
1684
        avcodec_open(enc, codec) < 0)
1685
        return -1;
1686
#if defined(HAVE_THREADS)
1687
    if(thread_count>1)
1688
        avcodec_thread_init(enc, thread_count);
1689
#endif
1690
    enc->thread_count= thread_count;
1691
    switch(enc->codec_type) {
1692
    case CODEC_TYPE_AUDIO:
1693
        is->audio_stream = stream_index;
1694
        is->audio_st = ic->streams[stream_index];
1695
        is->audio_buf_size = 0;
1696
        is->audio_buf_index = 0;
1697

    
1698
        /* init averaging filter */
1699
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1700
        is->audio_diff_avg_count = 0;
1701
        /* since we do not have a precise anough audio fifo fullness,
1702
           we correct audio sync only if larger than this threshold */
1703
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1704

    
1705
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1706
        packet_queue_init(&is->audioq);
1707
        SDL_PauseAudio(0);
1708
        break;
1709
    case CODEC_TYPE_VIDEO:
1710
        is->video_stream = stream_index;
1711
        is->video_st = ic->streams[stream_index];
1712

    
1713
        is->frame_last_delay = 40e-3;
1714
        is->frame_timer = (double)av_gettime() / 1000000.0;
1715
        is->video_current_pts_time = av_gettime();
1716

    
1717
        packet_queue_init(&is->videoq);
1718
        is->video_tid = SDL_CreateThread(video_thread, is);
1719
        break;
1720
    case CODEC_TYPE_SUBTITLE:
1721
        is->subtitle_stream = stream_index;
1722
        is->subtitle_st = ic->streams[stream_index];
1723
        packet_queue_init(&is->subtitleq);
1724

    
1725
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1726
        break;
1727
    default:
1728
        break;
1729
    }
1730
    return 0;
1731
}
1732

    
1733
static void stream_component_close(VideoState *is, int stream_index)
1734
{
1735
    AVFormatContext *ic = is->ic;
1736
    AVCodecContext *enc;
1737

    
1738
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1739
        return;
1740
    enc = ic->streams[stream_index]->codec;
1741

    
1742
    switch(enc->codec_type) {
1743
    case CODEC_TYPE_AUDIO:
1744
        packet_queue_abort(&is->audioq);
1745

    
1746
        SDL_CloseAudio();
1747

    
1748
        packet_queue_end(&is->audioq);
1749
        break;
1750
    case CODEC_TYPE_VIDEO:
1751
        packet_queue_abort(&is->videoq);
1752

    
1753
        /* note: we also signal this mutex to make sure we deblock the
1754
           video thread in all cases */
1755
        SDL_LockMutex(is->pictq_mutex);
1756
        SDL_CondSignal(is->pictq_cond);
1757
        SDL_UnlockMutex(is->pictq_mutex);
1758

    
1759
        SDL_WaitThread(is->video_tid, NULL);
1760

    
1761
        packet_queue_end(&is->videoq);
1762
        break;
1763
    case CODEC_TYPE_SUBTITLE:
1764
        packet_queue_abort(&is->subtitleq);
1765

    
1766
        /* note: we also signal this mutex to make sure we deblock the
1767
           video thread in all cases */
1768
        SDL_LockMutex(is->subpq_mutex);
1769
        is->subtitle_stream_changed = 1;
1770

    
1771
        SDL_CondSignal(is->subpq_cond);
1772
        SDL_UnlockMutex(is->subpq_mutex);
1773

    
1774
        SDL_WaitThread(is->subtitle_tid, NULL);
1775

    
1776
        packet_queue_end(&is->subtitleq);
1777
        break;
1778
    default:
1779
        break;
1780
    }
1781

    
1782
    avcodec_close(enc);
1783
    switch(enc->codec_type) {
1784
    case CODEC_TYPE_AUDIO:
1785
        is->audio_st = NULL;
1786
        is->audio_stream = -1;
1787
        break;
1788
    case CODEC_TYPE_VIDEO:
1789
        is->video_st = NULL;
1790
        is->video_stream = -1;
1791
        break;
1792
    case CODEC_TYPE_SUBTITLE:
1793
        is->subtitle_st = NULL;
1794
        is->subtitle_stream = -1;
1795
        break;
1796
    default:
1797
        break;
1798
    }
1799
}
1800

    
1801
static void dump_stream_info(const AVFormatContext *s)
1802
{
1803
    if (s->track != 0)
1804
        fprintf(stderr, "Track: %d\n", s->track);
1805
    if (s->title[0] != '\0')
1806
        fprintf(stderr, "Title: %s\n", s->title);
1807
    if (s->author[0] != '\0')
1808
        fprintf(stderr, "Author: %s\n", s->author);
1809
    if (s->copyright[0] != '\0')
1810
        fprintf(stderr, "Copyright: %s\n", s->copyright);
1811
    if (s->comment[0] != '\0')
1812
        fprintf(stderr, "Comment: %s\n", s->comment);
1813
    if (s->album[0] != '\0')
1814
        fprintf(stderr, "Album: %s\n", s->album);
1815
    if (s->year != 0)
1816
        fprintf(stderr, "Year: %d\n", s->year);
1817
    if (s->genre[0] != '\0')
1818
        fprintf(stderr, "Genre: %s\n", s->genre);
1819
}
1820

    
1821
/* since we have only one decoding thread, we can use a global
1822
   variable instead of a thread local variable */
1823
static VideoState *global_video_state;
1824

    
1825
static int decode_interrupt_cb(void)
1826
{
1827
    return (global_video_state && global_video_state->abort_request);
1828
}
1829

    
1830
/* this thread gets the stream from the disk or the network */
1831
static int decode_thread(void *arg)
1832
{
1833
    VideoState *is = arg;
1834
    AVFormatContext *ic;
1835
    int err, i, ret, video_index, audio_index, use_play;
1836
    AVPacket pkt1, *pkt = &pkt1;
1837
    AVFormatParameters params, *ap = &params;
1838

    
1839
    video_index = -1;
1840
    audio_index = -1;
1841
    is->video_stream = -1;
1842
    is->audio_stream = -1;
1843
    is->subtitle_stream = -1;
1844

    
1845
    global_video_state = is;
1846
    url_set_interrupt_cb(decode_interrupt_cb);
1847

    
1848
    memset(ap, 0, sizeof(*ap));
1849
    ap->initial_pause = 1; /* we force a pause when starting an RTSP
1850
                              stream */
1851

    
1852
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1853
    if (err < 0) {
1854
        print_error(is->filename, err);
1855
        ret = -1;
1856
        goto fail;
1857
    }
1858
    is->ic = ic;
1859
#ifdef CONFIG_NETWORK
1860
    use_play = (ic->iformat == &rtsp_demuxer);
1861
#else
1862
    use_play = 0;
1863
#endif
1864

    
1865
    if(genpts)
1866
        ic->flags |= AVFMT_FLAG_GENPTS;
1867

    
1868
    if (!use_play) {
1869
        err = av_find_stream_info(ic);
1870
        if (err < 0) {
1871
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1872
            ret = -1;
1873
            goto fail;
1874
        }
1875
        ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
1876
    }
1877

    
1878
    /* if seeking requested, we execute it */
1879
    if (start_time != AV_NOPTS_VALUE) {
1880
        int64_t timestamp;
1881

    
1882
        timestamp = start_time;
1883
        /* add the stream start time */
1884
        if (ic->start_time != AV_NOPTS_VALUE)
1885
            timestamp += ic->start_time;
1886
        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1887
        if (ret < 0) {
1888
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
1889
                    is->filename, (double)timestamp / AV_TIME_BASE);
1890
        }
1891
    }
1892

    
1893
    /* now we can begin to play (RTSP stream only) */
1894
    av_read_play(ic);
1895

    
1896
    if (use_play) {
1897
        err = av_find_stream_info(ic);
1898
        if (err < 0) {
1899
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1900
            ret = -1;
1901
            goto fail;
1902
        }
1903
    }
1904

    
1905
    for(i = 0; i < ic->nb_streams; i++) {
1906
        AVCodecContext *enc = ic->streams[i]->codec;
1907
        switch(enc->codec_type) {
1908
        case CODEC_TYPE_AUDIO:
1909
            if (audio_index < 0 && !audio_disable)
1910
                audio_index = i;
1911
            break;
1912
        case CODEC_TYPE_VIDEO:
1913
            if (video_index < 0 && !video_disable)
1914
                video_index = i;
1915
            break;
1916
        default:
1917
            break;
1918
        }
1919
    }
1920
    if (show_status) {
1921
        dump_format(ic, 0, is->filename, 0);
1922
        dump_stream_info(ic);
1923
    }
1924

    
1925
    /* open the streams */
1926
    if (audio_index >= 0) {
1927
        stream_component_open(is, audio_index);
1928
    }
1929

    
1930
    if (video_index >= 0) {
1931
        stream_component_open(is, video_index);
1932
    } else {
1933
        if (!display_disable)
1934
            is->show_audio = 1;
1935
    }
1936

    
1937
    if (is->video_stream < 0 && is->audio_stream < 0) {
1938
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
1939
        ret = -1;
1940
        goto fail;
1941
    }
1942

    
1943
    for(;;) {
1944
        if (is->abort_request)
1945
            break;
1946
#ifdef CONFIG_NETWORK
1947
        if (is->paused != is->last_paused) {
1948
            is->last_paused = is->paused;
1949
            if (is->paused)
1950
                av_read_pause(ic);
1951
            else
1952
                av_read_play(ic);
1953
        }
1954
        if (is->paused && ic->iformat == &rtsp_demuxer) {
1955
            /* wait 10 ms to avoid trying to get another packet */
1956
            /* XXX: horrible */
1957
            SDL_Delay(10);
1958
            continue;
1959
        }
1960
#endif
1961
        if (is->seek_req) {
1962
            ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags);
1963
            if (ret < 0) {
1964
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
1965
            }else{
1966
                if (is->audio_stream >= 0) {
1967
                    packet_queue_flush(&is->audioq);
1968
                    packet_queue_put(&is->audioq, &flush_pkt);
1969
                }
1970
                if (is->subtitle_stream >= 0) {
1971
                    packet_queue_flush(&is->subtitleq);
1972
                    packet_queue_put(&is->subtitleq, &flush_pkt);
1973
                }
1974
                if (is->video_stream >= 0) {
1975
                    packet_queue_flush(&is->videoq);
1976
                    packet_queue_put(&is->videoq, &flush_pkt);
1977
                }
1978
            }
1979
            is->seek_req = 0;
1980
        }
1981

    
1982
        /* if the queue are full, no need to read more */
1983
        if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1984
            is->videoq.size > MAX_VIDEOQ_SIZE ||
1985
            is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1986
            url_feof(&ic->pb)) {
1987
            /* wait 10 ms */
1988
            SDL_Delay(10);
1989
            continue;
1990
        }
1991
        ret = av_read_frame(ic, pkt);
1992
        if (ret < 0) {
1993
            if (url_ferror(&ic->pb) == 0) {
1994
                SDL_Delay(100); /* wait for user event */
1995
                continue;
1996
            } else
1997
                break;
1998
        }
1999
        if (pkt->stream_index == is->audio_stream) {
2000
            packet_queue_put(&is->audioq, pkt);
2001
        } else if (pkt->stream_index == is->video_stream) {
2002
            packet_queue_put(&is->videoq, pkt);
2003
        } else if (pkt->stream_index == is->subtitle_stream) {
2004
            packet_queue_put(&is->subtitleq, pkt);
2005
        } else {
2006
            av_free_packet(pkt);
2007
        }
2008
    }
2009
    /* wait until the end */
2010
    while (!is->abort_request) {
2011
        SDL_Delay(100);
2012
    }
2013

    
2014
    ret = 0;
2015
 fail:
2016
    /* disable interrupting */
2017
    global_video_state = NULL;
2018

    
2019
    /* close each stream */
2020
    if (is->audio_stream >= 0)
2021
        stream_component_close(is, is->audio_stream);
2022
    if (is->video_stream >= 0)
2023
        stream_component_close(is, is->video_stream);
2024
    if (is->subtitle_stream >= 0)
2025
        stream_component_close(is, is->subtitle_stream);
2026
    if (is->ic) {
2027
        av_close_input_file(is->ic);
2028
        is->ic = NULL; /* safety */
2029
    }
2030
    url_set_interrupt_cb(NULL);
2031

    
2032
    if (ret != 0) {
2033
        SDL_Event event;
2034

    
2035
        event.type = FF_QUIT_EVENT;
2036
        event.user.data1 = is;
2037
        SDL_PushEvent(&event);
2038
    }
2039
    return 0;
2040
}
2041

    
2042
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2043
{
2044
    VideoState *is;
2045

    
2046
    is = av_mallocz(sizeof(VideoState));
2047
    if (!is)
2048
        return NULL;
2049
    pstrcpy(is->filename, sizeof(is->filename), filename);
2050
    is->iformat = iformat;
2051
    is->ytop = 0;
2052
    is->xleft = 0;
2053

    
2054
    /* start video display */
2055
    is->pictq_mutex = SDL_CreateMutex();
2056
    is->pictq_cond = SDL_CreateCond();
2057

    
2058
    is->subpq_mutex = SDL_CreateMutex();
2059
    is->subpq_cond = SDL_CreateCond();
2060

    
2061
    /* add the refresh timer to draw the picture */
2062
    schedule_refresh(is, 40);
2063

    
2064
    is->av_sync_type = av_sync_type;
2065
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2066
    if (!is->parse_tid) {
2067
        av_free(is);
2068
        return NULL;
2069
    }
2070
    return is;
2071
}
2072

    
2073
static void stream_close(VideoState *is)
2074
{
2075
    VideoPicture *vp;
2076
    int i;
2077
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2078
    is->abort_request = 1;
2079
    SDL_WaitThread(is->parse_tid, NULL);
2080

    
2081
    /* free all pictures */
2082
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2083
        vp = &is->pictq[i];
2084
        if (vp->bmp) {
2085
            SDL_FreeYUVOverlay(vp->bmp);
2086
            vp->bmp = NULL;
2087
        }
2088
    }
2089
    SDL_DestroyMutex(is->pictq_mutex);
2090
    SDL_DestroyCond(is->pictq_cond);
2091
    SDL_DestroyMutex(is->subpq_mutex);
2092
    SDL_DestroyCond(is->subpq_cond);
2093
}
2094

    
2095
static void stream_cycle_channel(VideoState *is, int codec_type)
2096
{
2097
    AVFormatContext *ic = is->ic;
2098
    int start_index, stream_index;
2099
    AVStream *st;
2100

    
2101
    if (codec_type == CODEC_TYPE_VIDEO)
2102
        start_index = is->video_stream;
2103
    else if (codec_type == CODEC_TYPE_AUDIO)
2104
        start_index = is->audio_stream;
2105
    else
2106
        start_index = is->subtitle_stream;
2107
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2108
        return;
2109
    stream_index = start_index;
2110
    for(;;) {
2111
        if (++stream_index >= is->ic->nb_streams)
2112
        {
2113
            if (codec_type == CODEC_TYPE_SUBTITLE)
2114
            {
2115
                stream_index = -1;
2116
                goto the_end;
2117
            } else
2118
                stream_index = 0;
2119
        }
2120
        if (stream_index == start_index)
2121
            return;
2122
        st = ic->streams[stream_index];
2123
        if (st->codec->codec_type == codec_type) {
2124
            /* check that parameters are OK */
2125
            switch(codec_type) {
2126
            case CODEC_TYPE_AUDIO:
2127
                if (st->codec->sample_rate != 0 &&
2128
                    st->codec->channels != 0)
2129
                    goto the_end;
2130
                break;
2131
            case CODEC_TYPE_VIDEO:
2132
            case CODEC_TYPE_SUBTITLE:
2133
                goto the_end;
2134
            default:
2135
                break;
2136
            }
2137
        }
2138
    }
2139
 the_end:
2140
    stream_component_close(is, start_index);
2141
    stream_component_open(is, stream_index);
2142
}
2143

    
2144

    
2145
static void toggle_full_screen(void)
2146
{
2147
    is_full_screen = !is_full_screen;
2148
    if (!fs_screen_width) {
2149
        /* use default SDL method */
2150
        SDL_WM_ToggleFullScreen(screen);
2151
    } else {
2152
        /* use the recorded resolution */
2153
        video_open(cur_stream);
2154
    }
2155
}
2156

    
2157
static void toggle_pause(void)
2158
{
2159
    if (cur_stream)
2160
        stream_pause(cur_stream);
2161
    step = 0;
2162
}
2163

    
2164
static void step_to_next_frame(void)
2165
{
2166
    if (cur_stream) {
2167
        if (cur_stream->paused)
2168
            cur_stream->paused=0;
2169
        cur_stream->video_current_pts = get_video_clock(cur_stream);
2170
    }
2171
    step = 1;
2172
}
2173

    
2174
static void do_exit(void)
2175
{
2176
    if (cur_stream) {
2177
        stream_close(cur_stream);
2178
        cur_stream = NULL;
2179
    }
2180
    if (show_status)
2181
        printf("\n");
2182
    SDL_Quit();
2183
    exit(0);
2184
}
2185

    
2186
static void toggle_audio_display(void)
2187
{
2188
    if (cur_stream) {
2189
        cur_stream->show_audio = !cur_stream->show_audio;
2190
    }
2191
}
2192

    
2193
/* handle an event sent by the GUI */
2194
static void event_loop(void)
2195
{
2196
    SDL_Event event;
2197
    double incr, pos, frac;
2198

    
2199
    for(;;) {
2200
        SDL_WaitEvent(&event);
2201
        switch(event.type) {
2202
        case SDL_KEYDOWN:
2203
            switch(event.key.keysym.sym) {
2204
            case SDLK_ESCAPE:
2205
            case SDLK_q:
2206
                do_exit();
2207
                break;
2208
            case SDLK_f:
2209
                toggle_full_screen();
2210
                break;
2211
            case SDLK_p:
2212
            case SDLK_SPACE:
2213
                toggle_pause();
2214
                break;
2215
            case SDLK_s: //S: Step to next frame
2216
                step_to_next_frame();
2217
                break;
2218
            case SDLK_a:
2219
                if (cur_stream)
2220
                    stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2221
                break;
2222
            case SDLK_v:
2223
                if (cur_stream)
2224
                    stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2225
                break;
2226
            case SDLK_t:
2227
                if (cur_stream)
2228
                    stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2229
                break;
2230
            case SDLK_w:
2231
                toggle_audio_display();
2232
                break;
2233
            case SDLK_LEFT:
2234
                incr = -10.0;
2235
                goto do_seek;
2236
            case SDLK_RIGHT:
2237
                incr = 10.0;
2238
                goto do_seek;
2239
            case SDLK_UP:
2240
                incr = 60.0;
2241
                goto do_seek;
2242
            case SDLK_DOWN:
2243
                incr = -60.0;
2244
            do_seek:
2245
                if (cur_stream) {
2246
                    if (seek_by_bytes) {
2247
                        pos = url_ftell(&cur_stream->ic->pb);
2248
                        if (cur_stream->ic->bit_rate)
2249
                            incr *= cur_stream->ic->bit_rate / 60.0;
2250
                        else
2251
                            incr *= 180000.0;
2252
                        pos += incr;
2253
                        stream_seek(cur_stream, pos, incr);
2254
                    } else {
2255
                        pos = get_master_clock(cur_stream);
2256
                        pos += incr;
2257
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
2258
                    }
2259
                }
2260
                break;
2261
            default:
2262
                break;
2263
            }
2264
            break;
2265
        case SDL_MOUSEBUTTONDOWN:
2266
            if (cur_stream) {
2267
                int ns, hh, mm, ss;
2268
                int tns, thh, tmm, tss;
2269
                tns = cur_stream->ic->duration/1000000LL;
2270
                thh = tns/3600;
2271
                tmm = (tns%3600)/60;
2272
                tss = (tns%60);
2273
                frac = (double)event.button.x/(double)cur_stream->width;
2274
                ns = frac*tns;
2275
                hh = ns/3600;
2276
                mm = (ns%3600)/60;
2277
                ss = (ns%60);
2278
                fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2279
                        hh, mm, ss, thh, tmm, tss);
2280
                stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
2281
            }
2282
            break;
2283
        case SDL_VIDEORESIZE:
2284
            if (cur_stream) {
2285
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2286
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2287
                cur_stream->width = event.resize.w;
2288
                cur_stream->height = event.resize.h;
2289
            }
2290
            break;
2291
        case SDL_QUIT:
2292
        case FF_QUIT_EVENT:
2293
            do_exit();
2294
            break;
2295
        case FF_ALLOC_EVENT:
2296
            video_open(event.user.data1);
2297
            alloc_picture(event.user.data1);
2298
            break;
2299
        case FF_REFRESH_EVENT:
2300
            video_refresh_timer(event.user.data1);
2301
            break;
2302
        default:
2303
            break;
2304
        }
2305
    }
2306
}
2307

    
2308
void opt_width(const char *arg)
2309
{
2310
    screen_width = atoi(arg);
2311
}
2312

    
2313
void opt_height(const char *arg)
2314
{
2315
    screen_height = atoi(arg);
2316
}
2317

    
2318
static void opt_format(const char *arg)
2319
{
2320
    file_iformat = av_find_input_format(arg);
2321
    if (!file_iformat) {
2322
        fprintf(stderr, "Unknown input format: %s\n", arg);
2323
        exit(1);
2324
    }
2325
}
2326

    
2327
#ifdef CONFIG_NETWORK
2328
void opt_rtp_tcp(void)
2329
{
2330
    /* only tcp protocol */
2331
    rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
2332
}
2333
#endif
2334

    
2335
void opt_sync(const char *arg)
2336
{
2337
    if (!strcmp(arg, "audio"))
2338
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2339
    else if (!strcmp(arg, "video"))
2340
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2341
    else if (!strcmp(arg, "ext"))
2342
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2343
    else
2344
        show_help();
2345
}
2346

    
2347
void opt_seek(const char *arg)
2348
{
2349
    start_time = parse_date(arg, 1);
2350
}
2351

    
2352
static void opt_debug(const char *arg)
2353
{
2354
    av_log_set_level(99);
2355
    debug = atoi(arg);
2356
}
2357

    
2358
static void opt_vismv(const char *arg)
2359
{
2360
    debug_mv = atoi(arg);
2361
}
2362

    
2363
static void opt_thread_count(const char *arg)
2364
{
2365
    thread_count= atoi(arg);
2366
#if !defined(HAVE_THREADS)
2367
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2368
#endif
2369
}
2370

    
2371
const OptionDef options[] = {
2372
    { "h", 0, {(void*)show_help}, "show help" },
2373
    { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2374
    { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
2375
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2376
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2377
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2378
    { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2379
    { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2380
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2381
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2382
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2383
    { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2384
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2385
    { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2386
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2387
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2388
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2389
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2390
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2391
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2392
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2393
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)",  "threshold" },
2394
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2395
#ifdef CONFIG_NETWORK
2396
    { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
2397
#endif
2398
    { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2399
    { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2400
    { NULL, },
2401
};
2402

    
2403
void show_help(void)
2404
{
2405
    printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003-2006 Fabrice Bellard, et al.\n"
2406
           "usage: ffplay [options] input_file\n"
2407
           "Simple media player\n");
2408
    printf("\n");
2409
    show_help_options(options, "Main options:\n",
2410
                      OPT_EXPERT, 0);
2411
    show_help_options(options, "\nAdvanced options:\n",
2412
                      OPT_EXPERT, OPT_EXPERT);
2413
    printf("\nWhile playing:\n"
2414
           "q, ESC              quit\n"
2415
           "f                   toggle full screen\n"
2416
           "p, SPC              pause\n"
2417
           "a                   cycle audio channel\n"
2418
           "v                   cycle video channel\n"
2419
           "t                   cycle subtitle channel\n"
2420
           "w                   show audio waves\n"
2421
           "left/right          seek backward/forward 10 seconds\n"
2422
           "down/up             seek backward/forward 1 minute\n"
2423
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2424
           );
2425
    exit(1);
2426
}
2427

    
2428
void parse_arg_file(const char *filename)
2429
{
2430
    if (!strcmp(filename, "-"))
2431
                    filename = "pipe:";
2432
    input_filename = filename;
2433
}
2434

    
2435
/* Called from the main */
2436
int main(int argc, char **argv)
2437
{
2438
    int flags;
2439

    
2440
    /* register all codecs, demux and protocols */
2441
    av_register_all();
2442

    
2443
    #ifdef CONFIG_OS2
2444
      MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
2445

    
2446
      // Make stdout and stderr unbuffered
2447
      setbuf( stdout, NULL );
2448
      setbuf( stderr, NULL );
2449
    #endif
2450

    
2451
    parse_options(argc, argv, options);
2452

    
2453
    if (!input_filename)
2454
        show_help();
2455

    
2456
    if (display_disable) {
2457
        video_disable = 1;
2458
    }
2459
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2460
#if !defined(__MINGW32__) && !defined(CONFIG_DARWIN)
2461
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 or darwin */
2462
#endif
2463
    if (SDL_Init (flags)) {
2464
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2465
        exit(1);
2466
    }
2467

    
2468
    if (!display_disable) {
2469
#ifdef HAVE_SDL_VIDEO_SIZE
2470
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2471
        fs_screen_width = vi->current_w;
2472
        fs_screen_height = vi->current_h;
2473
#endif
2474
    }
2475

    
2476
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2477
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2478
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2479
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2480

    
2481
    av_init_packet(&flush_pkt);
2482
    flush_pkt.data= "FLUSH";
2483

    
2484
    cur_stream = stream_open(input_filename, file_iformat);
2485

    
2486
    event_loop();
2487

    
2488
    /* never returns */
2489

    
2490
    return 0;
2491
}