Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 6c7d3ead

History | View | Annotate | Download (80.8 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
/* packet queue handling */
243
static void packet_queue_init(PacketQueue *q)
244
{
245
    memset(q, 0, sizeof(PacketQueue));
246
    q->mutex = SDL_CreateMutex();
247
    q->cond = SDL_CreateCond();
248
}
249

    
250
static void packet_queue_flush(PacketQueue *q)
251
{
252
    AVPacketList *pkt, *pkt1;
253

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

    
267
static void packet_queue_end(PacketQueue *q)
268
{
269
    packet_queue_flush(q);
270
    SDL_DestroyMutex(q->mutex);
271
    SDL_DestroyCond(q->cond);
272
}
273

    
274
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
275
{
276
    AVPacketList *pkt1;
277

    
278
    /* duplicate the packet */
279
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
280
        return -1;
281

    
282
    pkt1 = av_malloc(sizeof(AVPacketList));
283
    if (!pkt1)
284
        return -1;
285
    pkt1->pkt = *pkt;
286
    pkt1->next = NULL;
287

    
288

    
289
    SDL_LockMutex(q->mutex);
290

    
291
    if (!q->last_pkt)
292

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

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

    
306
static void packet_queue_abort(PacketQueue *q)
307
{
308
    SDL_LockMutex(q->mutex);
309

    
310
    q->abort_request = 1;
311

    
312
    SDL_CondSignal(q->cond);
313

    
314
    SDL_UnlockMutex(q->mutex);
315
}
316

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

    
323
    SDL_LockMutex(q->mutex);
324

    
325
    for(;;) {
326
        if (q->abort_request) {
327
            ret = -1;
328
            break;
329
        }
330

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

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

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

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

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

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

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

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

    
428

    
429
#define BPP 1
430

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

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

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

    
455
    if (dsty & 1) {
456
        lum += dstx;
457
        cb += skip2;
458
        cr += skip2;
459

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

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

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

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

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

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

    
554
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
555
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
556

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

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

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

    
631
static void free_subpicture(SubPicture *sp)
632
{
633
    int i;
634

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

    
642
    av_free(sp->sub.rects);
643

    
644
    memset(&sp->sub, 0, sizeof(AVSubtitle));
645
}
646

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

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

    
704
        if (is->subtitle_st)
705
        {
706
            if (is->subpq_size > 0)
707
            {
708
                sp = &is->subpq[is->subpq_rindex];
709

    
710
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
711
                {
712
                    SDL_LockYUVOverlay (vp->bmp);
713

    
714
                    pict.data[0] = vp->bmp->pixels[0];
715
                    pict.data[1] = vp->bmp->pixels[2];
716
                    pict.data[2] = vp->bmp->pixels[1];
717

    
718
                    pict.linesize[0] = vp->bmp->pitches[0];
719
                    pict.linesize[1] = vp->bmp->pitches[2];
720
                    pict.linesize[2] = vp->bmp->pitches[1];
721

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

    
726
                    SDL_UnlockYUVOverlay (vp->bmp);
727
                }
728
            }
729
        }
730

    
731

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

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

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

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

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

    
791
        delay -= s->width / 2;
792
        if (delay < s->width)
793
            delay = s->width;
794

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

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

    
811
        s->last_i_start = i_start;
812
    } else {
813
        i_start = s->last_i_start;
814
    }
815

    
816
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
817
    fill_rectangle(screen,
818
                   s->xleft, s->ytop, s->width, s->height,
819
                   bgcolor);
820

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

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

    
847
    fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
848

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

    
858
static int video_open(VideoState *is){
859
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
860
    int w,h;
861

    
862
    if(is_full_screen) flags |= SDL_FULLSCREEN;
863
    else               flags |= SDL_RESIZABLE;
864

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

    
890
    is->width = screen->w;
891
    is->height = screen->h;
892

    
893
    return 0;
894
}
895

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

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

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

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

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

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

    
958
/* get the current master clock value */
959
static double get_master_clock(VideoState *is)
960
{
961
    double val;
962

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

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

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

    
1004
static double compute_frame_delay(double frame_current_pts, VideoState *is)
1005
{
1006
    double actual_delay, delay, sync_threshold, ref_clock, diff;
1007

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

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

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

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

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

    
1052
    return actual_delay;
1053
}
1054

    
1055
/* called to display each frame */
1056
static void video_refresh_timer(void *opaque)
1057
{
1058
    VideoState *is = opaque;
1059
    VideoPicture *vp;
1060

    
1061
    SubPicture *sp, *sp2;
1062

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

    
1070
            /* update current video pts */
1071
            is->video_current_pts = vp->pts;
1072
            is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1073

    
1074
            if(is->subtitle_st) {
1075
                if (is->subtitle_stream_changed) {
1076
                    SDL_LockMutex(is->subpq_mutex);
1077

    
1078
                    while (is->subpq_size) {
1079
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1080

    
1081
                        /* update queue size and signal for next picture */
1082
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1083
                            is->subpq_rindex = 0;
1084

    
1085
                        is->subpq_size--;
1086
                    }
1087
                    is->subtitle_stream_changed = 0;
1088

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

    
1095
                        if (is->subpq_size > 1)
1096
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1097
                        else
1098
                            sp2 = NULL;
1099

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

    
1105
                            /* update queue size and signal for next picture */
1106
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1107
                                is->subpq_rindex = 0;
1108

    
1109
                            SDL_LockMutex(is->subpq_mutex);
1110
                            is->subpq_size--;
1111
                            SDL_CondSignal(is->subpq_cond);
1112
                            SDL_UnlockMutex(is->subpq_mutex);
1113
                        }
1114
                    }
1115
                }
1116
            }
1117

    
1118
            /* display picture */
1119
            video_display(is);
1120

    
1121
            /* update queue size and signal for next picture */
1122
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1123
                is->pictq_rindex = 0;
1124

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

    
1134
        schedule_refresh(is, 40);
1135

    
1136
        /* if only audio stream, then display the audio bars (better
1137
           than nothing, just to test the implementation */
1138

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

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

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

    
1179
    vp = &is->pictq[is->pictq_windex];
1180

    
1181
    if (vp->bmp)
1182
        SDL_FreeYUVOverlay(vp->bmp);
1183

    
1184
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1185
                                   is->video_st->codec->height,
1186
                                   SDL_YV12_OVERLAY,
1187
                                   screen);
1188
    vp->width = is->video_st->codec->width;
1189
    vp->height = is->video_st->codec->height;
1190

    
1191
    SDL_LockMutex(is->pictq_mutex);
1192
    vp->allocated = 1;
1193
    SDL_CondSignal(is->pictq_cond);
1194
    SDL_UnlockMutex(is->pictq_mutex);
1195
}
1196

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

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

    
1214
    if (is->videoq.abort_request)
1215
        return -1;
1216

    
1217
    vp = &is->pictq[is->pictq_windex];
1218

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

    
1225
        vp->allocated = 0;
1226

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

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

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

    
1244
    /* if the frame is not skipped, then display it */
1245
    if (vp->bmp) {
1246
        AVPicture pict;
1247

    
1248
        /* get a pointer on the bitmap */
1249
        SDL_LockYUVOverlay (vp->bmp);
1250

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

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

    
1275
        vp->pts = pts;
1276

    
1277
        /* now we can update the picture count */
1278
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1279
            is->pictq_windex = 0;
1280
        SDL_LockMutex(is->pictq_mutex);
1281
        is->pictq_size++;
1282
        //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
1283
        vp->timer_id= schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1284
        SDL_UnlockMutex(is->pictq_mutex);
1285
    }
1286
    return 0;
1287
}
1288

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

    
1297
    pts = pts1;
1298

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

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

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

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

    
1343
        if(pkt->data == flush_pkt.data){
1344
            avcodec_flush_buffers(is->video_st->codec);
1345

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

    
1360
            is->last_dts_for_fault_detection=
1361
            is->last_pts_for_fault_detection= INT64_MIN;
1362
            continue;
1363
        }
1364

    
1365
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1366
           this packet, if any */
1367
        is->video_st->codec->reordered_opaque= pkt->pts;
1368
        len1 = avcodec_decode_video2(is->video_st->codec,
1369
                                    frame, &got_picture,
1370
                                    pkt);
1371

    
1372
        if(pkt->dts != AV_NOPTS_VALUE){
1373
            is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1374
            is->last_dts_for_fault_detection= pkt->dts;
1375
        }
1376
        if(frame->reordered_opaque != AV_NOPTS_VALUE){
1377
            is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1378
            is->last_pts_for_fault_detection= frame->reordered_opaque;
1379
        }
1380

    
1381
        if(   (   decoder_reorder_pts==1
1382
               || decoder_reorder_pts && is->faulty_pts<is->faulty_dts
1383
               || pkt->dts == AV_NOPTS_VALUE)
1384
           && frame->reordered_opaque != AV_NOPTS_VALUE)
1385
            pts= frame->reordered_opaque;
1386
        else if(pkt->dts != AV_NOPTS_VALUE)
1387
            pts= pkt->dts;
1388
        else
1389
            pts= 0;
1390
        pts *= av_q2d(is->video_st->time_base);
1391

    
1392
//            if (len1 < 0)
1393
//                break;
1394
        if (got_picture) {
1395
            if (output_picture2(is, frame, pts) < 0)
1396
                goto the_end;
1397
        }
1398
        av_free_packet(pkt);
1399
        if (step)
1400
            if (cur_stream)
1401
                stream_pause(cur_stream);
1402
    }
1403
 the_end:
1404
    av_free(frame);
1405
    return 0;
1406
}
1407

    
1408
static int subtitle_thread(void *arg)
1409
{
1410
    VideoState *is = arg;
1411
    SubPicture *sp;
1412
    AVPacket pkt1, *pkt = &pkt1;
1413
    int len1, got_subtitle;
1414
    double pts;
1415
    int i, j;
1416
    int r, g, b, y, u, v, a;
1417

    
1418
    for(;;) {
1419
        while (is->paused && !is->subtitleq.abort_request) {
1420
            SDL_Delay(10);
1421
        }
1422
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1423
            break;
1424

    
1425
        if(pkt->data == flush_pkt.data){
1426
            avcodec_flush_buffers(is->subtitle_st->codec);
1427
            continue;
1428
        }
1429
        SDL_LockMutex(is->subpq_mutex);
1430
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1431
               !is->subtitleq.abort_request) {
1432
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1433
        }
1434
        SDL_UnlockMutex(is->subpq_mutex);
1435

    
1436
        if (is->subtitleq.abort_request)
1437
            goto the_end;
1438

    
1439
        sp = &is->subpq[is->subpq_windex];
1440

    
1441
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1442
           this packet, if any */
1443
        pts = 0;
1444
        if (pkt->pts != AV_NOPTS_VALUE)
1445
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1446

    
1447
        len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1448
                                    &sp->sub, &got_subtitle,
1449
                                    pkt);
1450
//            if (len1 < 0)
1451
//                break;
1452
        if (got_subtitle && sp->sub.format == 0) {
1453
            sp->pts = pts;
1454

    
1455
            for (i = 0; i < sp->sub.num_rects; i++)
1456
            {
1457
                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1458
                {
1459
                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1460
                    y = RGB_TO_Y_CCIR(r, g, b);
1461
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1462
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1463
                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1464
                }
1465
            }
1466

    
1467
            /* now we can update the picture count */
1468
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1469
                is->subpq_windex = 0;
1470
            SDL_LockMutex(is->subpq_mutex);
1471
            is->subpq_size++;
1472
            SDL_UnlockMutex(is->subpq_mutex);
1473
        }
1474
        av_free_packet(pkt);
1475
//        if (step)
1476
//            if (cur_stream)
1477
//                stream_pause(cur_stream);
1478
    }
1479
 the_end:
1480
    return 0;
1481
}
1482

    
1483
/* copy samples for viewing in editor window */
1484
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1485
{
1486
    int size, len, channels;
1487

    
1488
    channels = is->audio_st->codec->channels;
1489

    
1490
    size = samples_size / sizeof(short);
1491
    while (size > 0) {
1492
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1493
        if (len > size)
1494
            len = size;
1495
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1496
        samples += len;
1497
        is->sample_array_index += len;
1498
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1499
            is->sample_array_index = 0;
1500
        size -= len;
1501
    }
1502
}
1503

    
1504
/* return the new audio buffer size (samples can be added or deleted
1505
   to get better sync if video or external master clock) */
1506
static int synchronize_audio(VideoState *is, short *samples,
1507
                             int samples_size1, double pts)
1508
{
1509
    int n, samples_size;
1510
    double ref_clock;
1511

    
1512
    n = 2 * is->audio_st->codec->channels;
1513
    samples_size = samples_size1;
1514

    
1515
    /* if not master, then we try to remove or add samples to correct the clock */
1516
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1517
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1518
        double diff, avg_diff;
1519
        int wanted_size, min_size, max_size, nb_samples;
1520

    
1521
        ref_clock = get_master_clock(is);
1522
        diff = get_audio_clock(is) - ref_clock;
1523

    
1524
        if (diff < AV_NOSYNC_THRESHOLD) {
1525
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1526
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1527
                /* not enough measures to have a correct estimate */
1528
                is->audio_diff_avg_count++;
1529
            } else {
1530
                /* estimate the A-V difference */
1531
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1532

    
1533
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1534
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1535
                    nb_samples = samples_size / n;
1536

    
1537
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1538
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1539
                    if (wanted_size < min_size)
1540
                        wanted_size = min_size;
1541
                    else if (wanted_size > max_size)
1542
                        wanted_size = max_size;
1543

    
1544
                    /* add or remove samples to correction the synchro */
1545
                    if (wanted_size < samples_size) {
1546
                        /* remove samples */
1547
                        samples_size = wanted_size;
1548
                    } else if (wanted_size > samples_size) {
1549
                        uint8_t *samples_end, *q;
1550
                        int nb;
1551

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

    
1578
    return samples_size;
1579
}
1580

    
1581
/* decode one audio frame and returns its uncompressed size */
1582
static int audio_decode_frame(VideoState *is, double *pts_ptr)
1583
{
1584
    AVPacket *pkt_temp = &is->audio_pkt_temp;
1585
    AVPacket *pkt = &is->audio_pkt;
1586
    AVCodecContext *dec= is->audio_st->codec;
1587
    int n, len1, data_size;
1588
    double pts;
1589

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

    
1603
            pkt_temp->data += len1;
1604
            pkt_temp->size -= len1;
1605
            if (data_size <= 0)
1606
                continue;
1607

    
1608
            if (dec->sample_fmt != is->audio_src_fmt) {
1609
                if (is->reformat_ctx)
1610
                    av_audio_convert_free(is->reformat_ctx);
1611
                is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1612
                                                         dec->sample_fmt, 1, NULL, 0);
1613
                if (!is->reformat_ctx) {
1614
                    fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1615
                        avcodec_get_sample_fmt_name(dec->sample_fmt),
1616
                        avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1617
                        break;
1618
                }
1619
                is->audio_src_fmt= dec->sample_fmt;
1620
            }
1621

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

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

    
1658
        /* free the current packet */
1659
        if (pkt->data)
1660
            av_free_packet(pkt);
1661

    
1662
        if (is->paused || is->audioq.abort_request) {
1663
            return -1;
1664
        }
1665

    
1666
        /* read next packet */
1667
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1668
            return -1;
1669
        if(pkt->data == flush_pkt.data){
1670
            avcodec_flush_buffers(dec);
1671
            continue;
1672
        }
1673

    
1674
        pkt_temp->data = pkt->data;
1675
        pkt_temp->size = pkt->size;
1676

    
1677
        /* if update the audio clock with the pts */
1678
        if (pkt->pts != AV_NOPTS_VALUE) {
1679
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1680
        }
1681
    }
1682
}
1683

    
1684
/* get the current audio output buffer size, in samples. With SDL, we
1685
   cannot have a precise information */
1686
static int audio_write_get_buf_size(VideoState *is)
1687
{
1688
    return is->audio_buf_size - is->audio_buf_index;
1689
}
1690

    
1691

    
1692
/* prepare a new audio buffer */
1693
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1694
{
1695
    VideoState *is = opaque;
1696
    int audio_size, len1;
1697
    double pts;
1698

    
1699
    audio_callback_time = av_gettime();
1700

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

    
1728
/* open a given stream. Return 0 if OK */
1729
static int stream_component_open(VideoState *is, int stream_index)
1730
{
1731
    AVFormatContext *ic = is->ic;
1732
    AVCodecContext *enc;
1733
    AVCodec *codec;
1734
    SDL_AudioSpec wanted_spec, spec;
1735

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

    
1740
    /* prepare audio output */
1741
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1742
        if (enc->channels > 0) {
1743
            enc->request_channels = FFMIN(2, enc->channels);
1744
        } else {
1745
            enc->request_channels = 2;
1746
        }
1747
    }
1748

    
1749
    codec = avcodec_find_decoder(enc->codec_id);
1750
    enc->debug_mv = debug_mv;
1751
    enc->debug = debug;
1752
    enc->workaround_bugs = workaround_bugs;
1753
    enc->lowres = lowres;
1754
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1755
    enc->idct_algo= idct;
1756
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1757
    enc->skip_frame= skip_frame;
1758
    enc->skip_idct= skip_idct;
1759
    enc->skip_loop_filter= skip_loop_filter;
1760
    enc->error_recognition= error_recognition;
1761
    enc->error_concealment= error_concealment;
1762
    avcodec_thread_init(enc, thread_count);
1763

    
1764
    set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1765

    
1766
    if (!codec ||
1767
        avcodec_open(enc, codec) < 0)
1768
        return -1;
1769

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

    
1787
    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1788
    switch(enc->codec_type) {
1789
    case CODEC_TYPE_AUDIO:
1790
        is->audio_stream = stream_index;
1791
        is->audio_st = ic->streams[stream_index];
1792
        is->audio_buf_size = 0;
1793
        is->audio_buf_index = 0;
1794

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

    
1802
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1803
        packet_queue_init(&is->audioq);
1804
        SDL_PauseAudio(0);
1805
        break;
1806
    case CODEC_TYPE_VIDEO:
1807
        is->video_stream = stream_index;
1808
        is->video_st = ic->streams[stream_index];
1809

    
1810
        is->frame_last_delay = 40e-3;
1811
        is->frame_timer = (double)av_gettime() / 1000000.0;
1812
//        is->video_current_pts_time = av_gettime();
1813

    
1814
        packet_queue_init(&is->videoq);
1815
        is->video_tid = SDL_CreateThread(video_thread, is);
1816
        break;
1817
    case CODEC_TYPE_SUBTITLE:
1818
        is->subtitle_stream = stream_index;
1819
        is->subtitle_st = ic->streams[stream_index];
1820
        packet_queue_init(&is->subtitleq);
1821

    
1822
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1823
        break;
1824
    default:
1825
        break;
1826
    }
1827
    return 0;
1828
}
1829

    
1830
static void stream_component_close(VideoState *is, int stream_index)
1831
{
1832
    AVFormatContext *ic = is->ic;
1833
    AVCodecContext *enc;
1834

    
1835
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1836
        return;
1837
    enc = ic->streams[stream_index]->codec;
1838

    
1839
    switch(enc->codec_type) {
1840
    case CODEC_TYPE_AUDIO:
1841
        packet_queue_abort(&is->audioq);
1842

    
1843
        SDL_CloseAudio();
1844

    
1845
        packet_queue_end(&is->audioq);
1846
        if (is->reformat_ctx)
1847
            av_audio_convert_free(is->reformat_ctx);
1848
        break;
1849
    case CODEC_TYPE_VIDEO:
1850
        packet_queue_abort(&is->videoq);
1851

    
1852
        /* note: we also signal this mutex to make sure we deblock the
1853
           video thread in all cases */
1854
        SDL_LockMutex(is->pictq_mutex);
1855
        SDL_CondSignal(is->pictq_cond);
1856
        SDL_UnlockMutex(is->pictq_mutex);
1857

    
1858
        SDL_WaitThread(is->video_tid, NULL);
1859

    
1860
        packet_queue_end(&is->videoq);
1861
        break;
1862
    case CODEC_TYPE_SUBTITLE:
1863
        packet_queue_abort(&is->subtitleq);
1864

    
1865
        /* note: we also signal this mutex to make sure we deblock the
1866
           video thread in all cases */
1867
        SDL_LockMutex(is->subpq_mutex);
1868
        is->subtitle_stream_changed = 1;
1869

    
1870
        SDL_CondSignal(is->subpq_cond);
1871
        SDL_UnlockMutex(is->subpq_mutex);
1872

    
1873
        SDL_WaitThread(is->subtitle_tid, NULL);
1874

    
1875
        packet_queue_end(&is->subtitleq);
1876
        break;
1877
    default:
1878
        break;
1879
    }
1880

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

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

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

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

    
1920
    ic = avformat_alloc_context();
1921

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

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

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

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

    
1940
    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1941

    
1942
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1943
    if (err < 0) {
1944
        print_error(is->filename, err);
1945
        ret = -1;
1946
        goto fail;
1947
    }
1948
    is->ic = ic;
1949

    
1950
    if(genpts)
1951
        ic->flags |= AVFMT_FLAG_GENPTS;
1952

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

    
1962
    /* if seeking requested, we execute it */
1963
    if (start_time != AV_NOPTS_VALUE) {
1964
        int64_t timestamp;
1965

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

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

    
2001
    /* open the streams */
2002
    if (audio_index >= 0) {
2003
        stream_component_open(is, audio_index);
2004
    }
2005

    
2006
    if (video_index >= 0) {
2007
        stream_component_open(is, video_index);
2008
    } else {
2009
        if (!display_disable)
2010
            is->show_audio = 1;
2011
    }
2012

    
2013
    if (subtitle_index >= 0) {
2014
        stream_component_open(is, subtitle_index);
2015
    }
2016

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

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

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

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

    
2113
    ret = 0;
2114
 fail:
2115
    /* disable interrupting */
2116
    global_video_state = NULL;
2117

    
2118
    /* close each stream */
2119
    if (is->audio_stream >= 0)
2120
        stream_component_close(is, is->audio_stream);
2121
    if (is->video_stream >= 0)
2122
        stream_component_close(is, is->video_stream);
2123
    if (is->subtitle_stream >= 0)
2124
        stream_component_close(is, is->subtitle_stream);
2125
    if (is->ic) {
2126
        av_close_input_file(is->ic);
2127
        is->ic = NULL; /* safety */
2128
    }
2129
    url_set_interrupt_cb(NULL);
2130

    
2131
    if (ret != 0) {
2132
        SDL_Event event;
2133

    
2134
        event.type = FF_QUIT_EVENT;
2135
        event.user.data1 = is;
2136
        SDL_PushEvent(&event);
2137
    }
2138
    return 0;
2139
}
2140

    
2141
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2142
{
2143
    VideoState *is;
2144

    
2145
    is = av_mallocz(sizeof(VideoState));
2146
    if (!is)
2147
        return NULL;
2148
    av_strlcpy(is->filename, filename, sizeof(is->filename));
2149
    is->iformat = iformat;
2150
    is->ytop = 0;
2151
    is->xleft = 0;
2152

    
2153
    /* start video display */
2154
    is->pictq_mutex = SDL_CreateMutex();
2155
    is->pictq_cond = SDL_CreateCond();
2156

    
2157
    is->subpq_mutex = SDL_CreateMutex();
2158
    is->subpq_cond = SDL_CreateCond();
2159

    
2160
    /* add the refresh timer to draw the picture */
2161
    schedule_refresh(is, 40);
2162

    
2163
    is->av_sync_type = av_sync_type;
2164
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2165
    if (!is->parse_tid) {
2166
        av_free(is);
2167
        return NULL;
2168
    }
2169
    return is;
2170
}
2171

    
2172
static void stream_close(VideoState *is)
2173
{
2174
    VideoPicture *vp;
2175
    int i;
2176
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2177
    is->abort_request = 1;
2178
    SDL_WaitThread(is->parse_tid, NULL);
2179

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

    
2197
static void stream_cycle_channel(VideoState *is, int codec_type)
2198
{
2199
    AVFormatContext *ic = is->ic;
2200
    int start_index, stream_index;
2201
    AVStream *st;
2202

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

    
2246

    
2247
static void toggle_full_screen(void)
2248
{
2249
    is_full_screen = !is_full_screen;
2250
    if (!fs_screen_width) {
2251
        /* use default SDL method */
2252
//        SDL_WM_ToggleFullScreen(screen);
2253
    }
2254
    video_open(cur_stream);
2255
}
2256

    
2257
static void toggle_pause(void)
2258
{
2259
    if (cur_stream)
2260
        stream_pause(cur_stream);
2261
    step = 0;
2262
}
2263

    
2264
static void step_to_next_frame(void)
2265
{
2266
    if (cur_stream) {
2267
        /* if the stream is paused unpause it, then step */
2268
        if (cur_stream->paused)
2269
            stream_pause(cur_stream);
2270
    }
2271
    step = 1;
2272
}
2273

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

    
2291
static void toggle_audio_display(void)
2292
{
2293
    if (cur_stream) {
2294
        cur_stream->show_audio = !cur_stream->show_audio;
2295
    }
2296
}
2297

    
2298
/* handle an event sent by the GUI */
2299
static void event_loop(void)
2300
{
2301
    SDL_Event event;
2302
    double incr, pos, frac;
2303

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

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

    
2434
static int opt_width(const char *opt, const char *arg)
2435
{
2436
    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2437
    return 0;
2438
}
2439

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

    
2446
static void opt_format(const char *arg)
2447
{
2448
    file_iformat = av_find_input_format(arg);
2449
    if (!file_iformat) {
2450
        fprintf(stderr, "Unknown input format: %s\n", arg);
2451
        exit(1);
2452
    }
2453
}
2454

    
2455
static void opt_frame_pix_fmt(const char *arg)
2456
{
2457
    frame_pix_fmt = av_get_pix_fmt(arg);
2458
}
2459

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

    
2475
static int opt_seek(const char *opt, const char *arg)
2476
{
2477
    start_time = parse_time_or_die(opt, arg, 1);
2478
    return 0;
2479
}
2480

    
2481
static int opt_debug(const char *opt, const char *arg)
2482
{
2483
    av_log_set_level(99);
2484
    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2485
    return 0;
2486
}
2487

    
2488
static int opt_vismv(const char *opt, const char *arg)
2489
{
2490
    debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2491
    return 0;
2492
}
2493

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

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

    
2539
static void show_usage(void)
2540
{
2541
    printf("Simple media player\n");
2542
    printf("usage: ffplay [options] input_file\n");
2543
    printf("\n");
2544
}
2545

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

    
2567
static void opt_input_file(const char *filename)
2568
{
2569
    if (!strcmp(filename, "-"))
2570
        filename = "pipe:";
2571
    input_filename = filename;
2572
}
2573

    
2574
/* Called from the main */
2575
int main(int argc, char **argv)
2576
{
2577
    int flags, i;
2578

    
2579
    /* register all codecs, demux and protocols */
2580
    avcodec_register_all();
2581
    avdevice_register_all();
2582
    av_register_all();
2583

    
2584
    for(i=0; i<CODEC_TYPE_NB; i++){
2585
        avcodec_opts[i]= avcodec_alloc_context2(i);
2586
    }
2587
    avformat_opts = avformat_alloc_context();
2588
    sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2589

    
2590
    show_banner();
2591

    
2592
    parse_options(argc, argv, options, opt_input_file);
2593

    
2594
    if (!input_filename) {
2595
        show_usage();
2596
        fprintf(stderr, "An input file must be specified\n");
2597
        fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2598
        exit(1);
2599
    }
2600

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

    
2613
    if (!display_disable) {
2614
#if HAVE_SDL_VIDEO_SIZE
2615
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2616
        fs_screen_width = vi->current_w;
2617
        fs_screen_height = vi->current_h;
2618
#endif
2619
    }
2620

    
2621
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2622
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2623
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2624
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2625

    
2626
    av_init_packet(&flush_pkt);
2627
    flush_pkt.data= "FLUSH";
2628

    
2629
    cur_stream = stream_open(input_filename, file_iformat);
2630

    
2631
    event_loop();
2632

    
2633
    /* never returns */
2634

    
2635
    return 0;
2636
}