Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 9f8008a9

History | View | Annotate | Download (98.3 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
#define _XOPEN_SOURCE 600
23

    
24
#include "config.h"
25
#include <inttypes.h>
26
#include <math.h>
27
#include <limits.h>
28
#include "libavutil/avstring.h"
29
#include "libavutil/colorspace.h"
30
#include "libavutil/pixdesc.h"
31
#include "libavutil/imgutils.h"
32
#include "libavutil/parseutils.h"
33
#include "libavutil/samplefmt.h"
34
#include "libavformat/avformat.h"
35
#include "libavdevice/avdevice.h"
36
#include "libswscale/swscale.h"
37
#include "libavcodec/audioconvert.h"
38
#include "libavcodec/opt.h"
39
#include "libavcodec/avfft.h"
40

    
41
#if CONFIG_AVFILTER
42
# include "libavfilter/avfilter.h"
43
# include "libavfilter/avfiltergraph.h"
44
#endif
45

    
46
#include "cmdutils.h"
47

    
48
#include <SDL.h>
49
#include <SDL_thread.h>
50

    
51
#ifdef __MINGW32__
52
#undef main /* We don't want SDL to override our main() */
53
#endif
54

    
55
#include <unistd.h>
56
#include <assert.h>
57

    
58
const char program_name[] = "FFplay";
59
const int program_birth_year = 2003;
60

    
61
//#define DEBUG
62
//#define DEBUG_SYNC
63

    
64
#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
65
#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
66
#define MIN_FRAMES 5
67

    
68
/* SDL audio buffer size, in samples. Should be small to have precise
69
   A/V sync as SDL does not have hardware buffer fullness info. */
70
#define SDL_AUDIO_BUFFER_SIZE 1024
71

    
72
/* no AV sync correction is done if below the AV sync threshold */
73
#define AV_SYNC_THRESHOLD 0.01
74
/* no AV correction is done if too big error */
75
#define AV_NOSYNC_THRESHOLD 10.0
76

    
77
#define FRAME_SKIP_FACTOR 0.05
78

    
79
/* maximum audio speed change to get correct sync */
80
#define SAMPLE_CORRECTION_PERCENT_MAX 10
81

    
82
/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
83
#define AUDIO_DIFF_AVG_NB   20
84

    
85
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
86
#define SAMPLE_ARRAY_SIZE (2*65536)
87

    
88
static int sws_flags = SWS_BICUBIC;
89

    
90
typedef struct PacketQueue {
91
    AVPacketList *first_pkt, *last_pkt;
92
    int nb_packets;
93
    int size;
94
    int abort_request;
95
    SDL_mutex *mutex;
96
    SDL_cond *cond;
97
} PacketQueue;
98

    
99
#define VIDEO_PICTURE_QUEUE_SIZE 2
100
#define SUBPICTURE_QUEUE_SIZE 4
101

    
102
typedef struct VideoPicture {
103
    double pts;                                  ///<presentation time stamp for this picture
104
    double target_clock;                         ///<av_gettime() time at which this should be displayed ideally
105
    int64_t pos;                                 ///<byte position in file
106
    SDL_Overlay *bmp;
107
    int width, height; /* source height & width */
108
    int allocated;
109
    enum PixelFormat pix_fmt;
110

    
111
#if CONFIG_AVFILTER
112
    AVFilterBufferRef *picref;
113
#endif
114
} VideoPicture;
115

    
116
typedef struct SubPicture {
117
    double pts; /* presentation time stamp for this picture */
118
    AVSubtitle sub;
119
} SubPicture;
120

    
121
enum {
122
    AV_SYNC_AUDIO_MASTER, /* default choice */
123
    AV_SYNC_VIDEO_MASTER,
124
    AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
125
};
126

    
127
typedef struct VideoState {
128
    SDL_Thread *parse_tid;
129
    SDL_Thread *video_tid;
130
    SDL_Thread *refresh_tid;
131
    AVInputFormat *iformat;
132
    int no_background;
133
    int abort_request;
134
    int paused;
135
    int last_paused;
136
    int seek_req;
137
    int seek_flags;
138
    int64_t seek_pos;
139
    int64_t seek_rel;
140
    int read_pause_return;
141
    AVFormatContext *ic;
142
    int dtg_active_format;
143

    
144
    int audio_stream;
145

    
146
    int av_sync_type;
147
    double external_clock; /* external clock base */
148
    int64_t external_clock_time;
149

    
150
    double audio_clock;
151
    double audio_diff_cum; /* used for AV difference average computation */
152
    double audio_diff_avg_coef;
153
    double audio_diff_threshold;
154
    int audio_diff_avg_count;
155
    AVStream *audio_st;
156
    PacketQueue audioq;
157
    int audio_hw_buf_size;
158
    /* samples output by the codec. we reserve more space for avsync
159
       compensation */
160
    DECLARE_ALIGNED(16,uint8_t,audio_buf1)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
161
    DECLARE_ALIGNED(16,uint8_t,audio_buf2)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
162
    uint8_t *audio_buf;
163
    unsigned int audio_buf_size; /* in bytes */
164
    int audio_buf_index; /* in bytes */
165
    AVPacket audio_pkt_temp;
166
    AVPacket audio_pkt;
167
    enum AVSampleFormat audio_src_fmt;
168
    AVAudioConvert *reformat_ctx;
169

    
170
    int show_audio; /* if true, display audio samples */
171
    int16_t sample_array[SAMPLE_ARRAY_SIZE];
172
    int sample_array_index;
173
    int last_i_start;
174
    RDFTContext *rdft;
175
    int rdft_bits;
176
    FFTSample *rdft_data;
177
    int xpos;
178

    
179
    SDL_Thread *subtitle_tid;
180
    int subtitle_stream;
181
    int subtitle_stream_changed;
182
    AVStream *subtitle_st;
183
    PacketQueue subtitleq;
184
    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
185
    int subpq_size, subpq_rindex, subpq_windex;
186
    SDL_mutex *subpq_mutex;
187
    SDL_cond *subpq_cond;
188

    
189
    double frame_timer;
190
    double frame_last_pts;
191
    double frame_last_delay;
192
    double video_clock;                          ///<pts of last decoded frame / predicted pts of next decoded frame
193
    int video_stream;
194
    AVStream *video_st;
195
    PacketQueue videoq;
196
    double video_current_pts;                    ///<current displayed pts (different from video_clock if frame fifos are used)
197
    double video_current_pts_drift;              ///<video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
198
    int64_t video_current_pos;                   ///<current displayed file pos
199
    VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
200
    int pictq_size, pictq_rindex, pictq_windex;
201
    SDL_mutex *pictq_mutex;
202
    SDL_cond *pictq_cond;
203
#if !CONFIG_AVFILTER
204
    struct SwsContext *img_convert_ctx;
205
#endif
206

    
207
    //    QETimer *video_timer;
208
    char filename[1024];
209
    int width, height, xleft, ytop;
210

    
211
#if CONFIG_AVFILTER
212
    AVFilterContext *out_video_filter;          ///<the last filter in the video chain
213
#endif
214

    
215
    float skip_frames;
216
    float skip_frames_index;
217
    int refresh;
218
} VideoState;
219

    
220
static void show_help(void);
221
static int audio_write_get_buf_size(VideoState *is);
222

    
223
/* options specified by the user */
224
static AVInputFormat *file_iformat;
225
static const char *input_filename;
226
static const char *window_title;
227
static int fs_screen_width;
228
static int fs_screen_height;
229
static int screen_width = 0;
230
static int screen_height = 0;
231
static int frame_width = 0;
232
static int frame_height = 0;
233
static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
234
static int audio_disable;
235
static int video_disable;
236
static int wanted_stream[AVMEDIA_TYPE_NB]={
237
    [AVMEDIA_TYPE_AUDIO]=-1,
238
    [AVMEDIA_TYPE_VIDEO]=-1,
239
    [AVMEDIA_TYPE_SUBTITLE]=-1,
240
};
241
static int seek_by_bytes=-1;
242
static int display_disable;
243
static int show_status = 1;
244
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
245
static int64_t start_time = AV_NOPTS_VALUE;
246
static int64_t duration = AV_NOPTS_VALUE;
247
static int debug = 0;
248
static int debug_mv = 0;
249
static int step = 0;
250
static int thread_count = 1;
251
static int workaround_bugs = 1;
252
static int fast = 0;
253
static int genpts = 0;
254
static int lowres = 0;
255
static int idct = FF_IDCT_AUTO;
256
static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
257
static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
258
static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
259
static int error_recognition = FF_ER_CAREFUL;
260
static int error_concealment = 3;
261
static int decoder_reorder_pts= -1;
262
static int autoexit;
263
static int exit_on_keydown;
264
static int exit_on_mousedown;
265
static int loop=1;
266
static int framedrop=1;
267

    
268
static int rdftspeed=20;
269
#if CONFIG_AVFILTER
270
static char *vfilters = NULL;
271
#endif
272

    
273
/* current context */
274
static int is_full_screen;
275
static VideoState *cur_stream;
276
static int64_t audio_callback_time;
277

    
278
static AVPacket flush_pkt;
279

    
280
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
281
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
282
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
283

    
284
static SDL_Surface *screen;
285

    
286
static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
287

    
288
/* packet queue handling */
289
static void packet_queue_init(PacketQueue *q)
290
{
291
    memset(q, 0, sizeof(PacketQueue));
292
    q->mutex = SDL_CreateMutex();
293
    q->cond = SDL_CreateCond();
294
    packet_queue_put(q, &flush_pkt);
295
}
296

    
297
static void packet_queue_flush(PacketQueue *q)
298
{
299
    AVPacketList *pkt, *pkt1;
300

    
301
    SDL_LockMutex(q->mutex);
302
    for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
303
        pkt1 = pkt->next;
304
        av_free_packet(&pkt->pkt);
305
        av_freep(&pkt);
306
    }
307
    q->last_pkt = NULL;
308
    q->first_pkt = NULL;
309
    q->nb_packets = 0;
310
    q->size = 0;
311
    SDL_UnlockMutex(q->mutex);
312
}
313

    
314
static void packet_queue_end(PacketQueue *q)
315
{
316
    packet_queue_flush(q);
317
    SDL_DestroyMutex(q->mutex);
318
    SDL_DestroyCond(q->cond);
319
}
320

    
321
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
322
{
323
    AVPacketList *pkt1;
324

    
325
    /* duplicate the packet */
326
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
327
        return -1;
328

    
329
    pkt1 = av_malloc(sizeof(AVPacketList));
330
    if (!pkt1)
331
        return -1;
332
    pkt1->pkt = *pkt;
333
    pkt1->next = NULL;
334

    
335

    
336
    SDL_LockMutex(q->mutex);
337

    
338
    if (!q->last_pkt)
339

    
340
        q->first_pkt = pkt1;
341
    else
342
        q->last_pkt->next = pkt1;
343
    q->last_pkt = pkt1;
344
    q->nb_packets++;
345
    q->size += pkt1->pkt.size + sizeof(*pkt1);
346
    /* XXX: should duplicate packet data in DV case */
347
    SDL_CondSignal(q->cond);
348

    
349
    SDL_UnlockMutex(q->mutex);
350
    return 0;
351
}
352

    
353
static void packet_queue_abort(PacketQueue *q)
354
{
355
    SDL_LockMutex(q->mutex);
356

    
357
    q->abort_request = 1;
358

    
359
    SDL_CondSignal(q->cond);
360

    
361
    SDL_UnlockMutex(q->mutex);
362
}
363

    
364
/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
365
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
366
{
367
    AVPacketList *pkt1;
368
    int ret;
369

    
370
    SDL_LockMutex(q->mutex);
371

    
372
    for(;;) {
373
        if (q->abort_request) {
374
            ret = -1;
375
            break;
376
        }
377

    
378
        pkt1 = q->first_pkt;
379
        if (pkt1) {
380
            q->first_pkt = pkt1->next;
381
            if (!q->first_pkt)
382
                q->last_pkt = NULL;
383
            q->nb_packets--;
384
            q->size -= pkt1->pkt.size + sizeof(*pkt1);
385
            *pkt = pkt1->pkt;
386
            av_free(pkt1);
387
            ret = 1;
388
            break;
389
        } else if (!block) {
390
            ret = 0;
391
            break;
392
        } else {
393
            SDL_CondWait(q->cond, q->mutex);
394
        }
395
    }
396
    SDL_UnlockMutex(q->mutex);
397
    return ret;
398
}
399

    
400
static inline void fill_rectangle(SDL_Surface *screen,
401
                                  int x, int y, int w, int h, int color)
402
{
403
    SDL_Rect rect;
404
    rect.x = x;
405
    rect.y = y;
406
    rect.w = w;
407
    rect.h = h;
408
    SDL_FillRect(screen, &rect, color);
409
}
410

    
411
#if 0
412
/* draw only the border of a rectangle */
413
void fill_border(VideoState *s, int x, int y, int w, int h, int color)
414
{
415
    int w1, w2, h1, h2;
416

417
    /* fill the background */
418
    w1 = x;
419
    if (w1 < 0)
420
        w1 = 0;
421
    w2 = s->width - (x + w);
422
    if (w2 < 0)
423
        w2 = 0;
424
    h1 = y;
425
    if (h1 < 0)
426
        h1 = 0;
427
    h2 = s->height - (y + h);
428
    if (h2 < 0)
429
        h2 = 0;
430
    fill_rectangle(screen,
431
                   s->xleft, s->ytop,
432
                   w1, s->height,
433
                   color);
434
    fill_rectangle(screen,
435
                   s->xleft + s->width - w2, s->ytop,
436
                   w2, s->height,
437
                   color);
438
    fill_rectangle(screen,
439
                   s->xleft + w1, s->ytop,
440
                   s->width - w1 - w2, h1,
441
                   color);
442
    fill_rectangle(screen,
443
                   s->xleft + w1, s->ytop + s->height - h2,
444
                   s->width - w1 - w2, h2,
445
                   color);
446
}
447
#endif
448

    
449
#define ALPHA_BLEND(a, oldp, newp, s)\
450
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
451

    
452
#define RGBA_IN(r, g, b, a, s)\
453
{\
454
    unsigned int v = ((const uint32_t *)(s))[0];\
455
    a = (v >> 24) & 0xff;\
456
    r = (v >> 16) & 0xff;\
457
    g = (v >> 8) & 0xff;\
458
    b = v & 0xff;\
459
}
460

    
461
#define YUVA_IN(y, u, v, a, s, pal)\
462
{\
463
    unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
464
    a = (val >> 24) & 0xff;\
465
    y = (val >> 16) & 0xff;\
466
    u = (val >> 8) & 0xff;\
467
    v = val & 0xff;\
468
}
469

    
470
#define YUVA_OUT(d, y, u, v, a)\
471
{\
472
    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
473
}
474

    
475

    
476
#define BPP 1
477

    
478
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
479
{
480
    int wrap, wrap3, width2, skip2;
481
    int y, u, v, a, u1, v1, a1, w, h;
482
    uint8_t *lum, *cb, *cr;
483
    const uint8_t *p;
484
    const uint32_t *pal;
485
    int dstx, dsty, dstw, dsth;
486

    
487
    dstw = av_clip(rect->w, 0, imgw);
488
    dsth = av_clip(rect->h, 0, imgh);
489
    dstx = av_clip(rect->x, 0, imgw - dstw);
490
    dsty = av_clip(rect->y, 0, imgh - dsth);
491
    lum = dst->data[0] + dsty * dst->linesize[0];
492
    cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
493
    cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
494

    
495
    width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
496
    skip2 = dstx >> 1;
497
    wrap = dst->linesize[0];
498
    wrap3 = rect->pict.linesize[0];
499
    p = rect->pict.data[0];
500
    pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
501

    
502
    if (dsty & 1) {
503
        lum += dstx;
504
        cb += skip2;
505
        cr += skip2;
506

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

    
524
            YUVA_IN(y, u, v, a, p + BPP, pal);
525
            u1 += u;
526
            v1 += v;
527
            a1 += a;
528
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
529
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
530
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
531
            cb++;
532
            cr++;
533
            p += 2 * BPP;
534
            lum += 2;
535
        }
536
        if (w) {
537
            YUVA_IN(y, u, v, a, p, pal);
538
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
539
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
540
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
541
            p++;
542
            lum++;
543
        }
544
        p += wrap3 - dstw * BPP;
545
        lum += wrap - dstw - dstx;
546
        cb += dst->linesize[1] - width2 - skip2;
547
        cr += dst->linesize[2] - width2 - skip2;
548
    }
549
    for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
550
        lum += dstx;
551
        cb += skip2;
552
        cr += skip2;
553

    
554
        if (dstx & 1) {
555
            YUVA_IN(y, u, v, a, p, pal);
556
            u1 = u;
557
            v1 = v;
558
            a1 = a;
559
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
560
            p += wrap3;
561
            lum += wrap;
562
            YUVA_IN(y, u, v, a, p, pal);
563
            u1 += u;
564
            v1 += v;
565
            a1 += a;
566
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
567
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
568
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
569
            cb++;
570
            cr++;
571
            p += -wrap3 + BPP;
572
            lum += -wrap + 1;
573
        }
574
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
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

    
581
            YUVA_IN(y, u, v, a, p + BPP, pal);
582
            u1 += u;
583
            v1 += v;
584
            a1 += a;
585
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
586
            p += wrap3;
587
            lum += wrap;
588

    
589
            YUVA_IN(y, u, v, a, p, pal);
590
            u1 += u;
591
            v1 += v;
592
            a1 += a;
593
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
594

    
595
            YUVA_IN(y, u, v, a, p + BPP, pal);
596
            u1 += u;
597
            v1 += v;
598
            a1 += a;
599
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
600

    
601
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
602
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
603

    
604
            cb++;
605
            cr++;
606
            p += -wrap3 + 2 * BPP;
607
            lum += -wrap + 2;
608
        }
609
        if (w) {
610
            YUVA_IN(y, u, v, a, p, pal);
611
            u1 = u;
612
            v1 = v;
613
            a1 = a;
614
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
615
            p += wrap3;
616
            lum += wrap;
617
            YUVA_IN(y, u, v, a, p, pal);
618
            u1 += u;
619
            v1 += v;
620
            a1 += a;
621
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
622
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
623
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
624
            cb++;
625
            cr++;
626
            p += -wrap3 + BPP;
627
            lum += -wrap + 1;
628
        }
629
        p += wrap3 + (wrap3 - dstw * BPP);
630
        lum += wrap + (wrap - dstw - dstx);
631
        cb += dst->linesize[1] - width2 - skip2;
632
        cr += dst->linesize[2] - width2 - skip2;
633
    }
634
    /* handle odd height */
635
    if (h) {
636
        lum += dstx;
637
        cb += skip2;
638
        cr += skip2;
639

    
640
        if (dstx & 1) {
641
            YUVA_IN(y, u, v, a, p, pal);
642
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
643
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
644
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
645
            cb++;
646
            cr++;
647
            lum++;
648
            p += BPP;
649
        }
650
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
651
            YUVA_IN(y, u, v, a, p, pal);
652
            u1 = u;
653
            v1 = v;
654
            a1 = a;
655
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
656

    
657
            YUVA_IN(y, u, v, a, p + BPP, pal);
658
            u1 += u;
659
            v1 += v;
660
            a1 += a;
661
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
662
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
663
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
664
            cb++;
665
            cr++;
666
            p += 2 * BPP;
667
            lum += 2;
668
        }
669
        if (w) {
670
            YUVA_IN(y, u, v, a, p, pal);
671
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
672
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
673
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
674
        }
675
    }
676
}
677

    
678
static void free_subpicture(SubPicture *sp)
679
{
680
    avsubtitle_free(&sp->sub);
681
}
682

    
683
static void video_image_display(VideoState *is)
684
{
685
    VideoPicture *vp;
686
    SubPicture *sp;
687
    AVPicture pict;
688
    float aspect_ratio;
689
    int width, height, x, y;
690
    SDL_Rect rect;
691
    int i;
692

    
693
    vp = &is->pictq[is->pictq_rindex];
694
    if (vp->bmp) {
695
#if CONFIG_AVFILTER
696
         if (vp->picref->video->pixel_aspect.num == 0)
697
             aspect_ratio = 0;
698
         else
699
             aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);
700
#else
701

    
702
        /* XXX: use variable in the frame */
703
        if (is->video_st->sample_aspect_ratio.num)
704
            aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
705
        else if (is->video_st->codec->sample_aspect_ratio.num)
706
            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
707
        else
708
            aspect_ratio = 0;
709
#endif
710
        if (aspect_ratio <= 0.0)
711
            aspect_ratio = 1.0;
712
        aspect_ratio *= (float)vp->width / (float)vp->height;
713

    
714
        if (is->subtitle_st)
715
        {
716
            if (is->subpq_size > 0)
717
            {
718
                sp = &is->subpq[is->subpq_rindex];
719

    
720
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
721
                {
722
                    SDL_LockYUVOverlay (vp->bmp);
723

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

    
728
                    pict.linesize[0] = vp->bmp->pitches[0];
729
                    pict.linesize[1] = vp->bmp->pitches[2];
730
                    pict.linesize[2] = vp->bmp->pitches[1];
731

    
732
                    for (i = 0; i < sp->sub.num_rects; i++)
733
                        blend_subrect(&pict, sp->sub.rects[i],
734
                                      vp->bmp->w, vp->bmp->h);
735

    
736
                    SDL_UnlockYUVOverlay (vp->bmp);
737
                }
738
            }
739
        }
740

    
741

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

    
771
static inline int compute_mod(int a, int b)
772
{
773
    a = a % b;
774
    if (a >= 0)
775
        return a;
776
    else
777
        return a + b;
778
}
779

    
780
static void video_audio_display(VideoState *s)
781
{
782
    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
783
    int ch, channels, h, h2, bgcolor, fgcolor;
784
    int16_t time_diff;
785
    int rdft_bits, nb_freq;
786

    
787
    for(rdft_bits=1; (1<<rdft_bits)<2*s->height; rdft_bits++)
788
        ;
789
    nb_freq= 1<<(rdft_bits-1);
790

    
791
    /* compute display index : center on currently output samples */
792
    channels = s->audio_st->codec->channels;
793
    nb_display_channels = channels;
794
    if (!s->paused) {
795
        int data_used= s->show_audio==1 ? s->width : (2*nb_freq);
796
        n = 2 * channels;
797
        delay = audio_write_get_buf_size(s);
798
        delay /= n;
799

    
800
        /* to be more precise, we take into account the time spent since
801
           the last buffer computation */
802
        if (audio_callback_time) {
803
            time_diff = av_gettime() - audio_callback_time;
804
            delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000;
805
        }
806

    
807
        delay += 2*data_used;
808
        if (delay < data_used)
809
            delay = data_used;
810

    
811
        i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
812
        if(s->show_audio==1){
813
            h= INT_MIN;
814
            for(i=0; i<1000; i+=channels){
815
                int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
816
                int a= s->sample_array[idx];
817
                int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
818
                int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
819
                int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
820
                int score= a-d;
821
                if(h<score && (b^c)<0){
822
                    h= score;
823
                    i_start= idx;
824
                }
825
            }
826
        }
827

    
828
        s->last_i_start = i_start;
829
    } else {
830
        i_start = s->last_i_start;
831
    }
832

    
833
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
834
    if(s->show_audio==1){
835
        fill_rectangle(screen,
836
                       s->xleft, s->ytop, s->width, s->height,
837
                       bgcolor);
838

    
839
        fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
840

    
841
        /* total height for one channel */
842
        h = s->height / nb_display_channels;
843
        /* graph height / 2 */
844
        h2 = (h * 9) / 20;
845
        for(ch = 0;ch < nb_display_channels; ch++) {
846
            i = i_start + ch;
847
            y1 = s->ytop + ch * h + (h / 2); /* position of center line */
848
            for(x = 0; x < s->width; x++) {
849
                y = (s->sample_array[i] * h2) >> 15;
850
                if (y < 0) {
851
                    y = -y;
852
                    ys = y1 - y;
853
                } else {
854
                    ys = y1;
855
                }
856
                fill_rectangle(screen,
857
                               s->xleft + x, ys, 1, y,
858
                               fgcolor);
859
                i += channels;
860
                if (i >= SAMPLE_ARRAY_SIZE)
861
                    i -= SAMPLE_ARRAY_SIZE;
862
            }
863
        }
864

    
865
        fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
866

    
867
        for(ch = 1;ch < nb_display_channels; ch++) {
868
            y = s->ytop + ch * h;
869
            fill_rectangle(screen,
870
                           s->xleft, y, s->width, 1,
871
                           fgcolor);
872
        }
873
        SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
874
    }else{
875
        nb_display_channels= FFMIN(nb_display_channels, 2);
876
        if(rdft_bits != s->rdft_bits){
877
            av_rdft_end(s->rdft);
878
            av_free(s->rdft_data);
879
            s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
880
            s->rdft_bits= rdft_bits;
881
            s->rdft_data= av_malloc(4*nb_freq*sizeof(*s->rdft_data));
882
        }
883
        {
884
            FFTSample *data[2];
885
            for(ch = 0;ch < nb_display_channels; ch++) {
886
                data[ch] = s->rdft_data + 2*nb_freq*ch;
887
                i = i_start + ch;
888
                for(x = 0; x < 2*nb_freq; x++) {
889
                    double w= (x-nb_freq)*(1.0/nb_freq);
890
                    data[ch][x]= s->sample_array[i]*(1.0-w*w);
891
                    i += channels;
892
                    if (i >= SAMPLE_ARRAY_SIZE)
893
                        i -= SAMPLE_ARRAY_SIZE;
894
                }
895
                av_rdft_calc(s->rdft, data[ch]);
896
            }
897
            //least efficient way to do this, we should of course directly access it but its more than fast enough
898
            for(y=0; y<s->height; y++){
899
                double w= 1/sqrt(nb_freq);
900
                int a= sqrt(w*sqrt(data[0][2*y+0]*data[0][2*y+0] + data[0][2*y+1]*data[0][2*y+1]));
901
                int b= (nb_display_channels == 2 ) ? sqrt(w*sqrt(data[1][2*y+0]*data[1][2*y+0]
902
                       + data[1][2*y+1]*data[1][2*y+1])) : a;
903
                a= FFMIN(a,255);
904
                b= FFMIN(b,255);
905
                fgcolor = SDL_MapRGB(screen->format, a, b, (a+b)/2);
906

    
907
                fill_rectangle(screen,
908
                            s->xpos, s->height-y, 1, 1,
909
                            fgcolor);
910
            }
911
        }
912
        SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
913
        s->xpos++;
914
        if(s->xpos >= s->width)
915
            s->xpos= s->xleft;
916
    }
917
}
918

    
919
static int video_open(VideoState *is){
920
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
921
    int w,h;
922

    
923
    if(is_full_screen) flags |= SDL_FULLSCREEN;
924
    else               flags |= SDL_RESIZABLE;
925

    
926
    if (is_full_screen && fs_screen_width) {
927
        w = fs_screen_width;
928
        h = fs_screen_height;
929
    } else if(!is_full_screen && screen_width){
930
        w = screen_width;
931
        h = screen_height;
932
#if CONFIG_AVFILTER
933
    }else if (is->out_video_filter && is->out_video_filter->inputs[0]){
934
        w = is->out_video_filter->inputs[0]->w;
935
        h = is->out_video_filter->inputs[0]->h;
936
#else
937
    }else if (is->video_st && is->video_st->codec->width){
938
        w = is->video_st->codec->width;
939
        h = is->video_st->codec->height;
940
#endif
941
    } else {
942
        w = 640;
943
        h = 480;
944
    }
945
    if(screen && is->width == screen->w && screen->w == w
946
       && is->height== screen->h && screen->h == h)
947
        return 0;
948

    
949
#ifndef __APPLE__
950
    screen = SDL_SetVideoMode(w, h, 0, flags);
951
#else
952
    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
953
    screen = SDL_SetVideoMode(w, h, 24, flags);
954
#endif
955
    if (!screen) {
956
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
957
        return -1;
958
    }
959
    if (!window_title)
960
        window_title = input_filename;
961
    SDL_WM_SetCaption(window_title, window_title);
962

    
963
    is->width = screen->w;
964
    is->height = screen->h;
965

    
966
    return 0;
967
}
968

    
969
/* display the current picture, if any */
970
static void video_display(VideoState *is)
971
{
972
    if(!screen)
973
        video_open(cur_stream);
974
    if (is->audio_st && is->show_audio)
975
        video_audio_display(is);
976
    else if (is->video_st)
977
        video_image_display(is);
978
}
979

    
980
static int refresh_thread(void *opaque)
981
{
982
    VideoState *is= opaque;
983
    while(!is->abort_request){
984
        SDL_Event event;
985
        event.type = FF_REFRESH_EVENT;
986
        event.user.data1 = opaque;
987
        if(!is->refresh){
988
            is->refresh=1;
989
            SDL_PushEvent(&event);
990
        }
991
        usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000); //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
992
    }
993
    return 0;
994
}
995

    
996
/* get the current audio clock value */
997
static double get_audio_clock(VideoState *is)
998
{
999
    double pts;
1000
    int hw_buf_size, bytes_per_sec;
1001
    pts = is->audio_clock;
1002
    hw_buf_size = audio_write_get_buf_size(is);
1003
    bytes_per_sec = 0;
1004
    if (is->audio_st) {
1005
        bytes_per_sec = is->audio_st->codec->sample_rate *
1006
            2 * is->audio_st->codec->channels;
1007
    }
1008
    if (bytes_per_sec)
1009
        pts -= (double)hw_buf_size / bytes_per_sec;
1010
    return pts;
1011
}
1012

    
1013
/* get the current video clock value */
1014
static double get_video_clock(VideoState *is)
1015
{
1016
    if (is->paused) {
1017
        return is->video_current_pts;
1018
    } else {
1019
        return is->video_current_pts_drift + av_gettime() / 1000000.0;
1020
    }
1021
}
1022

    
1023
/* get the current external clock value */
1024
static double get_external_clock(VideoState *is)
1025
{
1026
    int64_t ti;
1027
    ti = av_gettime();
1028
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
1029
}
1030

    
1031
/* get the current master clock value */
1032
static double get_master_clock(VideoState *is)
1033
{
1034
    double val;
1035

    
1036
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1037
        if (is->video_st)
1038
            val = get_video_clock(is);
1039
        else
1040
            val = get_audio_clock(is);
1041
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1042
        if (is->audio_st)
1043
            val = get_audio_clock(is);
1044
        else
1045
            val = get_video_clock(is);
1046
    } else {
1047
        val = get_external_clock(is);
1048
    }
1049
    return val;
1050
}
1051

    
1052
/* seek in the stream */
1053
static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1054
{
1055
    if (!is->seek_req) {
1056
        is->seek_pos = pos;
1057
        is->seek_rel = rel;
1058
        is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1059
        if (seek_by_bytes)
1060
            is->seek_flags |= AVSEEK_FLAG_BYTE;
1061
        is->seek_req = 1;
1062
    }
1063
}
1064

    
1065
/* pause or resume the video */
1066
static void stream_pause(VideoState *is)
1067
{
1068
    if (is->paused) {
1069
        is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1070
        if(is->read_pause_return != AVERROR(ENOSYS)){
1071
            is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1072
        }
1073
        is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1074
    }
1075
    is->paused = !is->paused;
1076
}
1077

    
1078
static double compute_target_time(double frame_current_pts, VideoState *is)
1079
{
1080
    double delay, sync_threshold, diff;
1081

    
1082
    /* compute nominal delay */
1083
    delay = frame_current_pts - is->frame_last_pts;
1084
    if (delay <= 0 || delay >= 10.0) {
1085
        /* if incorrect delay, use previous one */
1086
        delay = is->frame_last_delay;
1087
    } else {
1088
        is->frame_last_delay = delay;
1089
    }
1090
    is->frame_last_pts = frame_current_pts;
1091

    
1092
    /* update delay to follow master synchronisation source */
1093
    if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1094
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1095
        /* if video is slave, we try to correct big delays by
1096
           duplicating or deleting a frame */
1097
        diff = get_video_clock(is) - get_master_clock(is);
1098

    
1099
        /* skip or repeat frame. We take into account the
1100
           delay to compute the threshold. I still don't know
1101
           if it is the best guess */
1102
        sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1103
        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1104
            if (diff <= -sync_threshold)
1105
                delay = 0;
1106
            else if (diff >= sync_threshold)
1107
                delay = 2 * delay;
1108
        }
1109
    }
1110
    is->frame_timer += delay;
1111
#if defined(DEBUG_SYNC)
1112
    printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1113
            delay, actual_delay, frame_current_pts, -diff);
1114
#endif
1115

    
1116
    return is->frame_timer;
1117
}
1118

    
1119
/* called to display each frame */
1120
static void video_refresh_timer(void *opaque)
1121
{
1122
    VideoState *is = opaque;
1123
    VideoPicture *vp;
1124

    
1125
    SubPicture *sp, *sp2;
1126

    
1127
    if (is->video_st) {
1128
retry:
1129
        if (is->pictq_size == 0) {
1130
            //nothing to do, no picture to display in the que
1131
        } else {
1132
            double time= av_gettime()/1000000.0;
1133
            double next_target;
1134
            /* dequeue the picture */
1135
            vp = &is->pictq[is->pictq_rindex];
1136

    
1137
            if(time < vp->target_clock)
1138
                return;
1139
            /* update current video pts */
1140
            is->video_current_pts = vp->pts;
1141
            is->video_current_pts_drift = is->video_current_pts - time;
1142
            is->video_current_pos = vp->pos;
1143
            if(is->pictq_size > 1){
1144
                VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE];
1145
                assert(nextvp->target_clock >= vp->target_clock);
1146
                next_target= nextvp->target_clock;
1147
            }else{
1148
                next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly
1149
            }
1150
            if(framedrop && time > next_target){
1151
                is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
1152
                if(is->pictq_size > 1 || time > next_target + 0.5){
1153
                    /* update queue size and signal for next picture */
1154
                    if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1155
                        is->pictq_rindex = 0;
1156

    
1157
                    SDL_LockMutex(is->pictq_mutex);
1158
                    is->pictq_size--;
1159
                    SDL_CondSignal(is->pictq_cond);
1160
                    SDL_UnlockMutex(is->pictq_mutex);
1161
                    goto retry;
1162
                }
1163
            }
1164

    
1165
            if(is->subtitle_st) {
1166
                if (is->subtitle_stream_changed) {
1167
                    SDL_LockMutex(is->subpq_mutex);
1168

    
1169
                    while (is->subpq_size) {
1170
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1171

    
1172
                        /* update queue size and signal for next picture */
1173
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1174
                            is->subpq_rindex = 0;
1175

    
1176
                        is->subpq_size--;
1177
                    }
1178
                    is->subtitle_stream_changed = 0;
1179

    
1180
                    SDL_CondSignal(is->subpq_cond);
1181
                    SDL_UnlockMutex(is->subpq_mutex);
1182
                } else {
1183
                    if (is->subpq_size > 0) {
1184
                        sp = &is->subpq[is->subpq_rindex];
1185

    
1186
                        if (is->subpq_size > 1)
1187
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1188
                        else
1189
                            sp2 = NULL;
1190

    
1191
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1192
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1193
                        {
1194
                            free_subpicture(sp);
1195

    
1196
                            /* update queue size and signal for next picture */
1197
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1198
                                is->subpq_rindex = 0;
1199

    
1200
                            SDL_LockMutex(is->subpq_mutex);
1201
                            is->subpq_size--;
1202
                            SDL_CondSignal(is->subpq_cond);
1203
                            SDL_UnlockMutex(is->subpq_mutex);
1204
                        }
1205
                    }
1206
                }
1207
            }
1208

    
1209
            /* display picture */
1210
            if (!display_disable)
1211
                video_display(is);
1212

    
1213
            /* update queue size and signal for next picture */
1214
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1215
                is->pictq_rindex = 0;
1216

    
1217
            SDL_LockMutex(is->pictq_mutex);
1218
            is->pictq_size--;
1219
            SDL_CondSignal(is->pictq_cond);
1220
            SDL_UnlockMutex(is->pictq_mutex);
1221
        }
1222
    } else if (is->audio_st) {
1223
        /* draw the next audio frame */
1224

    
1225
        /* if only audio stream, then display the audio bars (better
1226
           than nothing, just to test the implementation */
1227

    
1228
        /* display picture */
1229
        if (!display_disable)
1230
            video_display(is);
1231
    }
1232
    if (show_status) {
1233
        static int64_t last_time;
1234
        int64_t cur_time;
1235
        int aqsize, vqsize, sqsize;
1236
        double av_diff;
1237

    
1238
        cur_time = av_gettime();
1239
        if (!last_time || (cur_time - last_time) >= 30000) {
1240
            aqsize = 0;
1241
            vqsize = 0;
1242
            sqsize = 0;
1243
            if (is->audio_st)
1244
                aqsize = is->audioq.size;
1245
            if (is->video_st)
1246
                vqsize = is->videoq.size;
1247
            if (is->subtitle_st)
1248
                sqsize = is->subtitleq.size;
1249
            av_diff = 0;
1250
            if (is->audio_st && is->video_st)
1251
                av_diff = get_audio_clock(is) - get_video_clock(is);
1252
            printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
1253
                   get_master_clock(is),
1254
                   av_diff,
1255
                   FFMAX(is->skip_frames-1, 0),
1256
                   aqsize / 1024,
1257
                   vqsize / 1024,
1258
                   sqsize,
1259
                   is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
1260
                   is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
1261
            fflush(stdout);
1262
            last_time = cur_time;
1263
        }
1264
    }
1265
}
1266

    
1267
static void stream_close(VideoState *is)
1268
{
1269
    VideoPicture *vp;
1270
    int i;
1271
    /* XXX: use a special url_shutdown call to abort parse cleanly */
1272
    is->abort_request = 1;
1273
    SDL_WaitThread(is->parse_tid, NULL);
1274
    SDL_WaitThread(is->refresh_tid, NULL);
1275

    
1276
    /* free all pictures */
1277
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
1278
        vp = &is->pictq[i];
1279
#if CONFIG_AVFILTER
1280
        if (vp->picref) {
1281
            avfilter_unref_buffer(vp->picref);
1282
            vp->picref = NULL;
1283
        }
1284
#endif
1285
        if (vp->bmp) {
1286
            SDL_FreeYUVOverlay(vp->bmp);
1287
            vp->bmp = NULL;
1288
        }
1289
    }
1290
    SDL_DestroyMutex(is->pictq_mutex);
1291
    SDL_DestroyCond(is->pictq_cond);
1292
    SDL_DestroyMutex(is->subpq_mutex);
1293
    SDL_DestroyCond(is->subpq_cond);
1294
#if !CONFIG_AVFILTER
1295
    if (is->img_convert_ctx)
1296
        sws_freeContext(is->img_convert_ctx);
1297
#endif
1298
    av_free(is);
1299
}
1300

    
1301
static void do_exit(void)
1302
{
1303
    if (cur_stream) {
1304
        stream_close(cur_stream);
1305
        cur_stream = NULL;
1306
    }
1307
    uninit_opts();
1308
#if CONFIG_AVFILTER
1309
    avfilter_uninit();
1310
#endif
1311
    if (show_status)
1312
        printf("\n");
1313
    SDL_Quit();
1314
    av_log(NULL, AV_LOG_QUIET, "");
1315
    exit(0);
1316
}
1317

    
1318
/* allocate a picture (needs to do that in main thread to avoid
1319
   potential locking problems */
1320
static void alloc_picture(void *opaque)
1321
{
1322
    VideoState *is = opaque;
1323
    VideoPicture *vp;
1324

    
1325
    vp = &is->pictq[is->pictq_windex];
1326

    
1327
    if (vp->bmp)
1328
        SDL_FreeYUVOverlay(vp->bmp);
1329

    
1330
#if CONFIG_AVFILTER
1331
    if (vp->picref)
1332
        avfilter_unref_buffer(vp->picref);
1333
    vp->picref = NULL;
1334

    
1335
    vp->width   = is->out_video_filter->inputs[0]->w;
1336
    vp->height  = is->out_video_filter->inputs[0]->h;
1337
    vp->pix_fmt = is->out_video_filter->inputs[0]->format;
1338
#else
1339
    vp->width   = is->video_st->codec->width;
1340
    vp->height  = is->video_st->codec->height;
1341
    vp->pix_fmt = is->video_st->codec->pix_fmt;
1342
#endif
1343

    
1344
    vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1345
                                   SDL_YV12_OVERLAY,
1346
                                   screen);
1347
    if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
1348
        /* SDL allocates a buffer smaller than requested if the video
1349
         * overlay hardware is unable to support the requested size. */
1350
        fprintf(stderr, "Error: the video system does not support an image\n"
1351
                        "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
1352
                        "to reduce the image size.\n", vp->width, vp->height );
1353
        do_exit();
1354
    }
1355

    
1356
    SDL_LockMutex(is->pictq_mutex);
1357
    vp->allocated = 1;
1358
    SDL_CondSignal(is->pictq_cond);
1359
    SDL_UnlockMutex(is->pictq_mutex);
1360
}
1361

    
1362
/**
1363
 *
1364
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1365
 */
1366
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
1367
{
1368
    VideoPicture *vp;
1369
    int dst_pix_fmt;
1370
#if CONFIG_AVFILTER
1371
    AVPicture pict_src;
1372
#endif
1373
    /* wait until we have space to put a new picture */
1374
    SDL_LockMutex(is->pictq_mutex);
1375

    
1376
    if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
1377
        is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR));
1378

    
1379
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1380
           !is->videoq.abort_request) {
1381
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1382
    }
1383
    SDL_UnlockMutex(is->pictq_mutex);
1384

    
1385
    if (is->videoq.abort_request)
1386
        return -1;
1387

    
1388
    vp = &is->pictq[is->pictq_windex];
1389

    
1390
    /* alloc or resize hardware picture buffer */
1391
    if (!vp->bmp ||
1392
#if CONFIG_AVFILTER
1393
        vp->width  != is->out_video_filter->inputs[0]->w ||
1394
        vp->height != is->out_video_filter->inputs[0]->h) {
1395
#else
1396
        vp->width != is->video_st->codec->width ||
1397
        vp->height != is->video_st->codec->height) {
1398
#endif
1399
        SDL_Event event;
1400

    
1401
        vp->allocated = 0;
1402

    
1403
        /* the allocation must be done in the main thread to avoid
1404
           locking problems */
1405
        event.type = FF_ALLOC_EVENT;
1406
        event.user.data1 = is;
1407
        SDL_PushEvent(&event);
1408

    
1409
        /* wait until the picture is allocated */
1410
        SDL_LockMutex(is->pictq_mutex);
1411
        while (!vp->allocated && !is->videoq.abort_request) {
1412
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1413
        }
1414
        SDL_UnlockMutex(is->pictq_mutex);
1415

    
1416
        if (is->videoq.abort_request)
1417
            return -1;
1418
    }
1419

    
1420
    /* if the frame is not skipped, then display it */
1421
    if (vp->bmp) {
1422
        AVPicture pict;
1423
#if CONFIG_AVFILTER
1424
        if(vp->picref)
1425
            avfilter_unref_buffer(vp->picref);
1426
        vp->picref = src_frame->opaque;
1427
#endif
1428

    
1429
        /* get a pointer on the bitmap */
1430
        SDL_LockYUVOverlay (vp->bmp);
1431

    
1432
        dst_pix_fmt = PIX_FMT_YUV420P;
1433
        memset(&pict,0,sizeof(AVPicture));
1434
        pict.data[0] = vp->bmp->pixels[0];
1435
        pict.data[1] = vp->bmp->pixels[2];
1436
        pict.data[2] = vp->bmp->pixels[1];
1437

    
1438
        pict.linesize[0] = vp->bmp->pitches[0];
1439
        pict.linesize[1] = vp->bmp->pitches[2];
1440
        pict.linesize[2] = vp->bmp->pitches[1];
1441

    
1442
#if CONFIG_AVFILTER
1443
        pict_src.data[0] = src_frame->data[0];
1444
        pict_src.data[1] = src_frame->data[1];
1445
        pict_src.data[2] = src_frame->data[2];
1446

    
1447
        pict_src.linesize[0] = src_frame->linesize[0];
1448
        pict_src.linesize[1] = src_frame->linesize[1];
1449
        pict_src.linesize[2] = src_frame->linesize[2];
1450

    
1451
        //FIXME use direct rendering
1452
        av_picture_copy(&pict, &pict_src,
1453
                        vp->pix_fmt, vp->width, vp->height);
1454
#else
1455
        sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1456
        is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1457
            vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
1458
            dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1459
        if (is->img_convert_ctx == NULL) {
1460
            fprintf(stderr, "Cannot initialize the conversion context\n");
1461
            exit(1);
1462
        }
1463
        sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1464
                  0, vp->height, pict.data, pict.linesize);
1465
#endif
1466
        /* update the bitmap content */
1467
        SDL_UnlockYUVOverlay(vp->bmp);
1468

    
1469
        vp->pts = pts;
1470
        vp->pos = pos;
1471

    
1472
        /* now we can update the picture count */
1473
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1474
            is->pictq_windex = 0;
1475
        SDL_LockMutex(is->pictq_mutex);
1476
        vp->target_clock= compute_target_time(vp->pts, is);
1477

    
1478
        is->pictq_size++;
1479
        SDL_UnlockMutex(is->pictq_mutex);
1480
    }
1481
    return 0;
1482
}
1483

    
1484
/**
1485
 * compute the exact PTS for the picture if it is omitted in the stream
1486
 * @param pts1 the dts of the pkt / pts of the frame
1487
 */
1488
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1489
{
1490
    double frame_delay, pts;
1491

    
1492
    pts = pts1;
1493

    
1494
    if (pts != 0) {
1495
        /* update video clock with pts, if present */
1496
        is->video_clock = pts;
1497
    } else {
1498
        pts = is->video_clock;
1499
    }
1500
    /* update video clock for next frame */
1501
    frame_delay = av_q2d(is->video_st->codec->time_base);
1502
    /* for MPEG2, the frame can be repeated, so we update the
1503
       clock accordingly */
1504
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1505
    is->video_clock += frame_delay;
1506

    
1507
#if defined(DEBUG_SYNC) && 0
1508
    printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1509
           av_get_pict_type_char(src_frame->pict_type), pts, pts1);
1510
#endif
1511
    return queue_picture(is, src_frame, pts, pos);
1512
}
1513

    
1514
static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
1515
{
1516
    int len1, got_picture, i;
1517

    
1518
    if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1519
        return -1;
1520

    
1521
    if (pkt->data == flush_pkt.data) {
1522
        avcodec_flush_buffers(is->video_st->codec);
1523

    
1524
        SDL_LockMutex(is->pictq_mutex);
1525
        //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1526
        for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
1527
            is->pictq[i].target_clock= 0;
1528
        }
1529
        while (is->pictq_size && !is->videoq.abort_request) {
1530
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1531
        }
1532
        is->video_current_pos = -1;
1533
        SDL_UnlockMutex(is->pictq_mutex);
1534

    
1535
        is->frame_last_pts = AV_NOPTS_VALUE;
1536
        is->frame_last_delay = 0;
1537
        is->frame_timer = (double)av_gettime() / 1000000.0;
1538
        is->skip_frames = 1;
1539
        is->skip_frames_index = 0;
1540
        return 0;
1541
    }
1542

    
1543
    len1 = avcodec_decode_video2(is->video_st->codec,
1544
                                 frame, &got_picture,
1545
                                 pkt);
1546

    
1547
    if (got_picture) {
1548
        if (decoder_reorder_pts == -1) {
1549
            *pts = frame->best_effort_timestamp;
1550
        } else if (decoder_reorder_pts) {
1551
            *pts = frame->pkt_pts;
1552
        } else {
1553
            *pts = frame->pkt_dts;
1554
        }
1555

    
1556
        if (*pts == AV_NOPTS_VALUE) {
1557
            *pts = 0;
1558
        }
1559

    
1560
        is->skip_frames_index += 1;
1561
        if(is->skip_frames_index >= is->skip_frames){
1562
            is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
1563
            return 1;
1564
        }
1565

    
1566
    }
1567
    return 0;
1568
}
1569

    
1570
#if CONFIG_AVFILTER
1571
typedef struct {
1572
    VideoState *is;
1573
    AVFrame *frame;
1574
    int use_dr1;
1575
} FilterPriv;
1576

    
1577
static int input_get_buffer(AVCodecContext *codec, AVFrame *pic)
1578
{
1579
    AVFilterContext *ctx = codec->opaque;
1580
    AVFilterBufferRef  *ref;
1581
    int perms = AV_PERM_WRITE;
1582
    int i, w, h, stride[4];
1583
    unsigned edge;
1584

    
1585
    if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
1586
        perms |= AV_PERM_NEG_LINESIZES;
1587

    
1588
    if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
1589
        if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
1590
        if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
1591
        if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2;
1592
    }
1593
    if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE;
1594

    
1595
    w = codec->width;
1596
    h = codec->height;
1597

    
1598
    if(av_image_check_size(w, h, 0, codec))
1599
        return -1;
1600

    
1601
    avcodec_align_dimensions2(codec, &w, &h, stride);
1602
    edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width();
1603
    w += edge << 1;
1604
    h += edge << 1;
1605

    
1606
    if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
1607
        return -1;
1608

    
1609
    ref->video->w = codec->width;
1610
    ref->video->h = codec->height;
1611
    for(i = 0; i < 4; i ++) {
1612
        unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
1613
        unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
1614

    
1615
        if (ref->data[i]) {
1616
            ref->data[i]    += (edge >> hshift) + ((edge * ref->linesize[i]) >> vshift);
1617
        }
1618
        pic->data[i]     = ref->data[i];
1619
        pic->linesize[i] = ref->linesize[i];
1620
    }
1621
    pic->opaque = ref;
1622
    pic->age    = INT_MAX;
1623
    pic->type   = FF_BUFFER_TYPE_USER;
1624
    pic->reordered_opaque = codec->reordered_opaque;
1625
    if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
1626
    else           pic->pkt_pts = AV_NOPTS_VALUE;
1627
    return 0;
1628
}
1629

    
1630
static void input_release_buffer(AVCodecContext *codec, AVFrame *pic)
1631
{
1632
    memset(pic->data, 0, sizeof(pic->data));
1633
    avfilter_unref_buffer(pic->opaque);
1634
}
1635

    
1636
static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic)
1637
{
1638
    AVFilterBufferRef *ref = pic->opaque;
1639

    
1640
    if (pic->data[0] == NULL) {
1641
        pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
1642
        return codec->get_buffer(codec, pic);
1643
    }
1644

    
1645
    if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
1646
        (codec->pix_fmt != ref->format)) {
1647
        av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
1648
        return -1;
1649
    }
1650

    
1651
    pic->reordered_opaque = codec->reordered_opaque;
1652
    if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
1653
    else           pic->pkt_pts = AV_NOPTS_VALUE;
1654
    return 0;
1655
}
1656

    
1657
static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1658
{
1659
    FilterPriv *priv = ctx->priv;
1660
    AVCodecContext *codec;
1661
    if(!opaque) return -1;
1662

    
1663
    priv->is = opaque;
1664
    codec    = priv->is->video_st->codec;
1665
    codec->opaque = ctx;
1666
    if((codec->codec->capabilities & CODEC_CAP_DR1)
1667
       && codec->codec_id != CODEC_ID_SVQ1 //chroma alignment from lavfi is insufficient
1668
    ) {
1669
        priv->use_dr1 = 1;
1670
        codec->get_buffer     = input_get_buffer;
1671
        codec->release_buffer = input_release_buffer;
1672
        codec->reget_buffer   = input_reget_buffer;
1673
        codec->thread_safe_callbacks = 1;
1674
    }
1675

    
1676
    priv->frame = avcodec_alloc_frame();
1677

    
1678
    return 0;
1679
}
1680

    
1681
static void input_uninit(AVFilterContext *ctx)
1682
{
1683
    FilterPriv *priv = ctx->priv;
1684
    av_free(priv->frame);
1685
}
1686

    
1687
static int input_request_frame(AVFilterLink *link)
1688
{
1689
    FilterPriv *priv = link->src->priv;
1690
    AVFilterBufferRef *picref;
1691
    int64_t pts = 0;
1692
    AVPacket pkt;
1693
    int ret;
1694

    
1695
    while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1696
        av_free_packet(&pkt);
1697
    if (ret < 0)
1698
        return -1;
1699

    
1700
    if(priv->use_dr1) {
1701
        picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
1702
    } else {
1703
        picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
1704
        av_image_copy(picref->data, picref->linesize,
1705
                      priv->frame->data, priv->frame->linesize,
1706
                      picref->format, link->w, link->h);
1707
    }
1708
    av_free_packet(&pkt);
1709

    
1710
    picref->pts = pts;
1711
    picref->pos = pkt.pos;
1712
    picref->video->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
1713
    avfilter_start_frame(link, picref);
1714
    avfilter_draw_slice(link, 0, link->h, 1);
1715
    avfilter_end_frame(link);
1716

    
1717
    return 0;
1718
}
1719

    
1720
static int input_query_formats(AVFilterContext *ctx)
1721
{
1722
    FilterPriv *priv = ctx->priv;
1723
    enum PixelFormat pix_fmts[] = {
1724
        priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1725
    };
1726

    
1727
    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1728
    return 0;
1729
}
1730

    
1731
static int input_config_props(AVFilterLink *link)
1732
{
1733
    FilterPriv *priv  = link->src->priv;
1734
    AVCodecContext *c = priv->is->video_st->codec;
1735

    
1736
    link->w = c->width;
1737
    link->h = c->height;
1738
    link->time_base = priv->is->video_st->time_base;
1739

    
1740
    return 0;
1741
}
1742

    
1743
static AVFilter input_filter =
1744
{
1745
    .name      = "ffplay_input",
1746

    
1747
    .priv_size = sizeof(FilterPriv),
1748

    
1749
    .init      = input_init,
1750
    .uninit    = input_uninit,
1751

    
1752
    .query_formats = input_query_formats,
1753

    
1754
    .inputs    = (AVFilterPad[]) {{ .name = NULL }},
1755
    .outputs   = (AVFilterPad[]) {{ .name = "default",
1756
                                    .type = AVMEDIA_TYPE_VIDEO,
1757
                                    .request_frame = input_request_frame,
1758
                                    .config_props  = input_config_props, },
1759
                                  { .name = NULL }},
1760
};
1761

    
1762
static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
1763
{
1764
    char sws_flags_str[128];
1765
    int ret;
1766
    FFSinkContext ffsink_ctx = { .pix_fmt = PIX_FMT_YUV420P };
1767
    AVFilterContext *filt_src = NULL, *filt_out = NULL;
1768
    snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
1769
    graph->scale_sws_opts = av_strdup(sws_flags_str);
1770

    
1771
    if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
1772
                                            NULL, is, graph)) < 0)
1773
        goto the_end;
1774
    if ((ret = avfilter_graph_create_filter(&filt_out, &ffsink, "out",
1775
                                            NULL, &ffsink_ctx, graph)) < 0)
1776
        goto the_end;
1777

    
1778
    if(vfilters) {
1779
        AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
1780
        AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
1781

    
1782
        outputs->name    = av_strdup("in");
1783
        outputs->filter_ctx = filt_src;
1784
        outputs->pad_idx = 0;
1785
        outputs->next    = NULL;
1786

    
1787
        inputs->name    = av_strdup("out");
1788
        inputs->filter_ctx = filt_out;
1789
        inputs->pad_idx = 0;
1790
        inputs->next    = NULL;
1791

    
1792
        if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
1793
            goto the_end;
1794
        av_freep(&vfilters);
1795
    } else {
1796
        if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
1797
            goto the_end;
1798
    }
1799

    
1800
    if ((ret = avfilter_graph_config(graph, NULL)) < 0)
1801
        goto the_end;
1802

    
1803
    is->out_video_filter = filt_out;
1804
the_end:
1805
    return ret;
1806
}
1807

    
1808
#endif  /* CONFIG_AVFILTER */
1809

    
1810
static int video_thread(void *arg)
1811
{
1812
    VideoState *is = arg;
1813
    AVFrame *frame= avcodec_alloc_frame();
1814
    int64_t pts_int;
1815
    double pts;
1816
    int ret;
1817

    
1818
#if CONFIG_AVFILTER
1819
    AVFilterGraph *graph = avfilter_graph_alloc();
1820
    AVFilterContext *filt_out = NULL;
1821
    int64_t pos;
1822

    
1823
    if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
1824
        goto the_end;
1825
    filt_out = is->out_video_filter;
1826
#endif
1827

    
1828
    for(;;) {
1829
#if !CONFIG_AVFILTER
1830
        AVPacket pkt;
1831
#else
1832
        AVFilterBufferRef *picref;
1833
        AVRational tb;
1834
#endif
1835
        while (is->paused && !is->videoq.abort_request)
1836
            SDL_Delay(10);
1837
#if CONFIG_AVFILTER
1838
        ret = get_filtered_video_frame(filt_out, frame, &picref, &tb);
1839
        if (picref) {
1840
            pts_int = picref->pts;
1841
            pos     = picref->pos;
1842
            frame->opaque = picref;
1843
        }
1844

    
1845
        if (av_cmp_q(tb, is->video_st->time_base)) {
1846
            av_unused int64_t pts1 = pts_int;
1847
            pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
1848
            av_dlog(NULL, "video_thread(): "
1849
                    "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
1850
                    tb.num, tb.den, pts1,
1851
                    is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
1852
        }
1853
#else
1854
        ret = get_video_frame(is, frame, &pts_int, &pkt);
1855
#endif
1856

    
1857
        if (ret < 0) goto the_end;
1858

    
1859
        if (!ret)
1860
            continue;
1861

    
1862
        pts = pts_int*av_q2d(is->video_st->time_base);
1863

    
1864
#if CONFIG_AVFILTER
1865
        ret = output_picture2(is, frame, pts, pos);
1866
#else
1867
        ret = output_picture2(is, frame, pts,  pkt.pos);
1868
        av_free_packet(&pkt);
1869
#endif
1870
        if (ret < 0)
1871
            goto the_end;
1872

    
1873
        if (step)
1874
            if (cur_stream)
1875
                stream_pause(cur_stream);
1876
    }
1877
 the_end:
1878
#if CONFIG_AVFILTER
1879
    avfilter_graph_free(&graph);
1880
#endif
1881
    av_free(frame);
1882
    return 0;
1883
}
1884

    
1885
static int subtitle_thread(void *arg)
1886
{
1887
    VideoState *is = arg;
1888
    SubPicture *sp;
1889
    AVPacket pkt1, *pkt = &pkt1;
1890
    int len1, got_subtitle;
1891
    double pts;
1892
    int i, j;
1893
    int r, g, b, y, u, v, a;
1894

    
1895
    for(;;) {
1896
        while (is->paused && !is->subtitleq.abort_request) {
1897
            SDL_Delay(10);
1898
        }
1899
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1900
            break;
1901

    
1902
        if(pkt->data == flush_pkt.data){
1903
            avcodec_flush_buffers(is->subtitle_st->codec);
1904
            continue;
1905
        }
1906
        SDL_LockMutex(is->subpq_mutex);
1907
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1908
               !is->subtitleq.abort_request) {
1909
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1910
        }
1911
        SDL_UnlockMutex(is->subpq_mutex);
1912

    
1913
        if (is->subtitleq.abort_request)
1914
            goto the_end;
1915

    
1916
        sp = &is->subpq[is->subpq_windex];
1917

    
1918
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1919
           this packet, if any */
1920
        pts = 0;
1921
        if (pkt->pts != AV_NOPTS_VALUE)
1922
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1923

    
1924
        len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1925
                                    &sp->sub, &got_subtitle,
1926
                                    pkt);
1927
//            if (len1 < 0)
1928
//                break;
1929
        if (got_subtitle && sp->sub.format == 0) {
1930
            sp->pts = pts;
1931

    
1932
            for (i = 0; i < sp->sub.num_rects; i++)
1933
            {
1934
                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1935
                {
1936
                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1937
                    y = RGB_TO_Y_CCIR(r, g, b);
1938
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1939
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1940
                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1941
                }
1942
            }
1943

    
1944
            /* now we can update the picture count */
1945
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1946
                is->subpq_windex = 0;
1947
            SDL_LockMutex(is->subpq_mutex);
1948
            is->subpq_size++;
1949
            SDL_UnlockMutex(is->subpq_mutex);
1950
        }
1951
        av_free_packet(pkt);
1952
//        if (step)
1953
//            if (cur_stream)
1954
//                stream_pause(cur_stream);
1955
    }
1956
 the_end:
1957
    return 0;
1958
}
1959

    
1960
/* copy samples for viewing in editor window */
1961
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1962
{
1963
    int size, len, channels;
1964

    
1965
    channels = is->audio_st->codec->channels;
1966

    
1967
    size = samples_size / sizeof(short);
1968
    while (size > 0) {
1969
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1970
        if (len > size)
1971
            len = size;
1972
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1973
        samples += len;
1974
        is->sample_array_index += len;
1975
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1976
            is->sample_array_index = 0;
1977
        size -= len;
1978
    }
1979
}
1980

    
1981
/* return the new audio buffer size (samples can be added or deleted
1982
   to get better sync if video or external master clock) */
1983
static int synchronize_audio(VideoState *is, short *samples,
1984
                             int samples_size1, double pts)
1985
{
1986
    int n, samples_size;
1987
    double ref_clock;
1988

    
1989
    n = 2 * is->audio_st->codec->channels;
1990
    samples_size = samples_size1;
1991

    
1992
    /* if not master, then we try to remove or add samples to correct the clock */
1993
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1994
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1995
        double diff, avg_diff;
1996
        int wanted_size, min_size, max_size, nb_samples;
1997

    
1998
        ref_clock = get_master_clock(is);
1999
        diff = get_audio_clock(is) - ref_clock;
2000

    
2001
        if (diff < AV_NOSYNC_THRESHOLD) {
2002
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
2003
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
2004
                /* not enough measures to have a correct estimate */
2005
                is->audio_diff_avg_count++;
2006
            } else {
2007
                /* estimate the A-V difference */
2008
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
2009

    
2010
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
2011
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
2012
                    nb_samples = samples_size / n;
2013

    
2014
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
2015
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
2016
                    if (wanted_size < min_size)
2017
                        wanted_size = min_size;
2018
                    else if (wanted_size > max_size)
2019
                        wanted_size = max_size;
2020

    
2021
                    /* add or remove samples to correction the synchro */
2022
                    if (wanted_size < samples_size) {
2023
                        /* remove samples */
2024
                        samples_size = wanted_size;
2025
                    } else if (wanted_size > samples_size) {
2026
                        uint8_t *samples_end, *q;
2027
                        int nb;
2028

    
2029
                        /* add samples */
2030
                        nb = (samples_size - wanted_size);
2031
                        samples_end = (uint8_t *)samples + samples_size - n;
2032
                        q = samples_end + n;
2033
                        while (nb > 0) {
2034
                            memcpy(q, samples_end, n);
2035
                            q += n;
2036
                            nb -= n;
2037
                        }
2038
                        samples_size = wanted_size;
2039
                    }
2040
                }
2041
#if 0
2042
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
2043
                       diff, avg_diff, samples_size - samples_size1,
2044
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
2045
#endif
2046
            }
2047
        } else {
2048
            /* too big difference : may be initial PTS errors, so
2049
               reset A-V filter */
2050
            is->audio_diff_avg_count = 0;
2051
            is->audio_diff_cum = 0;
2052
        }
2053
    }
2054

    
2055
    return samples_size;
2056
}
2057

    
2058
/* decode one audio frame and returns its uncompressed size */
2059
static int audio_decode_frame(VideoState *is, double *pts_ptr)
2060
{
2061
    AVPacket *pkt_temp = &is->audio_pkt_temp;
2062
    AVPacket *pkt = &is->audio_pkt;
2063
    AVCodecContext *dec= is->audio_st->codec;
2064
    int n, len1, data_size;
2065
    double pts;
2066

    
2067
    for(;;) {
2068
        /* NOTE: the audio packet can contain several frames */
2069
        while (pkt_temp->size > 0) {
2070
            data_size = sizeof(is->audio_buf1);
2071
            len1 = avcodec_decode_audio3(dec,
2072
                                        (int16_t *)is->audio_buf1, &data_size,
2073
                                        pkt_temp);
2074
            if (len1 < 0) {
2075
                /* if error, we skip the frame */
2076
                pkt_temp->size = 0;
2077
                break;
2078
            }
2079

    
2080
            pkt_temp->data += len1;
2081
            pkt_temp->size -= len1;
2082
            if (data_size <= 0)
2083
                continue;
2084

    
2085
            if (dec->sample_fmt != is->audio_src_fmt) {
2086
                if (is->reformat_ctx)
2087
                    av_audio_convert_free(is->reformat_ctx);
2088
                is->reformat_ctx= av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
2089
                                                         dec->sample_fmt, 1, NULL, 0);
2090
                if (!is->reformat_ctx) {
2091
                    fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
2092
                        av_get_sample_fmt_name(dec->sample_fmt),
2093
                        av_get_sample_fmt_name(AV_SAMPLE_FMT_S16));
2094
                        break;
2095
                }
2096
                is->audio_src_fmt= dec->sample_fmt;
2097
            }
2098

    
2099
            if (is->reformat_ctx) {
2100
                const void *ibuf[6]= {is->audio_buf1};
2101
                void *obuf[6]= {is->audio_buf2};
2102
                int istride[6]= {av_get_bits_per_sample_fmt(dec->sample_fmt)/8};
2103
                int ostride[6]= {2};
2104
                int len= data_size/istride[0];
2105
                if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
2106
                    printf("av_audio_convert() failed\n");
2107
                    break;
2108
                }
2109
                is->audio_buf= is->audio_buf2;
2110
                /* FIXME: existing code assume that data_size equals framesize*channels*2
2111
                          remove this legacy cruft */
2112
                data_size= len*2;
2113
            }else{
2114
                is->audio_buf= is->audio_buf1;
2115
            }
2116

    
2117
            /* if no pts, then compute it */
2118
            pts = is->audio_clock;
2119
            *pts_ptr = pts;
2120
            n = 2 * dec->channels;
2121
            is->audio_clock += (double)data_size /
2122
                (double)(n * dec->sample_rate);
2123
#if defined(DEBUG_SYNC)
2124
            {
2125
                static double last_clock;
2126
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
2127
                       is->audio_clock - last_clock,
2128
                       is->audio_clock, pts);
2129
                last_clock = is->audio_clock;
2130
            }
2131
#endif
2132
            return data_size;
2133
        }
2134

    
2135
        /* free the current packet */
2136
        if (pkt->data)
2137
            av_free_packet(pkt);
2138

    
2139
        if (is->paused || is->audioq.abort_request) {
2140
            return -1;
2141
        }
2142

    
2143
        /* read next packet */
2144
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
2145
            return -1;
2146
        if(pkt->data == flush_pkt.data){
2147
            avcodec_flush_buffers(dec);
2148
            continue;
2149
        }
2150

    
2151
        pkt_temp->data = pkt->data;
2152
        pkt_temp->size = pkt->size;
2153

    
2154
        /* if update the audio clock with the pts */
2155
        if (pkt->pts != AV_NOPTS_VALUE) {
2156
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
2157
        }
2158
    }
2159
}
2160

    
2161
/* get the current audio output buffer size, in samples. With SDL, we
2162
   cannot have a precise information */
2163
static int audio_write_get_buf_size(VideoState *is)
2164
{
2165
    return is->audio_buf_size - is->audio_buf_index;
2166
}
2167

    
2168

    
2169
/* prepare a new audio buffer */
2170
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2171
{
2172
    VideoState *is = opaque;
2173
    int audio_size, len1;
2174
    double pts;
2175

    
2176
    audio_callback_time = av_gettime();
2177

    
2178
    while (len > 0) {
2179
        if (is->audio_buf_index >= is->audio_buf_size) {
2180
           audio_size = audio_decode_frame(is, &pts);
2181
           if (audio_size < 0) {
2182
                /* if error, just output silence */
2183
               is->audio_buf = is->audio_buf1;
2184
               is->audio_buf_size = 1024;
2185
               memset(is->audio_buf, 0, is->audio_buf_size);
2186
           } else {
2187
               if (is->show_audio)
2188
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2189
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
2190
                                              pts);
2191
               is->audio_buf_size = audio_size;
2192
           }
2193
           is->audio_buf_index = 0;
2194
        }
2195
        len1 = is->audio_buf_size - is->audio_buf_index;
2196
        if (len1 > len)
2197
            len1 = len;
2198
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2199
        len -= len1;
2200
        stream += len1;
2201
        is->audio_buf_index += len1;
2202
    }
2203
}
2204

    
2205
/* open a given stream. Return 0 if OK */
2206
static int stream_component_open(VideoState *is, int stream_index)
2207
{
2208
    AVFormatContext *ic = is->ic;
2209
    AVCodecContext *avctx;
2210
    AVCodec *codec;
2211
    SDL_AudioSpec wanted_spec, spec;
2212

    
2213
    if (stream_index < 0 || stream_index >= ic->nb_streams)
2214
        return -1;
2215
    avctx = ic->streams[stream_index]->codec;
2216

    
2217
    /* prepare audio output */
2218
    if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2219
        if (avctx->channels > 0) {
2220
            avctx->request_channels = FFMIN(2, avctx->channels);
2221
        } else {
2222
            avctx->request_channels = 2;
2223
        }
2224
    }
2225

    
2226
    codec = avcodec_find_decoder(avctx->codec_id);
2227
    avctx->debug_mv = debug_mv;
2228
    avctx->debug = debug;
2229
    avctx->workaround_bugs = workaround_bugs;
2230
    avctx->lowres = lowres;
2231
    if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2232
    avctx->idct_algo= idct;
2233
    if(fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2234
    avctx->skip_frame= skip_frame;
2235
    avctx->skip_idct= skip_idct;
2236
    avctx->skip_loop_filter= skip_loop_filter;
2237
    avctx->error_recognition= error_recognition;
2238
    avctx->error_concealment= error_concealment;
2239
    avctx->thread_count= thread_count;
2240

    
2241
    set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0, codec);
2242

    
2243
    if (!codec ||
2244
        avcodec_open(avctx, codec) < 0)
2245
        return -1;
2246

    
2247
    /* prepare audio output */
2248
    if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
2249
        wanted_spec.freq = avctx->sample_rate;
2250
        wanted_spec.format = AUDIO_S16SYS;
2251
        wanted_spec.channels = avctx->channels;
2252
        wanted_spec.silence = 0;
2253
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2254
        wanted_spec.callback = sdl_audio_callback;
2255
        wanted_spec.userdata = is;
2256
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2257
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2258
            return -1;
2259
        }
2260
        is->audio_hw_buf_size = spec.size;
2261
        is->audio_src_fmt= AV_SAMPLE_FMT_S16;
2262
    }
2263

    
2264
    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2265
    switch(avctx->codec_type) {
2266
    case AVMEDIA_TYPE_AUDIO:
2267
        is->audio_stream = stream_index;
2268
        is->audio_st = ic->streams[stream_index];
2269
        is->audio_buf_size = 0;
2270
        is->audio_buf_index = 0;
2271

    
2272
        /* init averaging filter */
2273
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2274
        is->audio_diff_avg_count = 0;
2275
        /* since we do not have a precise anough audio fifo fullness,
2276
           we correct audio sync only if larger than this threshold */
2277
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
2278

    
2279
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2280
        packet_queue_init(&is->audioq);
2281
        SDL_PauseAudio(0);
2282
        break;
2283
    case AVMEDIA_TYPE_VIDEO:
2284
        is->video_stream = stream_index;
2285
        is->video_st = ic->streams[stream_index];
2286

    
2287
//        is->video_current_pts_time = av_gettime();
2288

    
2289
        packet_queue_init(&is->videoq);
2290
        is->video_tid = SDL_CreateThread(video_thread, is);
2291
        break;
2292
    case AVMEDIA_TYPE_SUBTITLE:
2293
        is->subtitle_stream = stream_index;
2294
        is->subtitle_st = ic->streams[stream_index];
2295
        packet_queue_init(&is->subtitleq);
2296

    
2297
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2298
        break;
2299
    default:
2300
        break;
2301
    }
2302
    return 0;
2303
}
2304

    
2305
static void stream_component_close(VideoState *is, int stream_index)
2306
{
2307
    AVFormatContext *ic = is->ic;
2308
    AVCodecContext *avctx;
2309

    
2310
    if (stream_index < 0 || stream_index >= ic->nb_streams)
2311
        return;
2312
    avctx = ic->streams[stream_index]->codec;
2313

    
2314
    switch(avctx->codec_type) {
2315
    case AVMEDIA_TYPE_AUDIO:
2316
        packet_queue_abort(&is->audioq);
2317

    
2318
        SDL_CloseAudio();
2319

    
2320
        packet_queue_end(&is->audioq);
2321
        if (is->reformat_ctx)
2322
            av_audio_convert_free(is->reformat_ctx);
2323
        is->reformat_ctx = NULL;
2324
        break;
2325
    case AVMEDIA_TYPE_VIDEO:
2326
        packet_queue_abort(&is->videoq);
2327

    
2328
        /* note: we also signal this mutex to make sure we deblock the
2329
           video thread in all cases */
2330
        SDL_LockMutex(is->pictq_mutex);
2331
        SDL_CondSignal(is->pictq_cond);
2332
        SDL_UnlockMutex(is->pictq_mutex);
2333

    
2334
        SDL_WaitThread(is->video_tid, NULL);
2335

    
2336
        packet_queue_end(&is->videoq);
2337
        break;
2338
    case AVMEDIA_TYPE_SUBTITLE:
2339
        packet_queue_abort(&is->subtitleq);
2340

    
2341
        /* note: we also signal this mutex to make sure we deblock the
2342
           video thread in all cases */
2343
        SDL_LockMutex(is->subpq_mutex);
2344
        is->subtitle_stream_changed = 1;
2345

    
2346
        SDL_CondSignal(is->subpq_cond);
2347
        SDL_UnlockMutex(is->subpq_mutex);
2348

    
2349
        SDL_WaitThread(is->subtitle_tid, NULL);
2350

    
2351
        packet_queue_end(&is->subtitleq);
2352
        break;
2353
    default:
2354
        break;
2355
    }
2356

    
2357
    ic->streams[stream_index]->discard = AVDISCARD_ALL;
2358
    avcodec_close(avctx);
2359
    switch(avctx->codec_type) {
2360
    case AVMEDIA_TYPE_AUDIO:
2361
        is->audio_st = NULL;
2362
        is->audio_stream = -1;
2363
        break;
2364
    case AVMEDIA_TYPE_VIDEO:
2365
        is->video_st = NULL;
2366
        is->video_stream = -1;
2367
        break;
2368
    case AVMEDIA_TYPE_SUBTITLE:
2369
        is->subtitle_st = NULL;
2370
        is->subtitle_stream = -1;
2371
        break;
2372
    default:
2373
        break;
2374
    }
2375
}
2376

    
2377
/* since we have only one decoding thread, we can use a global
2378
   variable instead of a thread local variable */
2379
static VideoState *global_video_state;
2380

    
2381
static int decode_interrupt_cb(void)
2382
{
2383
    return (global_video_state && global_video_state->abort_request);
2384
}
2385

    
2386
/* this thread gets the stream from the disk or the network */
2387
static int decode_thread(void *arg)
2388
{
2389
    VideoState *is = arg;
2390
    AVFormatContext *ic;
2391
    int err, i, ret;
2392
    int st_index[AVMEDIA_TYPE_NB];
2393
    AVPacket pkt1, *pkt = &pkt1;
2394
    AVFormatParameters params, *ap = &params;
2395
    int eof=0;
2396
    int pkt_in_play_range = 0;
2397

    
2398
    ic = avformat_alloc_context();
2399

    
2400
    memset(st_index, -1, sizeof(st_index));
2401
    is->video_stream = -1;
2402
    is->audio_stream = -1;
2403
    is->subtitle_stream = -1;
2404

    
2405
    global_video_state = is;
2406
    url_set_interrupt_cb(decode_interrupt_cb);
2407

    
2408
    memset(ap, 0, sizeof(*ap));
2409

    
2410
    ap->prealloced_context = 1;
2411
    ap->width = frame_width;
2412
    ap->height= frame_height;
2413
    ap->time_base= (AVRational){1, 25};
2414
    ap->pix_fmt = frame_pix_fmt;
2415

    
2416
    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
2417

    
2418
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
2419
    if (err < 0) {
2420
        print_error(is->filename, err);
2421
        ret = -1;
2422
        goto fail;
2423
    }
2424
    is->ic = ic;
2425

    
2426
    if(genpts)
2427
        ic->flags |= AVFMT_FLAG_GENPTS;
2428

    
2429
    err = av_find_stream_info(ic);
2430
    if (err < 0) {
2431
        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2432
        ret = -1;
2433
        goto fail;
2434
    }
2435
    if(ic->pb)
2436
        ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
2437

    
2438
    if(seek_by_bytes<0)
2439
        seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
2440

    
2441
    /* if seeking requested, we execute it */
2442
    if (start_time != AV_NOPTS_VALUE) {
2443
        int64_t timestamp;
2444

    
2445
        timestamp = start_time;
2446
        /* add the stream start time */
2447
        if (ic->start_time != AV_NOPTS_VALUE)
2448
            timestamp += ic->start_time;
2449
        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2450
        if (ret < 0) {
2451
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
2452
                    is->filename, (double)timestamp / AV_TIME_BASE);
2453
        }
2454
    }
2455

    
2456
    for (i = 0; i < ic->nb_streams; i++)
2457
        ic->streams[i]->discard = AVDISCARD_ALL;
2458
    if (!video_disable)
2459
        st_index[AVMEDIA_TYPE_VIDEO] =
2460
            av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
2461
                                wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
2462
    if (!audio_disable)
2463
        st_index[AVMEDIA_TYPE_AUDIO] =
2464
            av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
2465
                                wanted_stream[AVMEDIA_TYPE_AUDIO],
2466
                                st_index[AVMEDIA_TYPE_VIDEO],
2467
                                NULL, 0);
2468
    if (!video_disable)
2469
        st_index[AVMEDIA_TYPE_SUBTITLE] =
2470
            av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
2471
                                wanted_stream[AVMEDIA_TYPE_SUBTITLE],
2472
                                (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
2473
                                 st_index[AVMEDIA_TYPE_AUDIO] :
2474
                                 st_index[AVMEDIA_TYPE_VIDEO]),
2475
                                NULL, 0);
2476
    if (show_status) {
2477
        av_dump_format(ic, 0, is->filename, 0);
2478
    }
2479

    
2480
    /* open the streams */
2481
    if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
2482
        stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
2483
    }
2484

    
2485
    ret=-1;
2486
    if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
2487
        ret= stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
2488
    }
2489
    is->refresh_tid = SDL_CreateThread(refresh_thread, is);
2490
    if(ret<0) {
2491
        if (!display_disable)
2492
            is->show_audio = 2;
2493
    }
2494

    
2495
    if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
2496
        stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
2497
    }
2498

    
2499
    if (is->video_stream < 0 && is->audio_stream < 0) {
2500
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
2501
        ret = -1;
2502
        goto fail;
2503
    }
2504

    
2505
    for(;;) {
2506
        if (is->abort_request)
2507
            break;
2508
        if (is->paused != is->last_paused) {
2509
            is->last_paused = is->paused;
2510
            if (is->paused)
2511
                is->read_pause_return= av_read_pause(ic);
2512
            else
2513
                av_read_play(ic);
2514
        }
2515
#if CONFIG_RTSP_DEMUXER
2516
        if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2517
            /* wait 10 ms to avoid trying to get another packet */
2518
            /* XXX: horrible */
2519
            SDL_Delay(10);
2520
            continue;
2521
        }
2522
#endif
2523
        if (is->seek_req) {
2524
            int64_t seek_target= is->seek_pos;
2525
            int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2526
            int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2527
//FIXME the +-2 is due to rounding being not done in the correct direction in generation
2528
//      of the seek_pos/seek_rel variables
2529

    
2530
            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2531
            if (ret < 0) {
2532
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2533
            }else{
2534
                if (is->audio_stream >= 0) {
2535
                    packet_queue_flush(&is->audioq);
2536
                    packet_queue_put(&is->audioq, &flush_pkt);
2537
                }
2538
                if (is->subtitle_stream >= 0) {
2539
                    packet_queue_flush(&is->subtitleq);
2540
                    packet_queue_put(&is->subtitleq, &flush_pkt);
2541
                }
2542
                if (is->video_stream >= 0) {
2543
                    packet_queue_flush(&is->videoq);
2544
                    packet_queue_put(&is->videoq, &flush_pkt);
2545
                }
2546
            }
2547
            is->seek_req = 0;
2548
            eof= 0;
2549
        }
2550

    
2551
        /* if the queue are full, no need to read more */
2552
        if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2553
            || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2554
                && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2555
                && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2556
            /* wait 10 ms */
2557
            SDL_Delay(10);
2558
            continue;
2559
        }
2560
        if(eof) {
2561
            if(is->video_stream >= 0){
2562
                av_init_packet(pkt);
2563
                pkt->data=NULL;
2564
                pkt->size=0;
2565
                pkt->stream_index= is->video_stream;
2566
                packet_queue_put(&is->videoq, pkt);
2567
            }
2568
            SDL_Delay(10);
2569
            if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
2570
                if(loop!=1 && (!loop || --loop)){
2571
                    stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
2572
                }else if(autoexit){
2573
                    ret=AVERROR_EOF;
2574
                    goto fail;
2575
                }
2576
            }
2577
            eof=0;
2578
            continue;
2579
        }
2580
        ret = av_read_frame(ic, pkt);
2581
        if (ret < 0) {
2582
            if (ret == AVERROR_EOF || url_feof(ic->pb))
2583
                eof=1;
2584
            if (ic->pb && ic->pb->error)
2585
                break;
2586
            SDL_Delay(100); /* wait for user event */
2587
            continue;
2588
        }
2589
        /* check if packet is in play range specified by user, then queue, otherwise discard */
2590
        pkt_in_play_range = duration == AV_NOPTS_VALUE ||
2591
                (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
2592
                av_q2d(ic->streams[pkt->stream_index]->time_base) -
2593
                (double)(start_time != AV_NOPTS_VALUE ? start_time : 0)/1000000
2594
                <= ((double)duration/1000000);
2595
        if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
2596
            packet_queue_put(&is->audioq, pkt);
2597
        } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
2598
            packet_queue_put(&is->videoq, pkt);
2599
        } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
2600
            packet_queue_put(&is->subtitleq, pkt);
2601
        } else {
2602
            av_free_packet(pkt);
2603
        }
2604
    }
2605
    /* wait until the end */
2606
    while (!is->abort_request) {
2607
        SDL_Delay(100);
2608
    }
2609

    
2610
    ret = 0;
2611
 fail:
2612
    /* disable interrupting */
2613
    global_video_state = NULL;
2614

    
2615
    /* close each stream */
2616
    if (is->audio_stream >= 0)
2617
        stream_component_close(is, is->audio_stream);
2618
    if (is->video_stream >= 0)
2619
        stream_component_close(is, is->video_stream);
2620
    if (is->subtitle_stream >= 0)
2621
        stream_component_close(is, is->subtitle_stream);
2622
    if (is->ic) {
2623
        av_close_input_file(is->ic);
2624
        is->ic = NULL; /* safety */
2625
    }
2626
    url_set_interrupt_cb(NULL);
2627

    
2628
    if (ret != 0) {
2629
        SDL_Event event;
2630

    
2631
        event.type = FF_QUIT_EVENT;
2632
        event.user.data1 = is;
2633
        SDL_PushEvent(&event);
2634
    }
2635
    return 0;
2636
}
2637

    
2638
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2639
{
2640
    VideoState *is;
2641

    
2642
    is = av_mallocz(sizeof(VideoState));
2643
    if (!is)
2644
        return NULL;
2645
    av_strlcpy(is->filename, filename, sizeof(is->filename));
2646
    is->iformat = iformat;
2647
    is->ytop = 0;
2648
    is->xleft = 0;
2649

    
2650
    /* start video display */
2651
    is->pictq_mutex = SDL_CreateMutex();
2652
    is->pictq_cond = SDL_CreateCond();
2653

    
2654
    is->subpq_mutex = SDL_CreateMutex();
2655
    is->subpq_cond = SDL_CreateCond();
2656

    
2657
    is->av_sync_type = av_sync_type;
2658
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2659
    if (!is->parse_tid) {
2660
        av_free(is);
2661
        return NULL;
2662
    }
2663
    return is;
2664
}
2665

    
2666
static void stream_cycle_channel(VideoState *is, int codec_type)
2667
{
2668
    AVFormatContext *ic = is->ic;
2669
    int start_index, stream_index;
2670
    AVStream *st;
2671

    
2672
    if (codec_type == AVMEDIA_TYPE_VIDEO)
2673
        start_index = is->video_stream;
2674
    else if (codec_type == AVMEDIA_TYPE_AUDIO)
2675
        start_index = is->audio_stream;
2676
    else
2677
        start_index = is->subtitle_stream;
2678
    if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
2679
        return;
2680
    stream_index = start_index;
2681
    for(;;) {
2682
        if (++stream_index >= is->ic->nb_streams)
2683
        {
2684
            if (codec_type == AVMEDIA_TYPE_SUBTITLE)
2685
            {
2686
                stream_index = -1;
2687
                goto the_end;
2688
            } else
2689
                stream_index = 0;
2690
        }
2691
        if (stream_index == start_index)
2692
            return;
2693
        st = ic->streams[stream_index];
2694
        if (st->codec->codec_type == codec_type) {
2695
            /* check that parameters are OK */
2696
            switch(codec_type) {
2697
            case AVMEDIA_TYPE_AUDIO:
2698
                if (st->codec->sample_rate != 0 &&
2699
                    st->codec->channels != 0)
2700
                    goto the_end;
2701
                break;
2702
            case AVMEDIA_TYPE_VIDEO:
2703
            case AVMEDIA_TYPE_SUBTITLE:
2704
                goto the_end;
2705
            default:
2706
                break;
2707
            }
2708
        }
2709
    }
2710
 the_end:
2711
    stream_component_close(is, start_index);
2712
    stream_component_open(is, stream_index);
2713
}
2714

    
2715

    
2716
static void toggle_full_screen(void)
2717
{
2718
    is_full_screen = !is_full_screen;
2719
    if (!fs_screen_width) {
2720
        /* use default SDL method */
2721
//        SDL_WM_ToggleFullScreen(screen);
2722
    }
2723
    video_open(cur_stream);
2724
}
2725

    
2726
static void toggle_pause(void)
2727
{
2728
    if (cur_stream)
2729
        stream_pause(cur_stream);
2730
    step = 0;
2731
}
2732

    
2733
static void step_to_next_frame(void)
2734
{
2735
    if (cur_stream) {
2736
        /* if the stream is paused unpause it, then step */
2737
        if (cur_stream->paused)
2738
            stream_pause(cur_stream);
2739
    }
2740
    step = 1;
2741
}
2742

    
2743
static void toggle_audio_display(void)
2744
{
2745
    if (cur_stream) {
2746
        int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
2747
        cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
2748
        fill_rectangle(screen,
2749
                    cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
2750
                    bgcolor);
2751
        SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
2752
    }
2753
}
2754

    
2755
/* handle an event sent by the GUI */
2756
static void event_loop(void)
2757
{
2758
    SDL_Event event;
2759
    double incr, pos, frac;
2760

    
2761
    for(;;) {
2762
        double x;
2763
        SDL_WaitEvent(&event);
2764
        switch(event.type) {
2765
        case SDL_KEYDOWN:
2766
            if (exit_on_keydown) {
2767
                do_exit();
2768
                break;
2769
            }
2770
            switch(event.key.keysym.sym) {
2771
            case SDLK_ESCAPE:
2772
            case SDLK_q:
2773
                do_exit();
2774
                break;
2775
            case SDLK_f:
2776
                toggle_full_screen();
2777
                break;
2778
            case SDLK_p:
2779
            case SDLK_SPACE:
2780
                toggle_pause();
2781
                break;
2782
            case SDLK_s: //S: Step to next frame
2783
                step_to_next_frame();
2784
                break;
2785
            case SDLK_a:
2786
                if (cur_stream)
2787
                    stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
2788
                break;
2789
            case SDLK_v:
2790
                if (cur_stream)
2791
                    stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
2792
                break;
2793
            case SDLK_t:
2794
                if (cur_stream)
2795
                    stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
2796
                break;
2797
            case SDLK_w:
2798
                toggle_audio_display();
2799
                break;
2800
            case SDLK_LEFT:
2801
                incr = -10.0;
2802
                goto do_seek;
2803
            case SDLK_RIGHT:
2804
                incr = 10.0;
2805
                goto do_seek;
2806
            case SDLK_UP:
2807
                incr = 60.0;
2808
                goto do_seek;
2809
            case SDLK_DOWN:
2810
                incr = -60.0;
2811
            do_seek:
2812
                if (cur_stream) {
2813
                    if (seek_by_bytes) {
2814
                        if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
2815
                            pos= cur_stream->video_current_pos;
2816
                        }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
2817
                            pos= cur_stream->audio_pkt.pos;
2818
                        }else
2819
                            pos = avio_tell(cur_stream->ic->pb);
2820
                        if (cur_stream->ic->bit_rate)
2821
                            incr *= cur_stream->ic->bit_rate / 8.0;
2822
                        else
2823
                            incr *= 180000.0;
2824
                        pos += incr;
2825
                        stream_seek(cur_stream, pos, incr, 1);
2826
                    } else {
2827
                        pos = get_master_clock(cur_stream);
2828
                        pos += incr;
2829
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2830
                    }
2831
                }
2832
                break;
2833
            default:
2834
                break;
2835
            }
2836
            break;
2837
        case SDL_MOUSEBUTTONDOWN:
2838
            if (exit_on_mousedown) {
2839
                do_exit();
2840
                break;
2841
            }
2842
        case SDL_MOUSEMOTION:
2843
            if(event.type ==SDL_MOUSEBUTTONDOWN){
2844
                x= event.button.x;
2845
            }else{
2846
                if(event.motion.state != SDL_PRESSED)
2847
                    break;
2848
                x= event.motion.x;
2849
            }
2850
            if (cur_stream) {
2851
                if(seek_by_bytes || cur_stream->ic->duration<=0){
2852
                    uint64_t size=  avio_size(cur_stream->ic->pb);
2853
                    stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
2854
                }else{
2855
                    int64_t ts;
2856
                    int ns, hh, mm, ss;
2857
                    int tns, thh, tmm, tss;
2858
                    tns = cur_stream->ic->duration/1000000LL;
2859
                    thh = tns/3600;
2860
                    tmm = (tns%3600)/60;
2861
                    tss = (tns%60);
2862
                    frac = x/cur_stream->width;
2863
                    ns = frac*tns;
2864
                    hh = ns/3600;
2865
                    mm = (ns%3600)/60;
2866
                    ss = (ns%60);
2867
                    fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2868
                            hh, mm, ss, thh, tmm, tss);
2869
                    ts = frac*cur_stream->ic->duration;
2870
                    if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2871
                        ts += cur_stream->ic->start_time;
2872
                    stream_seek(cur_stream, ts, 0, 0);
2873
                }
2874
            }
2875
            break;
2876
        case SDL_VIDEORESIZE:
2877
            if (cur_stream) {
2878
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2879
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2880
                screen_width = cur_stream->width = event.resize.w;
2881
                screen_height= cur_stream->height= event.resize.h;
2882
            }
2883
            break;
2884
        case SDL_QUIT:
2885
        case FF_QUIT_EVENT:
2886
            do_exit();
2887
            break;
2888
        case FF_ALLOC_EVENT:
2889
            video_open(event.user.data1);
2890
            alloc_picture(event.user.data1);
2891
            break;
2892
        case FF_REFRESH_EVENT:
2893
            video_refresh_timer(event.user.data1);
2894
            cur_stream->refresh=0;
2895
            break;
2896
        default:
2897
            break;
2898
        }
2899
    }
2900
}
2901

    
2902
static void opt_frame_size(const char *arg)
2903
{
2904
    if (av_parse_video_size(&frame_width, &frame_height, arg) < 0) {
2905
        fprintf(stderr, "Incorrect frame size\n");
2906
        exit(1);
2907
    }
2908
    if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2909
        fprintf(stderr, "Frame size must be a multiple of 2\n");
2910
        exit(1);
2911
    }
2912
}
2913

    
2914
static int opt_width(const char *opt, const char *arg)
2915
{
2916
    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2917
    return 0;
2918
}
2919

    
2920
static int opt_height(const char *opt, const char *arg)
2921
{
2922
    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2923
    return 0;
2924
}
2925

    
2926
static void opt_format(const char *arg)
2927
{
2928
    file_iformat = av_find_input_format(arg);
2929
    if (!file_iformat) {
2930
        fprintf(stderr, "Unknown input format: %s\n", arg);
2931
        exit(1);
2932
    }
2933
}
2934

    
2935
static void opt_frame_pix_fmt(const char *arg)
2936
{
2937
    frame_pix_fmt = av_get_pix_fmt(arg);
2938
}
2939

    
2940
static int opt_sync(const char *opt, const char *arg)
2941
{
2942
    if (!strcmp(arg, "audio"))
2943
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2944
    else if (!strcmp(arg, "video"))
2945
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2946
    else if (!strcmp(arg, "ext"))
2947
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2948
    else {
2949
        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2950
        exit(1);
2951
    }
2952
    return 0;
2953
}
2954

    
2955
static int opt_seek(const char *opt, const char *arg)
2956
{
2957
    start_time = parse_time_or_die(opt, arg, 1);
2958
    return 0;
2959
}
2960

    
2961
static int opt_duration(const char *opt, const char *arg)
2962
{
2963
    duration = parse_time_or_die(opt, arg, 1);
2964
    return 0;
2965
}
2966

    
2967
static int opt_debug(const char *opt, const char *arg)
2968
{
2969
    av_log_set_level(99);
2970
    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2971
    return 0;
2972
}
2973

    
2974
static int opt_vismv(const char *opt, const char *arg)
2975
{
2976
    debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2977
    return 0;
2978
}
2979

    
2980
static int opt_thread_count(const char *opt, const char *arg)
2981
{
2982
    thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2983
#if !HAVE_THREADS
2984
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2985
#endif
2986
    return 0;
2987
}
2988

    
2989
static const OptionDef options[] = {
2990
#include "cmdutils_common_opts.h"
2991
    { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2992
    { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2993
    { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2994
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2995
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2996
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2997
    { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },
2998
    { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" },
2999
    { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },
3000
    { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
3001
    { "t", HAS_ARG | OPT_FUNC2, {(void*)&opt_duration}, "play  \"duration\" seconds of audio/video", "duration" },
3002
    { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" },
3003
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
3004
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
3005
    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
3006
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
3007
    { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
3008
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
3009
    { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
3010
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
3011
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
3012
    { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
3013
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
3014
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
3015
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
3016
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
3017
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
3018
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
3019
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
3020
    { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
3021
    { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
3022
    { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
3023
    { "exitonkeydown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_keydown}, "exit on key down", "" },
3024
    { "exitonmousedown", OPT_BOOL | OPT_EXPERT, {(void*)&exit_on_mousedown}, "exit on mouse down", "" },
3025
    { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" },
3026
    { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" },
3027
    { "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" },
3028
#if CONFIG_AVFILTER
3029
    { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
3030
#endif
3031
    { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" },
3032
    { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
3033
    { "i", OPT_DUMMY, {NULL}, "ffmpeg compatibility dummy option", ""},
3034
    { NULL, },
3035
};
3036

    
3037
static void show_usage(void)
3038
{
3039
    printf("Simple media player\n");
3040
    printf("usage: ffplay [options] input_file\n");
3041
    printf("\n");
3042
}
3043

    
3044
static void show_help(void)
3045
{
3046
    av_log_set_callback(log_callback_help);
3047
    show_usage();
3048
    show_help_options(options, "Main options:\n",
3049
                      OPT_EXPERT, 0);
3050
    show_help_options(options, "\nAdvanced options:\n",
3051
                      OPT_EXPERT, OPT_EXPERT);
3052
    printf("\n");
3053
    av_opt_show2(avcodec_opts[0], NULL,
3054
                 AV_OPT_FLAG_DECODING_PARAM, 0);
3055
    printf("\n");
3056
    av_opt_show2(avformat_opts, NULL,
3057
                 AV_OPT_FLAG_DECODING_PARAM, 0);
3058
#if !CONFIG_AVFILTER
3059
    printf("\n");
3060
    av_opt_show2(sws_opts, NULL,
3061
                 AV_OPT_FLAG_ENCODING_PARAM, 0);
3062
#endif
3063
    printf("\nWhile playing:\n"
3064
           "q, ESC              quit\n"
3065
           "f                   toggle full screen\n"
3066
           "p, SPC              pause\n"
3067
           "a                   cycle audio channel\n"
3068
           "v                   cycle video channel\n"
3069
           "t                   cycle subtitle channel\n"
3070
           "w                   show audio waves\n"
3071
           "s                   activate frame-step mode\n"
3072
           "left/right          seek backward/forward 10 seconds\n"
3073
           "down/up             seek backward/forward 1 minute\n"
3074
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
3075
           );
3076
}
3077

    
3078
static void opt_input_file(const char *filename)
3079
{
3080
    if (input_filename) {
3081
        fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3082
                filename, input_filename);
3083
        exit(1);
3084
    }
3085
    if (!strcmp(filename, "-"))
3086
        filename = "pipe:";
3087
    input_filename = filename;
3088
}
3089

    
3090
/* Called from the main */
3091
int main(int argc, char **argv)
3092
{
3093
    int flags;
3094

    
3095
    av_log_set_flags(AV_LOG_SKIP_REPEATED);
3096

    
3097
    /* register all codecs, demux and protocols */
3098
    avcodec_register_all();
3099
#if CONFIG_AVDEVICE
3100
    avdevice_register_all();
3101
#endif
3102
#if CONFIG_AVFILTER
3103
    avfilter_register_all();
3104
#endif
3105
    av_register_all();
3106

    
3107
    init_opts();
3108

    
3109
    show_banner();
3110

    
3111
    parse_options(argc, argv, options, opt_input_file);
3112

    
3113
    if (!input_filename) {
3114
        show_usage();
3115
        fprintf(stderr, "An input file must be specified\n");
3116
        fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
3117
        exit(1);
3118
    }
3119

    
3120
    if (display_disable) {
3121
        video_disable = 1;
3122
    }
3123
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3124
#if !defined(__MINGW32__) && !defined(__APPLE__)
3125
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3126
#endif
3127
    if (SDL_Init (flags)) {
3128
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3129
        exit(1);
3130
    }
3131

    
3132
    if (!display_disable) {
3133
#if HAVE_SDL_VIDEO_SIZE
3134
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3135
        fs_screen_width = vi->current_w;
3136
        fs_screen_height = vi->current_h;
3137
#endif
3138
    }
3139

    
3140
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3141
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3142
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3143

    
3144
    av_init_packet(&flush_pkt);
3145
    flush_pkt.data= "FLUSH";
3146

    
3147
    cur_stream = stream_open(input_filename, file_iformat);
3148

    
3149
    event_loop();
3150

    
3151
    /* never returns */
3152

    
3153
    return 0;
3154
}