Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 4ed29207

History | View | Annotate | Download (79.2 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

    
22
#include <math.h>
23
#include <limits.h>
24
#include "libavutil/avstring.h"
25
#include "libavformat/avformat.h"
26
#include "libavformat/rtsp.h"
27
#include "libavdevice/avdevice.h"
28
#include "libswscale/swscale.h"
29
#include "libavcodec/audioconvert.h"
30
#include "libavcodec/opt.h"
31

    
32
#include "cmdutils.h"
33

    
34
#include <SDL.h>
35
#include <SDL_thread.h>
36

    
37
#ifdef __MINGW32__
38
#undef main /* We don't want SDL to override our main() */
39
#endif
40

    
41
#undef exit
42

    
43
const char program_name[] = "FFplay";
44
const int program_birth_year = 2003;
45

    
46
//#define DEBUG_SYNC
47

    
48
#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
49
#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
50
#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
51

    
52
/* SDL audio buffer size, in samples. Should be small to have precise
53
   A/V sync as SDL does not have hardware buffer fullness info. */
54
#define SDL_AUDIO_BUFFER_SIZE 1024
55

    
56
/* no AV sync correction is done if below the AV sync threshold */
57
#define AV_SYNC_THRESHOLD 0.01
58
/* no AV correction is done if too big error */
59
#define AV_NOSYNC_THRESHOLD 10.0
60

    
61
/* maximum audio speed change to get correct sync */
62
#define SAMPLE_CORRECTION_PERCENT_MAX 10
63

    
64
/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
65
#define AUDIO_DIFF_AVG_NB   20
66

    
67
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
68
#define SAMPLE_ARRAY_SIZE (2*65536)
69

    
70
static int sws_flags = SWS_BICUBIC;
71

    
72
typedef struct PacketQueue {
73
    AVPacketList *first_pkt, *last_pkt;
74
    int nb_packets;
75
    int size;
76
    int abort_request;
77
    SDL_mutex *mutex;
78
    SDL_cond *cond;
79
} PacketQueue;
80

    
81
#define VIDEO_PICTURE_QUEUE_SIZE 1
82
#define SUBPICTURE_QUEUE_SIZE 4
83

    
84
typedef struct VideoPicture {
85
    double pts;                                  ///<presentation time stamp for this picture
86
    SDL_Overlay *bmp;
87
    int width, height; /* source height & width */
88
    int allocated;
89
} VideoPicture;
90

    
91
typedef struct SubPicture {
92
    double pts; /* presentation time stamp for this picture */
93
    AVSubtitle sub;
94
} SubPicture;
95

    
96
enum {
97
    AV_SYNC_AUDIO_MASTER, /* default choice */
98
    AV_SYNC_VIDEO_MASTER,
99
    AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
100
};
101

    
102
typedef struct VideoState {
103
    SDL_Thread *parse_tid;
104
    SDL_Thread *video_tid;
105
    AVInputFormat *iformat;
106
    int no_background;
107
    int abort_request;
108
    int paused;
109
    int last_paused;
110
    int seek_req;
111
    int seek_flags;
112
    int64_t seek_pos;
113
    int64_t seek_rel;
114
    AVFormatContext *ic;
115
    int dtg_active_format;
116

    
117
    int audio_stream;
118

    
119
    int av_sync_type;
120
    double external_clock; /* external clock base */
121
    int64_t external_clock_time;
122

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

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

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

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

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

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

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

    
217
/* current context */
218
static int is_full_screen;
219
static VideoState *cur_stream;
220
static int64_t audio_callback_time;
221

    
222
static AVPacket flush_pkt;
223

    
224
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
225
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
226
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
227

    
228
static SDL_Surface *screen;
229

    
230
/* packet queue handling */
231
static void packet_queue_init(PacketQueue *q)
232
{
233
    memset(q, 0, sizeof(PacketQueue));
234
    q->mutex = SDL_CreateMutex();
235
    q->cond = SDL_CreateCond();
236
}
237

    
238
static void packet_queue_flush(PacketQueue *q)
239
{
240
    AVPacketList *pkt, *pkt1;
241

    
242
    SDL_LockMutex(q->mutex);
243
    for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
244
        pkt1 = pkt->next;
245
        av_free_packet(&pkt->pkt);
246
        av_freep(&pkt);
247
    }
248
    q->last_pkt = NULL;
249
    q->first_pkt = NULL;
250
    q->nb_packets = 0;
251
    q->size = 0;
252
    SDL_UnlockMutex(q->mutex);
253
}
254

    
255
static void packet_queue_end(PacketQueue *q)
256
{
257
    packet_queue_flush(q);
258
    SDL_DestroyMutex(q->mutex);
259
    SDL_DestroyCond(q->cond);
260
}
261

    
262
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
263
{
264
    AVPacketList *pkt1;
265

    
266
    /* duplicate the packet */
267
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
268
        return -1;
269

    
270
    pkt1 = av_malloc(sizeof(AVPacketList));
271
    if (!pkt1)
272
        return -1;
273
    pkt1->pkt = *pkt;
274
    pkt1->next = NULL;
275

    
276

    
277
    SDL_LockMutex(q->mutex);
278

    
279
    if (!q->last_pkt)
280

    
281
        q->first_pkt = pkt1;
282
    else
283
        q->last_pkt->next = pkt1;
284
    q->last_pkt = pkt1;
285
    q->nb_packets++;
286
    q->size += pkt1->pkt.size + sizeof(*pkt1);
287
    /* XXX: should duplicate packet data in DV case */
288
    SDL_CondSignal(q->cond);
289

    
290
    SDL_UnlockMutex(q->mutex);
291
    return 0;
292
}
293

    
294
static void packet_queue_abort(PacketQueue *q)
295
{
296
    SDL_LockMutex(q->mutex);
297

    
298
    q->abort_request = 1;
299

    
300
    SDL_CondSignal(q->cond);
301

    
302
    SDL_UnlockMutex(q->mutex);
303
}
304

    
305
/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
306
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
307
{
308
    AVPacketList *pkt1;
309
    int ret;
310

    
311
    SDL_LockMutex(q->mutex);
312

    
313
    for(;;) {
314
        if (q->abort_request) {
315
            ret = -1;
316
            break;
317
        }
318

    
319
        pkt1 = q->first_pkt;
320
        if (pkt1) {
321
            q->first_pkt = pkt1->next;
322
            if (!q->first_pkt)
323
                q->last_pkt = NULL;
324
            q->nb_packets--;
325
            q->size -= pkt1->pkt.size + sizeof(*pkt1);
326
            *pkt = pkt1->pkt;
327
            av_free(pkt1);
328
            ret = 1;
329
            break;
330
        } else if (!block) {
331
            ret = 0;
332
            break;
333
        } else {
334
            SDL_CondWait(q->cond, q->mutex);
335
        }
336
    }
337
    SDL_UnlockMutex(q->mutex);
338
    return ret;
339
}
340

    
341
static inline void fill_rectangle(SDL_Surface *screen,
342
                                  int x, int y, int w, int h, int color)
343
{
344
    SDL_Rect rect;
345
    rect.x = x;
346
    rect.y = y;
347
    rect.w = w;
348
    rect.h = h;
349
    SDL_FillRect(screen, &rect, color);
350
}
351

    
352
#if 0
353
/* draw only the border of a rectangle */
354
void fill_border(VideoState *s, int x, int y, int w, int h, int color)
355
{
356
    int w1, w2, h1, h2;
357

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

    
390

    
391

    
392
#define SCALEBITS 10
393
#define ONE_HALF  (1 << (SCALEBITS - 1))
394
#define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
395

    
396
#define RGB_TO_Y_CCIR(r, g, b) \
397
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
398
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
399

    
400
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
401
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
402
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
403

    
404
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
405
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
406
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
407

    
408
#define ALPHA_BLEND(a, oldp, newp, s)\
409
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
410

    
411
#define RGBA_IN(r, g, b, a, s)\
412
{\
413
    unsigned int v = ((const uint32_t *)(s))[0];\
414
    a = (v >> 24) & 0xff;\
415
    r = (v >> 16) & 0xff;\
416
    g = (v >> 8) & 0xff;\
417
    b = v & 0xff;\
418
}
419

    
420
#define YUVA_IN(y, u, v, a, s, pal)\
421
{\
422
    unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
423
    a = (val >> 24) & 0xff;\
424
    y = (val >> 16) & 0xff;\
425
    u = (val >> 8) & 0xff;\
426
    v = val & 0xff;\
427
}
428

    
429
#define YUVA_OUT(d, y, u, v, a)\
430
{\
431
    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
432
}
433

    
434

    
435
#define BPP 1
436

    
437
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
438
{
439
    int wrap, wrap3, width2, skip2;
440
    int y, u, v, a, u1, v1, a1, w, h;
441
    uint8_t *lum, *cb, *cr;
442
    const uint8_t *p;
443
    const uint32_t *pal;
444
    int dstx, dsty, dstw, dsth;
445

    
446
    dstw = av_clip(rect->w, 0, imgw);
447
    dsth = av_clip(rect->h, 0, imgh);
448
    dstx = av_clip(rect->x, 0, imgw - dstw);
449
    dsty = av_clip(rect->y, 0, imgh - dsth);
450
    lum = dst->data[0] + dsty * dst->linesize[0];
451
    cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
452
    cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
453

    
454
    width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
455
    skip2 = dstx >> 1;
456
    wrap = dst->linesize[0];
457
    wrap3 = rect->pict.linesize[0];
458
    p = rect->pict.data[0];
459
    pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
460

    
461
    if (dsty & 1) {
462
        lum += dstx;
463
        cb += skip2;
464
        cr += skip2;
465

    
466
        if (dstx & 1) {
467
            YUVA_IN(y, u, v, a, p, pal);
468
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
469
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
470
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
471
            cb++;
472
            cr++;
473
            lum++;
474
            p += BPP;
475
        }
476
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
477
            YUVA_IN(y, u, v, a, p, pal);
478
            u1 = u;
479
            v1 = v;
480
            a1 = a;
481
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
482

    
483
            YUVA_IN(y, u, v, a, p + BPP, pal);
484
            u1 += u;
485
            v1 += v;
486
            a1 += a;
487
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
488
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
489
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
490
            cb++;
491
            cr++;
492
            p += 2 * BPP;
493
            lum += 2;
494
        }
495
        if (w) {
496
            YUVA_IN(y, u, v, a, p, pal);
497
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
498
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
499
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
500
            p++;
501
            lum++;
502
        }
503
        p += wrap3 - dstw * BPP;
504
        lum += wrap - dstw - dstx;
505
        cb += dst->linesize[1] - width2 - skip2;
506
        cr += dst->linesize[2] - width2 - skip2;
507
    }
508
    for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
509
        lum += dstx;
510
        cb += skip2;
511
        cr += skip2;
512

    
513
        if (dstx & 1) {
514
            YUVA_IN(y, u, v, a, p, pal);
515
            u1 = u;
516
            v1 = v;
517
            a1 = a;
518
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
519
            p += wrap3;
520
            lum += wrap;
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
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
527
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
528
            cb++;
529
            cr++;
530
            p += -wrap3 + BPP;
531
            lum += -wrap + 1;
532
        }
533
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
534
            YUVA_IN(y, u, v, a, p, pal);
535
            u1 = u;
536
            v1 = v;
537
            a1 = a;
538
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
539

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

    
548
            YUVA_IN(y, u, v, a, p, pal);
549
            u1 += u;
550
            v1 += v;
551
            a1 += a;
552
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
553

    
554
            YUVA_IN(y, u, v, a, p + BPP, pal);
555
            u1 += u;
556
            v1 += v;
557
            a1 += a;
558
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
559

    
560
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
561
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
562

    
563
            cb++;
564
            cr++;
565
            p += -wrap3 + 2 * BPP;
566
            lum += -wrap + 2;
567
        }
568
        if (w) {
569
            YUVA_IN(y, u, v, a, p, pal);
570
            u1 = u;
571
            v1 = v;
572
            a1 = a;
573
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
574
            p += wrap3;
575
            lum += wrap;
576
            YUVA_IN(y, u, v, a, p, pal);
577
            u1 += u;
578
            v1 += v;
579
            a1 += a;
580
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
581
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
582
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
583
            cb++;
584
            cr++;
585
            p += -wrap3 + BPP;
586
            lum += -wrap + 1;
587
        }
588
        p += wrap3 + (wrap3 - dstw * BPP);
589
        lum += wrap + (wrap - dstw - dstx);
590
        cb += dst->linesize[1] - width2 - skip2;
591
        cr += dst->linesize[2] - width2 - skip2;
592
    }
593
    /* handle odd height */
594
    if (h) {
595
        lum += dstx;
596
        cb += skip2;
597
        cr += skip2;
598

    
599
        if (dstx & 1) {
600
            YUVA_IN(y, u, v, a, p, pal);
601
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
602
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
603
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
604
            cb++;
605
            cr++;
606
            lum++;
607
            p += BPP;
608
        }
609
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
610
            YUVA_IN(y, u, v, a, p, pal);
611
            u1 = u;
612
            v1 = v;
613
            a1 = a;
614
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
615

    
616
            YUVA_IN(y, u, v, a, p + BPP, pal);
617
            u1 += u;
618
            v1 += v;
619
            a1 += a;
620
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
621
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
622
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
623
            cb++;
624
            cr++;
625
            p += 2 * BPP;
626
            lum += 2;
627
        }
628
        if (w) {
629
            YUVA_IN(y, u, v, a, p, pal);
630
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
631
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
632
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
633
        }
634
    }
635
}
636

    
637
static void free_subpicture(SubPicture *sp)
638
{
639
    int i;
640

    
641
    for (i = 0; i < sp->sub.num_rects; i++)
642
    {
643
        av_freep(&sp->sub.rects[i]->pict.data[0]);
644
        av_freep(&sp->sub.rects[i]->pict.data[1]);
645
        av_freep(&sp->sub.rects[i]);
646
    }
647

    
648
    av_free(sp->sub.rects);
649

    
650
    memset(&sp->sub, 0, sizeof(AVSubtitle));
651
}
652

    
653
static void video_image_display(VideoState *is)
654
{
655
    VideoPicture *vp;
656
    SubPicture *sp;
657
    AVPicture pict;
658
    float aspect_ratio;
659
    int width, height, x, y;
660
    SDL_Rect rect;
661
    int i;
662

    
663
    vp = &is->pictq[is->pictq_rindex];
664
    if (vp->bmp) {
665
        /* XXX: use variable in the frame */
666
        if (is->video_st->sample_aspect_ratio.num)
667
            aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
668
        else if (is->video_st->codec->sample_aspect_ratio.num)
669
            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
670
        else
671
            aspect_ratio = 0;
672
        if (aspect_ratio <= 0.0)
673
            aspect_ratio = 1.0;
674
        aspect_ratio *= (float)is->video_st->codec->width / is->video_st->codec->height;
675
        /* if an active format is indicated, then it overrides the
676
           mpeg format */
677
#if 0
678
        if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
679
            is->dtg_active_format = is->video_st->codec->dtg_active_format;
680
            printf("dtg_active_format=%d\n", is->dtg_active_format);
681
        }
682
#endif
683
#if 0
684
        switch(is->video_st->codec->dtg_active_format) {
685
        case FF_DTG_AFD_SAME:
686
        default:
687
            /* nothing to do */
688
            break;
689
        case FF_DTG_AFD_4_3:
690
            aspect_ratio = 4.0 / 3.0;
691
            break;
692
        case FF_DTG_AFD_16_9:
693
            aspect_ratio = 16.0 / 9.0;
694
            break;
695
        case FF_DTG_AFD_14_9:
696
            aspect_ratio = 14.0 / 9.0;
697
            break;
698
        case FF_DTG_AFD_4_3_SP_14_9:
699
            aspect_ratio = 14.0 / 9.0;
700
            break;
701
        case FF_DTG_AFD_16_9_SP_14_9:
702
            aspect_ratio = 14.0 / 9.0;
703
            break;
704
        case FF_DTG_AFD_SP_4_3:
705
            aspect_ratio = 4.0 / 3.0;
706
            break;
707
        }
708
#endif
709

    
710
        if (is->subtitle_st)
711
        {
712
            if (is->subpq_size > 0)
713
            {
714
                sp = &is->subpq[is->subpq_rindex];
715

    
716
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
717
                {
718
                    SDL_LockYUVOverlay (vp->bmp);
719

    
720
                    pict.data[0] = vp->bmp->pixels[0];
721
                    pict.data[1] = vp->bmp->pixels[2];
722
                    pict.data[2] = vp->bmp->pixels[1];
723

    
724
                    pict.linesize[0] = vp->bmp->pitches[0];
725
                    pict.linesize[1] = vp->bmp->pitches[2];
726
                    pict.linesize[2] = vp->bmp->pitches[1];
727

    
728
                    for (i = 0; i < sp->sub.num_rects; i++)
729
                        blend_subrect(&pict, sp->sub.rects[i],
730
                                      vp->bmp->w, vp->bmp->h);
731

    
732
                    SDL_UnlockYUVOverlay (vp->bmp);
733
                }
734
            }
735
        }
736

    
737

    
738
        /* XXX: we suppose the screen has a 1.0 pixel ratio */
739
        height = is->height;
740
        width = ((int)rint(height * aspect_ratio)) & ~1;
741
        if (width > is->width) {
742
            width = is->width;
743
            height = ((int)rint(width / aspect_ratio)) & ~1;
744
        }
745
        x = (is->width - width) / 2;
746
        y = (is->height - height) / 2;
747
        if (!is->no_background) {
748
            /* fill the background */
749
            //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
750
        } else {
751
            is->no_background = 0;
752
        }
753
        rect.x = is->xleft + x;
754
        rect.y = is->ytop  + y;
755
        rect.w = width;
756
        rect.h = height;
757
        SDL_DisplayYUVOverlay(vp->bmp, &rect);
758
    } else {
759
#if 0
760
        fill_rectangle(screen,
761
                       is->xleft, is->ytop, is->width, is->height,
762
                       QERGB(0x00, 0x00, 0x00));
763
#endif
764
    }
765
}
766

    
767
static inline int compute_mod(int a, int b)
768
{
769
    a = a % b;
770
    if (a >= 0)
771
        return a;
772
    else
773
        return a + b;
774
}
775

    
776
static void video_audio_display(VideoState *s)
777
{
778
    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
779
    int ch, channels, h, h2, bgcolor, fgcolor;
780
    int16_t time_diff;
781

    
782
    /* compute display index : center on currently output samples */
783
    channels = s->audio_st->codec->channels;
784
    nb_display_channels = channels;
785
    if (!s->paused) {
786
        n = 2 * channels;
787
        delay = audio_write_get_buf_size(s);
788
        delay /= n;
789

    
790
        /* to be more precise, we take into account the time spent since
791
           the last buffer computation */
792
        if (audio_callback_time) {
793
            time_diff = av_gettime() - audio_callback_time;
794
            delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
795
        }
796

    
797
        delay -= s->width / 2;
798
        if (delay < s->width)
799
            delay = s->width;
800

    
801
        i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
802

    
803
        h= INT_MIN;
804
        for(i=0; i<1000; i+=channels){
805
            int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
806
            int a= s->sample_array[idx];
807
            int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
808
            int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
809
            int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
810
            int score= a-d;
811
            if(h<score && (b^c)<0){
812
                h= score;
813
                i_start= idx;
814
            }
815
        }
816

    
817
        s->last_i_start = i_start;
818
    } else {
819
        i_start = s->last_i_start;
820
    }
821

    
822
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
823
    fill_rectangle(screen,
824
                   s->xleft, s->ytop, s->width, s->height,
825
                   bgcolor);
826

    
827
    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
828

    
829
    /* total height for one channel */
830
    h = s->height / nb_display_channels;
831
    /* graph height / 2 */
832
    h2 = (h * 9) / 20;
833
    for(ch = 0;ch < nb_display_channels; ch++) {
834
        i = i_start + ch;
835
        y1 = s->ytop + ch * h + (h / 2); /* position of center line */
836
        for(x = 0; x < s->width; x++) {
837
            y = (s->sample_array[i] * h2) >> 15;
838
            if (y < 0) {
839
                y = -y;
840
                ys = y1 - y;
841
            } else {
842
                ys = y1;
843
            }
844
            fill_rectangle(screen,
845
                           s->xleft + x, ys, 1, y,
846
                           fgcolor);
847
            i += channels;
848
            if (i >= SAMPLE_ARRAY_SIZE)
849
                i -= SAMPLE_ARRAY_SIZE;
850
        }
851
    }
852

    
853
    fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
854

    
855
    for(ch = 1;ch < nb_display_channels; ch++) {
856
        y = s->ytop + ch * h;
857
        fill_rectangle(screen,
858
                       s->xleft, y, s->width, 1,
859
                       fgcolor);
860
    }
861
    SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
862
}
863

    
864
static int video_open(VideoState *is){
865
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
866
    int w,h;
867

    
868
    if(is_full_screen) flags |= SDL_FULLSCREEN;
869
    else               flags |= SDL_RESIZABLE;
870

    
871
    if (is_full_screen && fs_screen_width) {
872
        w = fs_screen_width;
873
        h = fs_screen_height;
874
    } else if(!is_full_screen && screen_width){
875
        w = screen_width;
876
        h = screen_height;
877
    }else if (is->video_st && is->video_st->codec->width){
878
        w = is->video_st->codec->width;
879
        h = is->video_st->codec->height;
880
    } else {
881
        w = 640;
882
        h = 480;
883
    }
884
#ifndef __APPLE__
885
    screen = SDL_SetVideoMode(w, h, 0, flags);
886
#else
887
    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
888
    screen = SDL_SetVideoMode(w, h, 24, flags);
889
#endif
890
    if (!screen) {
891
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
892
        return -1;
893
    }
894
    SDL_WM_SetCaption("FFplay", "FFplay");
895

    
896
    is->width = screen->w;
897
    is->height = screen->h;
898

    
899
    return 0;
900
}
901

    
902
/* display the current picture, if any */
903
static void video_display(VideoState *is)
904
{
905
    if(!screen)
906
        video_open(cur_stream);
907
    if (is->audio_st && is->show_audio)
908
        video_audio_display(is);
909
    else if (is->video_st)
910
        video_image_display(is);
911
}
912

    
913
static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
914
{
915
    SDL_Event event;
916
    event.type = FF_REFRESH_EVENT;
917
    event.user.data1 = opaque;
918
    SDL_PushEvent(&event);
919
    return 0; /* 0 means stop timer */
920
}
921

    
922
/* schedule a video refresh in 'delay' ms */
923
static void schedule_refresh(VideoState *is, int delay)
924
{
925
    if(!delay) delay=1; //SDL seems to be buggy when the delay is 0
926
    SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
927
}
928

    
929
/* get the current audio clock value */
930
static double get_audio_clock(VideoState *is)
931
{
932
    double pts;
933
    int hw_buf_size, bytes_per_sec;
934
    pts = is->audio_clock;
935
    hw_buf_size = audio_write_get_buf_size(is);
936
    bytes_per_sec = 0;
937
    if (is->audio_st) {
938
        bytes_per_sec = is->audio_st->codec->sample_rate *
939
            2 * is->audio_st->codec->channels;
940
    }
941
    if (bytes_per_sec)
942
        pts -= (double)hw_buf_size / bytes_per_sec;
943
    return pts;
944
}
945

    
946
/* get the current video clock value */
947
static double get_video_clock(VideoState *is)
948
{
949
    double delta;
950
    if (is->paused) {
951
        delta = 0;
952
    } else {
953
        delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
954
    }
955
    return is->video_current_pts + delta;
956
}
957

    
958
/* get the current external clock value */
959
static double get_external_clock(VideoState *is)
960
{
961
    int64_t ti;
962
    ti = av_gettime();
963
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
964
}
965

    
966
/* get the current master clock value */
967
static double get_master_clock(VideoState *is)
968
{
969
    double val;
970

    
971
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
972
        if (is->video_st)
973
            val = get_video_clock(is);
974
        else
975
            val = get_audio_clock(is);
976
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
977
        if (is->audio_st)
978
            val = get_audio_clock(is);
979
        else
980
            val = get_video_clock(is);
981
    } else {
982
        val = get_external_clock(is);
983
    }
984
    return val;
985
}
986

    
987
/* seek in the stream */
988
static void stream_seek(VideoState *is, int64_t pos, int64_t rel)
989
{
990
    if (!is->seek_req) {
991
        is->seek_pos = pos;
992
        is->seek_rel = rel;
993
        if (seek_by_bytes)
994
            is->seek_flags |= AVSEEK_FLAG_BYTE;
995
        is->seek_req = 1;
996
    }
997
}
998

    
999
/* pause or resume the video */
1000
static void stream_pause(VideoState *is)
1001
{
1002
    is->paused = !is->paused;
1003
    if (!is->paused) {
1004
        is->video_current_pts = get_video_clock(is);
1005
        is->frame_timer += (av_gettime() - is->video_current_pts_time) / 1000000.0;
1006
    }
1007
}
1008

    
1009
static double compute_frame_delay(double frame_current_pts, VideoState *is)
1010
{
1011
    double actual_delay, delay, sync_threshold, ref_clock, diff;
1012

    
1013
    /* compute nominal delay */
1014
    delay = frame_current_pts - is->frame_last_pts;
1015
    if (delay <= 0 || delay >= 10.0) {
1016
        /* if incorrect delay, use previous one */
1017
        delay = is->frame_last_delay;
1018
    } else {
1019
        is->frame_last_delay = delay;
1020
    }
1021
    is->frame_last_pts = frame_current_pts;
1022

    
1023
    /* update delay to follow master synchronisation source */
1024
    if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1025
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1026
        /* if video is slave, we try to correct big delays by
1027
           duplicating or deleting a frame */
1028
        ref_clock = get_master_clock(is);
1029
        diff = frame_current_pts - ref_clock;
1030

    
1031
        /* skip or repeat frame. We take into account the
1032
           delay to compute the threshold. I still don't know
1033
           if it is the best guess */
1034
        sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1035
        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1036
            if (diff <= -sync_threshold)
1037
                delay = 0;
1038
            else if (diff >= sync_threshold)
1039
                delay = 2 * delay;
1040
        }
1041
    }
1042

    
1043
    is->frame_timer += delay;
1044
    /* compute the REAL delay (we need to do that to avoid
1045
       long term errors */
1046
    actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1047
    if (actual_delay < 0.010) {
1048
        /* XXX: should skip picture */
1049
        actual_delay = 0.010;
1050
    }
1051

    
1052
#if defined(DEBUG_SYNC)
1053
    printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1054
            delay, actual_delay, frame_current_pts, -diff);
1055
#endif
1056

    
1057
    return actual_delay;
1058
}
1059

    
1060
/* called to display each frame */
1061
static void video_refresh_timer(void *opaque)
1062
{
1063
    VideoState *is = opaque;
1064
    VideoPicture *vp;
1065

    
1066
    SubPicture *sp, *sp2;
1067

    
1068
    if (is->video_st) {
1069
        if (is->pictq_size == 0) {
1070
            /* if no picture, need to wait */
1071
            schedule_refresh(is, 1);
1072
        } else {
1073
            /* dequeue the picture */
1074
            vp = &is->pictq[is->pictq_rindex];
1075

    
1076
            /* update current video pts */
1077
            is->video_current_pts = vp->pts;
1078
            is->video_current_pts_time = av_gettime();
1079

    
1080
            /* launch timer for next picture */
1081
            schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1082

    
1083
            if(is->subtitle_st) {
1084
                if (is->subtitle_stream_changed) {
1085
                    SDL_LockMutex(is->subpq_mutex);
1086

    
1087
                    while (is->subpq_size) {
1088
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1089

    
1090
                        /* update queue size and signal for next picture */
1091
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1092
                            is->subpq_rindex = 0;
1093

    
1094
                        is->subpq_size--;
1095
                    }
1096
                    is->subtitle_stream_changed = 0;
1097

    
1098
                    SDL_CondSignal(is->subpq_cond);
1099
                    SDL_UnlockMutex(is->subpq_mutex);
1100
                } else {
1101
                    if (is->subpq_size > 0) {
1102
                        sp = &is->subpq[is->subpq_rindex];
1103

    
1104
                        if (is->subpq_size > 1)
1105
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1106
                        else
1107
                            sp2 = NULL;
1108

    
1109
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1110
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1111
                        {
1112
                            free_subpicture(sp);
1113

    
1114
                            /* update queue size and signal for next picture */
1115
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1116
                                is->subpq_rindex = 0;
1117

    
1118
                            SDL_LockMutex(is->subpq_mutex);
1119
                            is->subpq_size--;
1120
                            SDL_CondSignal(is->subpq_cond);
1121
                            SDL_UnlockMutex(is->subpq_mutex);
1122
                        }
1123
                    }
1124
                }
1125
            }
1126

    
1127
            /* display picture */
1128
            video_display(is);
1129

    
1130
            /* update queue size and signal for next picture */
1131
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1132
                is->pictq_rindex = 0;
1133

    
1134
            SDL_LockMutex(is->pictq_mutex);
1135
            is->pictq_size--;
1136
            SDL_CondSignal(is->pictq_cond);
1137
            SDL_UnlockMutex(is->pictq_mutex);
1138
        }
1139
    } else if (is->audio_st) {
1140
        /* draw the next audio frame */
1141

    
1142
        schedule_refresh(is, 40);
1143

    
1144
        /* if only audio stream, then display the audio bars (better
1145
           than nothing, just to test the implementation */
1146

    
1147
        /* display picture */
1148
        video_display(is);
1149
    } else {
1150
        schedule_refresh(is, 100);
1151
    }
1152
    if (show_status) {
1153
        static int64_t last_time;
1154
        int64_t cur_time;
1155
        int aqsize, vqsize, sqsize;
1156
        double av_diff;
1157

    
1158
        cur_time = av_gettime();
1159
        if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1160
            aqsize = 0;
1161
            vqsize = 0;
1162
            sqsize = 0;
1163
            if (is->audio_st)
1164
                aqsize = is->audioq.size;
1165
            if (is->video_st)
1166
                vqsize = is->videoq.size;
1167
            if (is->subtitle_st)
1168
                sqsize = is->subtitleq.size;
1169
            av_diff = 0;
1170
            if (is->audio_st && is->video_st)
1171
                av_diff = get_audio_clock(is) - get_video_clock(is);
1172
            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1173
                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1174
            fflush(stdout);
1175
            last_time = cur_time;
1176
        }
1177
    }
1178
}
1179

    
1180
/* allocate a picture (needs to do that in main thread to avoid
1181
   potential locking problems */
1182
static void alloc_picture(void *opaque)
1183
{
1184
    VideoState *is = opaque;
1185
    VideoPicture *vp;
1186

    
1187
    vp = &is->pictq[is->pictq_windex];
1188

    
1189
    if (vp->bmp)
1190
        SDL_FreeYUVOverlay(vp->bmp);
1191

    
1192
#if 0
1193
    /* XXX: use generic function */
1194
    /* XXX: disable overlay if no hardware acceleration or if RGB format */
1195
    switch(is->video_st->codec->pix_fmt) {
1196
    case PIX_FMT_YUV420P:
1197
    case PIX_FMT_YUV422P:
1198
    case PIX_FMT_YUV444P:
1199
    case PIX_FMT_YUYV422:
1200
    case PIX_FMT_YUV410P:
1201
    case PIX_FMT_YUV411P:
1202
        is_yuv = 1;
1203
        break;
1204
    default:
1205
        is_yuv = 0;
1206
        break;
1207
    }
1208
#endif
1209
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1210
                                   is->video_st->codec->height,
1211
                                   SDL_YV12_OVERLAY,
1212
                                   screen);
1213
    vp->width = is->video_st->codec->width;
1214
    vp->height = is->video_st->codec->height;
1215

    
1216
    SDL_LockMutex(is->pictq_mutex);
1217
    vp->allocated = 1;
1218
    SDL_CondSignal(is->pictq_cond);
1219
    SDL_UnlockMutex(is->pictq_mutex);
1220
}
1221

    
1222
/**
1223
 *
1224
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1225
 */
1226
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1227
{
1228
    VideoPicture *vp;
1229
    int dst_pix_fmt;
1230
    AVPicture pict;
1231
    static struct SwsContext *img_convert_ctx;
1232

    
1233
    /* wait until we have space to put a new picture */
1234
    SDL_LockMutex(is->pictq_mutex);
1235
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1236
           !is->videoq.abort_request) {
1237
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1238
    }
1239
    SDL_UnlockMutex(is->pictq_mutex);
1240

    
1241
    if (is->videoq.abort_request)
1242
        return -1;
1243

    
1244
    vp = &is->pictq[is->pictq_windex];
1245

    
1246
    /* alloc or resize hardware picture buffer */
1247
    if (!vp->bmp ||
1248
        vp->width != is->video_st->codec->width ||
1249
        vp->height != is->video_st->codec->height) {
1250
        SDL_Event event;
1251

    
1252
        vp->allocated = 0;
1253

    
1254
        /* the allocation must be done in the main thread to avoid
1255
           locking problems */
1256
        event.type = FF_ALLOC_EVENT;
1257
        event.user.data1 = is;
1258
        SDL_PushEvent(&event);
1259

    
1260
        /* wait until the picture is allocated */
1261
        SDL_LockMutex(is->pictq_mutex);
1262
        while (!vp->allocated && !is->videoq.abort_request) {
1263
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1264
        }
1265
        SDL_UnlockMutex(is->pictq_mutex);
1266

    
1267
        if (is->videoq.abort_request)
1268
            return -1;
1269
    }
1270

    
1271
    /* if the frame is not skipped, then display it */
1272
    if (vp->bmp) {
1273
        /* get a pointer on the bitmap */
1274
        SDL_LockYUVOverlay (vp->bmp);
1275

    
1276
        dst_pix_fmt = PIX_FMT_YUV420P;
1277
        pict.data[0] = vp->bmp->pixels[0];
1278
        pict.data[1] = vp->bmp->pixels[2];
1279
        pict.data[2] = vp->bmp->pixels[1];
1280

    
1281
        pict.linesize[0] = vp->bmp->pitches[0];
1282
        pict.linesize[1] = vp->bmp->pitches[2];
1283
        pict.linesize[2] = vp->bmp->pitches[1];
1284
        sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1285
        img_convert_ctx = sws_getCachedContext(img_convert_ctx,
1286
            is->video_st->codec->width, is->video_st->codec->height,
1287
            is->video_st->codec->pix_fmt,
1288
            is->video_st->codec->width, is->video_st->codec->height,
1289
            dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1290
        if (img_convert_ctx == NULL) {
1291
            fprintf(stderr, "Cannot initialize the conversion context\n");
1292
            exit(1);
1293
        }
1294
        sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
1295
                  0, is->video_st->codec->height, pict.data, pict.linesize);
1296
        /* update the bitmap content */
1297
        SDL_UnlockYUVOverlay(vp->bmp);
1298

    
1299
        vp->pts = pts;
1300

    
1301
        /* now we can update the picture count */
1302
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1303
            is->pictq_windex = 0;
1304
        SDL_LockMutex(is->pictq_mutex);
1305
        is->pictq_size++;
1306
        SDL_UnlockMutex(is->pictq_mutex);
1307
    }
1308
    return 0;
1309
}
1310

    
1311
/**
1312
 * compute the exact PTS for the picture if it is omitted in the stream
1313
 * @param pts1 the dts of the pkt / pts of the frame
1314
 */
1315
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1316
{
1317
    double frame_delay, pts;
1318

    
1319
    pts = pts1;
1320

    
1321
    if (pts != 0) {
1322
        /* update video clock with pts, if present */
1323
        is->video_clock = pts;
1324
    } else {
1325
        pts = is->video_clock;
1326
    }
1327
    /* update video clock for next frame */
1328
    frame_delay = av_q2d(is->video_st->codec->time_base);
1329
    /* for MPEG2, the frame can be repeated, so we update the
1330
       clock accordingly */
1331
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1332
    is->video_clock += frame_delay;
1333

    
1334
#if defined(DEBUG_SYNC) && 0
1335
    {
1336
        int ftype;
1337
        if (src_frame->pict_type == FF_B_TYPE)
1338
            ftype = 'B';
1339
        else if (src_frame->pict_type == FF_I_TYPE)
1340
            ftype = 'I';
1341
        else
1342
            ftype = 'P';
1343
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1344
               ftype, pts, pts1);
1345
    }
1346
#endif
1347
    return queue_picture(is, src_frame, pts);
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
        is->video_st->codec->reordered_opaque= 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->reordered_opaque != AV_NOPTS_VALUE)
1379
            pts= frame->reordered_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, (uint32_t*)sp->sub.rects[i]->pict.data[1] + 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((uint32_t*)sp->sub.rects[i]->pict.data[1] + 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, double *pts_ptr)
1577
{
1578
    AVPacket *pkt = &is->audio_pkt;
1579
    AVCodecContext *dec= is->audio_st->codec;
1580
    int n, len1, data_size;
1581
    double pts;
1582

    
1583
    for(;;) {
1584
        /* NOTE: the audio packet can contain several frames */
1585
        while (is->audio_pkt_size > 0) {
1586
            data_size = sizeof(is->audio_buf1);
1587
            len1 = avcodec_decode_audio2(dec,
1588
                                        (int16_t *)is->audio_buf1, &data_size,
1589
                                        is->audio_pkt_data, is->audio_pkt_size);
1590
            if (len1 < 0) {
1591
                /* if error, we skip the frame */
1592
                is->audio_pkt_size = 0;
1593
                break;
1594
            }
1595

    
1596
            is->audio_pkt_data += len1;
1597
            is->audio_pkt_size -= len1;
1598
            if (data_size <= 0)
1599
                continue;
1600

    
1601
            if (dec->sample_fmt != is->audio_src_fmt) {
1602
                if (is->reformat_ctx)
1603
                    av_audio_convert_free(is->reformat_ctx);
1604
                is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1605
                                                         dec->sample_fmt, 1, NULL, 0);
1606
                if (!is->reformat_ctx) {
1607
                    fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1608
                        avcodec_get_sample_fmt_name(dec->sample_fmt),
1609
                        avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1610
                        break;
1611
                }
1612
                is->audio_src_fmt= dec->sample_fmt;
1613
            }
1614

    
1615
            if (is->reformat_ctx) {
1616
                const void *ibuf[6]= {is->audio_buf1};
1617
                void *obuf[6]= {is->audio_buf2};
1618
                int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1619
                int ostride[6]= {2};
1620
                int len= data_size/istride[0];
1621
                if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1622
                    printf("av_audio_convert() failed\n");
1623
                    break;
1624
                }
1625
                is->audio_buf= is->audio_buf2;
1626
                /* FIXME: existing code assume that data_size equals framesize*channels*2
1627
                          remove this legacy cruft */
1628
                data_size= len*2;
1629
            }else{
1630
                is->audio_buf= is->audio_buf1;
1631
            }
1632

    
1633
            /* if no pts, then compute it */
1634
            pts = is->audio_clock;
1635
            *pts_ptr = pts;
1636
            n = 2 * dec->channels;
1637
            is->audio_clock += (double)data_size /
1638
                (double)(n * dec->sample_rate);
1639
#if defined(DEBUG_SYNC)
1640
            {
1641
                static double last_clock;
1642
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1643
                       is->audio_clock - last_clock,
1644
                       is->audio_clock, pts);
1645
                last_clock = is->audio_clock;
1646
            }
1647
#endif
1648
            return data_size;
1649
        }
1650

    
1651
        /* free the current packet */
1652
        if (pkt->data)
1653
            av_free_packet(pkt);
1654

    
1655
        if (is->paused || is->audioq.abort_request) {
1656
            return -1;
1657
        }
1658

    
1659
        /* read next packet */
1660
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1661
            return -1;
1662
        if(pkt->data == flush_pkt.data){
1663
            avcodec_flush_buffers(dec);
1664
            continue;
1665
        }
1666

    
1667
        is->audio_pkt_data = pkt->data;
1668
        is->audio_pkt_size = pkt->size;
1669

    
1670
        /* if update the audio clock with the pts */
1671
        if (pkt->pts != AV_NOPTS_VALUE) {
1672
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1673
        }
1674
    }
1675
}
1676

    
1677
/* get the current audio output buffer size, in samples. With SDL, we
1678
   cannot have a precise information */
1679
static int audio_write_get_buf_size(VideoState *is)
1680
{
1681
    return is->audio_buf_size - is->audio_buf_index;
1682
}
1683

    
1684

    
1685
/* prepare a new audio buffer */
1686
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1687
{
1688
    VideoState *is = opaque;
1689
    int audio_size, len1;
1690
    double pts;
1691

    
1692
    audio_callback_time = av_gettime();
1693

    
1694
    while (len > 0) {
1695
        if (is->audio_buf_index >= is->audio_buf_size) {
1696
           audio_size = audio_decode_frame(is, &pts);
1697
           if (audio_size < 0) {
1698
                /* if error, just output silence */
1699
               is->audio_buf = is->audio_buf1;
1700
               is->audio_buf_size = 1024;
1701
               memset(is->audio_buf, 0, is->audio_buf_size);
1702
           } else {
1703
               if (is->show_audio)
1704
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1705
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1706
                                              pts);
1707
               is->audio_buf_size = audio_size;
1708
           }
1709
           is->audio_buf_index = 0;
1710
        }
1711
        len1 = is->audio_buf_size - is->audio_buf_index;
1712
        if (len1 > len)
1713
            len1 = len;
1714
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1715
        len -= len1;
1716
        stream += len1;
1717
        is->audio_buf_index += len1;
1718
    }
1719
}
1720

    
1721
/* open a given stream. Return 0 if OK */
1722
static int stream_component_open(VideoState *is, int stream_index)
1723
{
1724
    AVFormatContext *ic = is->ic;
1725
    AVCodecContext *enc;
1726
    AVCodec *codec;
1727
    SDL_AudioSpec wanted_spec, spec;
1728

    
1729
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1730
        return -1;
1731
    enc = ic->streams[stream_index]->codec;
1732

    
1733
    /* prepare audio output */
1734
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1735
        if (enc->channels > 0) {
1736
            enc->request_channels = FFMIN(2, enc->channels);
1737
        } else {
1738
            enc->request_channels = 2;
1739
        }
1740
    }
1741

    
1742
    codec = avcodec_find_decoder(enc->codec_id);
1743
    enc->debug_mv = debug_mv;
1744
    enc->debug = debug;
1745
    enc->workaround_bugs = workaround_bugs;
1746
    enc->lowres = lowres;
1747
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1748
    enc->idct_algo= idct;
1749
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1750
    enc->skip_frame= skip_frame;
1751
    enc->skip_idct= skip_idct;
1752
    enc->skip_loop_filter= skip_loop_filter;
1753
    enc->error_recognition= error_recognition;
1754
    enc->error_concealment= error_concealment;
1755

    
1756
    set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1757

    
1758
    if (!codec ||
1759
        avcodec_open(enc, codec) < 0)
1760
        return -1;
1761

    
1762
    /* prepare audio output */
1763
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1764
        wanted_spec.freq = enc->sample_rate;
1765
        wanted_spec.format = AUDIO_S16SYS;
1766
        wanted_spec.channels = enc->channels;
1767
        wanted_spec.silence = 0;
1768
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1769
        wanted_spec.callback = sdl_audio_callback;
1770
        wanted_spec.userdata = is;
1771
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1772
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1773
            return -1;
1774
        }
1775
        is->audio_hw_buf_size = spec.size;
1776
        is->audio_src_fmt= SAMPLE_FMT_S16;
1777
    }
1778

    
1779
    if(thread_count>1)
1780
        avcodec_thread_init(enc, thread_count);
1781
    enc->thread_count= thread_count;
1782
    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1783
    switch(enc->codec_type) {
1784
    case CODEC_TYPE_AUDIO:
1785
        is->audio_stream = stream_index;
1786
        is->audio_st = ic->streams[stream_index];
1787
        is->audio_buf_size = 0;
1788
        is->audio_buf_index = 0;
1789

    
1790
        /* init averaging filter */
1791
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1792
        is->audio_diff_avg_count = 0;
1793
        /* since we do not have a precise anough audio fifo fullness,
1794
           we correct audio sync only if larger than this threshold */
1795
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1796

    
1797
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1798
        packet_queue_init(&is->audioq);
1799
        SDL_PauseAudio(0);
1800
        break;
1801
    case CODEC_TYPE_VIDEO:
1802
        is->video_stream = stream_index;
1803
        is->video_st = ic->streams[stream_index];
1804

    
1805
        is->frame_last_delay = 40e-3;
1806
        is->frame_timer = (double)av_gettime() / 1000000.0;
1807
        is->video_current_pts_time = av_gettime();
1808

    
1809
        packet_queue_init(&is->videoq);
1810
        is->video_tid = SDL_CreateThread(video_thread, is);
1811
        break;
1812
    case CODEC_TYPE_SUBTITLE:
1813
        is->subtitle_stream = stream_index;
1814
        is->subtitle_st = ic->streams[stream_index];
1815
        packet_queue_init(&is->subtitleq);
1816

    
1817
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1818
        break;
1819
    default:
1820
        break;
1821
    }
1822
    return 0;
1823
}
1824

    
1825
static void stream_component_close(VideoState *is, int stream_index)
1826
{
1827
    AVFormatContext *ic = is->ic;
1828
    AVCodecContext *enc;
1829

    
1830
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1831
        return;
1832
    enc = ic->streams[stream_index]->codec;
1833

    
1834
    switch(enc->codec_type) {
1835
    case CODEC_TYPE_AUDIO:
1836
        packet_queue_abort(&is->audioq);
1837

    
1838
        SDL_CloseAudio();
1839

    
1840
        packet_queue_end(&is->audioq);
1841
        if (is->reformat_ctx)
1842
            av_audio_convert_free(is->reformat_ctx);
1843
        break;
1844
    case CODEC_TYPE_VIDEO:
1845
        packet_queue_abort(&is->videoq);
1846

    
1847
        /* note: we also signal this mutex to make sure we deblock the
1848
           video thread in all cases */
1849
        SDL_LockMutex(is->pictq_mutex);
1850
        SDL_CondSignal(is->pictq_cond);
1851
        SDL_UnlockMutex(is->pictq_mutex);
1852

    
1853
        SDL_WaitThread(is->video_tid, NULL);
1854

    
1855
        packet_queue_end(&is->videoq);
1856
        break;
1857
    case CODEC_TYPE_SUBTITLE:
1858
        packet_queue_abort(&is->subtitleq);
1859

    
1860
        /* note: we also signal this mutex to make sure we deblock the
1861
           video thread in all cases */
1862
        SDL_LockMutex(is->subpq_mutex);
1863
        is->subtitle_stream_changed = 1;
1864

    
1865
        SDL_CondSignal(is->subpq_cond);
1866
        SDL_UnlockMutex(is->subpq_mutex);
1867

    
1868
        SDL_WaitThread(is->subtitle_tid, NULL);
1869

    
1870
        packet_queue_end(&is->subtitleq);
1871
        break;
1872
    default:
1873
        break;
1874
    }
1875

    
1876
    ic->streams[stream_index]->discard = AVDISCARD_ALL;
1877
    avcodec_close(enc);
1878
    switch(enc->codec_type) {
1879
    case CODEC_TYPE_AUDIO:
1880
        is->audio_st = NULL;
1881
        is->audio_stream = -1;
1882
        break;
1883
    case CODEC_TYPE_VIDEO:
1884
        is->video_st = NULL;
1885
        is->video_stream = -1;
1886
        break;
1887
    case CODEC_TYPE_SUBTITLE:
1888
        is->subtitle_st = NULL;
1889
        is->subtitle_stream = -1;
1890
        break;
1891
    default:
1892
        break;
1893
    }
1894
}
1895

    
1896
static void dump_stream_info(const AVFormatContext *s)
1897
{
1898
    AVMetadataTag *tag = NULL;
1899
    while ((tag=av_metadata_get(s->metadata,"",tag,AV_METADATA_IGNORE_SUFFIX)))
1900
        fprintf(stderr, "%s: %s\n", tag->key, tag->value);
1901
}
1902

    
1903
/* since we have only one decoding thread, we can use a global
1904
   variable instead of a thread local variable */
1905
static VideoState *global_video_state;
1906

    
1907
static int decode_interrupt_cb(void)
1908
{
1909
    return (global_video_state && global_video_state->abort_request);
1910
}
1911

    
1912
/* this thread gets the stream from the disk or the network */
1913
static int decode_thread(void *arg)
1914
{
1915
    VideoState *is = arg;
1916
    AVFormatContext *ic;
1917
    int err, i, ret, video_index, audio_index, subtitle_index;
1918
    AVPacket pkt1, *pkt = &pkt1;
1919
    AVFormatParameters params, *ap = &params;
1920

    
1921
    video_index = -1;
1922
    audio_index = -1;
1923
    subtitle_index = -1;
1924
    is->video_stream = -1;
1925
    is->audio_stream = -1;
1926
    is->subtitle_stream = -1;
1927

    
1928
    global_video_state = is;
1929
    url_set_interrupt_cb(decode_interrupt_cb);
1930

    
1931
    memset(ap, 0, sizeof(*ap));
1932

    
1933
    ap->width = frame_width;
1934
    ap->height= frame_height;
1935
    ap->time_base= (AVRational){1, 25};
1936
    ap->pix_fmt = frame_pix_fmt;
1937

    
1938
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1939
    if (err < 0) {
1940
        print_error(is->filename, err);
1941
        ret = -1;
1942
        goto fail;
1943
    }
1944
    is->ic = ic;
1945

    
1946
    if(genpts)
1947
        ic->flags |= AVFMT_FLAG_GENPTS;
1948

    
1949
    err = av_find_stream_info(ic);
1950
    if (err < 0) {
1951
        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1952
        ret = -1;
1953
        goto fail;
1954
    }
1955
    if(ic->pb)
1956
        ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1957

    
1958
    /* if seeking requested, we execute it */
1959
    if (start_time != AV_NOPTS_VALUE) {
1960
        int64_t timestamp;
1961

    
1962
        timestamp = start_time;
1963
        /* add the stream start time */
1964
        if (ic->start_time != AV_NOPTS_VALUE)
1965
            timestamp += ic->start_time;
1966
        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1967
        if (ret < 0) {
1968
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
1969
                    is->filename, (double)timestamp / AV_TIME_BASE);
1970
        }
1971
    }
1972

    
1973
    for(i = 0; i < ic->nb_streams; i++) {
1974
        AVCodecContext *enc = ic->streams[i]->codec;
1975
        ic->streams[i]->discard = AVDISCARD_ALL;
1976
        switch(enc->codec_type) {
1977
        case CODEC_TYPE_AUDIO:
1978
            if (wanted_audio_stream-- >= 0 && !audio_disable)
1979
                audio_index = i;
1980
            break;
1981
        case CODEC_TYPE_VIDEO:
1982
            if (wanted_video_stream-- >= 0 && !video_disable)
1983
                video_index = i;
1984
            break;
1985
        case CODEC_TYPE_SUBTITLE:
1986
            if (wanted_subtitle_stream-- >= 0 && !video_disable)
1987
                subtitle_index = i;
1988
            break;
1989
        default:
1990
            break;
1991
        }
1992
    }
1993
    if (show_status) {
1994
        dump_format(ic, 0, is->filename, 0);
1995
        dump_stream_info(ic);
1996
    }
1997

    
1998
    /* open the streams */
1999
    if (audio_index >= 0) {
2000
        stream_component_open(is, audio_index);
2001
    }
2002

    
2003
    if (video_index >= 0) {
2004
        stream_component_open(is, video_index);
2005
    } else {
2006
        if (!display_disable)
2007
            is->show_audio = 1;
2008
    }
2009

    
2010
    if (subtitle_index >= 0) {
2011
        stream_component_open(is, subtitle_index);
2012
    }
2013

    
2014
    if (is->video_stream < 0 && is->audio_stream < 0) {
2015
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
2016
        ret = -1;
2017
        goto fail;
2018
    }
2019

    
2020
    for(;;) {
2021
        if (is->abort_request)
2022
            break;
2023
        if (is->paused != is->last_paused) {
2024
            is->last_paused = is->paused;
2025
            if (is->paused)
2026
                av_read_pause(ic);
2027
            else
2028
                av_read_play(ic);
2029
        }
2030
#if CONFIG_RTSP_DEMUXER
2031
        if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2032
            /* wait 10 ms to avoid trying to get another packet */
2033
            /* XXX: horrible */
2034
            SDL_Delay(10);
2035
            continue;
2036
        }
2037
#endif
2038
        if (is->seek_req) {
2039
            int64_t seek_target= is->seek_pos;
2040
            int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2041
            int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2042
//FIXME the +-2 is due to rounding being not done in the correct direction in generation
2043
//      of the seek_pos/seek_rel variables
2044

    
2045
            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2046
            if (ret < 0) {
2047
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2048
            }else{
2049
                if (is->audio_stream >= 0) {
2050
                    packet_queue_flush(&is->audioq);
2051
                    packet_queue_put(&is->audioq, &flush_pkt);
2052
                }
2053
                if (is->subtitle_stream >= 0) {
2054
                    packet_queue_flush(&is->subtitleq);
2055
                    packet_queue_put(&is->subtitleq, &flush_pkt);
2056
                }
2057
                if (is->video_stream >= 0) {
2058
                    packet_queue_flush(&is->videoq);
2059
                    packet_queue_put(&is->videoq, &flush_pkt);
2060
                }
2061
            }
2062
            is->seek_req = 0;
2063
        }
2064

    
2065
        /* if the queue are full, no need to read more */
2066
        if (is->audioq.size > MAX_AUDIOQ_SIZE ||
2067
            is->videoq.size > MAX_VIDEOQ_SIZE ||
2068
            is->subtitleq.size > MAX_SUBTITLEQ_SIZE) {
2069
            /* wait 10 ms */
2070
            SDL_Delay(10);
2071
            continue;
2072
        }
2073
        if(url_feof(ic->pb)) {
2074
            av_init_packet(pkt);
2075
            pkt->data=NULL;
2076
            pkt->size=0;
2077
            pkt->stream_index= is->video_stream;
2078
            packet_queue_put(&is->videoq, pkt);
2079
            continue;
2080
        }
2081
        ret = av_read_frame(ic, pkt);
2082
        if (ret < 0) {
2083
            if (ret != AVERROR_EOF && url_ferror(ic->pb) == 0) {
2084
                SDL_Delay(100); /* wait for user event */
2085
                continue;
2086
            } else
2087
                break;
2088
        }
2089
        if (pkt->stream_index == is->audio_stream) {
2090
            packet_queue_put(&is->audioq, pkt);
2091
        } else if (pkt->stream_index == is->video_stream) {
2092
            packet_queue_put(&is->videoq, pkt);
2093
        } else if (pkt->stream_index == is->subtitle_stream) {
2094
            packet_queue_put(&is->subtitleq, pkt);
2095
        } else {
2096
            av_free_packet(pkt);
2097
        }
2098
    }
2099
    /* wait until the end */
2100
    while (!is->abort_request) {
2101
        SDL_Delay(100);
2102
    }
2103

    
2104
    ret = 0;
2105
 fail:
2106
    /* disable interrupting */
2107
    global_video_state = NULL;
2108

    
2109
    /* close each stream */
2110
    if (is->audio_stream >= 0)
2111
        stream_component_close(is, is->audio_stream);
2112
    if (is->video_stream >= 0)
2113
        stream_component_close(is, is->video_stream);
2114
    if (is->subtitle_stream >= 0)
2115
        stream_component_close(is, is->subtitle_stream);
2116
    if (is->ic) {
2117
        av_close_input_file(is->ic);
2118
        is->ic = NULL; /* safety */
2119
    }
2120
    url_set_interrupt_cb(NULL);
2121

    
2122
    if (ret != 0) {
2123
        SDL_Event event;
2124

    
2125
        event.type = FF_QUIT_EVENT;
2126
        event.user.data1 = is;
2127
        SDL_PushEvent(&event);
2128
    }
2129
    return 0;
2130
}
2131

    
2132
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2133
{
2134
    VideoState *is;
2135

    
2136
    is = av_mallocz(sizeof(VideoState));
2137
    if (!is)
2138
        return NULL;
2139
    av_strlcpy(is->filename, filename, sizeof(is->filename));
2140
    is->iformat = iformat;
2141
    is->ytop = 0;
2142
    is->xleft = 0;
2143

    
2144
    /* start video display */
2145
    is->pictq_mutex = SDL_CreateMutex();
2146
    is->pictq_cond = SDL_CreateCond();
2147

    
2148
    is->subpq_mutex = SDL_CreateMutex();
2149
    is->subpq_cond = SDL_CreateCond();
2150

    
2151
    /* add the refresh timer to draw the picture */
2152
    schedule_refresh(is, 40);
2153

    
2154
    is->av_sync_type = av_sync_type;
2155
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2156
    if (!is->parse_tid) {
2157
        av_free(is);
2158
        return NULL;
2159
    }
2160
    return is;
2161
}
2162

    
2163
static void stream_close(VideoState *is)
2164
{
2165
    VideoPicture *vp;
2166
    int i;
2167
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2168
    is->abort_request = 1;
2169
    SDL_WaitThread(is->parse_tid, NULL);
2170

    
2171
    /* free all pictures */
2172
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2173
        vp = &is->pictq[i];
2174
        if (vp->bmp) {
2175
            SDL_FreeYUVOverlay(vp->bmp);
2176
            vp->bmp = NULL;
2177
        }
2178
    }
2179
    SDL_DestroyMutex(is->pictq_mutex);
2180
    SDL_DestroyCond(is->pictq_cond);
2181
    SDL_DestroyMutex(is->subpq_mutex);
2182
    SDL_DestroyCond(is->subpq_cond);
2183
}
2184

    
2185
static void stream_cycle_channel(VideoState *is, int codec_type)
2186
{
2187
    AVFormatContext *ic = is->ic;
2188
    int start_index, stream_index;
2189
    AVStream *st;
2190

    
2191
    if (codec_type == CODEC_TYPE_VIDEO)
2192
        start_index = is->video_stream;
2193
    else if (codec_type == CODEC_TYPE_AUDIO)
2194
        start_index = is->audio_stream;
2195
    else
2196
        start_index = is->subtitle_stream;
2197
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2198
        return;
2199
    stream_index = start_index;
2200
    for(;;) {
2201
        if (++stream_index >= is->ic->nb_streams)
2202
        {
2203
            if (codec_type == CODEC_TYPE_SUBTITLE)
2204
            {
2205
                stream_index = -1;
2206
                goto the_end;
2207
            } else
2208
                stream_index = 0;
2209
        }
2210
        if (stream_index == start_index)
2211
            return;
2212
        st = ic->streams[stream_index];
2213
        if (st->codec->codec_type == codec_type) {
2214
            /* check that parameters are OK */
2215
            switch(codec_type) {
2216
            case CODEC_TYPE_AUDIO:
2217
                if (st->codec->sample_rate != 0 &&
2218
                    st->codec->channels != 0)
2219
                    goto the_end;
2220
                break;
2221
            case CODEC_TYPE_VIDEO:
2222
            case CODEC_TYPE_SUBTITLE:
2223
                goto the_end;
2224
            default:
2225
                break;
2226
            }
2227
        }
2228
    }
2229
 the_end:
2230
    stream_component_close(is, start_index);
2231
    stream_component_open(is, stream_index);
2232
}
2233

    
2234

    
2235
static void toggle_full_screen(void)
2236
{
2237
    is_full_screen = !is_full_screen;
2238
    if (!fs_screen_width) {
2239
        /* use default SDL method */
2240
//        SDL_WM_ToggleFullScreen(screen);
2241
    }
2242
    video_open(cur_stream);
2243
}
2244

    
2245
static void toggle_pause(void)
2246
{
2247
    if (cur_stream)
2248
        stream_pause(cur_stream);
2249
    step = 0;
2250
}
2251

    
2252
static void step_to_next_frame(void)
2253
{
2254
    if (cur_stream) {
2255
        /* if the stream is paused unpause it, then step */
2256
        if (cur_stream->paused)
2257
            stream_pause(cur_stream);
2258
    }
2259
    step = 1;
2260
}
2261

    
2262
static void do_exit(void)
2263
{
2264
    if (cur_stream) {
2265
        stream_close(cur_stream);
2266
        cur_stream = NULL;
2267
    }
2268
    if (show_status)
2269
        printf("\n");
2270
    SDL_Quit();
2271
    exit(0);
2272
}
2273

    
2274
static void toggle_audio_display(void)
2275
{
2276
    if (cur_stream) {
2277
        cur_stream->show_audio = !cur_stream->show_audio;
2278
    }
2279
}
2280

    
2281
/* handle an event sent by the GUI */
2282
static void event_loop(void)
2283
{
2284
    SDL_Event event;
2285
    double incr, pos, frac;
2286

    
2287
    for(;;) {
2288
        SDL_WaitEvent(&event);
2289
        switch(event.type) {
2290
        case SDL_KEYDOWN:
2291
            switch(event.key.keysym.sym) {
2292
            case SDLK_ESCAPE:
2293
            case SDLK_q:
2294
                do_exit();
2295
                break;
2296
            case SDLK_f:
2297
                toggle_full_screen();
2298
                break;
2299
            case SDLK_p:
2300
            case SDLK_SPACE:
2301
                toggle_pause();
2302
                break;
2303
            case SDLK_s: //S: Step to next frame
2304
                step_to_next_frame();
2305
                break;
2306
            case SDLK_a:
2307
                if (cur_stream)
2308
                    stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2309
                break;
2310
            case SDLK_v:
2311
                if (cur_stream)
2312
                    stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2313
                break;
2314
            case SDLK_t:
2315
                if (cur_stream)
2316
                    stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2317
                break;
2318
            case SDLK_w:
2319
                toggle_audio_display();
2320
                break;
2321
            case SDLK_LEFT:
2322
                incr = -10.0;
2323
                goto do_seek;
2324
            case SDLK_RIGHT:
2325
                incr = 10.0;
2326
                goto do_seek;
2327
            case SDLK_UP:
2328
                incr = 60.0;
2329
                goto do_seek;
2330
            case SDLK_DOWN:
2331
                incr = -60.0;
2332
            do_seek:
2333
                if (cur_stream) {
2334
                    if (seek_by_bytes) {
2335
                        pos = url_ftell(cur_stream->ic->pb);
2336
                        if (cur_stream->ic->bit_rate)
2337
                            incr *= cur_stream->ic->bit_rate / 60.0;
2338
                        else
2339
                            incr *= 180000.0;
2340
                        pos += incr;
2341
                        stream_seek(cur_stream, pos, incr);
2342
                    } else {
2343
                        pos = get_master_clock(cur_stream);
2344
                        pos += incr;
2345
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE));
2346
                    }
2347
                }
2348
                break;
2349
            default:
2350
                break;
2351
            }
2352
            break;
2353
        case SDL_MOUSEBUTTONDOWN:
2354
            if (cur_stream) {
2355
                int ns, hh, mm, ss;
2356
                int tns, thh, tmm, tss;
2357
                tns = cur_stream->ic->duration/1000000LL;
2358
                thh = tns/3600;
2359
                tmm = (tns%3600)/60;
2360
                tss = (tns%60);
2361
                frac = (double)event.button.x/(double)cur_stream->width;
2362
                ns = frac*tns;
2363
                hh = ns/3600;
2364
                mm = (ns%3600)/60;
2365
                ss = (ns%60);
2366
                fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2367
                        hh, mm, ss, thh, tmm, tss);
2368
                stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
2369
            }
2370
            break;
2371
        case SDL_VIDEORESIZE:
2372
            if (cur_stream) {
2373
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2374
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2375
                screen_width = cur_stream->width = event.resize.w;
2376
                screen_height= cur_stream->height= event.resize.h;
2377
            }
2378
            break;
2379
        case SDL_QUIT:
2380
        case FF_QUIT_EVENT:
2381
            do_exit();
2382
            break;
2383
        case FF_ALLOC_EVENT:
2384
            video_open(event.user.data1);
2385
            alloc_picture(event.user.data1);
2386
            break;
2387
        case FF_REFRESH_EVENT:
2388
            video_refresh_timer(event.user.data1);
2389
            break;
2390
        default:
2391
            break;
2392
        }
2393
    }
2394
}
2395

    
2396
static void opt_frame_size(const char *arg)
2397
{
2398
    if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2399
        fprintf(stderr, "Incorrect frame size\n");
2400
        exit(1);
2401
    }
2402
    if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2403
        fprintf(stderr, "Frame size must be a multiple of 2\n");
2404
        exit(1);
2405
    }
2406
}
2407

    
2408
static int opt_width(const char *opt, const char *arg)
2409
{
2410
    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2411
    return 0;
2412
}
2413

    
2414
static int opt_height(const char *opt, const char *arg)
2415
{
2416
    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2417
    return 0;
2418
}
2419

    
2420
static void opt_format(const char *arg)
2421
{
2422
    file_iformat = av_find_input_format(arg);
2423
    if (!file_iformat) {
2424
        fprintf(stderr, "Unknown input format: %s\n", arg);
2425
        exit(1);
2426
    }
2427
}
2428

    
2429
static void opt_frame_pix_fmt(const char *arg)
2430
{
2431
    frame_pix_fmt = avcodec_get_pix_fmt(arg);
2432
}
2433

    
2434
static int opt_sync(const char *opt, const char *arg)
2435
{
2436
    if (!strcmp(arg, "audio"))
2437
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2438
    else if (!strcmp(arg, "video"))
2439
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2440
    else if (!strcmp(arg, "ext"))
2441
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2442
    else {
2443
        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2444
        exit(1);
2445
    }
2446
    return 0;
2447
}
2448

    
2449
static int opt_seek(const char *opt, const char *arg)
2450
{
2451
    start_time = parse_time_or_die(opt, arg, 1);
2452
    return 0;
2453
}
2454

    
2455
static int opt_debug(const char *opt, const char *arg)
2456
{
2457
    av_log_set_level(99);
2458
    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2459
    return 0;
2460
}
2461

    
2462
static int opt_vismv(const char *opt, const char *arg)
2463
{
2464
    debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2465
    return 0;
2466
}
2467

    
2468
static int opt_thread_count(const char *opt, const char *arg)
2469
{
2470
    thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2471
#if !HAVE_THREADS
2472
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2473
#endif
2474
    return 0;
2475
}
2476

    
2477
static const OptionDef options[] = {
2478
    { "h", OPT_EXIT, {(void*)show_help}, "show help" },
2479
    { "version", OPT_EXIT, {(void*)show_version}, "show version" },
2480
    { "L", OPT_EXIT, {(void*)show_license}, "show license" },
2481
    { "formats", OPT_EXIT, {(void*)show_formats}, "show available formats, codecs, protocols, ..." },
2482
    { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2483
    { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2484
    { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2485
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2486
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2487
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2488
    { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2489
    { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2490
    { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2491
    { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2492
    { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2493
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2494
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2495
    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2496
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2497
    { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2498
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2499
    { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2500
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2501
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2502
    { "drp", OPT_BOOL |OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts", ""},
2503
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2504
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2505
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2506
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2507
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2508
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2509
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2510
    { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2511
    { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2512
    { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2513
    { NULL, },
2514
};
2515

    
2516
static void show_help(void)
2517
{
2518
    printf("usage: ffplay [options] input_file\n"
2519
           "Simple media player\n");
2520
    printf("\n");
2521
    show_help_options(options, "Main options:\n",
2522
                      OPT_EXPERT, 0);
2523
    show_help_options(options, "\nAdvanced options:\n",
2524
                      OPT_EXPERT, OPT_EXPERT);
2525
    printf("\nWhile playing:\n"
2526
           "q, ESC              quit\n"
2527
           "f                   toggle full screen\n"
2528
           "p, SPC              pause\n"
2529
           "a                   cycle audio channel\n"
2530
           "v                   cycle video channel\n"
2531
           "t                   cycle subtitle channel\n"
2532
           "w                   show audio waves\n"
2533
           "left/right          seek backward/forward 10 seconds\n"
2534
           "down/up             seek backward/forward 1 minute\n"
2535
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2536
           );
2537
}
2538

    
2539
static void opt_input_file(const char *filename)
2540
{
2541
    if (!strcmp(filename, "-"))
2542
        filename = "pipe:";
2543
    input_filename = filename;
2544
}
2545

    
2546
/* Called from the main */
2547
int main(int argc, char **argv)
2548
{
2549
    int flags, i;
2550

    
2551
    /* register all codecs, demux and protocols */
2552
    avcodec_register_all();
2553
    avdevice_register_all();
2554
    av_register_all();
2555

    
2556
    for(i=0; i<CODEC_TYPE_NB; i++){
2557
        avcodec_opts[i]= avcodec_alloc_context2(i);
2558
    }
2559
    avformat_opts = avformat_alloc_context();
2560
    sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2561

    
2562
    show_banner();
2563

    
2564
    parse_options(argc, argv, options, opt_input_file);
2565

    
2566
    if (!input_filename) {
2567
        fprintf(stderr, "An input file must be specified\n");
2568
        exit(1);
2569
    }
2570

    
2571
    if (display_disable) {
2572
        video_disable = 1;
2573
    }
2574
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2575
#if !defined(__MINGW32__) && !defined(__APPLE__)
2576
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2577
#endif
2578
    if (SDL_Init (flags)) {
2579
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2580
        exit(1);
2581
    }
2582

    
2583
    if (!display_disable) {
2584
#if HAVE_SDL_VIDEO_SIZE
2585
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2586
        fs_screen_width = vi->current_w;
2587
        fs_screen_height = vi->current_h;
2588
#endif
2589
    }
2590

    
2591
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2592
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2593
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2594
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2595

    
2596
    av_init_packet(&flush_pkt);
2597
    flush_pkt.data= "FLUSH";
2598

    
2599
    cur_stream = stream_open(input_filename, file_iformat);
2600

    
2601
    event_loop();
2602

    
2603
    /* never returns */
2604

    
2605
    return 0;
2606
}