Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 566cd2cb

History | View | Annotate | Download (81.7 KB)

1
/*
2
 * FFplay : Simple Media Player based on the ffmpeg libraries
3
 * Copyright (c) 2003 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
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
    int64_t pos;                                 ///<byte position in file
91
    SDL_Overlay *bmp;
92
    int width, height; /* source height & width */
93
    int allocated;
94
    SDL_TimerID timer_id;
95
} VideoPicture;
96

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

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

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

    
124
    int audio_stream;
125

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

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

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

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

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

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

    
185
    int64_t faulty_pts;
186
    int64_t faulty_dts;
187
    int64_t last_dts_for_fault_detection;
188
    int64_t last_pts_for_fault_detection;
189

    
190
} VideoState;
191

    
192
static void show_help(void);
193
static int audio_write_get_buf_size(VideoState *is);
194

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

    
231
/* current context */
232
static int is_full_screen;
233
static VideoState *cur_stream;
234
static int64_t audio_callback_time;
235

    
236
static AVPacket flush_pkt;
237

    
238
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
239
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
240
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
241

    
242
static SDL_Surface *screen;
243

    
244
static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
245

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

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

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

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

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

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

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

    
293

    
294
    SDL_LockMutex(q->mutex);
295

    
296
    if (!q->last_pkt)
297

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

    
307
    SDL_UnlockMutex(q->mutex);
308
    return 0;
309
}
310

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

    
315
    q->abort_request = 1;
316

    
317
    SDL_CondSignal(q->cond);
318

    
319
    SDL_UnlockMutex(q->mutex);
320
}
321

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

    
328
    SDL_LockMutex(q->mutex);
329

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

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

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

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

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

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

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

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

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

    
433

    
434
#define BPP 1
435

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
736

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
898
    return 0;
899
}
900

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1057
    return actual_delay;
1058
}
1059

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

    
1066
    SubPicture *sp, *sp2;
1067

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

    
1075
            /* update current video pts */
1076
            is->video_current_pts = vp->pts;
1077
            is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1078
            is->video_current_pos = vp->pos;
1079

    
1080
            if(is->subtitle_st) {
1081
                if (is->subtitle_stream_changed) {
1082
                    SDL_LockMutex(is->subpq_mutex);
1083

    
1084
                    while (is->subpq_size) {
1085
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1086

    
1087
                        /* update queue size and signal for next picture */
1088
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1089
                            is->subpq_rindex = 0;
1090

    
1091
                        is->subpq_size--;
1092
                    }
1093
                    is->subtitle_stream_changed = 0;
1094

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

    
1101
                        if (is->subpq_size > 1)
1102
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1103
                        else
1104
                            sp2 = NULL;
1105

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

    
1111
                            /* update queue size and signal for next picture */
1112
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1113
                                is->subpq_rindex = 0;
1114

    
1115
                            SDL_LockMutex(is->subpq_mutex);
1116
                            is->subpq_size--;
1117
                            SDL_CondSignal(is->subpq_cond);
1118
                            SDL_UnlockMutex(is->subpq_mutex);
1119
                        }
1120
                    }
1121
                }
1122
            }
1123

    
1124
            /* display picture */
1125
            video_display(is);
1126

    
1127
            /* update queue size and signal for next picture */
1128
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1129
                is->pictq_rindex = 0;
1130

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

    
1140
        schedule_refresh(is, 40);
1141

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

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

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

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

    
1185
    vp = &is->pictq[is->pictq_windex];
1186

    
1187
    if (vp->bmp)
1188
        SDL_FreeYUVOverlay(vp->bmp);
1189

    
1190
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1191
                                   is->video_st->codec->height,
1192
                                   SDL_YV12_OVERLAY,
1193
                                   screen);
1194
    vp->width = is->video_st->codec->width;
1195
    vp->height = is->video_st->codec->height;
1196

    
1197
    SDL_LockMutex(is->pictq_mutex);
1198
    vp->allocated = 1;
1199
    SDL_CondSignal(is->pictq_cond);
1200
    SDL_UnlockMutex(is->pictq_mutex);
1201
}
1202

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

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

    
1220
    if (is->videoq.abort_request)
1221
        return -1;
1222

    
1223
    vp = &is->pictq[is->pictq_windex];
1224

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

    
1231
        vp->allocated = 0;
1232

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

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

    
1246
        if (is->videoq.abort_request)
1247
            return -1;
1248
    }
1249

    
1250
    /* if the frame is not skipped, then display it */
1251
    if (vp->bmp) {
1252
        AVPicture pict;
1253

    
1254
        /* get a pointer on the bitmap */
1255
        SDL_LockYUVOverlay (vp->bmp);
1256

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

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

    
1281
        vp->pts = pts;
1282
        vp->pos = pos;
1283

    
1284
        /* now we can update the picture count */
1285
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1286
            is->pictq_windex = 0;
1287
        SDL_LockMutex(is->pictq_mutex);
1288
        is->pictq_size++;
1289
        //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
1290
        vp->timer_id= schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1291
        SDL_UnlockMutex(is->pictq_mutex);
1292
    }
1293
    return 0;
1294
}
1295

    
1296
/**
1297
 * compute the exact PTS for the picture if it is omitted in the stream
1298
 * @param pts1 the dts of the pkt / pts of the frame
1299
 */
1300
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1301
{
1302
    double frame_delay, pts;
1303

    
1304
    pts = pts1;
1305

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

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

    
1335
static int video_thread(void *arg)
1336
{
1337
    VideoState *is = arg;
1338
    AVPacket pkt1, *pkt = &pkt1;
1339
    int len1, got_picture, i;
1340
    AVFrame *frame= avcodec_alloc_frame();
1341
    double pts;
1342

    
1343
    for(;;) {
1344
        while (is->paused && !is->videoq.abort_request) {
1345
            SDL_Delay(10);
1346
        }
1347
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1348
            break;
1349

    
1350
        if(pkt->data == flush_pkt.data){
1351
            avcodec_flush_buffers(is->video_st->codec);
1352

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

    
1368
            is->last_dts_for_fault_detection=
1369
            is->last_pts_for_fault_detection= INT64_MIN;
1370
            is->frame_last_pts= AV_NOPTS_VALUE;
1371
            is->frame_last_delay = 0;
1372

    
1373
            continue;
1374
        }
1375

    
1376
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1377
           this packet, if any */
1378
        is->video_st->codec->reordered_opaque= pkt->pts;
1379
        len1 = avcodec_decode_video2(is->video_st->codec,
1380
                                    frame, &got_picture,
1381
                                    pkt);
1382

    
1383
        if (got_picture) {
1384
            if(pkt->dts != AV_NOPTS_VALUE){
1385
                is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1386
                is->last_dts_for_fault_detection= pkt->dts;
1387
            }
1388
            if(frame->reordered_opaque != AV_NOPTS_VALUE){
1389
                is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1390
                is->last_pts_for_fault_detection= frame->reordered_opaque;
1391
            }
1392
        }
1393

    
1394
        if(   (   decoder_reorder_pts==1
1395
               || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
1396
               || pkt->dts == AV_NOPTS_VALUE)
1397
           && frame->reordered_opaque != AV_NOPTS_VALUE)
1398
            pts= frame->reordered_opaque;
1399
        else if(pkt->dts != AV_NOPTS_VALUE)
1400
            pts= pkt->dts;
1401
        else
1402
            pts= 0;
1403
        pts *= av_q2d(is->video_st->time_base);
1404

    
1405
//            if (len1 < 0)
1406
//                break;
1407
        if (got_picture) {
1408
            if (output_picture2(is, frame, pts, pkt->pos) < 0)
1409
                goto the_end;
1410
        }
1411
        av_free_packet(pkt);
1412
        if (step)
1413
            if (cur_stream)
1414
                stream_pause(cur_stream);
1415
    }
1416
 the_end:
1417
    av_free(frame);
1418
    return 0;
1419
}
1420

    
1421
static int subtitle_thread(void *arg)
1422
{
1423
    VideoState *is = arg;
1424
    SubPicture *sp;
1425
    AVPacket pkt1, *pkt = &pkt1;
1426
    int len1, got_subtitle;
1427
    double pts;
1428
    int i, j;
1429
    int r, g, b, y, u, v, a;
1430

    
1431
    for(;;) {
1432
        while (is->paused && !is->subtitleq.abort_request) {
1433
            SDL_Delay(10);
1434
        }
1435
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1436
            break;
1437

    
1438
        if(pkt->data == flush_pkt.data){
1439
            avcodec_flush_buffers(is->subtitle_st->codec);
1440
            continue;
1441
        }
1442
        SDL_LockMutex(is->subpq_mutex);
1443
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1444
               !is->subtitleq.abort_request) {
1445
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1446
        }
1447
        SDL_UnlockMutex(is->subpq_mutex);
1448

    
1449
        if (is->subtitleq.abort_request)
1450
            goto the_end;
1451

    
1452
        sp = &is->subpq[is->subpq_windex];
1453

    
1454
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1455
           this packet, if any */
1456
        pts = 0;
1457
        if (pkt->pts != AV_NOPTS_VALUE)
1458
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1459

    
1460
        len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1461
                                    &sp->sub, &got_subtitle,
1462
                                    pkt);
1463
//            if (len1 < 0)
1464
//                break;
1465
        if (got_subtitle && sp->sub.format == 0) {
1466
            sp->pts = pts;
1467

    
1468
            for (i = 0; i < sp->sub.num_rects; i++)
1469
            {
1470
                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1471
                {
1472
                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1473
                    y = RGB_TO_Y_CCIR(r, g, b);
1474
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1475
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1476
                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1477
                }
1478
            }
1479

    
1480
            /* now we can update the picture count */
1481
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1482
                is->subpq_windex = 0;
1483
            SDL_LockMutex(is->subpq_mutex);
1484
            is->subpq_size++;
1485
            SDL_UnlockMutex(is->subpq_mutex);
1486
        }
1487
        av_free_packet(pkt);
1488
//        if (step)
1489
//            if (cur_stream)
1490
//                stream_pause(cur_stream);
1491
    }
1492
 the_end:
1493
    return 0;
1494
}
1495

    
1496
/* copy samples for viewing in editor window */
1497
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1498
{
1499
    int size, len, channels;
1500

    
1501
    channels = is->audio_st->codec->channels;
1502

    
1503
    size = samples_size / sizeof(short);
1504
    while (size > 0) {
1505
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1506
        if (len > size)
1507
            len = size;
1508
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1509
        samples += len;
1510
        is->sample_array_index += len;
1511
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1512
            is->sample_array_index = 0;
1513
        size -= len;
1514
    }
1515
}
1516

    
1517
/* return the new audio buffer size (samples can be added or deleted
1518
   to get better sync if video or external master clock) */
1519
static int synchronize_audio(VideoState *is, short *samples,
1520
                             int samples_size1, double pts)
1521
{
1522
    int n, samples_size;
1523
    double ref_clock;
1524

    
1525
    n = 2 * is->audio_st->codec->channels;
1526
    samples_size = samples_size1;
1527

    
1528
    /* if not master, then we try to remove or add samples to correct the clock */
1529
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1530
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1531
        double diff, avg_diff;
1532
        int wanted_size, min_size, max_size, nb_samples;
1533

    
1534
        ref_clock = get_master_clock(is);
1535
        diff = get_audio_clock(is) - ref_clock;
1536

    
1537
        if (diff < AV_NOSYNC_THRESHOLD) {
1538
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1539
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1540
                /* not enough measures to have a correct estimate */
1541
                is->audio_diff_avg_count++;
1542
            } else {
1543
                /* estimate the A-V difference */
1544
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1545

    
1546
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1547
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1548
                    nb_samples = samples_size / n;
1549

    
1550
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1551
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1552
                    if (wanted_size < min_size)
1553
                        wanted_size = min_size;
1554
                    else if (wanted_size > max_size)
1555
                        wanted_size = max_size;
1556

    
1557
                    /* add or remove samples to correction the synchro */
1558
                    if (wanted_size < samples_size) {
1559
                        /* remove samples */
1560
                        samples_size = wanted_size;
1561
                    } else if (wanted_size > samples_size) {
1562
                        uint8_t *samples_end, *q;
1563
                        int nb;
1564

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

    
1591
    return samples_size;
1592
}
1593

    
1594
/* decode one audio frame and returns its uncompressed size */
1595
static int audio_decode_frame(VideoState *is, double *pts_ptr)
1596
{
1597
    AVPacket *pkt_temp = &is->audio_pkt_temp;
1598
    AVPacket *pkt = &is->audio_pkt;
1599
    AVCodecContext *dec= is->audio_st->codec;
1600
    int n, len1, data_size;
1601
    double pts;
1602

    
1603
    for(;;) {
1604
        /* NOTE: the audio packet can contain several frames */
1605
        while (pkt_temp->size > 0) {
1606
            data_size = sizeof(is->audio_buf1);
1607
            len1 = avcodec_decode_audio3(dec,
1608
                                        (int16_t *)is->audio_buf1, &data_size,
1609
                                        pkt_temp);
1610
            if (len1 < 0) {
1611
                /* if error, we skip the frame */
1612
                pkt_temp->size = 0;
1613
                break;
1614
            }
1615

    
1616
            pkt_temp->data += len1;
1617
            pkt_temp->size -= len1;
1618
            if (data_size <= 0)
1619
                continue;
1620

    
1621
            if (dec->sample_fmt != is->audio_src_fmt) {
1622
                if (is->reformat_ctx)
1623
                    av_audio_convert_free(is->reformat_ctx);
1624
                is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1625
                                                         dec->sample_fmt, 1, NULL, 0);
1626
                if (!is->reformat_ctx) {
1627
                    fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1628
                        avcodec_get_sample_fmt_name(dec->sample_fmt),
1629
                        avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1630
                        break;
1631
                }
1632
                is->audio_src_fmt= dec->sample_fmt;
1633
            }
1634

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

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

    
1671
        /* free the current packet */
1672
        if (pkt->data)
1673
            av_free_packet(pkt);
1674

    
1675
        if (is->paused || is->audioq.abort_request) {
1676
            return -1;
1677
        }
1678

    
1679
        /* read next packet */
1680
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1681
            return -1;
1682
        if(pkt->data == flush_pkt.data){
1683
            avcodec_flush_buffers(dec);
1684
            continue;
1685
        }
1686

    
1687
        pkt_temp->data = pkt->data;
1688
        pkt_temp->size = pkt->size;
1689

    
1690
        /* if update the audio clock with the pts */
1691
        if (pkt->pts != AV_NOPTS_VALUE) {
1692
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1693
        }
1694
    }
1695
}
1696

    
1697
/* get the current audio output buffer size, in samples. With SDL, we
1698
   cannot have a precise information */
1699
static int audio_write_get_buf_size(VideoState *is)
1700
{
1701
    return is->audio_buf_size - is->audio_buf_index;
1702
}
1703

    
1704

    
1705
/* prepare a new audio buffer */
1706
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1707
{
1708
    VideoState *is = opaque;
1709
    int audio_size, len1;
1710
    double pts;
1711

    
1712
    audio_callback_time = av_gettime();
1713

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

    
1741
/* open a given stream. Return 0 if OK */
1742
static int stream_component_open(VideoState *is, int stream_index)
1743
{
1744
    AVFormatContext *ic = is->ic;
1745
    AVCodecContext *enc;
1746
    AVCodec *codec;
1747
    SDL_AudioSpec wanted_spec, spec;
1748

    
1749
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1750
        return -1;
1751
    enc = ic->streams[stream_index]->codec;
1752

    
1753
    /* prepare audio output */
1754
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1755
        if (enc->channels > 0) {
1756
            enc->request_channels = FFMIN(2, enc->channels);
1757
        } else {
1758
            enc->request_channels = 2;
1759
        }
1760
    }
1761

    
1762
    codec = avcodec_find_decoder(enc->codec_id);
1763
    enc->debug_mv = debug_mv;
1764
    enc->debug = debug;
1765
    enc->workaround_bugs = workaround_bugs;
1766
    enc->lowres = lowres;
1767
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1768
    enc->idct_algo= idct;
1769
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1770
    enc->skip_frame= skip_frame;
1771
    enc->skip_idct= skip_idct;
1772
    enc->skip_loop_filter= skip_loop_filter;
1773
    enc->error_recognition= error_recognition;
1774
    enc->error_concealment= error_concealment;
1775
    avcodec_thread_init(enc, thread_count);
1776

    
1777
    set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1778

    
1779
    if (!codec ||
1780
        avcodec_open(enc, codec) < 0)
1781
        return -1;
1782

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

    
1800
    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1801
    switch(enc->codec_type) {
1802
    case CODEC_TYPE_AUDIO:
1803
        is->audio_stream = stream_index;
1804
        is->audio_st = ic->streams[stream_index];
1805
        is->audio_buf_size = 0;
1806
        is->audio_buf_index = 0;
1807

    
1808
        /* init averaging filter */
1809
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1810
        is->audio_diff_avg_count = 0;
1811
        /* since we do not have a precise anough audio fifo fullness,
1812
           we correct audio sync only if larger than this threshold */
1813
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1814

    
1815
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1816
        packet_queue_init(&is->audioq);
1817
        SDL_PauseAudio(0);
1818
        break;
1819
    case CODEC_TYPE_VIDEO:
1820
        is->video_stream = stream_index;
1821
        is->video_st = ic->streams[stream_index];
1822

    
1823
        is->frame_timer = (double)av_gettime() / 1000000.0;
1824
//        is->video_current_pts_time = av_gettime();
1825

    
1826
        packet_queue_init(&is->videoq);
1827
        is->video_tid = SDL_CreateThread(video_thread, is);
1828
        break;
1829
    case CODEC_TYPE_SUBTITLE:
1830
        is->subtitle_stream = stream_index;
1831
        is->subtitle_st = ic->streams[stream_index];
1832
        packet_queue_init(&is->subtitleq);
1833

    
1834
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1835
        break;
1836
    default:
1837
        break;
1838
    }
1839
    return 0;
1840
}
1841

    
1842
static void stream_component_close(VideoState *is, int stream_index)
1843
{
1844
    AVFormatContext *ic = is->ic;
1845
    AVCodecContext *enc;
1846

    
1847
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1848
        return;
1849
    enc = ic->streams[stream_index]->codec;
1850

    
1851
    switch(enc->codec_type) {
1852
    case CODEC_TYPE_AUDIO:
1853
        packet_queue_abort(&is->audioq);
1854

    
1855
        SDL_CloseAudio();
1856

    
1857
        packet_queue_end(&is->audioq);
1858
        if (is->reformat_ctx)
1859
            av_audio_convert_free(is->reformat_ctx);
1860
        break;
1861
    case CODEC_TYPE_VIDEO:
1862
        packet_queue_abort(&is->videoq);
1863

    
1864
        /* note: we also signal this mutex to make sure we deblock the
1865
           video thread in all cases */
1866
        SDL_LockMutex(is->pictq_mutex);
1867
        SDL_CondSignal(is->pictq_cond);
1868
        SDL_UnlockMutex(is->pictq_mutex);
1869

    
1870
        SDL_WaitThread(is->video_tid, NULL);
1871

    
1872
        packet_queue_end(&is->videoq);
1873
        break;
1874
    case CODEC_TYPE_SUBTITLE:
1875
        packet_queue_abort(&is->subtitleq);
1876

    
1877
        /* note: we also signal this mutex to make sure we deblock the
1878
           video thread in all cases */
1879
        SDL_LockMutex(is->subpq_mutex);
1880
        is->subtitle_stream_changed = 1;
1881

    
1882
        SDL_CondSignal(is->subpq_cond);
1883
        SDL_UnlockMutex(is->subpq_mutex);
1884

    
1885
        SDL_WaitThread(is->subtitle_tid, NULL);
1886

    
1887
        packet_queue_end(&is->subtitleq);
1888
        break;
1889
    default:
1890
        break;
1891
    }
1892

    
1893
    ic->streams[stream_index]->discard = AVDISCARD_ALL;
1894
    avcodec_close(enc);
1895
    switch(enc->codec_type) {
1896
    case CODEC_TYPE_AUDIO:
1897
        is->audio_st = NULL;
1898
        is->audio_stream = -1;
1899
        break;
1900
    case CODEC_TYPE_VIDEO:
1901
        is->video_st = NULL;
1902
        is->video_stream = -1;
1903
        break;
1904
    case CODEC_TYPE_SUBTITLE:
1905
        is->subtitle_st = NULL;
1906
        is->subtitle_stream = -1;
1907
        break;
1908
    default:
1909
        break;
1910
    }
1911
}
1912

    
1913
/* since we have only one decoding thread, we can use a global
1914
   variable instead of a thread local variable */
1915
static VideoState *global_video_state;
1916

    
1917
static int decode_interrupt_cb(void)
1918
{
1919
    return (global_video_state && global_video_state->abort_request);
1920
}
1921

    
1922
/* this thread gets the stream from the disk or the network */
1923
static int decode_thread(void *arg)
1924
{
1925
    VideoState *is = arg;
1926
    AVFormatContext *ic;
1927
    int err, i, ret, video_index, audio_index, subtitle_index;
1928
    AVPacket pkt1, *pkt = &pkt1;
1929
    AVFormatParameters params, *ap = &params;
1930
    int eof=0;
1931

    
1932
    ic = avformat_alloc_context();
1933

    
1934
    video_index = -1;
1935
    audio_index = -1;
1936
    subtitle_index = -1;
1937
    is->video_stream = -1;
1938
    is->audio_stream = -1;
1939
    is->subtitle_stream = -1;
1940

    
1941
    global_video_state = is;
1942
    url_set_interrupt_cb(decode_interrupt_cb);
1943

    
1944
    memset(ap, 0, sizeof(*ap));
1945

    
1946
    ap->prealloced_context = 1;
1947
    ap->width = frame_width;
1948
    ap->height= frame_height;
1949
    ap->time_base= (AVRational){1, 25};
1950
    ap->pix_fmt = frame_pix_fmt;
1951

    
1952
    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
1953

    
1954
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1955
    if (err < 0) {
1956
        print_error(is->filename, err);
1957
        ret = -1;
1958
        goto fail;
1959
    }
1960
    is->ic = ic;
1961

    
1962
    if(genpts)
1963
        ic->flags |= AVFMT_FLAG_GENPTS;
1964

    
1965
    err = av_find_stream_info(ic);
1966
    if (err < 0) {
1967
        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1968
        ret = -1;
1969
        goto fail;
1970
    }
1971
    if(ic->pb)
1972
        ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1973

    
1974
    if(seek_by_bytes<0)
1975
        seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
1976

    
1977
    /* if seeking requested, we execute it */
1978
    if (start_time != AV_NOPTS_VALUE) {
1979
        int64_t timestamp;
1980

    
1981
        timestamp = start_time;
1982
        /* add the stream start time */
1983
        if (ic->start_time != AV_NOPTS_VALUE)
1984
            timestamp += ic->start_time;
1985
        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1986
        if (ret < 0) {
1987
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
1988
                    is->filename, (double)timestamp / AV_TIME_BASE);
1989
        }
1990
    }
1991

    
1992
    for(i = 0; i < ic->nb_streams; i++) {
1993
        AVCodecContext *enc = ic->streams[i]->codec;
1994
        ic->streams[i]->discard = AVDISCARD_ALL;
1995
        switch(enc->codec_type) {
1996
        case CODEC_TYPE_AUDIO:
1997
            if (wanted_audio_stream-- >= 0 && !audio_disable)
1998
                audio_index = i;
1999
            break;
2000
        case CODEC_TYPE_VIDEO:
2001
            if (wanted_video_stream-- >= 0 && !video_disable)
2002
                video_index = i;
2003
            break;
2004
        case CODEC_TYPE_SUBTITLE:
2005
            if (wanted_subtitle_stream-- >= 0 && !video_disable)
2006
                subtitle_index = i;
2007
            break;
2008
        default:
2009
            break;
2010
        }
2011
    }
2012
    if (show_status) {
2013
        dump_format(ic, 0, is->filename, 0);
2014
    }
2015

    
2016
    /* open the streams */
2017
    if (audio_index >= 0) {
2018
        stream_component_open(is, audio_index);
2019
    }
2020

    
2021
    if (video_index >= 0) {
2022
        stream_component_open(is, video_index);
2023
    } else {
2024
        /* add the refresh timer to draw the picture */
2025
        schedule_refresh(is, 40);
2026

    
2027
        if (!display_disable)
2028
            is->show_audio = 1;
2029
    }
2030

    
2031
    if (subtitle_index >= 0) {
2032
        stream_component_open(is, subtitle_index);
2033
    }
2034

    
2035
    if (is->video_stream < 0 && is->audio_stream < 0) {
2036
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
2037
        ret = -1;
2038
        goto fail;
2039
    }
2040

    
2041
    for(;;) {
2042
        if (is->abort_request)
2043
            break;
2044
        if (is->paused != is->last_paused) {
2045
            is->last_paused = is->paused;
2046
            if (is->paused)
2047
                is->read_pause_return= av_read_pause(ic);
2048
            else
2049
                av_read_play(ic);
2050
        }
2051
#if CONFIG_RTSP_DEMUXER
2052
        if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2053
            /* wait 10 ms to avoid trying to get another packet */
2054
            /* XXX: horrible */
2055
            SDL_Delay(10);
2056
            continue;
2057
        }
2058
#endif
2059
        if (is->seek_req) {
2060
            int64_t seek_target= is->seek_pos;
2061
            int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2062
            int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2063
//FIXME the +-2 is due to rounding being not done in the correct direction in generation
2064
//      of the seek_pos/seek_rel variables
2065

    
2066
            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2067
            if (ret < 0) {
2068
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2069
            }else{
2070
                if (is->audio_stream >= 0) {
2071
                    packet_queue_flush(&is->audioq);
2072
                    packet_queue_put(&is->audioq, &flush_pkt);
2073
                }
2074
                if (is->subtitle_stream >= 0) {
2075
                    packet_queue_flush(&is->subtitleq);
2076
                    packet_queue_put(&is->subtitleq, &flush_pkt);
2077
                }
2078
                if (is->video_stream >= 0) {
2079
                    packet_queue_flush(&is->videoq);
2080
                    packet_queue_put(&is->videoq, &flush_pkt);
2081
                }
2082
            }
2083
            is->seek_req = 0;
2084
            eof= 0;
2085
        }
2086

    
2087
        /* if the queue are full, no need to read more */
2088
        if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2089
            || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2090
                && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2091
                && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2092
            /* wait 10 ms */
2093
            SDL_Delay(10);
2094
            continue;
2095
        }
2096
        if(url_feof(ic->pb) || eof) {
2097
            if(is->video_stream >= 0){
2098
                av_init_packet(pkt);
2099
                pkt->data=NULL;
2100
                pkt->size=0;
2101
                pkt->stream_index= is->video_stream;
2102
                packet_queue_put(&is->videoq, pkt);
2103
            }
2104
            SDL_Delay(10);
2105
            continue;
2106
        }
2107
        ret = av_read_frame(ic, pkt);
2108
        if (ret < 0) {
2109
            if (ret == AVERROR_EOF)
2110
                eof=1;
2111
            if (url_ferror(ic->pb))
2112
                break;
2113
            SDL_Delay(100); /* wait for user event */
2114
            continue;
2115
        }
2116
        if (pkt->stream_index == is->audio_stream) {
2117
            packet_queue_put(&is->audioq, pkt);
2118
        } else if (pkt->stream_index == is->video_stream) {
2119
            packet_queue_put(&is->videoq, pkt);
2120
        } else if (pkt->stream_index == is->subtitle_stream) {
2121
            packet_queue_put(&is->subtitleq, pkt);
2122
        } else {
2123
            av_free_packet(pkt);
2124
        }
2125
    }
2126
    /* wait until the end */
2127
    while (!is->abort_request) {
2128
        SDL_Delay(100);
2129
    }
2130

    
2131
    ret = 0;
2132
 fail:
2133
    /* disable interrupting */
2134
    global_video_state = NULL;
2135

    
2136
    /* close each stream */
2137
    if (is->audio_stream >= 0)
2138
        stream_component_close(is, is->audio_stream);
2139
    if (is->video_stream >= 0)
2140
        stream_component_close(is, is->video_stream);
2141
    if (is->subtitle_stream >= 0)
2142
        stream_component_close(is, is->subtitle_stream);
2143
    if (is->ic) {
2144
        av_close_input_file(is->ic);
2145
        is->ic = NULL; /* safety */
2146
    }
2147
    url_set_interrupt_cb(NULL);
2148

    
2149
    if (ret != 0) {
2150
        SDL_Event event;
2151

    
2152
        event.type = FF_QUIT_EVENT;
2153
        event.user.data1 = is;
2154
        SDL_PushEvent(&event);
2155
    }
2156
    return 0;
2157
}
2158

    
2159
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2160
{
2161
    VideoState *is;
2162

    
2163
    is = av_mallocz(sizeof(VideoState));
2164
    if (!is)
2165
        return NULL;
2166
    av_strlcpy(is->filename, filename, sizeof(is->filename));
2167
    is->iformat = iformat;
2168
    is->ytop = 0;
2169
    is->xleft = 0;
2170

    
2171
    /* start video display */
2172
    is->pictq_mutex = SDL_CreateMutex();
2173
    is->pictq_cond = SDL_CreateCond();
2174

    
2175
    is->subpq_mutex = SDL_CreateMutex();
2176
    is->subpq_cond = SDL_CreateCond();
2177

    
2178
    is->av_sync_type = av_sync_type;
2179
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2180
    if (!is->parse_tid) {
2181
        av_free(is);
2182
        return NULL;
2183
    }
2184
    return is;
2185
}
2186

    
2187
static void stream_close(VideoState *is)
2188
{
2189
    VideoPicture *vp;
2190
    int i;
2191
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2192
    is->abort_request = 1;
2193
    SDL_WaitThread(is->parse_tid, NULL);
2194

    
2195
    /* free all pictures */
2196
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2197
        vp = &is->pictq[i];
2198
        if (vp->bmp) {
2199
            SDL_FreeYUVOverlay(vp->bmp);
2200
            vp->bmp = NULL;
2201
        }
2202
    }
2203
    SDL_DestroyMutex(is->pictq_mutex);
2204
    SDL_DestroyCond(is->pictq_cond);
2205
    SDL_DestroyMutex(is->subpq_mutex);
2206
    SDL_DestroyCond(is->subpq_cond);
2207
    if (is->img_convert_ctx)
2208
        sws_freeContext(is->img_convert_ctx);
2209
    av_free(is);
2210
}
2211

    
2212
static void stream_cycle_channel(VideoState *is, int codec_type)
2213
{
2214
    AVFormatContext *ic = is->ic;
2215
    int start_index, stream_index;
2216
    AVStream *st;
2217

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

    
2261

    
2262
static void toggle_full_screen(void)
2263
{
2264
    is_full_screen = !is_full_screen;
2265
    if (!fs_screen_width) {
2266
        /* use default SDL method */
2267
//        SDL_WM_ToggleFullScreen(screen);
2268
    }
2269
    video_open(cur_stream);
2270
}
2271

    
2272
static void toggle_pause(void)
2273
{
2274
    if (cur_stream)
2275
        stream_pause(cur_stream);
2276
    step = 0;
2277
}
2278

    
2279
static void step_to_next_frame(void)
2280
{
2281
    if (cur_stream) {
2282
        /* if the stream is paused unpause it, then step */
2283
        if (cur_stream->paused)
2284
            stream_pause(cur_stream);
2285
    }
2286
    step = 1;
2287
}
2288

    
2289
static void do_exit(void)
2290
{
2291
    int i;
2292
    if (cur_stream) {
2293
        stream_close(cur_stream);
2294
        cur_stream = NULL;
2295
    }
2296
    for (i = 0; i < CODEC_TYPE_NB; i++)
2297
        av_free(avcodec_opts[i]);
2298
    av_free(avformat_opts);
2299
    av_free(sws_opts);
2300
    if (show_status)
2301
        printf("\n");
2302
    SDL_Quit();
2303
    exit(0);
2304
}
2305

    
2306
static void toggle_audio_display(void)
2307
{
2308
    if (cur_stream) {
2309
        cur_stream->show_audio = !cur_stream->show_audio;
2310
    }
2311
}
2312

    
2313
/* handle an event sent by the GUI */
2314
static void event_loop(void)
2315
{
2316
    SDL_Event event;
2317
    double incr, pos, frac;
2318

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

    
2442
static void opt_frame_size(const char *arg)
2443
{
2444
    if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2445
        fprintf(stderr, "Incorrect frame size\n");
2446
        exit(1);
2447
    }
2448
    if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2449
        fprintf(stderr, "Frame size must be a multiple of 2\n");
2450
        exit(1);
2451
    }
2452
}
2453

    
2454
static int opt_width(const char *opt, const char *arg)
2455
{
2456
    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2457
    return 0;
2458
}
2459

    
2460
static int opt_height(const char *opt, const char *arg)
2461
{
2462
    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2463
    return 0;
2464
}
2465

    
2466
static void opt_format(const char *arg)
2467
{
2468
    file_iformat = av_find_input_format(arg);
2469
    if (!file_iformat) {
2470
        fprintf(stderr, "Unknown input format: %s\n", arg);
2471
        exit(1);
2472
    }
2473
}
2474

    
2475
static void opt_frame_pix_fmt(const char *arg)
2476
{
2477
    frame_pix_fmt = av_get_pix_fmt(arg);
2478
}
2479

    
2480
static int opt_sync(const char *opt, const char *arg)
2481
{
2482
    if (!strcmp(arg, "audio"))
2483
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2484
    else if (!strcmp(arg, "video"))
2485
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2486
    else if (!strcmp(arg, "ext"))
2487
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2488
    else {
2489
        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2490
        exit(1);
2491
    }
2492
    return 0;
2493
}
2494

    
2495
static int opt_seek(const char *opt, const char *arg)
2496
{
2497
    start_time = parse_time_or_die(opt, arg, 1);
2498
    return 0;
2499
}
2500

    
2501
static int opt_debug(const char *opt, const char *arg)
2502
{
2503
    av_log_set_level(99);
2504
    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2505
    return 0;
2506
}
2507

    
2508
static int opt_vismv(const char *opt, const char *arg)
2509
{
2510
    debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2511
    return 0;
2512
}
2513

    
2514
static int opt_thread_count(const char *opt, const char *arg)
2515
{
2516
    thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2517
#if !HAVE_THREADS
2518
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2519
#endif
2520
    return 0;
2521
}
2522

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

    
2559
static void show_usage(void)
2560
{
2561
    printf("Simple media player\n");
2562
    printf("usage: ffplay [options] input_file\n");
2563
    printf("\n");
2564
}
2565

    
2566
static void show_help(void)
2567
{
2568
    show_usage();
2569
    show_help_options(options, "Main options:\n",
2570
                      OPT_EXPERT, 0);
2571
    show_help_options(options, "\nAdvanced options:\n",
2572
                      OPT_EXPERT, OPT_EXPERT);
2573
    printf("\nWhile playing:\n"
2574
           "q, ESC              quit\n"
2575
           "f                   toggle full screen\n"
2576
           "p, SPC              pause\n"
2577
           "a                   cycle audio channel\n"
2578
           "v                   cycle video channel\n"
2579
           "t                   cycle subtitle channel\n"
2580
           "w                   show audio waves\n"
2581
           "left/right          seek backward/forward 10 seconds\n"
2582
           "down/up             seek backward/forward 1 minute\n"
2583
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2584
           );
2585
}
2586

    
2587
static void opt_input_file(const char *filename)
2588
{
2589
    if (!strcmp(filename, "-"))
2590
        filename = "pipe:";
2591
    input_filename = filename;
2592
}
2593

    
2594
/* Called from the main */
2595
int main(int argc, char **argv)
2596
{
2597
    int flags, i;
2598

    
2599
    /* register all codecs, demux and protocols */
2600
    avcodec_register_all();
2601
    avdevice_register_all();
2602
    av_register_all();
2603

    
2604
    for(i=0; i<CODEC_TYPE_NB; i++){
2605
        avcodec_opts[i]= avcodec_alloc_context2(i);
2606
    }
2607
    avformat_opts = avformat_alloc_context();
2608
    sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2609

    
2610
    show_banner();
2611

    
2612
    parse_options(argc, argv, options, opt_input_file);
2613

    
2614
    if (!input_filename) {
2615
        show_usage();
2616
        fprintf(stderr, "An input file must be specified\n");
2617
        fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2618
        exit(1);
2619
    }
2620

    
2621
    if (display_disable) {
2622
        video_disable = 1;
2623
    }
2624
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2625
#if !defined(__MINGW32__) && !defined(__APPLE__)
2626
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2627
#endif
2628
    if (SDL_Init (flags)) {
2629
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2630
        exit(1);
2631
    }
2632

    
2633
    if (!display_disable) {
2634
#if HAVE_SDL_VIDEO_SIZE
2635
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2636
        fs_screen_width = vi->current_w;
2637
        fs_screen_height = vi->current_h;
2638
#endif
2639
    }
2640

    
2641
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2642
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2643
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2644
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2645

    
2646
    av_init_packet(&flush_pkt);
2647
    flush_pkt.data= "FLUSH";
2648

    
2649
    cur_stream = stream_open(input_filename, file_iformat);
2650

    
2651
    event_loop();
2652

    
2653
    /* never returns */
2654

    
2655
    return 0;
2656
}