Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 2f821b03

History | View | Annotate | Download (94.8 KB)

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

    
22
#include "config.h"
23
#include <inttypes.h>
24
#include <math.h>
25
#include <limits.h>
26
#include "libavutil/avstring.h"
27
#include "libavutil/pixdesc.h"
28
#include "libavformat/avformat.h"
29
#include "libavdevice/avdevice.h"
30
#include "libswscale/swscale.h"
31
#include "libavcodec/audioconvert.h"
32
#include "libavcodec/colorspace.h"
33
#include "libavcodec/opt.h"
34
#include "libavcodec/avfft.h"
35

    
36
#if CONFIG_AVFILTER
37
# include "libavfilter/avfilter.h"
38
# include "libavfilter/avfiltergraph.h"
39
# include "libavfilter/graphparser.h"
40
#endif
41

    
42
#include "cmdutils.h"
43

    
44
#include <SDL.h>
45
#include <SDL_thread.h>
46

    
47
#ifdef __MINGW32__
48
#undef main /* We don't want SDL to override our main() */
49
#endif
50

    
51
#include <unistd.h>
52
#include <assert.h>
53

    
54
const char program_name[] = "FFplay";
55
const int program_birth_year = 2003;
56

    
57
//#define DEBUG_SYNC
58

    
59
#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
60
#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
61
#define MIN_FRAMES 5
62

    
63
/* SDL audio buffer size, in samples. Should be small to have precise
64
   A/V sync as SDL does not have hardware buffer fullness info. */
65
#define SDL_AUDIO_BUFFER_SIZE 1024
66

    
67
/* no AV sync correction is done if below the AV sync threshold */
68
#define AV_SYNC_THRESHOLD 0.01
69
/* no AV correction is done if too big error */
70
#define AV_NOSYNC_THRESHOLD 10.0
71

    
72
#define FRAME_SKIP_FACTOR 0.05
73

    
74
/* maximum audio speed change to get correct sync */
75
#define SAMPLE_CORRECTION_PERCENT_MAX 10
76

    
77
/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
78
#define AUDIO_DIFF_AVG_NB   20
79

    
80
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
81
#define SAMPLE_ARRAY_SIZE (2*65536)
82

    
83
#if !CONFIG_AVFILTER
84
static int sws_flags = SWS_BICUBIC;
85
#endif
86

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

    
96
#define VIDEO_PICTURE_QUEUE_SIZE 2
97
#define SUBPICTURE_QUEUE_SIZE 4
98

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

    
108
#if CONFIG_AVFILTER
109
    AVFilterPicRef *picref;
110
#endif
111
} VideoPicture;
112

    
113
typedef struct SubPicture {
114
    double pts; /* presentation time stamp for this picture */
115
    AVSubtitle sub;
116
} SubPicture;
117

    
118
enum {
119
    AV_SYNC_AUDIO_MASTER, /* default choice */
120
    AV_SYNC_VIDEO_MASTER,
121
    AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
122
};
123

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

    
141
    int audio_stream;
142

    
143
    int av_sync_type;
144
    double external_clock; /* external clock base */
145
    int64_t external_clock_time;
146

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

    
167
    int show_audio; /* if true, display audio samples */
168
    int16_t sample_array[SAMPLE_ARRAY_SIZE];
169
    int sample_array_index;
170
    int last_i_start;
171
    RDFTContext *rdft;
172
    int rdft_bits;
173
    int xpos;
174

    
175
    SDL_Thread *subtitle_tid;
176
    int subtitle_stream;
177
    int subtitle_stream_changed;
178
    AVStream *subtitle_st;
179
    PacketQueue subtitleq;
180
    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
181
    int subpq_size, subpq_rindex, subpq_windex;
182
    SDL_mutex *subpq_mutex;
183
    SDL_cond *subpq_cond;
184

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

    
203
    //    QETimer *video_timer;
204
    char filename[1024];
205
    int width, height, xleft, ytop;
206

    
207
    int64_t faulty_pts;
208
    int64_t faulty_dts;
209
    int64_t last_dts_for_fault_detection;
210
    int64_t last_pts_for_fault_detection;
211

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

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

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

    
224
/* options specified by the user */
225
static AVInputFormat *file_iformat;
226
static const char *input_filename;
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[CODEC_TYPE_NB]={
237
    [CODEC_TYPE_AUDIO]=-1,
238
    [CODEC_TYPE_VIDEO]=-1,
239
    [CODEC_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 int debug = 0;
247
static int debug_mv = 0;
248
static int step = 0;
249
static int thread_count = 1;
250
static int workaround_bugs = 1;
251
static int fast = 0;
252
static int genpts = 0;
253
static int lowres = 0;
254
static int idct = FF_IDCT_AUTO;
255
static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
256
static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
257
static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
258
static int error_recognition = FF_ER_CAREFUL;
259
static int error_concealment = 3;
260
static int decoder_reorder_pts= -1;
261
static int autoexit;
262
static int framedrop=1;
263

    
264
static int rdftspeed=20;
265
#if CONFIG_AVFILTER
266
static char *vfilters = NULL;
267
#endif
268

    
269
/* current context */
270
static int is_full_screen;
271
static VideoState *cur_stream;
272
static int64_t audio_callback_time;
273

    
274
static AVPacket flush_pkt;
275

    
276
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
277
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
278
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
279

    
280
static SDL_Surface *screen;
281

    
282
static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
283

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

    
293
static void packet_queue_flush(PacketQueue *q)
294
{
295
    AVPacketList *pkt, *pkt1;
296

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

    
310
static void packet_queue_end(PacketQueue *q)
311
{
312
    packet_queue_flush(q);
313
    SDL_DestroyMutex(q->mutex);
314
    SDL_DestroyCond(q->cond);
315
}
316

    
317
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
318
{
319
    AVPacketList *pkt1;
320

    
321
    /* duplicate the packet */
322
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
323
        return -1;
324

    
325
    pkt1 = av_malloc(sizeof(AVPacketList));
326
    if (!pkt1)
327
        return -1;
328
    pkt1->pkt = *pkt;
329
    pkt1->next = NULL;
330

    
331

    
332
    SDL_LockMutex(q->mutex);
333

    
334
    if (!q->last_pkt)
335

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

    
345
    SDL_UnlockMutex(q->mutex);
346
    return 0;
347
}
348

    
349
static void packet_queue_abort(PacketQueue *q)
350
{
351
    SDL_LockMutex(q->mutex);
352

    
353
    q->abort_request = 1;
354

    
355
    SDL_CondSignal(q->cond);
356

    
357
    SDL_UnlockMutex(q->mutex);
358
}
359

    
360
/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
361
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
362
{
363
    AVPacketList *pkt1;
364
    int ret;
365

    
366
    SDL_LockMutex(q->mutex);
367

    
368
    for(;;) {
369
        if (q->abort_request) {
370
            ret = -1;
371
            break;
372
        }
373

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

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

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

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

    
445
#define ALPHA_BLEND(a, oldp, newp, s)\
446
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
447

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

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

    
466
#define YUVA_OUT(d, y, u, v, a)\
467
{\
468
    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
469
}
470

    
471

    
472
#define BPP 1
473

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

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

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

    
498
    if (dsty & 1) {
499
        lum += dstx;
500
        cb += skip2;
501
        cr += skip2;
502

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

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

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

    
577
            YUVA_IN(y, u, v, a, p + BPP, pal);
578
            u1 += u;
579
            v1 += v;
580
            a1 += a;
581
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
582
            p += wrap3;
583
            lum += wrap;
584

    
585
            YUVA_IN(y, u, v, a, p, pal);
586
            u1 += u;
587
            v1 += v;
588
            a1 += a;
589
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
590

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

    
597
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
598
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
599

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

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

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

    
674
static void free_subpicture(SubPicture *sp)
675
{
676
    int i;
677

    
678
    for (i = 0; i < sp->sub.num_rects; i++)
679
    {
680
        av_freep(&sp->sub.rects[i]->pict.data[0]);
681
        av_freep(&sp->sub.rects[i]->pict.data[1]);
682
        av_freep(&sp->sub.rects[i]);
683
    }
684

    
685
    av_free(sp->sub.rects);
686

    
687
    memset(&sp->sub, 0, sizeof(AVSubtitle));
688
}
689

    
690
static void video_image_display(VideoState *is)
691
{
692
    VideoPicture *vp;
693
    SubPicture *sp;
694
    AVPicture pict;
695
    float aspect_ratio;
696
    int width, height, x, y;
697
    SDL_Rect rect;
698
    int i;
699

    
700
    vp = &is->pictq[is->pictq_rindex];
701
    if (vp->bmp) {
702
#if CONFIG_AVFILTER
703
         if (vp->picref->pixel_aspect.num == 0)
704
             aspect_ratio = 0;
705
         else
706
             aspect_ratio = av_q2d(vp->picref->pixel_aspect);
707
#else
708

    
709
        /* XXX: use variable in the frame */
710
        if (is->video_st->sample_aspect_ratio.num)
711
            aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
712
        else if (is->video_st->codec->sample_aspect_ratio.num)
713
            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
714
        else
715
            aspect_ratio = 0;
716
#endif
717
        if (aspect_ratio <= 0.0)
718
            aspect_ratio = 1.0;
719
        aspect_ratio *= (float)vp->width / (float)vp->height;
720
        /* if an active format is indicated, then it overrides the
721
           mpeg format */
722
#if 0
723
        if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
724
            is->dtg_active_format = is->video_st->codec->dtg_active_format;
725
            printf("dtg_active_format=%d\n", is->dtg_active_format);
726
        }
727
#endif
728
#if 0
729
        switch(is->video_st->codec->dtg_active_format) {
730
        case FF_DTG_AFD_SAME:
731
        default:
732
            /* nothing to do */
733
            break;
734
        case FF_DTG_AFD_4_3:
735
            aspect_ratio = 4.0 / 3.0;
736
            break;
737
        case FF_DTG_AFD_16_9:
738
            aspect_ratio = 16.0 / 9.0;
739
            break;
740
        case FF_DTG_AFD_14_9:
741
            aspect_ratio = 14.0 / 9.0;
742
            break;
743
        case FF_DTG_AFD_4_3_SP_14_9:
744
            aspect_ratio = 14.0 / 9.0;
745
            break;
746
        case FF_DTG_AFD_16_9_SP_14_9:
747
            aspect_ratio = 14.0 / 9.0;
748
            break;
749
        case FF_DTG_AFD_SP_4_3:
750
            aspect_ratio = 4.0 / 3.0;
751
            break;
752
        }
753
#endif
754

    
755
        if (is->subtitle_st)
756
        {
757
            if (is->subpq_size > 0)
758
            {
759
                sp = &is->subpq[is->subpq_rindex];
760

    
761
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
762
                {
763
                    SDL_LockYUVOverlay (vp->bmp);
764

    
765
                    pict.data[0] = vp->bmp->pixels[0];
766
                    pict.data[1] = vp->bmp->pixels[2];
767
                    pict.data[2] = vp->bmp->pixels[1];
768

    
769
                    pict.linesize[0] = vp->bmp->pitches[0];
770
                    pict.linesize[1] = vp->bmp->pitches[2];
771
                    pict.linesize[2] = vp->bmp->pitches[1];
772

    
773
                    for (i = 0; i < sp->sub.num_rects; i++)
774
                        blend_subrect(&pict, sp->sub.rects[i],
775
                                      vp->bmp->w, vp->bmp->h);
776

    
777
                    SDL_UnlockYUVOverlay (vp->bmp);
778
                }
779
            }
780
        }
781

    
782

    
783
        /* XXX: we suppose the screen has a 1.0 pixel ratio */
784
        height = is->height;
785
        width = ((int)rint(height * aspect_ratio)) & ~1;
786
        if (width > is->width) {
787
            width = is->width;
788
            height = ((int)rint(width / aspect_ratio)) & ~1;
789
        }
790
        x = (is->width - width) / 2;
791
        y = (is->height - height) / 2;
792
        if (!is->no_background) {
793
            /* fill the background */
794
            //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
795
        } else {
796
            is->no_background = 0;
797
        }
798
        rect.x = is->xleft + x;
799
        rect.y = is->ytop  + y;
800
        rect.w = width;
801
        rect.h = height;
802
        SDL_DisplayYUVOverlay(vp->bmp, &rect);
803
    } else {
804
#if 0
805
        fill_rectangle(screen,
806
                       is->xleft, is->ytop, is->width, is->height,
807
                       QERGB(0x00, 0x00, 0x00));
808
#endif
809
    }
810
}
811

    
812
static inline int compute_mod(int a, int b)
813
{
814
    a = a % b;
815
    if (a >= 0)
816
        return a;
817
    else
818
        return a + b;
819
}
820

    
821
static void video_audio_display(VideoState *s)
822
{
823
    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
824
    int ch, channels, h, h2, bgcolor, fgcolor;
825
    int16_t time_diff;
826
    int rdft_bits, nb_freq;
827

    
828
    for(rdft_bits=1; (1<<rdft_bits)<2*s->height; rdft_bits++)
829
        ;
830
    nb_freq= 1<<(rdft_bits-1);
831

    
832
    /* compute display index : center on currently output samples */
833
    channels = s->audio_st->codec->channels;
834
    nb_display_channels = channels;
835
    if (!s->paused) {
836
        int data_used= s->show_audio==1 ? s->width : (2*nb_freq);
837
        n = 2 * channels;
838
        delay = audio_write_get_buf_size(s);
839
        delay /= n;
840

    
841
        /* to be more precise, we take into account the time spent since
842
           the last buffer computation */
843
        if (audio_callback_time) {
844
            time_diff = av_gettime() - audio_callback_time;
845
            delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000;
846
        }
847

    
848
        delay += 2*data_used;
849
        if (delay < data_used)
850
            delay = data_used;
851

    
852
        i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
853
        if(s->show_audio==1){
854
            h= INT_MIN;
855
            for(i=0; i<1000; i+=channels){
856
                int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
857
                int a= s->sample_array[idx];
858
                int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
859
                int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
860
                int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
861
                int score= a-d;
862
                if(h<score && (b^c)<0){
863
                    h= score;
864
                    i_start= idx;
865
                }
866
            }
867
        }
868

    
869
        s->last_i_start = i_start;
870
    } else {
871
        i_start = s->last_i_start;
872
    }
873

    
874
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
875
    if(s->show_audio==1){
876
        fill_rectangle(screen,
877
                       s->xleft, s->ytop, s->width, s->height,
878
                       bgcolor);
879

    
880
        fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
881

    
882
        /* total height for one channel */
883
        h = s->height / nb_display_channels;
884
        /* graph height / 2 */
885
        h2 = (h * 9) / 20;
886
        for(ch = 0;ch < nb_display_channels; ch++) {
887
            i = i_start + ch;
888
            y1 = s->ytop + ch * h + (h / 2); /* position of center line */
889
            for(x = 0; x < s->width; x++) {
890
                y = (s->sample_array[i] * h2) >> 15;
891
                if (y < 0) {
892
                    y = -y;
893
                    ys = y1 - y;
894
                } else {
895
                    ys = y1;
896
                }
897
                fill_rectangle(screen,
898
                               s->xleft + x, ys, 1, y,
899
                               fgcolor);
900
                i += channels;
901
                if (i >= SAMPLE_ARRAY_SIZE)
902
                    i -= SAMPLE_ARRAY_SIZE;
903
            }
904
        }
905

    
906
        fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
907

    
908
        for(ch = 1;ch < nb_display_channels; ch++) {
909
            y = s->ytop + ch * h;
910
            fill_rectangle(screen,
911
                           s->xleft, y, s->width, 1,
912
                           fgcolor);
913
        }
914
        SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
915
    }else{
916
        nb_display_channels= FFMIN(nb_display_channels, 2);
917
        if(rdft_bits != s->rdft_bits){
918
            av_rdft_end(s->rdft);
919
            s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
920
            s->rdft_bits= rdft_bits;
921
        }
922
        {
923
            FFTSample data[2][2*nb_freq];
924
            for(ch = 0;ch < nb_display_channels; ch++) {
925
                i = i_start + ch;
926
                for(x = 0; x < 2*nb_freq; x++) {
927
                    double w= (x-nb_freq)*(1.0/nb_freq);
928
                    data[ch][x]= s->sample_array[i]*(1.0-w*w);
929
                    i += channels;
930
                    if (i >= SAMPLE_ARRAY_SIZE)
931
                        i -= SAMPLE_ARRAY_SIZE;
932
                }
933
                av_rdft_calc(s->rdft, data[ch]);
934
            }
935
            //least efficient way to do this, we should of course directly access it but its more than fast enough
936
            for(y=0; y<s->height; y++){
937
                double w= 1/sqrt(nb_freq);
938
                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]));
939
                int b= sqrt(w*sqrt(data[1][2*y+0]*data[1][2*y+0] + data[1][2*y+1]*data[1][2*y+1]));
940
                a= FFMIN(a,255);
941
                b= FFMIN(b,255);
942
                fgcolor = SDL_MapRGB(screen->format, a, b, (a+b)/2);
943

    
944
                fill_rectangle(screen,
945
                            s->xpos, s->height-y, 1, 1,
946
                            fgcolor);
947
            }
948
        }
949
        SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
950
        s->xpos++;
951
        if(s->xpos >= s->width)
952
            s->xpos= s->xleft;
953
    }
954
}
955

    
956
static int video_open(VideoState *is){
957
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
958
    int w,h;
959

    
960
    if(is_full_screen) flags |= SDL_FULLSCREEN;
961
    else               flags |= SDL_RESIZABLE;
962

    
963
    if (is_full_screen && fs_screen_width) {
964
        w = fs_screen_width;
965
        h = fs_screen_height;
966
    } else if(!is_full_screen && screen_width){
967
        w = screen_width;
968
        h = screen_height;
969
#if CONFIG_AVFILTER
970
    }else if (is->out_video_filter && is->out_video_filter->inputs[0]){
971
        w = is->out_video_filter->inputs[0]->w;
972
        h = is->out_video_filter->inputs[0]->h;
973
#else
974
    }else if (is->video_st && is->video_st->codec->width){
975
        w = is->video_st->codec->width;
976
        h = is->video_st->codec->height;
977
#endif
978
    } else {
979
        w = 640;
980
        h = 480;
981
    }
982
    if(screen && is->width == screen->w && screen->w == w
983
       && is->height== screen->h && screen->h == h)
984
        return 0;
985

    
986
#ifndef __APPLE__
987
    screen = SDL_SetVideoMode(w, h, 0, flags);
988
#else
989
    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
990
    screen = SDL_SetVideoMode(w, h, 24, flags);
991
#endif
992
    if (!screen) {
993
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
994
        return -1;
995
    }
996
    SDL_WM_SetCaption("FFplay", "FFplay");
997

    
998
    is->width = screen->w;
999
    is->height = screen->h;
1000

    
1001
    return 0;
1002
}
1003

    
1004
/* display the current picture, if any */
1005
static void video_display(VideoState *is)
1006
{
1007
    if(!screen)
1008
        video_open(cur_stream);
1009
    if (is->audio_st && is->show_audio)
1010
        video_audio_display(is);
1011
    else if (is->video_st)
1012
        video_image_display(is);
1013
}
1014

    
1015
static int refresh_thread(void *opaque)
1016
{
1017
    VideoState *is= opaque;
1018
    while(!is->abort_request){
1019
    SDL_Event event;
1020
    event.type = FF_REFRESH_EVENT;
1021
    event.user.data1 = opaque;
1022
        if(!is->refresh){
1023
            is->refresh=1;
1024
    SDL_PushEvent(&event);
1025
        }
1026
        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
1027
    }
1028
    return 0;
1029
}
1030

    
1031
/* get the current audio clock value */
1032
static double get_audio_clock(VideoState *is)
1033
{
1034
    double pts;
1035
    int hw_buf_size, bytes_per_sec;
1036
    pts = is->audio_clock;
1037
    hw_buf_size = audio_write_get_buf_size(is);
1038
    bytes_per_sec = 0;
1039
    if (is->audio_st) {
1040
        bytes_per_sec = is->audio_st->codec->sample_rate *
1041
            2 * is->audio_st->codec->channels;
1042
    }
1043
    if (bytes_per_sec)
1044
        pts -= (double)hw_buf_size / bytes_per_sec;
1045
    return pts;
1046
}
1047

    
1048
/* get the current video clock value */
1049
static double get_video_clock(VideoState *is)
1050
{
1051
    if (is->paused) {
1052
        return is->video_current_pts;
1053
    } else {
1054
        return is->video_current_pts_drift + av_gettime() / 1000000.0;
1055
    }
1056
}
1057

    
1058
/* get the current external clock value */
1059
static double get_external_clock(VideoState *is)
1060
{
1061
    int64_t ti;
1062
    ti = av_gettime();
1063
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
1064
}
1065

    
1066
/* get the current master clock value */
1067
static double get_master_clock(VideoState *is)
1068
{
1069
    double val;
1070

    
1071
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
1072
        if (is->video_st)
1073
            val = get_video_clock(is);
1074
        else
1075
            val = get_audio_clock(is);
1076
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
1077
        if (is->audio_st)
1078
            val = get_audio_clock(is);
1079
        else
1080
            val = get_video_clock(is);
1081
    } else {
1082
        val = get_external_clock(is);
1083
    }
1084
    return val;
1085
}
1086

    
1087
/* seek in the stream */
1088
static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
1089
{
1090
    if (!is->seek_req) {
1091
        is->seek_pos = pos;
1092
        is->seek_rel = rel;
1093
        is->seek_flags &= ~AVSEEK_FLAG_BYTE;
1094
        if (seek_by_bytes)
1095
            is->seek_flags |= AVSEEK_FLAG_BYTE;
1096
        is->seek_req = 1;
1097
    }
1098
}
1099

    
1100
/* pause or resume the video */
1101
static void stream_pause(VideoState *is)
1102
{
1103
    if (is->paused) {
1104
        is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
1105
        if(is->read_pause_return != AVERROR(ENOSYS)){
1106
            is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
1107
        }
1108
        is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
1109
    }
1110
    is->paused = !is->paused;
1111
}
1112

    
1113
static double compute_target_time(double frame_current_pts, VideoState *is)
1114
{
1115
    double delay, sync_threshold, diff;
1116

    
1117
    /* compute nominal delay */
1118
    delay = frame_current_pts - is->frame_last_pts;
1119
    if (delay <= 0 || delay >= 10.0) {
1120
        /* if incorrect delay, use previous one */
1121
        delay = is->frame_last_delay;
1122
    } else {
1123
        is->frame_last_delay = delay;
1124
    }
1125
    is->frame_last_pts = frame_current_pts;
1126

    
1127
    /* update delay to follow master synchronisation source */
1128
    if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1129
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1130
        /* if video is slave, we try to correct big delays by
1131
           duplicating or deleting a frame */
1132
        diff = get_video_clock(is) - get_master_clock(is);
1133

    
1134
        /* skip or repeat frame. We take into account the
1135
           delay to compute the threshold. I still don't know
1136
           if it is the best guess */
1137
        sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1138
        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1139
            if (diff <= -sync_threshold)
1140
                delay = 0;
1141
            else if (diff >= sync_threshold)
1142
                delay = 2 * delay;
1143
        }
1144
    }
1145
    is->frame_timer += delay;
1146
#if defined(DEBUG_SYNC)
1147
    printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1148
            delay, actual_delay, frame_current_pts, -diff);
1149
#endif
1150

    
1151
    return is->frame_timer;
1152
}
1153

    
1154
/* called to display each frame */
1155
static void video_refresh_timer(void *opaque)
1156
{
1157
    VideoState *is = opaque;
1158
    VideoPicture *vp;
1159

    
1160
    SubPicture *sp, *sp2;
1161

    
1162
    if (is->video_st) {
1163
retry:
1164
        if (is->pictq_size == 0) {
1165
            //nothing to do, no picture to display in the que
1166
        } else {
1167
            double time= av_gettime()/1000000.0;
1168
            double next_target;
1169
            /* dequeue the picture */
1170
            vp = &is->pictq[is->pictq_rindex];
1171

    
1172
            if(time < vp->target_clock)
1173
                return;
1174
            /* update current video pts */
1175
            is->video_current_pts = vp->pts;
1176
            is->video_current_pts_drift = is->video_current_pts - time;
1177
            is->video_current_pos = vp->pos;
1178
            if(is->pictq_size > 1){
1179
                VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE];
1180
                assert(nextvp->target_clock >= vp->target_clock);
1181
                next_target= nextvp->target_clock;
1182
            }else{
1183
                next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly
1184
            }
1185
            if(framedrop && time > next_target){
1186
                is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
1187
                if(is->pictq_size > 1 || time > next_target + 0.5){
1188
                    /* update queue size and signal for next picture */
1189
                    if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1190
                        is->pictq_rindex = 0;
1191

    
1192
                    SDL_LockMutex(is->pictq_mutex);
1193
                    is->pictq_size--;
1194
                    SDL_CondSignal(is->pictq_cond);
1195
                    SDL_UnlockMutex(is->pictq_mutex);
1196
                    goto retry;
1197
                }
1198
            }
1199

    
1200
            if(is->subtitle_st) {
1201
                if (is->subtitle_stream_changed) {
1202
                    SDL_LockMutex(is->subpq_mutex);
1203

    
1204
                    while (is->subpq_size) {
1205
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1206

    
1207
                        /* update queue size and signal for next picture */
1208
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1209
                            is->subpq_rindex = 0;
1210

    
1211
                        is->subpq_size--;
1212
                    }
1213
                    is->subtitle_stream_changed = 0;
1214

    
1215
                    SDL_CondSignal(is->subpq_cond);
1216
                    SDL_UnlockMutex(is->subpq_mutex);
1217
                } else {
1218
                    if (is->subpq_size > 0) {
1219
                        sp = &is->subpq[is->subpq_rindex];
1220

    
1221
                        if (is->subpq_size > 1)
1222
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1223
                        else
1224
                            sp2 = NULL;
1225

    
1226
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1227
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1228
                        {
1229
                            free_subpicture(sp);
1230

    
1231
                            /* update queue size and signal for next picture */
1232
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1233
                                is->subpq_rindex = 0;
1234

    
1235
                            SDL_LockMutex(is->subpq_mutex);
1236
                            is->subpq_size--;
1237
                            SDL_CondSignal(is->subpq_cond);
1238
                            SDL_UnlockMutex(is->subpq_mutex);
1239
                        }
1240
                    }
1241
                }
1242
            }
1243

    
1244
            /* display picture */
1245
            video_display(is);
1246

    
1247
            /* update queue size and signal for next picture */
1248
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1249
                is->pictq_rindex = 0;
1250

    
1251
            SDL_LockMutex(is->pictq_mutex);
1252
            is->pictq_size--;
1253
            SDL_CondSignal(is->pictq_cond);
1254
            SDL_UnlockMutex(is->pictq_mutex);
1255
        }
1256
    } else if (is->audio_st) {
1257
        /* draw the next audio frame */
1258

    
1259
        /* if only audio stream, then display the audio bars (better
1260
           than nothing, just to test the implementation */
1261

    
1262
        /* display picture */
1263
        video_display(is);
1264
    }
1265
    if (show_status) {
1266
        static int64_t last_time;
1267
        int64_t cur_time;
1268
        int aqsize, vqsize, sqsize;
1269
        double av_diff;
1270

    
1271
        cur_time = av_gettime();
1272
        if (!last_time || (cur_time - last_time) >= 30000) {
1273
            aqsize = 0;
1274
            vqsize = 0;
1275
            sqsize = 0;
1276
            if (is->audio_st)
1277
                aqsize = is->audioq.size;
1278
            if (is->video_st)
1279
                vqsize = is->videoq.size;
1280
            if (is->subtitle_st)
1281
                sqsize = is->subtitleq.size;
1282
            av_diff = 0;
1283
            if (is->audio_st && is->video_st)
1284
                av_diff = get_audio_clock(is) - get_video_clock(is);
1285
            printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
1286
                   get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts);
1287
            fflush(stdout);
1288
            last_time = cur_time;
1289
        }
1290
    }
1291
}
1292

    
1293
/* allocate a picture (needs to do that in main thread to avoid
1294
   potential locking problems */
1295
static void alloc_picture(void *opaque)
1296
{
1297
    VideoState *is = opaque;
1298
    VideoPicture *vp;
1299

    
1300
    vp = &is->pictq[is->pictq_windex];
1301

    
1302
    if (vp->bmp)
1303
        SDL_FreeYUVOverlay(vp->bmp);
1304

    
1305
#if CONFIG_AVFILTER
1306
    if (vp->picref)
1307
        avfilter_unref_pic(vp->picref);
1308
    vp->picref = NULL;
1309

    
1310
    vp->width   = is->out_video_filter->inputs[0]->w;
1311
    vp->height  = is->out_video_filter->inputs[0]->h;
1312
    vp->pix_fmt = is->out_video_filter->inputs[0]->format;
1313
#else
1314
    vp->width   = is->video_st->codec->width;
1315
    vp->height  = is->video_st->codec->height;
1316
    vp->pix_fmt = is->video_st->codec->pix_fmt;
1317
#endif
1318

    
1319
    vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
1320
                                   SDL_YV12_OVERLAY,
1321
                                   screen);
1322

    
1323
    SDL_LockMutex(is->pictq_mutex);
1324
    vp->allocated = 1;
1325
    SDL_CondSignal(is->pictq_cond);
1326
    SDL_UnlockMutex(is->pictq_mutex);
1327
}
1328

    
1329
/**
1330
 *
1331
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1332
 */
1333
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
1334
{
1335
    VideoPicture *vp;
1336
    int dst_pix_fmt;
1337
#if CONFIG_AVFILTER
1338
    AVPicture pict_src;
1339
#endif
1340
    /* wait until we have space to put a new picture */
1341
    SDL_LockMutex(is->pictq_mutex);
1342

    
1343
    if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
1344
        is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR));
1345

    
1346
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1347
           !is->videoq.abort_request) {
1348
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1349
    }
1350
    SDL_UnlockMutex(is->pictq_mutex);
1351

    
1352
    if (is->videoq.abort_request)
1353
        return -1;
1354

    
1355
    vp = &is->pictq[is->pictq_windex];
1356

    
1357
    /* alloc or resize hardware picture buffer */
1358
    if (!vp->bmp ||
1359
#if CONFIG_AVFILTER
1360
        vp->width  != is->out_video_filter->inputs[0]->w ||
1361
        vp->height != is->out_video_filter->inputs[0]->h) {
1362
#else
1363
        vp->width != is->video_st->codec->width ||
1364
        vp->height != is->video_st->codec->height) {
1365
#endif
1366
        SDL_Event event;
1367

    
1368
        vp->allocated = 0;
1369

    
1370
        /* the allocation must be done in the main thread to avoid
1371
           locking problems */
1372
        event.type = FF_ALLOC_EVENT;
1373
        event.user.data1 = is;
1374
        SDL_PushEvent(&event);
1375

    
1376
        /* wait until the picture is allocated */
1377
        SDL_LockMutex(is->pictq_mutex);
1378
        while (!vp->allocated && !is->videoq.abort_request) {
1379
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1380
        }
1381
        SDL_UnlockMutex(is->pictq_mutex);
1382

    
1383
        if (is->videoq.abort_request)
1384
            return -1;
1385
    }
1386

    
1387
    /* if the frame is not skipped, then display it */
1388
    if (vp->bmp) {
1389
        AVPicture pict;
1390
#if CONFIG_AVFILTER
1391
        if(vp->picref)
1392
            avfilter_unref_pic(vp->picref);
1393
        vp->picref = src_frame->opaque;
1394
#endif
1395

    
1396
        /* get a pointer on the bitmap */
1397
        SDL_LockYUVOverlay (vp->bmp);
1398

    
1399
        dst_pix_fmt = PIX_FMT_YUV420P;
1400
        memset(&pict,0,sizeof(AVPicture));
1401
        pict.data[0] = vp->bmp->pixels[0];
1402
        pict.data[1] = vp->bmp->pixels[2];
1403
        pict.data[2] = vp->bmp->pixels[1];
1404

    
1405
        pict.linesize[0] = vp->bmp->pitches[0];
1406
        pict.linesize[1] = vp->bmp->pitches[2];
1407
        pict.linesize[2] = vp->bmp->pitches[1];
1408

    
1409
#if CONFIG_AVFILTER
1410
        pict_src.data[0] = src_frame->data[0];
1411
        pict_src.data[1] = src_frame->data[1];
1412
        pict_src.data[2] = src_frame->data[2];
1413

    
1414
        pict_src.linesize[0] = src_frame->linesize[0];
1415
        pict_src.linesize[1] = src_frame->linesize[1];
1416
        pict_src.linesize[2] = src_frame->linesize[2];
1417

    
1418
        //FIXME use direct rendering
1419
        av_picture_copy(&pict, &pict_src,
1420
                        vp->pix_fmt, vp->width, vp->height);
1421
#else
1422
        sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1423
        is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1424
            vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
1425
            dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1426
        if (is->img_convert_ctx == NULL) {
1427
            fprintf(stderr, "Cannot initialize the conversion context\n");
1428
            exit(1);
1429
        }
1430
        sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1431
                  0, vp->height, pict.data, pict.linesize);
1432
#endif
1433
        /* update the bitmap content */
1434
        SDL_UnlockYUVOverlay(vp->bmp);
1435

    
1436
        vp->pts = pts;
1437
        vp->pos = pos;
1438

    
1439
        /* now we can update the picture count */
1440
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1441
            is->pictq_windex = 0;
1442
        SDL_LockMutex(is->pictq_mutex);
1443
        vp->target_clock= compute_target_time(vp->pts, is);
1444

    
1445
        is->pictq_size++;
1446
        SDL_UnlockMutex(is->pictq_mutex);
1447
    }
1448
    return 0;
1449
}
1450

    
1451
/**
1452
 * compute the exact PTS for the picture if it is omitted in the stream
1453
 * @param pts1 the dts of the pkt / pts of the frame
1454
 */
1455
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1456
{
1457
    double frame_delay, pts;
1458

    
1459
    pts = pts1;
1460

    
1461
    if (pts != 0) {
1462
        /* update video clock with pts, if present */
1463
        is->video_clock = pts;
1464
    } else {
1465
        pts = is->video_clock;
1466
    }
1467
    /* update video clock for next frame */
1468
    frame_delay = av_q2d(is->video_st->codec->time_base);
1469
    /* for MPEG2, the frame can be repeated, so we update the
1470
       clock accordingly */
1471
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1472
    is->video_clock += frame_delay;
1473

    
1474
#if defined(DEBUG_SYNC) && 0
1475
    printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1476
           av_get_pict_type_char(src_frame->pict_type), pts, pts1);
1477
#endif
1478
    return queue_picture(is, src_frame, pts, pos);
1479
}
1480

    
1481
static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
1482
{
1483
    int len1, got_picture, i;
1484

    
1485
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1486
            return -1;
1487

    
1488
        if(pkt->data == flush_pkt.data){
1489
            avcodec_flush_buffers(is->video_st->codec);
1490

    
1491
            SDL_LockMutex(is->pictq_mutex);
1492
            //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
1493
            for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
1494
                is->pictq[i].target_clock= 0;
1495
            }
1496
            while (is->pictq_size && !is->videoq.abort_request) {
1497
                SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1498
            }
1499
            is->video_current_pos= -1;
1500
            SDL_UnlockMutex(is->pictq_mutex);
1501

    
1502
            is->last_dts_for_fault_detection=
1503
            is->last_pts_for_fault_detection= INT64_MIN;
1504
            is->frame_last_pts= AV_NOPTS_VALUE;
1505
            is->frame_last_delay = 0;
1506
            is->frame_timer = (double)av_gettime() / 1000000.0;
1507
            is->skip_frames= 1;
1508
            is->skip_frames_index= 0;
1509
            return 0;
1510
        }
1511

    
1512
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1513
           this packet, if any */
1514
        is->video_st->codec->reordered_opaque= pkt->pts;
1515
        len1 = avcodec_decode_video2(is->video_st->codec,
1516
                                    frame, &got_picture,
1517
                                    pkt);
1518

    
1519
        if (got_picture) {
1520
            if(pkt->dts != AV_NOPTS_VALUE){
1521
                is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
1522
                is->last_dts_for_fault_detection= pkt->dts;
1523
            }
1524
            if(frame->reordered_opaque != AV_NOPTS_VALUE){
1525
                is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
1526
                is->last_pts_for_fault_detection= frame->reordered_opaque;
1527
            }
1528
        }
1529

    
1530
        if(   (   decoder_reorder_pts==1
1531
               || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
1532
               || pkt->dts == AV_NOPTS_VALUE)
1533
           && frame->reordered_opaque != AV_NOPTS_VALUE)
1534
            *pts= frame->reordered_opaque;
1535
        else if(pkt->dts != AV_NOPTS_VALUE)
1536
            *pts= pkt->dts;
1537
        else
1538
            *pts= 0;
1539

    
1540
//            if (len1 < 0)
1541
//                break;
1542
    if (got_picture){
1543
        is->skip_frames_index += 1;
1544
        if(is->skip_frames_index >= is->skip_frames){
1545
            is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
1546
            return 1;
1547
        }
1548

    
1549
    }
1550
    return 0;
1551
}
1552

    
1553
#if CONFIG_AVFILTER
1554
typedef struct {
1555
    VideoState *is;
1556
    AVFrame *frame;
1557
} FilterPriv;
1558

    
1559
static int input_init(AVFilterContext *ctx, const char *args, void *opaque)
1560
{
1561
    FilterPriv *priv = ctx->priv;
1562
    if(!opaque) return -1;
1563

    
1564
    priv->is = opaque;
1565
    priv->frame = avcodec_alloc_frame();
1566

    
1567
    return 0;
1568
}
1569

    
1570
static void input_uninit(AVFilterContext *ctx)
1571
{
1572
    FilterPriv *priv = ctx->priv;
1573
    av_free(priv->frame);
1574
}
1575

    
1576
static int input_request_frame(AVFilterLink *link)
1577
{
1578
    FilterPriv *priv = link->src->priv;
1579
    AVFilterPicRef *picref;
1580
    int64_t pts = 0;
1581
    AVPacket pkt;
1582
    int ret;
1583

    
1584
    while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt)))
1585
        av_free_packet(&pkt);
1586
    if (ret < 0)
1587
        return -1;
1588

    
1589
    /* FIXME: until I figure out how to hook everything up to the codec
1590
     * right, we're just copying the entire frame. */
1591
    picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
1592
    av_picture_copy((AVPicture *)&picref->data, (AVPicture *)priv->frame,
1593
                    picref->pic->format, link->w, link->h);
1594
    av_free_packet(&pkt);
1595

    
1596
    picref->pts = pts;
1597
    picref->pos = pkt.pos;
1598
    picref->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
1599
    avfilter_start_frame(link, avfilter_ref_pic(picref, ~0));
1600
    avfilter_draw_slice(link, 0, link->h, 1);
1601
    avfilter_end_frame(link);
1602
    avfilter_unref_pic(picref);
1603

    
1604
    return 0;
1605
}
1606

    
1607
static int input_query_formats(AVFilterContext *ctx)
1608
{
1609
    FilterPriv *priv = ctx->priv;
1610
    enum PixelFormat pix_fmts[] = {
1611
        priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
1612
    };
1613

    
1614
    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1615
    return 0;
1616
}
1617

    
1618
static int input_config_props(AVFilterLink *link)
1619
{
1620
    FilterPriv *priv  = link->src->priv;
1621
    AVCodecContext *c = priv->is->video_st->codec;
1622

    
1623
    link->w = c->width;
1624
    link->h = c->height;
1625

    
1626
    return 0;
1627
}
1628

    
1629
static AVFilter input_filter =
1630
{
1631
    .name      = "ffplay_input",
1632

    
1633
    .priv_size = sizeof(FilterPriv),
1634

    
1635
    .init      = input_init,
1636
    .uninit    = input_uninit,
1637

    
1638
    .query_formats = input_query_formats,
1639

    
1640
    .inputs    = (AVFilterPad[]) {{ .name = NULL }},
1641
    .outputs   = (AVFilterPad[]) {{ .name = "default",
1642
                                    .type = CODEC_TYPE_VIDEO,
1643
                                    .request_frame = input_request_frame,
1644
                                    .config_props  = input_config_props, },
1645
                                  { .name = NULL }},
1646
};
1647

    
1648
static void output_end_frame(AVFilterLink *link)
1649
{
1650
}
1651

    
1652
static int output_query_formats(AVFilterContext *ctx)
1653
{
1654
    enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
1655

    
1656
    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1657
    return 0;
1658
}
1659

    
1660
static int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
1661
                                    int64_t *pts, int64_t *pos)
1662
{
1663
    AVFilterPicRef *pic;
1664

    
1665
    if(avfilter_request_frame(ctx->inputs[0]))
1666
        return -1;
1667
    if(!(pic = ctx->inputs[0]->cur_pic))
1668
        return -1;
1669
    ctx->inputs[0]->cur_pic = NULL;
1670

    
1671
    frame->opaque = pic;
1672
    *pts          = pic->pts;
1673
    *pos          = pic->pos;
1674

    
1675
    memcpy(frame->data,     pic->data,     sizeof(frame->data));
1676
    memcpy(frame->linesize, pic->linesize, sizeof(frame->linesize));
1677

    
1678
    return 1;
1679
}
1680

    
1681
static AVFilter output_filter =
1682
{
1683
    .name      = "ffplay_output",
1684

    
1685
    .query_formats = output_query_formats,
1686

    
1687
    .inputs    = (AVFilterPad[]) {{ .name          = "default",
1688
                                    .type          = CODEC_TYPE_VIDEO,
1689
                                    .end_frame     = output_end_frame,
1690
                                    .min_perms     = AV_PERM_READ, },
1691
                                  { .name = NULL }},
1692
    .outputs   = (AVFilterPad[]) {{ .name = NULL }},
1693
};
1694
#endif  /* CONFIG_AVFILTER */
1695

    
1696
static int video_thread(void *arg)
1697
{
1698
    VideoState *is = arg;
1699
    AVFrame *frame= avcodec_alloc_frame();
1700
    int64_t pts_int, pos;
1701
    double pts;
1702
    int ret;
1703

    
1704
#if CONFIG_AVFILTER
1705
    AVFilterContext *filt_src = NULL, *filt_out = NULL;
1706
    AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph));
1707
    graph->scale_sws_opts = av_strdup("sws_flags=bilinear");
1708

    
1709
    if(!(filt_src = avfilter_open(&input_filter,  "src")))   goto the_end;
1710
    if(!(filt_out = avfilter_open(&output_filter, "out")))   goto the_end;
1711

    
1712
    if(avfilter_init_filter(filt_src, NULL, is))             goto the_end;
1713
    if(avfilter_init_filter(filt_out, NULL, frame))          goto the_end;
1714

    
1715

    
1716
    if(vfilters) {
1717
        AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
1718
        AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
1719

    
1720
        outputs->name    = av_strdup("in");
1721
        outputs->filter  = filt_src;
1722
        outputs->pad_idx = 0;
1723
        outputs->next    = NULL;
1724

    
1725
        inputs->name    = av_strdup("out");
1726
        inputs->filter  = filt_out;
1727
        inputs->pad_idx = 0;
1728
        inputs->next    = NULL;
1729

    
1730
        if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0)
1731
            goto the_end;
1732
        av_freep(&vfilters);
1733
    } else {
1734
        if(avfilter_link(filt_src, 0, filt_out, 0) < 0)          goto the_end;
1735
    }
1736
    avfilter_graph_add_filter(graph, filt_src);
1737
    avfilter_graph_add_filter(graph, filt_out);
1738

    
1739
    if(avfilter_graph_check_validity(graph, NULL))           goto the_end;
1740
    if(avfilter_graph_config_formats(graph, NULL))           goto the_end;
1741
    if(avfilter_graph_config_links(graph, NULL))             goto the_end;
1742

    
1743
    is->out_video_filter = filt_out;
1744
#endif
1745

    
1746
    for(;;) {
1747
#if !CONFIG_AVFILTER
1748
        AVPacket pkt;
1749
#endif
1750
        while (is->paused && !is->videoq.abort_request)
1751
            SDL_Delay(10);
1752
#if CONFIG_AVFILTER
1753
        ret = get_filtered_video_frame(filt_out, frame, &pts_int, &pos);
1754
#else
1755
        ret = get_video_frame(is, frame, &pts_int, &pkt);
1756
#endif
1757

    
1758
        if (ret < 0) goto the_end;
1759

    
1760
        if (!ret)
1761
            continue;
1762

    
1763
        pts = pts_int*av_q2d(is->video_st->time_base);
1764

    
1765
#if CONFIG_AVFILTER
1766
        ret = output_picture2(is, frame, pts, pos);
1767
#else
1768
        ret = output_picture2(is, frame, pts,  pkt.pos);
1769
        av_free_packet(&pkt);
1770
#endif
1771
        if (ret < 0)
1772
            goto the_end;
1773

    
1774
        if (step)
1775
            if (cur_stream)
1776
                stream_pause(cur_stream);
1777
    }
1778
 the_end:
1779
#if CONFIG_AVFILTER
1780
    avfilter_graph_destroy(graph);
1781
    av_freep(&graph);
1782
#endif
1783
    av_free(frame);
1784
    return 0;
1785
}
1786

    
1787
static int subtitle_thread(void *arg)
1788
{
1789
    VideoState *is = arg;
1790
    SubPicture *sp;
1791
    AVPacket pkt1, *pkt = &pkt1;
1792
    int len1, got_subtitle;
1793
    double pts;
1794
    int i, j;
1795
    int r, g, b, y, u, v, a;
1796

    
1797
    for(;;) {
1798
        while (is->paused && !is->subtitleq.abort_request) {
1799
            SDL_Delay(10);
1800
        }
1801
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1802
            break;
1803

    
1804
        if(pkt->data == flush_pkt.data){
1805
            avcodec_flush_buffers(is->subtitle_st->codec);
1806
            continue;
1807
        }
1808
        SDL_LockMutex(is->subpq_mutex);
1809
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1810
               !is->subtitleq.abort_request) {
1811
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1812
        }
1813
        SDL_UnlockMutex(is->subpq_mutex);
1814

    
1815
        if (is->subtitleq.abort_request)
1816
            goto the_end;
1817

    
1818
        sp = &is->subpq[is->subpq_windex];
1819

    
1820
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1821
           this packet, if any */
1822
        pts = 0;
1823
        if (pkt->pts != AV_NOPTS_VALUE)
1824
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1825

    
1826
        len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1827
                                    &sp->sub, &got_subtitle,
1828
                                    pkt);
1829
//            if (len1 < 0)
1830
//                break;
1831
        if (got_subtitle && sp->sub.format == 0) {
1832
            sp->pts = pts;
1833

    
1834
            for (i = 0; i < sp->sub.num_rects; i++)
1835
            {
1836
                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1837
                {
1838
                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1839
                    y = RGB_TO_Y_CCIR(r, g, b);
1840
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1841
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1842
                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1843
                }
1844
            }
1845

    
1846
            /* now we can update the picture count */
1847
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1848
                is->subpq_windex = 0;
1849
            SDL_LockMutex(is->subpq_mutex);
1850
            is->subpq_size++;
1851
            SDL_UnlockMutex(is->subpq_mutex);
1852
        }
1853
        av_free_packet(pkt);
1854
//        if (step)
1855
//            if (cur_stream)
1856
//                stream_pause(cur_stream);
1857
    }
1858
 the_end:
1859
    return 0;
1860
}
1861

    
1862
/* copy samples for viewing in editor window */
1863
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1864
{
1865
    int size, len, channels;
1866

    
1867
    channels = is->audio_st->codec->channels;
1868

    
1869
    size = samples_size / sizeof(short);
1870
    while (size > 0) {
1871
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1872
        if (len > size)
1873
            len = size;
1874
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1875
        samples += len;
1876
        is->sample_array_index += len;
1877
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1878
            is->sample_array_index = 0;
1879
        size -= len;
1880
    }
1881
}
1882

    
1883
/* return the new audio buffer size (samples can be added or deleted
1884
   to get better sync if video or external master clock) */
1885
static int synchronize_audio(VideoState *is, short *samples,
1886
                             int samples_size1, double pts)
1887
{
1888
    int n, samples_size;
1889
    double ref_clock;
1890

    
1891
    n = 2 * is->audio_st->codec->channels;
1892
    samples_size = samples_size1;
1893

    
1894
    /* if not master, then we try to remove or add samples to correct the clock */
1895
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1896
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1897
        double diff, avg_diff;
1898
        int wanted_size, min_size, max_size, nb_samples;
1899

    
1900
        ref_clock = get_master_clock(is);
1901
        diff = get_audio_clock(is) - ref_clock;
1902

    
1903
        if (diff < AV_NOSYNC_THRESHOLD) {
1904
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1905
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1906
                /* not enough measures to have a correct estimate */
1907
                is->audio_diff_avg_count++;
1908
            } else {
1909
                /* estimate the A-V difference */
1910
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1911

    
1912
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1913
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1914
                    nb_samples = samples_size / n;
1915

    
1916
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1917
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1918
                    if (wanted_size < min_size)
1919
                        wanted_size = min_size;
1920
                    else if (wanted_size > max_size)
1921
                        wanted_size = max_size;
1922

    
1923
                    /* add or remove samples to correction the synchro */
1924
                    if (wanted_size < samples_size) {
1925
                        /* remove samples */
1926
                        samples_size = wanted_size;
1927
                    } else if (wanted_size > samples_size) {
1928
                        uint8_t *samples_end, *q;
1929
                        int nb;
1930

    
1931
                        /* add samples */
1932
                        nb = (samples_size - wanted_size);
1933
                        samples_end = (uint8_t *)samples + samples_size - n;
1934
                        q = samples_end + n;
1935
                        while (nb > 0) {
1936
                            memcpy(q, samples_end, n);
1937
                            q += n;
1938
                            nb -= n;
1939
                        }
1940
                        samples_size = wanted_size;
1941
                    }
1942
                }
1943
#if 0
1944
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1945
                       diff, avg_diff, samples_size - samples_size1,
1946
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
1947
#endif
1948
            }
1949
        } else {
1950
            /* too big difference : may be initial PTS errors, so
1951
               reset A-V filter */
1952
            is->audio_diff_avg_count = 0;
1953
            is->audio_diff_cum = 0;
1954
        }
1955
    }
1956

    
1957
    return samples_size;
1958
}
1959

    
1960
/* decode one audio frame and returns its uncompressed size */
1961
static int audio_decode_frame(VideoState *is, double *pts_ptr)
1962
{
1963
    AVPacket *pkt_temp = &is->audio_pkt_temp;
1964
    AVPacket *pkt = &is->audio_pkt;
1965
    AVCodecContext *dec= is->audio_st->codec;
1966
    int n, len1, data_size;
1967
    double pts;
1968

    
1969
    for(;;) {
1970
        /* NOTE: the audio packet can contain several frames */
1971
        while (pkt_temp->size > 0) {
1972
            data_size = sizeof(is->audio_buf1);
1973
            len1 = avcodec_decode_audio3(dec,
1974
                                        (int16_t *)is->audio_buf1, &data_size,
1975
                                        pkt_temp);
1976
            if (len1 < 0) {
1977
                /* if error, we skip the frame */
1978
                pkt_temp->size = 0;
1979
                break;
1980
            }
1981

    
1982
            pkt_temp->data += len1;
1983
            pkt_temp->size -= len1;
1984
            if (data_size <= 0)
1985
                continue;
1986

    
1987
            if (dec->sample_fmt != is->audio_src_fmt) {
1988
                if (is->reformat_ctx)
1989
                    av_audio_convert_free(is->reformat_ctx);
1990
                is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1991
                                                         dec->sample_fmt, 1, NULL, 0);
1992
                if (!is->reformat_ctx) {
1993
                    fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1994
                        avcodec_get_sample_fmt_name(dec->sample_fmt),
1995
                        avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1996
                        break;
1997
                }
1998
                is->audio_src_fmt= dec->sample_fmt;
1999
            }
2000

    
2001
            if (is->reformat_ctx) {
2002
                const void *ibuf[6]= {is->audio_buf1};
2003
                void *obuf[6]= {is->audio_buf2};
2004
                int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
2005
                int ostride[6]= {2};
2006
                int len= data_size/istride[0];
2007
                if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
2008
                    printf("av_audio_convert() failed\n");
2009
                    break;
2010
                }
2011
                is->audio_buf= is->audio_buf2;
2012
                /* FIXME: existing code assume that data_size equals framesize*channels*2
2013
                          remove this legacy cruft */
2014
                data_size= len*2;
2015
            }else{
2016
                is->audio_buf= is->audio_buf1;
2017
            }
2018

    
2019
            /* if no pts, then compute it */
2020
            pts = is->audio_clock;
2021
            *pts_ptr = pts;
2022
            n = 2 * dec->channels;
2023
            is->audio_clock += (double)data_size /
2024
                (double)(n * dec->sample_rate);
2025
#if defined(DEBUG_SYNC)
2026
            {
2027
                static double last_clock;
2028
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
2029
                       is->audio_clock - last_clock,
2030
                       is->audio_clock, pts);
2031
                last_clock = is->audio_clock;
2032
            }
2033
#endif
2034
            return data_size;
2035
        }
2036

    
2037
        /* free the current packet */
2038
        if (pkt->data)
2039
            av_free_packet(pkt);
2040

    
2041
        if (is->paused || is->audioq.abort_request) {
2042
            return -1;
2043
        }
2044

    
2045
        /* read next packet */
2046
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
2047
            return -1;
2048
        if(pkt->data == flush_pkt.data){
2049
            avcodec_flush_buffers(dec);
2050
            continue;
2051
        }
2052

    
2053
        pkt_temp->data = pkt->data;
2054
        pkt_temp->size = pkt->size;
2055

    
2056
        /* if update the audio clock with the pts */
2057
        if (pkt->pts != AV_NOPTS_VALUE) {
2058
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
2059
        }
2060
    }
2061
}
2062

    
2063
/* get the current audio output buffer size, in samples. With SDL, we
2064
   cannot have a precise information */
2065
static int audio_write_get_buf_size(VideoState *is)
2066
{
2067
    return is->audio_buf_size - is->audio_buf_index;
2068
}
2069

    
2070

    
2071
/* prepare a new audio buffer */
2072
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
2073
{
2074
    VideoState *is = opaque;
2075
    int audio_size, len1;
2076
    double pts;
2077

    
2078
    audio_callback_time = av_gettime();
2079

    
2080
    while (len > 0) {
2081
        if (is->audio_buf_index >= is->audio_buf_size) {
2082
           audio_size = audio_decode_frame(is, &pts);
2083
           if (audio_size < 0) {
2084
                /* if error, just output silence */
2085
               is->audio_buf = is->audio_buf1;
2086
               is->audio_buf_size = 1024;
2087
               memset(is->audio_buf, 0, is->audio_buf_size);
2088
           } else {
2089
               if (is->show_audio)
2090
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
2091
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
2092
                                              pts);
2093
               is->audio_buf_size = audio_size;
2094
           }
2095
           is->audio_buf_index = 0;
2096
        }
2097
        len1 = is->audio_buf_size - is->audio_buf_index;
2098
        if (len1 > len)
2099
            len1 = len;
2100
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
2101
        len -= len1;
2102
        stream += len1;
2103
        is->audio_buf_index += len1;
2104
    }
2105
}
2106

    
2107
/* open a given stream. Return 0 if OK */
2108
static int stream_component_open(VideoState *is, int stream_index)
2109
{
2110
    AVFormatContext *ic = is->ic;
2111
    AVCodecContext *avctx;
2112
    AVCodec *codec;
2113
    SDL_AudioSpec wanted_spec, spec;
2114

    
2115
    if (stream_index < 0 || stream_index >= ic->nb_streams)
2116
        return -1;
2117
    avctx = ic->streams[stream_index]->codec;
2118

    
2119
    /* prepare audio output */
2120
    if (avctx->codec_type == CODEC_TYPE_AUDIO) {
2121
        if (avctx->channels > 0) {
2122
            avctx->request_channels = FFMIN(2, avctx->channels);
2123
        } else {
2124
            avctx->request_channels = 2;
2125
        }
2126
    }
2127

    
2128
    codec = avcodec_find_decoder(avctx->codec_id);
2129
    avctx->debug_mv = debug_mv;
2130
    avctx->debug = debug;
2131
    avctx->workaround_bugs = workaround_bugs;
2132
    avctx->lowres = lowres;
2133
    if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
2134
    avctx->idct_algo= idct;
2135
    if(fast) avctx->flags2 |= CODEC_FLAG2_FAST;
2136
    avctx->skip_frame= skip_frame;
2137
    avctx->skip_idct= skip_idct;
2138
    avctx->skip_loop_filter= skip_loop_filter;
2139
    avctx->error_recognition= error_recognition;
2140
    avctx->error_concealment= error_concealment;
2141
    avcodec_thread_init(avctx, thread_count);
2142

    
2143
    set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0);
2144

    
2145
    if (!codec ||
2146
        avcodec_open(avctx, codec) < 0)
2147
        return -1;
2148

    
2149
    /* prepare audio output */
2150
    if (avctx->codec_type == CODEC_TYPE_AUDIO) {
2151
        wanted_spec.freq = avctx->sample_rate;
2152
        wanted_spec.format = AUDIO_S16SYS;
2153
        wanted_spec.channels = avctx->channels;
2154
        wanted_spec.silence = 0;
2155
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
2156
        wanted_spec.callback = sdl_audio_callback;
2157
        wanted_spec.userdata = is;
2158
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
2159
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
2160
            return -1;
2161
        }
2162
        is->audio_hw_buf_size = spec.size;
2163
        is->audio_src_fmt= SAMPLE_FMT_S16;
2164
    }
2165

    
2166
    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
2167
    switch(avctx->codec_type) {
2168
    case CODEC_TYPE_AUDIO:
2169
        is->audio_stream = stream_index;
2170
        is->audio_st = ic->streams[stream_index];
2171
        is->audio_buf_size = 0;
2172
        is->audio_buf_index = 0;
2173

    
2174
        /* init averaging filter */
2175
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
2176
        is->audio_diff_avg_count = 0;
2177
        /* since we do not have a precise anough audio fifo fullness,
2178
           we correct audio sync only if larger than this threshold */
2179
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
2180

    
2181
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
2182
        packet_queue_init(&is->audioq);
2183
        SDL_PauseAudio(0);
2184
        break;
2185
    case CODEC_TYPE_VIDEO:
2186
        is->video_stream = stream_index;
2187
        is->video_st = ic->streams[stream_index];
2188

    
2189
//        is->video_current_pts_time = av_gettime();
2190

    
2191
        packet_queue_init(&is->videoq);
2192
        is->video_tid = SDL_CreateThread(video_thread, is);
2193
        break;
2194
    case CODEC_TYPE_SUBTITLE:
2195
        is->subtitle_stream = stream_index;
2196
        is->subtitle_st = ic->streams[stream_index];
2197
        packet_queue_init(&is->subtitleq);
2198

    
2199
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
2200
        break;
2201
    default:
2202
        break;
2203
    }
2204
    return 0;
2205
}
2206

    
2207
static void stream_component_close(VideoState *is, int stream_index)
2208
{
2209
    AVFormatContext *ic = is->ic;
2210
    AVCodecContext *avctx;
2211

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

    
2216
    switch(avctx->codec_type) {
2217
    case CODEC_TYPE_AUDIO:
2218
        packet_queue_abort(&is->audioq);
2219

    
2220
        SDL_CloseAudio();
2221

    
2222
        packet_queue_end(&is->audioq);
2223
        if (is->reformat_ctx)
2224
            av_audio_convert_free(is->reformat_ctx);
2225
        is->reformat_ctx = NULL;
2226
        break;
2227
    case CODEC_TYPE_VIDEO:
2228
        packet_queue_abort(&is->videoq);
2229

    
2230
        /* note: we also signal this mutex to make sure we deblock the
2231
           video thread in all cases */
2232
        SDL_LockMutex(is->pictq_mutex);
2233
        SDL_CondSignal(is->pictq_cond);
2234
        SDL_UnlockMutex(is->pictq_mutex);
2235

    
2236
        SDL_WaitThread(is->video_tid, NULL);
2237

    
2238
        packet_queue_end(&is->videoq);
2239
        break;
2240
    case CODEC_TYPE_SUBTITLE:
2241
        packet_queue_abort(&is->subtitleq);
2242

    
2243
        /* note: we also signal this mutex to make sure we deblock the
2244
           video thread in all cases */
2245
        SDL_LockMutex(is->subpq_mutex);
2246
        is->subtitle_stream_changed = 1;
2247

    
2248
        SDL_CondSignal(is->subpq_cond);
2249
        SDL_UnlockMutex(is->subpq_mutex);
2250

    
2251
        SDL_WaitThread(is->subtitle_tid, NULL);
2252

    
2253
        packet_queue_end(&is->subtitleq);
2254
        break;
2255
    default:
2256
        break;
2257
    }
2258

    
2259
    ic->streams[stream_index]->discard = AVDISCARD_ALL;
2260
    avcodec_close(avctx);
2261
    switch(avctx->codec_type) {
2262
    case CODEC_TYPE_AUDIO:
2263
        is->audio_st = NULL;
2264
        is->audio_stream = -1;
2265
        break;
2266
    case CODEC_TYPE_VIDEO:
2267
        is->video_st = NULL;
2268
        is->video_stream = -1;
2269
        break;
2270
    case CODEC_TYPE_SUBTITLE:
2271
        is->subtitle_st = NULL;
2272
        is->subtitle_stream = -1;
2273
        break;
2274
    default:
2275
        break;
2276
    }
2277
}
2278

    
2279
/* since we have only one decoding thread, we can use a global
2280
   variable instead of a thread local variable */
2281
static VideoState *global_video_state;
2282

    
2283
static int decode_interrupt_cb(void)
2284
{
2285
    return (global_video_state && global_video_state->abort_request);
2286
}
2287

    
2288
/* this thread gets the stream from the disk or the network */
2289
static int decode_thread(void *arg)
2290
{
2291
    VideoState *is = arg;
2292
    AVFormatContext *ic;
2293
    int err, i, ret;
2294
    int st_index[CODEC_TYPE_NB];
2295
    int st_count[CODEC_TYPE_NB]={0};
2296
    int st_best_packet_count[CODEC_TYPE_NB];
2297
    AVPacket pkt1, *pkt = &pkt1;
2298
    AVFormatParameters params, *ap = &params;
2299
    int eof=0;
2300

    
2301
    ic = avformat_alloc_context();
2302

    
2303
    memset(st_index, -1, sizeof(st_index));
2304
    memset(st_best_packet_count, -1, sizeof(st_best_packet_count));
2305
    is->video_stream = -1;
2306
    is->audio_stream = -1;
2307
    is->subtitle_stream = -1;
2308

    
2309
    global_video_state = is;
2310
    url_set_interrupt_cb(decode_interrupt_cb);
2311

    
2312
    memset(ap, 0, sizeof(*ap));
2313

    
2314
    ap->prealloced_context = 1;
2315
    ap->width = frame_width;
2316
    ap->height= frame_height;
2317
    ap->time_base= (AVRational){1, 25};
2318
    ap->pix_fmt = frame_pix_fmt;
2319

    
2320
    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
2321

    
2322
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
2323
    if (err < 0) {
2324
        print_error(is->filename, err);
2325
        ret = -1;
2326
        goto fail;
2327
    }
2328
    is->ic = ic;
2329

    
2330
    if(genpts)
2331
        ic->flags |= AVFMT_FLAG_GENPTS;
2332

    
2333
    err = av_find_stream_info(ic);
2334
    if (err < 0) {
2335
        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
2336
        ret = -1;
2337
        goto fail;
2338
    }
2339
    if(ic->pb)
2340
        ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
2341

    
2342
    if(seek_by_bytes<0)
2343
        seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT);
2344

    
2345
    /* if seeking requested, we execute it */
2346
    if (start_time != AV_NOPTS_VALUE) {
2347
        int64_t timestamp;
2348

    
2349
        timestamp = start_time;
2350
        /* add the stream start time */
2351
        if (ic->start_time != AV_NOPTS_VALUE)
2352
            timestamp += ic->start_time;
2353
        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
2354
        if (ret < 0) {
2355
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
2356
                    is->filename, (double)timestamp / AV_TIME_BASE);
2357
        }
2358
    }
2359

    
2360
    for(i = 0; i < ic->nb_streams; i++) {
2361
        AVStream *st= ic->streams[i];
2362
        AVCodecContext *avctx = st->codec;
2363
        ic->streams[i]->discard = AVDISCARD_ALL;
2364
        if(avctx->codec_type >= (unsigned)CODEC_TYPE_NB)
2365
            continue;
2366
        if(st_count[avctx->codec_type]++ != wanted_stream[avctx->codec_type] && wanted_stream[avctx->codec_type] >= 0)
2367
            continue;
2368

    
2369
        if(st_best_packet_count[avctx->codec_type] >= st->codec_info_nb_frames)
2370
            continue;
2371
        st_best_packet_count[avctx->codec_type]= st->codec_info_nb_frames;
2372

    
2373
        switch(avctx->codec_type) {
2374
        case CODEC_TYPE_AUDIO:
2375
            if (!audio_disable)
2376
                st_index[CODEC_TYPE_AUDIO] = i;
2377
            break;
2378
        case CODEC_TYPE_VIDEO:
2379
        case CODEC_TYPE_SUBTITLE:
2380
            if (!video_disable)
2381
                st_index[avctx->codec_type] = i;
2382
            break;
2383
        default:
2384
            break;
2385
        }
2386
    }
2387
    if (show_status) {
2388
        dump_format(ic, 0, is->filename, 0);
2389
    }
2390

    
2391
    /* open the streams */
2392
    if (st_index[CODEC_TYPE_AUDIO] >= 0) {
2393
        stream_component_open(is, st_index[CODEC_TYPE_AUDIO]);
2394
    }
2395

    
2396
    ret=-1;
2397
    if (st_index[CODEC_TYPE_VIDEO] >= 0) {
2398
        ret= stream_component_open(is, st_index[CODEC_TYPE_VIDEO]);
2399
    }
2400
    is->refresh_tid = SDL_CreateThread(refresh_thread, is);
2401
    if(ret<0) {
2402
        if (!display_disable)
2403
            is->show_audio = 2;
2404
    }
2405

    
2406
    if (st_index[CODEC_TYPE_SUBTITLE] >= 0) {
2407
        stream_component_open(is, st_index[CODEC_TYPE_SUBTITLE]);
2408
    }
2409

    
2410
    if (is->video_stream < 0 && is->audio_stream < 0) {
2411
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
2412
        ret = -1;
2413
        goto fail;
2414
    }
2415

    
2416
    for(;;) {
2417
        if (is->abort_request)
2418
            break;
2419
        if (is->paused != is->last_paused) {
2420
            is->last_paused = is->paused;
2421
            if (is->paused)
2422
                is->read_pause_return= av_read_pause(ic);
2423
            else
2424
                av_read_play(ic);
2425
        }
2426
#if CONFIG_RTSP_DEMUXER
2427
        if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
2428
            /* wait 10 ms to avoid trying to get another packet */
2429
            /* XXX: horrible */
2430
            SDL_Delay(10);
2431
            continue;
2432
        }
2433
#endif
2434
        if (is->seek_req) {
2435
            int64_t seek_target= is->seek_pos;
2436
            int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2437
            int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2438
//FIXME the +-2 is due to rounding being not done in the correct direction in generation
2439
//      of the seek_pos/seek_rel variables
2440

    
2441
            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2442
            if (ret < 0) {
2443
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2444
            }else{
2445
                if (is->audio_stream >= 0) {
2446
                    packet_queue_flush(&is->audioq);
2447
                    packet_queue_put(&is->audioq, &flush_pkt);
2448
                }
2449
                if (is->subtitle_stream >= 0) {
2450
                    packet_queue_flush(&is->subtitleq);
2451
                    packet_queue_put(&is->subtitleq, &flush_pkt);
2452
                }
2453
                if (is->video_stream >= 0) {
2454
                    packet_queue_flush(&is->videoq);
2455
                    packet_queue_put(&is->videoq, &flush_pkt);
2456
                }
2457
            }
2458
            is->seek_req = 0;
2459
            eof= 0;
2460
        }
2461

    
2462
        /* if the queue are full, no need to read more */
2463
        if (   is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
2464
            || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream<0)
2465
                && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream<0)
2466
                && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) {
2467
            /* wait 10 ms */
2468
            SDL_Delay(10);
2469
            continue;
2470
        }
2471
        if(url_feof(ic->pb) || eof) {
2472
            if(is->video_stream >= 0){
2473
                av_init_packet(pkt);
2474
                pkt->data=NULL;
2475
                pkt->size=0;
2476
                pkt->stream_index= is->video_stream;
2477
                packet_queue_put(&is->videoq, pkt);
2478
            }
2479
            SDL_Delay(10);
2480
            if(autoexit && is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
2481
                ret=AVERROR_EOF;
2482
                goto fail;
2483
            }
2484
            continue;
2485
        }
2486
        ret = av_read_frame(ic, pkt);
2487
        if (ret < 0) {
2488
            if (ret == AVERROR_EOF)
2489
                eof=1;
2490
            if (url_ferror(ic->pb))
2491
                break;
2492
            SDL_Delay(100); /* wait for user event */
2493
            continue;
2494
        }
2495
        if (pkt->stream_index == is->audio_stream) {
2496
            packet_queue_put(&is->audioq, pkt);
2497
        } else if (pkt->stream_index == is->video_stream) {
2498
            packet_queue_put(&is->videoq, pkt);
2499
        } else if (pkt->stream_index == is->subtitle_stream) {
2500
            packet_queue_put(&is->subtitleq, pkt);
2501
        } else {
2502
            av_free_packet(pkt);
2503
        }
2504
    }
2505
    /* wait until the end */
2506
    while (!is->abort_request) {
2507
        SDL_Delay(100);
2508
    }
2509

    
2510
    ret = 0;
2511
 fail:
2512
    /* disable interrupting */
2513
    global_video_state = NULL;
2514

    
2515
    /* close each stream */
2516
    if (is->audio_stream >= 0)
2517
        stream_component_close(is, is->audio_stream);
2518
    if (is->video_stream >= 0)
2519
        stream_component_close(is, is->video_stream);
2520
    if (is->subtitle_stream >= 0)
2521
        stream_component_close(is, is->subtitle_stream);
2522
    if (is->ic) {
2523
        av_close_input_file(is->ic);
2524
        is->ic = NULL; /* safety */
2525
    }
2526
    url_set_interrupt_cb(NULL);
2527

    
2528
    if (ret != 0) {
2529
        SDL_Event event;
2530

    
2531
        event.type = FF_QUIT_EVENT;
2532
        event.user.data1 = is;
2533
        SDL_PushEvent(&event);
2534
    }
2535
    return 0;
2536
}
2537

    
2538
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2539
{
2540
    VideoState *is;
2541

    
2542
    is = av_mallocz(sizeof(VideoState));
2543
    if (!is)
2544
        return NULL;
2545
    av_strlcpy(is->filename, filename, sizeof(is->filename));
2546
    is->iformat = iformat;
2547
    is->ytop = 0;
2548
    is->xleft = 0;
2549

    
2550
    /* start video display */
2551
    is->pictq_mutex = SDL_CreateMutex();
2552
    is->pictq_cond = SDL_CreateCond();
2553

    
2554
    is->subpq_mutex = SDL_CreateMutex();
2555
    is->subpq_cond = SDL_CreateCond();
2556

    
2557
    is->av_sync_type = av_sync_type;
2558
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2559
    if (!is->parse_tid) {
2560
        av_free(is);
2561
        return NULL;
2562
    }
2563
    return is;
2564
}
2565

    
2566
static void stream_close(VideoState *is)
2567
{
2568
    VideoPicture *vp;
2569
    int i;
2570
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2571
    is->abort_request = 1;
2572
    SDL_WaitThread(is->parse_tid, NULL);
2573
    SDL_WaitThread(is->refresh_tid, NULL);
2574

    
2575
    /* free all pictures */
2576
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2577
        vp = &is->pictq[i];
2578
#if CONFIG_AVFILTER
2579
        if (vp->picref) {
2580
            avfilter_unref_pic(vp->picref);
2581
            vp->picref = NULL;
2582
        }
2583
#endif
2584
        if (vp->bmp) {
2585
            SDL_FreeYUVOverlay(vp->bmp);
2586
            vp->bmp = NULL;
2587
        }
2588
    }
2589
    SDL_DestroyMutex(is->pictq_mutex);
2590
    SDL_DestroyCond(is->pictq_cond);
2591
    SDL_DestroyMutex(is->subpq_mutex);
2592
    SDL_DestroyCond(is->subpq_cond);
2593
#if !CONFIG_AVFILTER
2594
    if (is->img_convert_ctx)
2595
        sws_freeContext(is->img_convert_ctx);
2596
#endif
2597
    av_free(is);
2598
}
2599

    
2600
static void stream_cycle_channel(VideoState *is, int codec_type)
2601
{
2602
    AVFormatContext *ic = is->ic;
2603
    int start_index, stream_index;
2604
    AVStream *st;
2605

    
2606
    if (codec_type == CODEC_TYPE_VIDEO)
2607
        start_index = is->video_stream;
2608
    else if (codec_type == CODEC_TYPE_AUDIO)
2609
        start_index = is->audio_stream;
2610
    else
2611
        start_index = is->subtitle_stream;
2612
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2613
        return;
2614
    stream_index = start_index;
2615
    for(;;) {
2616
        if (++stream_index >= is->ic->nb_streams)
2617
        {
2618
            if (codec_type == CODEC_TYPE_SUBTITLE)
2619
            {
2620
                stream_index = -1;
2621
                goto the_end;
2622
            } else
2623
                stream_index = 0;
2624
        }
2625
        if (stream_index == start_index)
2626
            return;
2627
        st = ic->streams[stream_index];
2628
        if (st->codec->codec_type == codec_type) {
2629
            /* check that parameters are OK */
2630
            switch(codec_type) {
2631
            case CODEC_TYPE_AUDIO:
2632
                if (st->codec->sample_rate != 0 &&
2633
                    st->codec->channels != 0)
2634
                    goto the_end;
2635
                break;
2636
            case CODEC_TYPE_VIDEO:
2637
            case CODEC_TYPE_SUBTITLE:
2638
                goto the_end;
2639
            default:
2640
                break;
2641
            }
2642
        }
2643
    }
2644
 the_end:
2645
    stream_component_close(is, start_index);
2646
    stream_component_open(is, stream_index);
2647
}
2648

    
2649

    
2650
static void toggle_full_screen(void)
2651
{
2652
    is_full_screen = !is_full_screen;
2653
    if (!fs_screen_width) {
2654
        /* use default SDL method */
2655
//        SDL_WM_ToggleFullScreen(screen);
2656
    }
2657
    video_open(cur_stream);
2658
}
2659

    
2660
static void toggle_pause(void)
2661
{
2662
    if (cur_stream)
2663
        stream_pause(cur_stream);
2664
    step = 0;
2665
}
2666

    
2667
static void step_to_next_frame(void)
2668
{
2669
    if (cur_stream) {
2670
        /* if the stream is paused unpause it, then step */
2671
        if (cur_stream->paused)
2672
            stream_pause(cur_stream);
2673
    }
2674
    step = 1;
2675
}
2676

    
2677
static void do_exit(void)
2678
{
2679
    int i;
2680
    if (cur_stream) {
2681
        stream_close(cur_stream);
2682
        cur_stream = NULL;
2683
    }
2684
    for (i = 0; i < CODEC_TYPE_NB; i++)
2685
        av_free(avcodec_opts[i]);
2686
    av_free(avformat_opts);
2687
    av_free(sws_opts);
2688
#if CONFIG_AVFILTER
2689
    avfilter_uninit();
2690
#endif
2691
    if (show_status)
2692
        printf("\n");
2693
    SDL_Quit();
2694
    exit(0);
2695
}
2696

    
2697
static void toggle_audio_display(void)
2698
{
2699
    if (cur_stream) {
2700
        int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
2701
        cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
2702
        fill_rectangle(screen,
2703
                    cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
2704
                    bgcolor);
2705
        SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
2706
    }
2707
}
2708

    
2709
/* handle an event sent by the GUI */
2710
static void event_loop(void)
2711
{
2712
    SDL_Event event;
2713
    double incr, pos, frac;
2714

    
2715
    for(;;) {
2716
        double x;
2717
        SDL_WaitEvent(&event);
2718
        switch(event.type) {
2719
        case SDL_KEYDOWN:
2720
            switch(event.key.keysym.sym) {
2721
            case SDLK_ESCAPE:
2722
            case SDLK_q:
2723
                do_exit();
2724
                break;
2725
            case SDLK_f:
2726
                toggle_full_screen();
2727
                break;
2728
            case SDLK_p:
2729
            case SDLK_SPACE:
2730
                toggle_pause();
2731
                break;
2732
            case SDLK_s: //S: Step to next frame
2733
                step_to_next_frame();
2734
                break;
2735
            case SDLK_a:
2736
                if (cur_stream)
2737
                    stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2738
                break;
2739
            case SDLK_v:
2740
                if (cur_stream)
2741
                    stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2742
                break;
2743
            case SDLK_t:
2744
                if (cur_stream)
2745
                    stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2746
                break;
2747
            case SDLK_w:
2748
                toggle_audio_display();
2749
                break;
2750
            case SDLK_LEFT:
2751
                incr = -10.0;
2752
                goto do_seek;
2753
            case SDLK_RIGHT:
2754
                incr = 10.0;
2755
                goto do_seek;
2756
            case SDLK_UP:
2757
                incr = 60.0;
2758
                goto do_seek;
2759
            case SDLK_DOWN:
2760
                incr = -60.0;
2761
            do_seek:
2762
                if (cur_stream) {
2763
                    if (seek_by_bytes) {
2764
                        if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){
2765
                            pos= cur_stream->video_current_pos;
2766
                        }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
2767
                            pos= cur_stream->audio_pkt.pos;
2768
                        }else
2769
                            pos = url_ftell(cur_stream->ic->pb);
2770
                        if (cur_stream->ic->bit_rate)
2771
                            incr *= cur_stream->ic->bit_rate / 8.0;
2772
                        else
2773
                            incr *= 180000.0;
2774
                        pos += incr;
2775
                        stream_seek(cur_stream, pos, incr, 1);
2776
                    } else {
2777
                        pos = get_master_clock(cur_stream);
2778
                        pos += incr;
2779
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
2780
                    }
2781
                }
2782
                break;
2783
            default:
2784
                break;
2785
            }
2786
            break;
2787
        case SDL_MOUSEBUTTONDOWN:
2788
        case SDL_MOUSEMOTION:
2789
            if(event.type ==SDL_MOUSEBUTTONDOWN){
2790
                x= event.button.x;
2791
            }else{
2792
                if(event.motion.state != SDL_PRESSED)
2793
                    break;
2794
                x= event.motion.x;
2795
            }
2796
            if (cur_stream) {
2797
                if(seek_by_bytes || cur_stream->ic->duration<=0){
2798
                    uint64_t size=  url_fsize(cur_stream->ic->pb);
2799
                    stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
2800
                }else{
2801
                    int64_t ts;
2802
                    int ns, hh, mm, ss;
2803
                    int tns, thh, tmm, tss;
2804
                    tns = cur_stream->ic->duration/1000000LL;
2805
                    thh = tns/3600;
2806
                    tmm = (tns%3600)/60;
2807
                    tss = (tns%60);
2808
                    frac = x/cur_stream->width;
2809
                    ns = frac*tns;
2810
                    hh = ns/3600;
2811
                    mm = (ns%3600)/60;
2812
                    ss = (ns%60);
2813
                    fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2814
                            hh, mm, ss, thh, tmm, tss);
2815
                    ts = frac*cur_stream->ic->duration;
2816
                    if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2817
                        ts += cur_stream->ic->start_time;
2818
                    stream_seek(cur_stream, ts, 0, 0);
2819
                }
2820
            }
2821
            break;
2822
        case SDL_VIDEORESIZE:
2823
            if (cur_stream) {
2824
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2825
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2826
                screen_width = cur_stream->width = event.resize.w;
2827
                screen_height= cur_stream->height= event.resize.h;
2828
            }
2829
            break;
2830
        case SDL_QUIT:
2831
        case FF_QUIT_EVENT:
2832
            do_exit();
2833
            break;
2834
        case FF_ALLOC_EVENT:
2835
            video_open(event.user.data1);
2836
            alloc_picture(event.user.data1);
2837
            break;
2838
        case FF_REFRESH_EVENT:
2839
            video_refresh_timer(event.user.data1);
2840
            cur_stream->refresh=0;
2841
            break;
2842
        default:
2843
            break;
2844
        }
2845
    }
2846
}
2847

    
2848
static void opt_frame_size(const char *arg)
2849
{
2850
    if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2851
        fprintf(stderr, "Incorrect frame size\n");
2852
        exit(1);
2853
    }
2854
    if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2855
        fprintf(stderr, "Frame size must be a multiple of 2\n");
2856
        exit(1);
2857
    }
2858
}
2859

    
2860
static int opt_width(const char *opt, const char *arg)
2861
{
2862
    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2863
    return 0;
2864
}
2865

    
2866
static int opt_height(const char *opt, const char *arg)
2867
{
2868
    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2869
    return 0;
2870
}
2871

    
2872
static void opt_format(const char *arg)
2873
{
2874
    file_iformat = av_find_input_format(arg);
2875
    if (!file_iformat) {
2876
        fprintf(stderr, "Unknown input format: %s\n", arg);
2877
        exit(1);
2878
    }
2879
}
2880

    
2881
static void opt_frame_pix_fmt(const char *arg)
2882
{
2883
    frame_pix_fmt = av_get_pix_fmt(arg);
2884
}
2885

    
2886
static int opt_sync(const char *opt, const char *arg)
2887
{
2888
    if (!strcmp(arg, "audio"))
2889
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2890
    else if (!strcmp(arg, "video"))
2891
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2892
    else if (!strcmp(arg, "ext"))
2893
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2894
    else {
2895
        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2896
        exit(1);
2897
    }
2898
    return 0;
2899
}
2900

    
2901
static int opt_seek(const char *opt, const char *arg)
2902
{
2903
    start_time = parse_time_or_die(opt, arg, 1);
2904
    return 0;
2905
}
2906

    
2907
static int opt_debug(const char *opt, const char *arg)
2908
{
2909
    av_log_set_level(99);
2910
    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2911
    return 0;
2912
}
2913

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

    
2920
static int opt_thread_count(const char *opt, const char *arg)
2921
{
2922
    thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2923
#if !HAVE_THREADS
2924
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2925
#endif
2926
    return 0;
2927
}
2928

    
2929
static const OptionDef options[] = {
2930
#include "cmdutils_common_opts.h"
2931
    { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2932
    { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2933
    { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2934
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2935
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2936
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2937
    { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[CODEC_TYPE_AUDIO]}, "select desired audio stream", "stream_number" },
2938
    { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[CODEC_TYPE_VIDEO]}, "select desired video stream", "stream_number" },
2939
    { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[CODEC_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" },
2940
    { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2941
    { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" },
2942
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2943
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2944
    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2945
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2946
    { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2947
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2948
    { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2949
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2950
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2951
    { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""},
2952
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2953
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2954
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2955
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2956
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2957
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2958
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2959
    { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2960
    { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2961
    { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" },
2962
    { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" },
2963
#if CONFIG_AVFILTER
2964
    { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
2965
#endif
2966
    { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" },
2967
    { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2968
    { NULL, },
2969
};
2970

    
2971
static void show_usage(void)
2972
{
2973
    printf("Simple media player\n");
2974
    printf("usage: ffplay [options] input_file\n");
2975
    printf("\n");
2976
}
2977

    
2978
static void show_help(void)
2979
{
2980
    show_usage();
2981
    show_help_options(options, "Main options:\n",
2982
                      OPT_EXPERT, 0);
2983
    show_help_options(options, "\nAdvanced options:\n",
2984
                      OPT_EXPERT, OPT_EXPERT);
2985
    printf("\nWhile playing:\n"
2986
           "q, ESC              quit\n"
2987
           "f                   toggle full screen\n"
2988
           "p, SPC              pause\n"
2989
           "a                   cycle audio channel\n"
2990
           "v                   cycle video channel\n"
2991
           "t                   cycle subtitle channel\n"
2992
           "w                   show audio waves\n"
2993
           "left/right          seek backward/forward 10 seconds\n"
2994
           "down/up             seek backward/forward 1 minute\n"
2995
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2996
           );
2997
}
2998

    
2999
static void opt_input_file(const char *filename)
3000
{
3001
    if (input_filename) {
3002
        fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3003
                filename, input_filename);
3004
        exit(1);
3005
    }
3006
    if (!strcmp(filename, "-"))
3007
        filename = "pipe:";
3008
    input_filename = filename;
3009
}
3010

    
3011
/* Called from the main */
3012
int main(int argc, char **argv)
3013
{
3014
    int flags, i;
3015

    
3016
    /* register all codecs, demux and protocols */
3017
    avcodec_register_all();
3018
    avdevice_register_all();
3019
#if CONFIG_AVFILTER
3020
    avfilter_register_all();
3021
#endif
3022
    av_register_all();
3023

    
3024
    for(i=0; i<CODEC_TYPE_NB; i++){
3025
        avcodec_opts[i]= avcodec_alloc_context2(i);
3026
    }
3027
    avformat_opts = avformat_alloc_context();
3028
#if !CONFIG_AVFILTER
3029
    sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
3030
#endif
3031

    
3032
    show_banner();
3033

    
3034
    parse_options(argc, argv, options, opt_input_file);
3035

    
3036
    if (!input_filename) {
3037
        show_usage();
3038
        fprintf(stderr, "An input file must be specified\n");
3039
        fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
3040
        exit(1);
3041
    }
3042

    
3043
    if (display_disable) {
3044
        video_disable = 1;
3045
    }
3046
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
3047
#if !defined(__MINGW32__) && !defined(__APPLE__)
3048
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
3049
#endif
3050
    if (SDL_Init (flags)) {
3051
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
3052
        exit(1);
3053
    }
3054

    
3055
    if (!display_disable) {
3056
#if HAVE_SDL_VIDEO_SIZE
3057
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
3058
        fs_screen_width = vi->current_w;
3059
        fs_screen_height = vi->current_h;
3060
#endif
3061
    }
3062

    
3063
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
3064
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
3065
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
3066

    
3067
    av_init_packet(&flush_pkt);
3068
    flush_pkt.data= "FLUSH";
3069

    
3070
    cur_stream = stream_open(input_filename, file_iformat);
3071

    
3072
    event_loop();
3073

    
3074
    /* never returns */
3075

    
3076
    return 0;
3077
}