Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ acf24b87

History | View | Annotate | Download (80.9 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 "config.h"
23
#include <math.h>
24
#include <limits.h>
25
#include "libavutil/avstring.h"
26
#include "libavutil/pixdesc.h"
27
#include "libavformat/avformat.h"
28
#include "libavdevice/avdevice.h"
29
#include "libswscale/swscale.h"
30
#include "libavcodec/audioconvert.h"
31
#include "libavcodec/colorspace.h"
32
#include "libavcodec/opt.h"
33

    
34
#include "cmdutils.h"
35

    
36
#include <SDL.h>
37
#include <SDL_thread.h>
38

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

    
43
#undef exit
44
#undef printf
45
#undef fprintf
46

    
47
const char program_name[] = "FFplay";
48
const int program_birth_year = 2003;
49

    
50
//#define DEBUG_SYNC
51

    
52
#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
53
#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
54
#define MIN_FRAMES 5
55

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

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

    
65
/* maximum audio speed change to get correct sync */
66
#define SAMPLE_CORRECTION_PERCENT_MAX 10
67

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

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

    
74
static int sws_flags = SWS_BICUBIC;
75

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

    
85
#define VIDEO_PICTURE_QUEUE_SIZE 1
86
#define SUBPICTURE_QUEUE_SIZE 4
87

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

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

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

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

    
123
    int audio_stream;
124

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

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

    
149
    int show_audio; /* if true, display audio samples */
150
    int16_t sample_array[SAMPLE_ARRAY_SIZE];
151
    int sample_array_index;
152
    int last_i_start;
153

    
154
    SDL_Thread *subtitle_tid;
155
    int subtitle_stream;
156
    int subtitle_stream_changed;
157
    AVStream *subtitle_st;
158
    PacketQueue subtitleq;
159
    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
160
    int subpq_size, subpq_rindex, subpq_windex;
161
    SDL_mutex *subpq_mutex;
162
    SDL_cond *subpq_cond;
163

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

    
179
    //    QETimer *video_timer;
180
    char filename[1024];
181
    int width, height, xleft, ytop;
182

    
183
    int64_t faulty_pts;
184
    int64_t faulty_dts;
185
    int64_t last_dts_for_fault_detection;
186
    int64_t last_pts_for_fault_detection;
187

    
188
} VideoState;
189

    
190
static void show_help(void);
191
static int audio_write_get_buf_size(VideoState *is);
192

    
193
/* options specified by the user */
194
static AVInputFormat *file_iformat;
195
static const char *input_filename;
196
static int fs_screen_width;
197
static int fs_screen_height;
198
static int screen_width = 0;
199
static int screen_height = 0;
200
static int frame_width = 0;
201
static int frame_height = 0;
202
static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
203
static int audio_disable;
204
static int video_disable;
205
static int wanted_audio_stream= 0;
206
static int wanted_video_stream= 0;
207
static int wanted_subtitle_stream= -1;
208
static int seek_by_bytes;
209
static int display_disable;
210
static int show_status = 1;
211
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
212
static int64_t start_time = AV_NOPTS_VALUE;
213
static int debug = 0;
214
static int debug_mv = 0;
215
static int step = 0;
216
static int thread_count = 1;
217
static int workaround_bugs = 1;
218
static int fast = 0;
219
static int genpts = 0;
220
static int lowres = 0;
221
static int idct = FF_IDCT_AUTO;
222
static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
223
static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
224
static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
225
static int error_recognition = FF_ER_CAREFUL;
226
static int error_concealment = 3;
227
static int decoder_reorder_pts= -1;
228

    
229
/* current context */
230
static int is_full_screen;
231
static VideoState *cur_stream;
232
static int64_t audio_callback_time;
233

    
234
static AVPacket flush_pkt;
235

    
236
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
237
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
238
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
239

    
240
static SDL_Surface *screen;
241

    
242
static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
243

    
244
/* packet queue handling */
245
static void packet_queue_init(PacketQueue *q)
246
{
247
    memset(q, 0, sizeof(PacketQueue));
248
    q->mutex = SDL_CreateMutex();
249
    q->cond = SDL_CreateCond();
250
    packet_queue_put(q, &flush_pkt);
251
}
252

    
253
static void packet_queue_flush(PacketQueue *q)
254
{
255
    AVPacketList *pkt, *pkt1;
256

    
257
    SDL_LockMutex(q->mutex);
258
    for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
259
        pkt1 = pkt->next;
260
        av_free_packet(&pkt->pkt);
261
        av_freep(&pkt);
262
    }
263
    q->last_pkt = NULL;
264
    q->first_pkt = NULL;
265
    q->nb_packets = 0;
266
    q->size = 0;
267
    SDL_UnlockMutex(q->mutex);
268
}
269

    
270
static void packet_queue_end(PacketQueue *q)
271
{
272
    packet_queue_flush(q);
273
    SDL_DestroyMutex(q->mutex);
274
    SDL_DestroyCond(q->cond);
275
}
276

    
277
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
278
{
279
    AVPacketList *pkt1;
280

    
281
    /* duplicate the packet */
282
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
283
        return -1;
284

    
285
    pkt1 = av_malloc(sizeof(AVPacketList));
286
    if (!pkt1)
287
        return -1;
288
    pkt1->pkt = *pkt;
289
    pkt1->next = NULL;
290

    
291

    
292
    SDL_LockMutex(q->mutex);
293

    
294
    if (!q->last_pkt)
295

    
296
        q->first_pkt = pkt1;
297
    else
298
        q->last_pkt->next = pkt1;
299
    q->last_pkt = pkt1;
300
    q->nb_packets++;
301
    q->size += pkt1->pkt.size + sizeof(*pkt1);
302
    /* XXX: should duplicate packet data in DV case */
303
    SDL_CondSignal(q->cond);
304

    
305
    SDL_UnlockMutex(q->mutex);
306
    return 0;
307
}
308

    
309
static void packet_queue_abort(PacketQueue *q)
310
{
311
    SDL_LockMutex(q->mutex);
312

    
313
    q->abort_request = 1;
314

    
315
    SDL_CondSignal(q->cond);
316

    
317
    SDL_UnlockMutex(q->mutex);
318
}
319

    
320
/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
321
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
322
{
323
    AVPacketList *pkt1;
324
    int ret;
325

    
326
    SDL_LockMutex(q->mutex);
327

    
328
    for(;;) {
329
        if (q->abort_request) {
330
            ret = -1;
331
            break;
332
        }
333

    
334
        pkt1 = q->first_pkt;
335
        if (pkt1) {
336
            q->first_pkt = pkt1->next;
337
            if (!q->first_pkt)
338
                q->last_pkt = NULL;
339
            q->nb_packets--;
340
            q->size -= pkt1->pkt.size + sizeof(*pkt1);
341
            *pkt = pkt1->pkt;
342
            av_free(pkt1);
343
            ret = 1;
344
            break;
345
        } else if (!block) {
346
            ret = 0;
347
            break;
348
        } else {
349
            SDL_CondWait(q->cond, q->mutex);
350
        }
351
    }
352
    SDL_UnlockMutex(q->mutex);
353
    return ret;
354
}
355

    
356
static inline void fill_rectangle(SDL_Surface *screen,
357
                                  int x, int y, int w, int h, int color)
358
{
359
    SDL_Rect rect;
360
    rect.x = x;
361
    rect.y = y;
362
    rect.w = w;
363
    rect.h = h;
364
    SDL_FillRect(screen, &rect, color);
365
}
366

    
367
#if 0
368
/* draw only the border of a rectangle */
369
void fill_border(VideoState *s, int x, int y, int w, int h, int color)
370
{
371
    int w1, w2, h1, h2;
372

373
    /* fill the background */
374
    w1 = x;
375
    if (w1 < 0)
376
        w1 = 0;
377
    w2 = s->width - (x + w);
378
    if (w2 < 0)
379
        w2 = 0;
380
    h1 = y;
381
    if (h1 < 0)
382
        h1 = 0;
383
    h2 = s->height - (y + h);
384
    if (h2 < 0)
385
        h2 = 0;
386
    fill_rectangle(screen,
387
                   s->xleft, s->ytop,
388
                   w1, s->height,
389
                   color);
390
    fill_rectangle(screen,
391
                   s->xleft + s->width - w2, s->ytop,
392
                   w2, s->height,
393
                   color);
394
    fill_rectangle(screen,
395
                   s->xleft + w1, s->ytop,
396
                   s->width - w1 - w2, h1,
397
                   color);
398
    fill_rectangle(screen,
399
                   s->xleft + w1, s->ytop + s->height - h2,
400
                   s->width - w1 - w2, h2,
401
                   color);
402
}
403
#endif
404

    
405
#define ALPHA_BLEND(a, oldp, newp, s)\
406
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
407

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

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

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

    
431

    
432
#define BPP 1
433

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

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

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

    
458
    if (dsty & 1) {
459
        lum += dstx;
460
        cb += skip2;
461
        cr += skip2;
462

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

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

    
510
        if (dstx & 1) {
511
            YUVA_IN(y, u, v, a, p, pal);
512
            u1 = u;
513
            v1 = v;
514
            a1 = a;
515
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
516
            p += wrap3;
517
            lum += wrap;
518
            YUVA_IN(y, u, v, a, p, pal);
519
            u1 += u;
520
            v1 += v;
521
            a1 += a;
522
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
523
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
524
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
525
            cb++;
526
            cr++;
527
            p += -wrap3 + BPP;
528
            lum += -wrap + 1;
529
        }
530
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
531
            YUVA_IN(y, u, v, a, p, pal);
532
            u1 = u;
533
            v1 = v;
534
            a1 = a;
535
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
536

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

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

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

    
557
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
558
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
559

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

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

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

    
634
static void free_subpicture(SubPicture *sp)
635
{
636
    int i;
637

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

    
645
    av_free(sp->sub.rects);
646

    
647
    memset(&sp->sub, 0, sizeof(AVSubtitle));
648
}
649

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

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

    
707
        if (is->subtitle_st)
708
        {
709
            if (is->subpq_size > 0)
710
            {
711
                sp = &is->subpq[is->subpq_rindex];
712

    
713
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
714
                {
715
                    SDL_LockYUVOverlay (vp->bmp);
716

    
717
                    pict.data[0] = vp->bmp->pixels[0];
718
                    pict.data[1] = vp->bmp->pixels[2];
719
                    pict.data[2] = vp->bmp->pixels[1];
720

    
721
                    pict.linesize[0] = vp->bmp->pitches[0];
722
                    pict.linesize[1] = vp->bmp->pitches[2];
723
                    pict.linesize[2] = vp->bmp->pitches[1];
724

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

    
729
                    SDL_UnlockYUVOverlay (vp->bmp);
730
                }
731
            }
732
        }
733

    
734

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

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

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

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

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

    
794
        delay -= s->width / 2;
795
        if (delay < s->width)
796
            delay = s->width;
797

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

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

    
814
        s->last_i_start = i_start;
815
    } else {
816
        i_start = s->last_i_start;
817
    }
818

    
819
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
820
    fill_rectangle(screen,
821
                   s->xleft, s->ytop, s->width, s->height,
822
                   bgcolor);
823

    
824
    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
825

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

    
850
    fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
851

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

    
861
static int video_open(VideoState *is){
862
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
863
    int w,h;
864

    
865
    if(is_full_screen) flags |= SDL_FULLSCREEN;
866
    else               flags |= SDL_RESIZABLE;
867

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

    
893
    is->width = screen->w;
894
    is->height = screen->h;
895

    
896
    return 0;
897
}
898

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

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

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

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

    
943
/* get the current video clock value */
944
static double get_video_clock(VideoState *is)
945
{
946
    if (is->paused) {
947
        return is->video_current_pts;
948
    } else {
949
        return is->video_current_pts_drift + av_gettime() / 1000000.0;
950
    }
951
}
952

    
953
/* get the current external clock value */
954
static double get_external_clock(VideoState *is)
955
{
956
    int64_t ti;
957
    ti = av_gettime();
958
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
959
}
960

    
961
/* get the current master clock value */
962
static double get_master_clock(VideoState *is)
963
{
964
    double val;
965

    
966
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
967
        if (is->video_st)
968
            val = get_video_clock(is);
969
        else
970
            val = get_audio_clock(is);
971
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
972
        if (is->audio_st)
973
            val = get_audio_clock(is);
974
        else
975
            val = get_video_clock(is);
976
    } else {
977
        val = get_external_clock(is);
978
    }
979
    return val;
980
}
981

    
982
/* seek in the stream */
983
static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
984
{
985
    if (!is->seek_req) {
986
        is->seek_pos = pos;
987
        is->seek_rel = rel;
988
        if (seek_by_bytes)
989
            is->seek_flags |= AVSEEK_FLAG_BYTE;
990
        is->seek_req = 1;
991
    }
992
}
993

    
994
/* pause or resume the video */
995
static void stream_pause(VideoState *is)
996
{
997
    if (is->paused) {
998
        is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
999
        if(is->read_pause_return != AVERROR(ENOSYS)){
1000
            is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1001
        }
1002
        is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1003
    }
1004
    is->paused = !is->paused;
1005
}
1006

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

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

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

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

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

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

    
1055
    return actual_delay;
1056
}
1057

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

    
1064
    SubPicture *sp, *sp2;
1065

    
1066
    if (is->video_st) {
1067
        if (is->pictq_size == 0) {
1068
//            fprintf(stderr, "Internal error detected in the SDL timer\n");
1069
        } else {
1070
            /* dequeue the picture */
1071
            vp = &is->pictq[is->pictq_rindex];
1072

    
1073
            /* update current video pts */
1074
            is->video_current_pts = vp->pts;
1075
            is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1076

    
1077
            if(is->subtitle_st) {
1078
                if (is->subtitle_stream_changed) {
1079
                    SDL_LockMutex(is->subpq_mutex);
1080

    
1081
                    while (is->subpq_size) {
1082
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1083

    
1084
                        /* update queue size and signal for next picture */
1085
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1086
                            is->subpq_rindex = 0;
1087

    
1088
                        is->subpq_size--;
1089
                    }
1090
                    is->subtitle_stream_changed = 0;
1091

    
1092
                    SDL_CondSignal(is->subpq_cond);
1093
                    SDL_UnlockMutex(is->subpq_mutex);
1094
                } else {
1095
                    if (is->subpq_size > 0) {
1096
                        sp = &is->subpq[is->subpq_rindex];
1097

    
1098
                        if (is->subpq_size > 1)
1099
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1100
                        else
1101
                            sp2 = NULL;
1102

    
1103
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1104
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1105
                        {
1106
                            free_subpicture(sp);
1107

    
1108
                            /* update queue size and signal for next picture */
1109
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1110
                                is->subpq_rindex = 0;
1111

    
1112
                            SDL_LockMutex(is->subpq_mutex);
1113
                            is->subpq_size--;
1114
                            SDL_CondSignal(is->subpq_cond);
1115
                            SDL_UnlockMutex(is->subpq_mutex);
1116
                        }
1117
                    }
1118
                }
1119
            }
1120

    
1121
            /* display picture */
1122
            video_display(is);
1123

    
1124
            /* update queue size and signal for next picture */
1125
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1126
                is->pictq_rindex = 0;
1127

    
1128
            SDL_LockMutex(is->pictq_mutex);
1129
            vp->timer_id= 0;
1130
            is->pictq_size--;
1131
            SDL_CondSignal(is->pictq_cond);
1132
            SDL_UnlockMutex(is->pictq_mutex);
1133
        }
1134
    } else if (is->audio_st) {
1135
        /* draw the next audio frame */
1136

    
1137
        schedule_refresh(is, 40);
1138

    
1139
        /* if only audio stream, then display the audio bars (better
1140
           than nothing, just to test the implementation */
1141

    
1142
        /* display picture */
1143
        video_display(is);
1144
    } else {
1145
        schedule_refresh(is, 100);
1146
    }
1147
    if (show_status) {
1148
        static int64_t last_time;
1149
        int64_t cur_time;
1150
        int aqsize, vqsize, sqsize;
1151
        double av_diff;
1152

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

    
1175
/* allocate a picture (needs to do that in main thread to avoid
1176
   potential locking problems */
1177
static void alloc_picture(void *opaque)
1178
{
1179
    VideoState *is = opaque;
1180
    VideoPicture *vp;
1181

    
1182
    vp = &is->pictq[is->pictq_windex];
1183

    
1184
    if (vp->bmp)
1185
        SDL_FreeYUVOverlay(vp->bmp);
1186

    
1187
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1188
                                   is->video_st->codec->height,
1189
                                   SDL_YV12_OVERLAY,
1190
                                   screen);
1191
    vp->width = is->video_st->codec->width;
1192
    vp->height = is->video_st->codec->height;
1193

    
1194
    SDL_LockMutex(is->pictq_mutex);
1195
    vp->allocated = 1;
1196
    SDL_CondSignal(is->pictq_cond);
1197
    SDL_UnlockMutex(is->pictq_mutex);
1198
}
1199

    
1200
/**
1201
 *
1202
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1203
 */
1204
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1205
{
1206
    VideoPicture *vp;
1207
    int dst_pix_fmt;
1208

    
1209
    /* wait until we have space to put a new picture */
1210
    SDL_LockMutex(is->pictq_mutex);
1211
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1212
           !is->videoq.abort_request) {
1213
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1214
    }
1215
    SDL_UnlockMutex(is->pictq_mutex);
1216

    
1217
    if (is->videoq.abort_request)
1218
        return -1;
1219

    
1220
    vp = &is->pictq[is->pictq_windex];
1221

    
1222
    /* alloc or resize hardware picture buffer */
1223
    if (!vp->bmp ||
1224
        vp->width != is->video_st->codec->width ||
1225
        vp->height != is->video_st->codec->height) {
1226
        SDL_Event event;
1227

    
1228
        vp->allocated = 0;
1229

    
1230
        /* the allocation must be done in the main thread to avoid
1231
           locking problems */
1232
        event.type = FF_ALLOC_EVENT;
1233
        event.user.data1 = is;
1234
        SDL_PushEvent(&event);
1235

    
1236
        /* wait until the picture is allocated */
1237
        SDL_LockMutex(is->pictq_mutex);
1238
        while (!vp->allocated && !is->videoq.abort_request) {
1239
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1240
        }
1241
        SDL_UnlockMutex(is->pictq_mutex);
1242

    
1243
        if (is->videoq.abort_request)
1244
            return -1;
1245
    }
1246

    
1247
    /* if the frame is not skipped, then display it */
1248
    if (vp->bmp) {
1249
        AVPicture pict;
1250

    
1251
        /* get a pointer on the bitmap */
1252
        SDL_LockYUVOverlay (vp->bmp);
1253

    
1254
        dst_pix_fmt = PIX_FMT_YUV420P;
1255
        memset(&pict,0,sizeof(AVPicture));
1256
        pict.data[0] = vp->bmp->pixels[0];
1257
        pict.data[1] = vp->bmp->pixels[2];
1258
        pict.data[2] = vp->bmp->pixels[1];
1259

    
1260
        pict.linesize[0] = vp->bmp->pitches[0];
1261
        pict.linesize[1] = vp->bmp->pitches[2];
1262
        pict.linesize[2] = vp->bmp->pitches[1];
1263
        sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1264
        is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1265
            is->video_st->codec->width, is->video_st->codec->height,
1266
            is->video_st->codec->pix_fmt,
1267
            is->video_st->codec->width, is->video_st->codec->height,
1268
            dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1269
        if (is->img_convert_ctx == NULL) {
1270
            fprintf(stderr, "Cannot initialize the conversion context\n");
1271
            exit(1);
1272
        }
1273
        sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1274
                  0, is->video_st->codec->height, pict.data, pict.linesize);
1275
        /* update the bitmap content */
1276
        SDL_UnlockYUVOverlay(vp->bmp);
1277

    
1278
        vp->pts = pts;
1279

    
1280
        /* now we can update the picture count */
1281
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1282
            is->pictq_windex = 0;
1283
        SDL_LockMutex(is->pictq_mutex);
1284
        is->pictq_size++;
1285
        //We must schedule in a mutex as we must store the timer id before the timer dies or might end up freeing a alraedy freed id
1286
        vp->timer_id= schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1287
        SDL_UnlockMutex(is->pictq_mutex);
1288
    }
1289
    return 0;
1290
}
1291

    
1292
/**
1293
 * compute the exact PTS for the picture if it is omitted in the stream
1294
 * @param pts1 the dts of the pkt / pts of the frame
1295
 */
1296
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1297
{
1298
    double frame_delay, pts;
1299

    
1300
    pts = pts1;
1301

    
1302
    if (pts != 0) {
1303
        /* update video clock with pts, if present */
1304
        is->video_clock = pts;
1305
    } else {
1306
        pts = is->video_clock;
1307
    }
1308
    /* update video clock for next frame */
1309
    frame_delay = av_q2d(is->video_st->codec->time_base);
1310
    /* for MPEG2, the frame can be repeated, so we update the
1311
       clock accordingly */
1312
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1313
    is->video_clock += frame_delay;
1314

    
1315
#if defined(DEBUG_SYNC) && 0
1316
    {
1317
        int ftype;
1318
        if (src_frame->pict_type == FF_B_TYPE)
1319
            ftype = 'B';
1320
        else if (src_frame->pict_type == FF_I_TYPE)
1321
            ftype = 'I';
1322
        else
1323
            ftype = 'P';
1324
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1325
               ftype, pts, pts1);
1326
    }
1327
#endif
1328
    return queue_picture(is, src_frame, pts);
1329
}
1330

    
1331
static int video_thread(void *arg)
1332
{
1333
    VideoState *is = arg;
1334
    AVPacket pkt1, *pkt = &pkt1;
1335
    int len1, got_picture, i;
1336
    AVFrame *frame= avcodec_alloc_frame();
1337
    double pts;
1338

    
1339
    for(;;) {
1340
        while (is->paused && !is->videoq.abort_request) {
1341
            SDL_Delay(10);
1342
        }
1343
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1344
            break;
1345

    
1346
        if(pkt->data == flush_pkt.data){
1347
            avcodec_flush_buffers(is->video_st->codec);
1348

    
1349
            SDL_LockMutex(is->pictq_mutex);
1350
            //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1351
            for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
1352
                if(is->pictq[i].timer_id){
1353
                    SDL_RemoveTimer(is->pictq[i].timer_id);
1354
                    is->pictq[i].timer_id=0;
1355
                    schedule_refresh(is, 1);
1356
                }
1357
            }
1358
            while (is->pictq_size && !is->videoq.abort_request) {
1359
                SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1360
            }
1361
            SDL_UnlockMutex(is->pictq_mutex);
1362

    
1363
            is->last_dts_for_fault_detection=
1364
            is->last_pts_for_fault_detection= INT64_MIN;
1365
            is->frame_last_pts= AV_NOPTS_VALUE;
1366
            is->frame_last_delay = 40e-3;
1367

    
1368
            continue;
1369
        }
1370

    
1371
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1372
           this packet, if any */
1373
        is->video_st->codec->reordered_opaque= pkt->pts;
1374
        len1 = avcodec_decode_video2(is->video_st->codec,
1375
                                    frame, &got_picture,
1376
                                    pkt);
1377

    
1378
        if(pkt->dts != AV_NOPTS_VALUE){
1379
            is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1380
            is->last_dts_for_fault_detection= pkt->dts;
1381
        }
1382
        if(frame->reordered_opaque != AV_NOPTS_VALUE){
1383
            is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1384
            is->last_pts_for_fault_detection= frame->reordered_opaque;
1385
        }
1386

    
1387
        if(   (   decoder_reorder_pts==1
1388
               || decoder_reorder_pts && is->faulty_pts<is->faulty_dts
1389
               || pkt->dts == AV_NOPTS_VALUE)
1390
           && frame->reordered_opaque != AV_NOPTS_VALUE)
1391
            pts= frame->reordered_opaque;
1392
        else if(pkt->dts != AV_NOPTS_VALUE)
1393
            pts= pkt->dts;
1394
        else
1395
            pts= 0;
1396
        pts *= av_q2d(is->video_st->time_base);
1397

    
1398
//            if (len1 < 0)
1399
//                break;
1400
        if (got_picture) {
1401
            if (output_picture2(is, frame, pts) < 0)
1402
                goto the_end;
1403
        }
1404
        av_free_packet(pkt);
1405
        if (step)
1406
            if (cur_stream)
1407
                stream_pause(cur_stream);
1408
    }
1409
 the_end:
1410
    av_free(frame);
1411
    return 0;
1412
}
1413

    
1414
static int subtitle_thread(void *arg)
1415
{
1416
    VideoState *is = arg;
1417
    SubPicture *sp;
1418
    AVPacket pkt1, *pkt = &pkt1;
1419
    int len1, got_subtitle;
1420
    double pts;
1421
    int i, j;
1422
    int r, g, b, y, u, v, a;
1423

    
1424
    for(;;) {
1425
        while (is->paused && !is->subtitleq.abort_request) {
1426
            SDL_Delay(10);
1427
        }
1428
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1429
            break;
1430

    
1431
        if(pkt->data == flush_pkt.data){
1432
            avcodec_flush_buffers(is->subtitle_st->codec);
1433
            continue;
1434
        }
1435
        SDL_LockMutex(is->subpq_mutex);
1436
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1437
               !is->subtitleq.abort_request) {
1438
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1439
        }
1440
        SDL_UnlockMutex(is->subpq_mutex);
1441

    
1442
        if (is->subtitleq.abort_request)
1443
            goto the_end;
1444

    
1445
        sp = &is->subpq[is->subpq_windex];
1446

    
1447
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1448
           this packet, if any */
1449
        pts = 0;
1450
        if (pkt->pts != AV_NOPTS_VALUE)
1451
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1452

    
1453
        len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1454
                                    &sp->sub, &got_subtitle,
1455
                                    pkt);
1456
//            if (len1 < 0)
1457
//                break;
1458
        if (got_subtitle && sp->sub.format == 0) {
1459
            sp->pts = pts;
1460

    
1461
            for (i = 0; i < sp->sub.num_rects; i++)
1462
            {
1463
                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1464
                {
1465
                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1466
                    y = RGB_TO_Y_CCIR(r, g, b);
1467
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1468
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1469
                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1470
                }
1471
            }
1472

    
1473
            /* now we can update the picture count */
1474
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1475
                is->subpq_windex = 0;
1476
            SDL_LockMutex(is->subpq_mutex);
1477
            is->subpq_size++;
1478
            SDL_UnlockMutex(is->subpq_mutex);
1479
        }
1480
        av_free_packet(pkt);
1481
//        if (step)
1482
//            if (cur_stream)
1483
//                stream_pause(cur_stream);
1484
    }
1485
 the_end:
1486
    return 0;
1487
}
1488

    
1489
/* copy samples for viewing in editor window */
1490
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1491
{
1492
    int size, len, channels;
1493

    
1494
    channels = is->audio_st->codec->channels;
1495

    
1496
    size = samples_size / sizeof(short);
1497
    while (size > 0) {
1498
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1499
        if (len > size)
1500
            len = size;
1501
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1502
        samples += len;
1503
        is->sample_array_index += len;
1504
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1505
            is->sample_array_index = 0;
1506
        size -= len;
1507
    }
1508
}
1509

    
1510
/* return the new audio buffer size (samples can be added or deleted
1511
   to get better sync if video or external master clock) */
1512
static int synchronize_audio(VideoState *is, short *samples,
1513
                             int samples_size1, double pts)
1514
{
1515
    int n, samples_size;
1516
    double ref_clock;
1517

    
1518
    n = 2 * is->audio_st->codec->channels;
1519
    samples_size = samples_size1;
1520

    
1521
    /* if not master, then we try to remove or add samples to correct the clock */
1522
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1523
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1524
        double diff, avg_diff;
1525
        int wanted_size, min_size, max_size, nb_samples;
1526

    
1527
        ref_clock = get_master_clock(is);
1528
        diff = get_audio_clock(is) - ref_clock;
1529

    
1530
        if (diff < AV_NOSYNC_THRESHOLD) {
1531
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1532
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1533
                /* not enough measures to have a correct estimate */
1534
                is->audio_diff_avg_count++;
1535
            } else {
1536
                /* estimate the A-V difference */
1537
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1538

    
1539
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1540
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1541
                    nb_samples = samples_size / n;
1542

    
1543
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1544
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1545
                    if (wanted_size < min_size)
1546
                        wanted_size = min_size;
1547
                    else if (wanted_size > max_size)
1548
                        wanted_size = max_size;
1549

    
1550
                    /* add or remove samples to correction the synchro */
1551
                    if (wanted_size < samples_size) {
1552
                        /* remove samples */
1553
                        samples_size = wanted_size;
1554
                    } else if (wanted_size > samples_size) {
1555
                        uint8_t *samples_end, *q;
1556
                        int nb;
1557

    
1558
                        /* add samples */
1559
                        nb = (samples_size - wanted_size);
1560
                        samples_end = (uint8_t *)samples + samples_size - n;
1561
                        q = samples_end + n;
1562
                        while (nb > 0) {
1563
                            memcpy(q, samples_end, n);
1564
                            q += n;
1565
                            nb -= n;
1566
                        }
1567
                        samples_size = wanted_size;
1568
                    }
1569
                }
1570
#if 0
1571
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1572
                       diff, avg_diff, samples_size - samples_size1,
1573
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
1574
#endif
1575
            }
1576
        } else {
1577
            /* too big difference : may be initial PTS errors, so
1578
               reset A-V filter */
1579
            is->audio_diff_avg_count = 0;
1580
            is->audio_diff_cum = 0;
1581
        }
1582
    }
1583

    
1584
    return samples_size;
1585
}
1586

    
1587
/* decode one audio frame and returns its uncompressed size */
1588
static int audio_decode_frame(VideoState *is, double *pts_ptr)
1589
{
1590
    AVPacket *pkt_temp = &is->audio_pkt_temp;
1591
    AVPacket *pkt = &is->audio_pkt;
1592
    AVCodecContext *dec= is->audio_st->codec;
1593
    int n, len1, data_size;
1594
    double pts;
1595

    
1596
    for(;;) {
1597
        /* NOTE: the audio packet can contain several frames */
1598
        while (pkt_temp->size > 0) {
1599
            data_size = sizeof(is->audio_buf1);
1600
            len1 = avcodec_decode_audio3(dec,
1601
                                        (int16_t *)is->audio_buf1, &data_size,
1602
                                        pkt_temp);
1603
            if (len1 < 0) {
1604
                /* if error, we skip the frame */
1605
                pkt_temp->size = 0;
1606
                break;
1607
            }
1608

    
1609
            pkt_temp->data += len1;
1610
            pkt_temp->size -= len1;
1611
            if (data_size <= 0)
1612
                continue;
1613

    
1614
            if (dec->sample_fmt != is->audio_src_fmt) {
1615
                if (is->reformat_ctx)
1616
                    av_audio_convert_free(is->reformat_ctx);
1617
                is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1618
                                                         dec->sample_fmt, 1, NULL, 0);
1619
                if (!is->reformat_ctx) {
1620
                    fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1621
                        avcodec_get_sample_fmt_name(dec->sample_fmt),
1622
                        avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1623
                        break;
1624
                }
1625
                is->audio_src_fmt= dec->sample_fmt;
1626
            }
1627

    
1628
            if (is->reformat_ctx) {
1629
                const void *ibuf[6]= {is->audio_buf1};
1630
                void *obuf[6]= {is->audio_buf2};
1631
                int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1632
                int ostride[6]= {2};
1633
                int len= data_size/istride[0];
1634
                if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1635
                    printf("av_audio_convert() failed\n");
1636
                    break;
1637
                }
1638
                is->audio_buf= is->audio_buf2;
1639
                /* FIXME: existing code assume that data_size equals framesize*channels*2
1640
                          remove this legacy cruft */
1641
                data_size= len*2;
1642
            }else{
1643
                is->audio_buf= is->audio_buf1;
1644
            }
1645

    
1646
            /* if no pts, then compute it */
1647
            pts = is->audio_clock;
1648
            *pts_ptr = pts;
1649
            n = 2 * dec->channels;
1650
            is->audio_clock += (double)data_size /
1651
                (double)(n * dec->sample_rate);
1652
#if defined(DEBUG_SYNC)
1653
            {
1654
                static double last_clock;
1655
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1656
                       is->audio_clock - last_clock,
1657
                       is->audio_clock, pts);
1658
                last_clock = is->audio_clock;
1659
            }
1660
#endif
1661
            return data_size;
1662
        }
1663

    
1664
        /* free the current packet */
1665
        if (pkt->data)
1666
            av_free_packet(pkt);
1667

    
1668
        if (is->paused || is->audioq.abort_request) {
1669
            return -1;
1670
        }
1671

    
1672
        /* read next packet */
1673
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1674
            return -1;
1675
        if(pkt->data == flush_pkt.data){
1676
            avcodec_flush_buffers(dec);
1677
            continue;
1678
        }
1679

    
1680
        pkt_temp->data = pkt->data;
1681
        pkt_temp->size = pkt->size;
1682

    
1683
        /* if update the audio clock with the pts */
1684
        if (pkt->pts != AV_NOPTS_VALUE) {
1685
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1686
        }
1687
    }
1688
}
1689

    
1690
/* get the current audio output buffer size, in samples. With SDL, we
1691
   cannot have a precise information */
1692
static int audio_write_get_buf_size(VideoState *is)
1693
{
1694
    return is->audio_buf_size - is->audio_buf_index;
1695
}
1696

    
1697

    
1698
/* prepare a new audio buffer */
1699
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1700
{
1701
    VideoState *is = opaque;
1702
    int audio_size, len1;
1703
    double pts;
1704

    
1705
    audio_callback_time = av_gettime();
1706

    
1707
    while (len > 0) {
1708
        if (is->audio_buf_index >= is->audio_buf_size) {
1709
           audio_size = audio_decode_frame(is, &pts);
1710
           if (audio_size < 0) {
1711
                /* if error, just output silence */
1712
               is->audio_buf = is->audio_buf1;
1713
               is->audio_buf_size = 1024;
1714
               memset(is->audio_buf, 0, is->audio_buf_size);
1715
           } else {
1716
               if (is->show_audio)
1717
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1718
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1719
                                              pts);
1720
               is->audio_buf_size = audio_size;
1721
           }
1722
           is->audio_buf_index = 0;
1723
        }
1724
        len1 = is->audio_buf_size - is->audio_buf_index;
1725
        if (len1 > len)
1726
            len1 = len;
1727
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1728
        len -= len1;
1729
        stream += len1;
1730
        is->audio_buf_index += len1;
1731
    }
1732
}
1733

    
1734
/* open a given stream. Return 0 if OK */
1735
static int stream_component_open(VideoState *is, int stream_index)
1736
{
1737
    AVFormatContext *ic = is->ic;
1738
    AVCodecContext *enc;
1739
    AVCodec *codec;
1740
    SDL_AudioSpec wanted_spec, spec;
1741

    
1742
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1743
        return -1;
1744
    enc = ic->streams[stream_index]->codec;
1745

    
1746
    /* prepare audio output */
1747
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1748
        if (enc->channels > 0) {
1749
            enc->request_channels = FFMIN(2, enc->channels);
1750
        } else {
1751
            enc->request_channels = 2;
1752
        }
1753
    }
1754

    
1755
    codec = avcodec_find_decoder(enc->codec_id);
1756
    enc->debug_mv = debug_mv;
1757
    enc->debug = debug;
1758
    enc->workaround_bugs = workaround_bugs;
1759
    enc->lowres = lowres;
1760
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1761
    enc->idct_algo= idct;
1762
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1763
    enc->skip_frame= skip_frame;
1764
    enc->skip_idct= skip_idct;
1765
    enc->skip_loop_filter= skip_loop_filter;
1766
    enc->error_recognition= error_recognition;
1767
    enc->error_concealment= error_concealment;
1768
    avcodec_thread_init(enc, thread_count);
1769

    
1770
    set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1771

    
1772
    if (!codec ||
1773
        avcodec_open(enc, codec) < 0)
1774
        return -1;
1775

    
1776
    /* prepare audio output */
1777
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1778
        wanted_spec.freq = enc->sample_rate;
1779
        wanted_spec.format = AUDIO_S16SYS;
1780
        wanted_spec.channels = enc->channels;
1781
        wanted_spec.silence = 0;
1782
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1783
        wanted_spec.callback = sdl_audio_callback;
1784
        wanted_spec.userdata = is;
1785
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1786
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1787
            return -1;
1788
        }
1789
        is->audio_hw_buf_size = spec.size;
1790
        is->audio_src_fmt= SAMPLE_FMT_S16;
1791
    }
1792

    
1793
    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1794
    switch(enc->codec_type) {
1795
    case CODEC_TYPE_AUDIO:
1796
        is->audio_stream = stream_index;
1797
        is->audio_st = ic->streams[stream_index];
1798
        is->audio_buf_size = 0;
1799
        is->audio_buf_index = 0;
1800

    
1801
        /* init averaging filter */
1802
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1803
        is->audio_diff_avg_count = 0;
1804
        /* since we do not have a precise anough audio fifo fullness,
1805
           we correct audio sync only if larger than this threshold */
1806
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1807

    
1808
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1809
        packet_queue_init(&is->audioq);
1810
        SDL_PauseAudio(0);
1811
        break;
1812
    case CODEC_TYPE_VIDEO:
1813
        is->video_stream = stream_index;
1814
        is->video_st = ic->streams[stream_index];
1815

    
1816
        is->frame_timer = (double)av_gettime() / 1000000.0;
1817
//        is->video_current_pts_time = av_gettime();
1818

    
1819
        packet_queue_init(&is->videoq);
1820
        is->video_tid = SDL_CreateThread(video_thread, is);
1821
        break;
1822
    case CODEC_TYPE_SUBTITLE:
1823
        is->subtitle_stream = stream_index;
1824
        is->subtitle_st = ic->streams[stream_index];
1825
        packet_queue_init(&is->subtitleq);
1826

    
1827
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1828
        break;
1829
    default:
1830
        break;
1831
    }
1832
    return 0;
1833
}
1834

    
1835
static void stream_component_close(VideoState *is, int stream_index)
1836
{
1837
    AVFormatContext *ic = is->ic;
1838
    AVCodecContext *enc;
1839

    
1840
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1841
        return;
1842
    enc = ic->streams[stream_index]->codec;
1843

    
1844
    switch(enc->codec_type) {
1845
    case CODEC_TYPE_AUDIO:
1846
        packet_queue_abort(&is->audioq);
1847

    
1848
        SDL_CloseAudio();
1849

    
1850
        packet_queue_end(&is->audioq);
1851
        if (is->reformat_ctx)
1852
            av_audio_convert_free(is->reformat_ctx);
1853
        break;
1854
    case CODEC_TYPE_VIDEO:
1855
        packet_queue_abort(&is->videoq);
1856

    
1857
        /* note: we also signal this mutex to make sure we deblock the
1858
           video thread in all cases */
1859
        SDL_LockMutex(is->pictq_mutex);
1860
        SDL_CondSignal(is->pictq_cond);
1861
        SDL_UnlockMutex(is->pictq_mutex);
1862

    
1863
        SDL_WaitThread(is->video_tid, NULL);
1864

    
1865
        packet_queue_end(&is->videoq);
1866
        break;
1867
    case CODEC_TYPE_SUBTITLE:
1868
        packet_queue_abort(&is->subtitleq);
1869

    
1870
        /* note: we also signal this mutex to make sure we deblock the
1871
           video thread in all cases */
1872
        SDL_LockMutex(is->subpq_mutex);
1873
        is->subtitle_stream_changed = 1;
1874

    
1875
        SDL_CondSignal(is->subpq_cond);
1876
        SDL_UnlockMutex(is->subpq_mutex);
1877

    
1878
        SDL_WaitThread(is->subtitle_tid, NULL);
1879

    
1880
        packet_queue_end(&is->subtitleq);
1881
        break;
1882
    default:
1883
        break;
1884
    }
1885

    
1886
    ic->streams[stream_index]->discard = AVDISCARD_ALL;
1887
    avcodec_close(enc);
1888
    switch(enc->codec_type) {
1889
    case CODEC_TYPE_AUDIO:
1890
        is->audio_st = NULL;
1891
        is->audio_stream = -1;
1892
        break;
1893
    case CODEC_TYPE_VIDEO:
1894
        is->video_st = NULL;
1895
        is->video_stream = -1;
1896
        break;
1897
    case CODEC_TYPE_SUBTITLE:
1898
        is->subtitle_st = NULL;
1899
        is->subtitle_stream = -1;
1900
        break;
1901
    default:
1902
        break;
1903
    }
1904
}
1905

    
1906
/* since we have only one decoding thread, we can use a global
1907
   variable instead of a thread local variable */
1908
static VideoState *global_video_state;
1909

    
1910
static int decode_interrupt_cb(void)
1911
{
1912
    return (global_video_state && global_video_state->abort_request);
1913
}
1914

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

    
1925
    ic = avformat_alloc_context();
1926

    
1927
    video_index = -1;
1928
    audio_index = -1;
1929
    subtitle_index = -1;
1930
    is->video_stream = -1;
1931
    is->audio_stream = -1;
1932
    is->subtitle_stream = -1;
1933

    
1934
    global_video_state = is;
1935
    url_set_interrupt_cb(decode_interrupt_cb);
1936

    
1937
    memset(ap, 0, sizeof(*ap));
1938

    
1939
    ap->prealloced_context = 1;
1940
    ap->width = frame_width;
1941
    ap->height= frame_height;
1942
    ap->time_base= (AVRational){1, 25};
1943
    ap->pix_fmt = frame_pix_fmt;
1944

    
1945
    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1946

    
1947
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1948
    if (err < 0) {
1949
        print_error(is->filename, err);
1950
        ret = -1;
1951
        goto fail;
1952
    }
1953
    is->ic = ic;
1954

    
1955
    if(genpts)
1956
        ic->flags |= AVFMT_FLAG_GENPTS;
1957

    
1958
    err = av_find_stream_info(ic);
1959
    if (err < 0) {
1960
        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1961
        ret = -1;
1962
        goto fail;
1963
    }
1964
    if(ic->pb)
1965
        ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1966

    
1967
    /* if seeking requested, we execute it */
1968
    if (start_time != AV_NOPTS_VALUE) {
1969
        int64_t timestamp;
1970

    
1971
        timestamp = start_time;
1972
        /* add the stream start time */
1973
        if (ic->start_time != AV_NOPTS_VALUE)
1974
            timestamp += ic->start_time;
1975
        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1976
        if (ret < 0) {
1977
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
1978
                    is->filename, (double)timestamp / AV_TIME_BASE);
1979
        }
1980
    }
1981

    
1982
    for(i = 0; i < ic->nb_streams; i++) {
1983
        AVCodecContext *enc = ic->streams[i]->codec;
1984
        ic->streams[i]->discard = AVDISCARD_ALL;
1985
        switch(enc->codec_type) {
1986
        case CODEC_TYPE_AUDIO:
1987
            if (wanted_audio_stream-- >= 0 && !audio_disable)
1988
                audio_index = i;
1989
            break;
1990
        case CODEC_TYPE_VIDEO:
1991
            if (wanted_video_stream-- >= 0 && !video_disable)
1992
                video_index = i;
1993
            break;
1994
        case CODEC_TYPE_SUBTITLE:
1995
            if (wanted_subtitle_stream-- >= 0 && !video_disable)
1996
                subtitle_index = i;
1997
            break;
1998
        default:
1999
            break;
2000
        }
2001
    }
2002
    if (show_status) {
2003
        dump_format(ic, 0, is->filename, 0);
2004
    }
2005

    
2006
    /* open the streams */
2007
    if (audio_index >= 0) {
2008
        stream_component_open(is, audio_index);
2009
    }
2010

    
2011
    if (video_index >= 0) {
2012
        stream_component_open(is, video_index);
2013
    } else {
2014
        if (!display_disable)
2015
            is->show_audio = 1;
2016
    }
2017

    
2018
    if (subtitle_index >= 0) {
2019
        stream_component_open(is, subtitle_index);
2020
    }
2021

    
2022
    if (is->video_stream < 0 && is->audio_stream < 0) {
2023
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
2024
        ret = -1;
2025
        goto fail;
2026
    }
2027

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

    
2053
            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2054
            if (ret < 0) {
2055
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2056
            }else{
2057
                if (is->audio_stream >= 0) {
2058
                    packet_queue_flush(&is->audioq);
2059
                    packet_queue_put(&is->audioq, &flush_pkt);
2060
                }
2061
                if (is->subtitle_stream >= 0) {
2062
                    packet_queue_flush(&is->subtitleq);
2063
                    packet_queue_put(&is->subtitleq, &flush_pkt);
2064
                }
2065
                if (is->video_stream >= 0) {
2066
                    packet_queue_flush(&is->videoq);
2067
                    packet_queue_put(&is->videoq, &flush_pkt);
2068
                }
2069
            }
2070
            is->seek_req = 0;
2071
            eof= 0;
2072
        }
2073

    
2074
        /* if the queue are full, no need to read more */
2075
        if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2076
            || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2077
                && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2078
                && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2079
            /* wait 10 ms */
2080
            SDL_Delay(10);
2081
            continue;
2082
        }
2083
        if(url_feof(ic->pb) || eof) {
2084
            if(is->video_stream >= 0){
2085
                av_init_packet(pkt);
2086
                pkt->data=NULL;
2087
                pkt->size=0;
2088
                pkt->stream_index= is->video_stream;
2089
                packet_queue_put(&is->videoq, pkt);
2090
            }
2091
            SDL_Delay(10);
2092
            continue;
2093
        }
2094
        ret = av_read_frame(ic, pkt);
2095
        if (ret < 0) {
2096
            if (ret == AVERROR_EOF)
2097
                eof=1;
2098
            if (url_ferror(ic->pb))
2099
                break;
2100
            SDL_Delay(100); /* wait for user event */
2101
            continue;
2102
        }
2103
        if (pkt->stream_index == is->audio_stream) {
2104
            packet_queue_put(&is->audioq, pkt);
2105
        } else if (pkt->stream_index == is->video_stream) {
2106
            packet_queue_put(&is->videoq, pkt);
2107
        } else if (pkt->stream_index == is->subtitle_stream) {
2108
            packet_queue_put(&is->subtitleq, pkt);
2109
        } else {
2110
            av_free_packet(pkt);
2111
        }
2112
    }
2113
    /* wait until the end */
2114
    while (!is->abort_request) {
2115
        SDL_Delay(100);
2116
    }
2117

    
2118
    ret = 0;
2119
 fail:
2120
    /* disable interrupting */
2121
    global_video_state = NULL;
2122

    
2123
    /* close each stream */
2124
    if (is->audio_stream >= 0)
2125
        stream_component_close(is, is->audio_stream);
2126
    if (is->video_stream >= 0)
2127
        stream_component_close(is, is->video_stream);
2128
    if (is->subtitle_stream >= 0)
2129
        stream_component_close(is, is->subtitle_stream);
2130
    if (is->ic) {
2131
        av_close_input_file(is->ic);
2132
        is->ic = NULL; /* safety */
2133
    }
2134
    url_set_interrupt_cb(NULL);
2135

    
2136
    if (ret != 0) {
2137
        SDL_Event event;
2138

    
2139
        event.type = FF_QUIT_EVENT;
2140
        event.user.data1 = is;
2141
        SDL_PushEvent(&event);
2142
    }
2143
    return 0;
2144
}
2145

    
2146
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2147
{
2148
    VideoState *is;
2149

    
2150
    is = av_mallocz(sizeof(VideoState));
2151
    if (!is)
2152
        return NULL;
2153
    av_strlcpy(is->filename, filename, sizeof(is->filename));
2154
    is->iformat = iformat;
2155
    is->ytop = 0;
2156
    is->xleft = 0;
2157

    
2158
    /* start video display */
2159
    is->pictq_mutex = SDL_CreateMutex();
2160
    is->pictq_cond = SDL_CreateCond();
2161

    
2162
    is->subpq_mutex = SDL_CreateMutex();
2163
    is->subpq_cond = SDL_CreateCond();
2164

    
2165
    /* add the refresh timer to draw the picture */
2166
    schedule_refresh(is, 40);
2167

    
2168
    is->av_sync_type = av_sync_type;
2169
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2170
    if (!is->parse_tid) {
2171
        av_free(is);
2172
        return NULL;
2173
    }
2174
    return is;
2175
}
2176

    
2177
static void stream_close(VideoState *is)
2178
{
2179
    VideoPicture *vp;
2180
    int i;
2181
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2182
    is->abort_request = 1;
2183
    SDL_WaitThread(is->parse_tid, NULL);
2184

    
2185
    /* free all pictures */
2186
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2187
        vp = &is->pictq[i];
2188
        if (vp->bmp) {
2189
            SDL_FreeYUVOverlay(vp->bmp);
2190
            vp->bmp = NULL;
2191
        }
2192
    }
2193
    SDL_DestroyMutex(is->pictq_mutex);
2194
    SDL_DestroyCond(is->pictq_cond);
2195
    SDL_DestroyMutex(is->subpq_mutex);
2196
    SDL_DestroyCond(is->subpq_cond);
2197
    if (is->img_convert_ctx)
2198
        sws_freeContext(is->img_convert_ctx);
2199
    av_free(is);
2200
}
2201

    
2202
static void stream_cycle_channel(VideoState *is, int codec_type)
2203
{
2204
    AVFormatContext *ic = is->ic;
2205
    int start_index, stream_index;
2206
    AVStream *st;
2207

    
2208
    if (codec_type == CODEC_TYPE_VIDEO)
2209
        start_index = is->video_stream;
2210
    else if (codec_type == CODEC_TYPE_AUDIO)
2211
        start_index = is->audio_stream;
2212
    else
2213
        start_index = is->subtitle_stream;
2214
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2215
        return;
2216
    stream_index = start_index;
2217
    for(;;) {
2218
        if (++stream_index >= is->ic->nb_streams)
2219
        {
2220
            if (codec_type == CODEC_TYPE_SUBTITLE)
2221
            {
2222
                stream_index = -1;
2223
                goto the_end;
2224
            } else
2225
                stream_index = 0;
2226
        }
2227
        if (stream_index == start_index)
2228
            return;
2229
        st = ic->streams[stream_index];
2230
        if (st->codec->codec_type == codec_type) {
2231
            /* check that parameters are OK */
2232
            switch(codec_type) {
2233
            case CODEC_TYPE_AUDIO:
2234
                if (st->codec->sample_rate != 0 &&
2235
                    st->codec->channels != 0)
2236
                    goto the_end;
2237
                break;
2238
            case CODEC_TYPE_VIDEO:
2239
            case CODEC_TYPE_SUBTITLE:
2240
                goto the_end;
2241
            default:
2242
                break;
2243
            }
2244
        }
2245
    }
2246
 the_end:
2247
    stream_component_close(is, start_index);
2248
    stream_component_open(is, stream_index);
2249
}
2250

    
2251

    
2252
static void toggle_full_screen(void)
2253
{
2254
    is_full_screen = !is_full_screen;
2255
    if (!fs_screen_width) {
2256
        /* use default SDL method */
2257
//        SDL_WM_ToggleFullScreen(screen);
2258
    }
2259
    video_open(cur_stream);
2260
}
2261

    
2262
static void toggle_pause(void)
2263
{
2264
    if (cur_stream)
2265
        stream_pause(cur_stream);
2266
    step = 0;
2267
}
2268

    
2269
static void step_to_next_frame(void)
2270
{
2271
    if (cur_stream) {
2272
        /* if the stream is paused unpause it, then step */
2273
        if (cur_stream->paused)
2274
            stream_pause(cur_stream);
2275
    }
2276
    step = 1;
2277
}
2278

    
2279
static void do_exit(void)
2280
{
2281
    int i;
2282
    if (cur_stream) {
2283
        stream_close(cur_stream);
2284
        cur_stream = NULL;
2285
    }
2286
    for (i = 0; i < CODEC_TYPE_NB; i++)
2287
        av_free(avcodec_opts[i]);
2288
    av_free(avformat_opts);
2289
    av_free(sws_opts);
2290
    if (show_status)
2291
        printf("\n");
2292
    SDL_Quit();
2293
    exit(0);
2294
}
2295

    
2296
static void toggle_audio_display(void)
2297
{
2298
    if (cur_stream) {
2299
        cur_stream->show_audio = !cur_stream->show_audio;
2300
    }
2301
}
2302

    
2303
/* handle an event sent by the GUI */
2304
static void event_loop(void)
2305
{
2306
    SDL_Event event;
2307
    double incr, pos, frac;
2308

    
2309
    for(;;) {
2310
        SDL_WaitEvent(&event);
2311
        switch(event.type) {
2312
        case SDL_KEYDOWN:
2313
            switch(event.key.keysym.sym) {
2314
            case SDLK_ESCAPE:
2315
            case SDLK_q:
2316
                do_exit();
2317
                break;
2318
            case SDLK_f:
2319
                toggle_full_screen();
2320
                break;
2321
            case SDLK_p:
2322
            case SDLK_SPACE:
2323
                toggle_pause();
2324
                break;
2325
            case SDLK_s: //S: Step to next frame
2326
                step_to_next_frame();
2327
                break;
2328
            case SDLK_a:
2329
                if (cur_stream)
2330
                    stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2331
                break;
2332
            case SDLK_v:
2333
                if (cur_stream)
2334
                    stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2335
                break;
2336
            case SDLK_t:
2337
                if (cur_stream)
2338
                    stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2339
                break;
2340
            case SDLK_w:
2341
                toggle_audio_display();
2342
                break;
2343
            case SDLK_LEFT:
2344
                incr = -10.0;
2345
                goto do_seek;
2346
            case SDLK_RIGHT:
2347
                incr = 10.0;
2348
                goto do_seek;
2349
            case SDLK_UP:
2350
                incr = 60.0;
2351
                goto do_seek;
2352
            case SDLK_DOWN:
2353
                incr = -60.0;
2354
            do_seek:
2355
                if (cur_stream) {
2356
                    if (seek_by_bytes) {
2357
                        pos = url_ftell(cur_stream->ic->pb);
2358
                        if (cur_stream->ic->bit_rate)
2359
                            incr *= cur_stream->ic->bit_rate / 60.0;
2360
                        else
2361
                            incr *= 180000.0;
2362
                        pos += incr;
2363
                        stream_seek(cur_stream, pos, incr, 1);
2364
                    } else {
2365
                        pos = get_master_clock(cur_stream);
2366
                        pos += incr;
2367
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2368
                    }
2369
                }
2370
                break;
2371
            default:
2372
                break;
2373
            }
2374
            break;
2375
        case SDL_MOUSEBUTTONDOWN:
2376
            if (cur_stream) {
2377
                if(seek_by_bytes || cur_stream->ic->duration<=0){
2378
                    uint64_t size=  url_fsize(cur_stream->ic->pb);
2379
                    stream_seek(cur_stream, size*(double)event.button.x/(double)cur_stream->width, 0, 1);
2380
                }else{
2381
                    int64_t ts;
2382
                    int ns, hh, mm, ss;
2383
                    int tns, thh, tmm, tss;
2384
                    tns = cur_stream->ic->duration/1000000LL;
2385
                    thh = tns/3600;
2386
                    tmm = (tns%3600)/60;
2387
                    tss = (tns%60);
2388
                    frac = (double)event.button.x/(double)cur_stream->width;
2389
                    ns = frac*tns;
2390
                    hh = ns/3600;
2391
                    mm = (ns%3600)/60;
2392
                    ss = (ns%60);
2393
                    fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2394
                            hh, mm, ss, thh, tmm, tss);
2395
                    ts = frac*cur_stream->ic->duration;
2396
                    if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2397
                        ts += cur_stream->ic->start_time;
2398
                    stream_seek(cur_stream, ts, 0, 0);
2399
                }
2400
            }
2401
            break;
2402
        case SDL_VIDEORESIZE:
2403
            if (cur_stream) {
2404
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2405
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2406
                screen_width = cur_stream->width = event.resize.w;
2407
                screen_height= cur_stream->height= event.resize.h;
2408
            }
2409
            break;
2410
        case SDL_QUIT:
2411
        case FF_QUIT_EVENT:
2412
            do_exit();
2413
            break;
2414
        case FF_ALLOC_EVENT:
2415
            video_open(event.user.data1);
2416
            alloc_picture(event.user.data1);
2417
            break;
2418
        case FF_REFRESH_EVENT:
2419
            video_refresh_timer(event.user.data1);
2420
            break;
2421
        default:
2422
            break;
2423
        }
2424
    }
2425
}
2426

    
2427
static void opt_frame_size(const char *arg)
2428
{
2429
    if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2430
        fprintf(stderr, "Incorrect frame size\n");
2431
        exit(1);
2432
    }
2433
    if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2434
        fprintf(stderr, "Frame size must be a multiple of 2\n");
2435
        exit(1);
2436
    }
2437
}
2438

    
2439
static int opt_width(const char *opt, const char *arg)
2440
{
2441
    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2442
    return 0;
2443
}
2444

    
2445
static int opt_height(const char *opt, const char *arg)
2446
{
2447
    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2448
    return 0;
2449
}
2450

    
2451
static void opt_format(const char *arg)
2452
{
2453
    file_iformat = av_find_input_format(arg);
2454
    if (!file_iformat) {
2455
        fprintf(stderr, "Unknown input format: %s\n", arg);
2456
        exit(1);
2457
    }
2458
}
2459

    
2460
static void opt_frame_pix_fmt(const char *arg)
2461
{
2462
    frame_pix_fmt = av_get_pix_fmt(arg);
2463
}
2464

    
2465
static int opt_sync(const char *opt, const char *arg)
2466
{
2467
    if (!strcmp(arg, "audio"))
2468
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2469
    else if (!strcmp(arg, "video"))
2470
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2471
    else if (!strcmp(arg, "ext"))
2472
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2473
    else {
2474
        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2475
        exit(1);
2476
    }
2477
    return 0;
2478
}
2479

    
2480
static int opt_seek(const char *opt, const char *arg)
2481
{
2482
    start_time = parse_time_or_die(opt, arg, 1);
2483
    return 0;
2484
}
2485

    
2486
static int opt_debug(const char *opt, const char *arg)
2487
{
2488
    av_log_set_level(99);
2489
    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2490
    return 0;
2491
}
2492

    
2493
static int opt_vismv(const char *opt, const char *arg)
2494
{
2495
    debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2496
    return 0;
2497
}
2498

    
2499
static int opt_thread_count(const char *opt, const char *arg)
2500
{
2501
    thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2502
#if !HAVE_THREADS
2503
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2504
#endif
2505
    return 0;
2506
}
2507

    
2508
static const OptionDef options[] = {
2509
#include "cmdutils_common_opts.h"
2510
    { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2511
    { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2512
    { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2513
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2514
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2515
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2516
    { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2517
    { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2518
    { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2519
    { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2520
    { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2521
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2522
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2523
    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2524
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2525
    { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2526
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2527
    { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2528
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2529
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2530
    { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2531
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2532
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2533
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2534
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2535
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2536
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2537
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2538
    { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2539
    { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2540
    { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2541
    { NULL, },
2542
};
2543

    
2544
static void show_usage(void)
2545
{
2546
    printf("Simple media player\n");
2547
    printf("usage: ffplay [options] input_file\n");
2548
    printf("\n");
2549
}
2550

    
2551
static void show_help(void)
2552
{
2553
    show_usage();
2554
    show_help_options(options, "Main options:\n",
2555
                      OPT_EXPERT, 0);
2556
    show_help_options(options, "\nAdvanced options:\n",
2557
                      OPT_EXPERT, OPT_EXPERT);
2558
    printf("\nWhile playing:\n"
2559
           "q, ESC              quit\n"
2560
           "f                   toggle full screen\n"
2561
           "p, SPC              pause\n"
2562
           "a                   cycle audio channel\n"
2563
           "v                   cycle video channel\n"
2564
           "t                   cycle subtitle channel\n"
2565
           "w                   show audio waves\n"
2566
           "left/right          seek backward/forward 10 seconds\n"
2567
           "down/up             seek backward/forward 1 minute\n"
2568
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2569
           );
2570
}
2571

    
2572
static void opt_input_file(const char *filename)
2573
{
2574
    if (!strcmp(filename, "-"))
2575
        filename = "pipe:";
2576
    input_filename = filename;
2577
}
2578

    
2579
/* Called from the main */
2580
int main(int argc, char **argv)
2581
{
2582
    int flags, i;
2583

    
2584
    /* register all codecs, demux and protocols */
2585
    avcodec_register_all();
2586
    avdevice_register_all();
2587
    av_register_all();
2588

    
2589
    for(i=0; i<CODEC_TYPE_NB; i++){
2590
        avcodec_opts[i]= avcodec_alloc_context2(i);
2591
    }
2592
    avformat_opts = avformat_alloc_context();
2593
    sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2594

    
2595
    show_banner();
2596

    
2597
    parse_options(argc, argv, options, opt_input_file);
2598

    
2599
    if (!input_filename) {
2600
        show_usage();
2601
        fprintf(stderr, "An input file must be specified\n");
2602
        fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2603
        exit(1);
2604
    }
2605

    
2606
    if (display_disable) {
2607
        video_disable = 1;
2608
    }
2609
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2610
#if !defined(__MINGW32__) && !defined(__APPLE__)
2611
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2612
#endif
2613
    if (SDL_Init (flags)) {
2614
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2615
        exit(1);
2616
    }
2617

    
2618
    if (!display_disable) {
2619
#if HAVE_SDL_VIDEO_SIZE
2620
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2621
        fs_screen_width = vi->current_w;
2622
        fs_screen_height = vi->current_h;
2623
#endif
2624
    }
2625

    
2626
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2627
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2628
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2629
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2630

    
2631
    av_init_packet(&flush_pkt);
2632
    flush_pkt.data= "FLUSH";
2633

    
2634
    cur_stream = stream_open(input_filename, file_iformat);
2635

    
2636
    event_loop();
2637

    
2638
    /* never returns */
2639

    
2640
    return 0;
2641
}