Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ c57d3469

History | View | Annotate | Download (73.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
#define HAVE_AV_CONFIG_H
22
#include "avformat.h"
23
#include "swscale.h"
24

    
25
#include "version.h"
26
#include "cmdutils.h"
27

    
28
#include <SDL.h>
29
#include <SDL_thread.h>
30

    
31
#ifdef __MINGW32__
32
#undef main /* We don't want SDL to override our main() */
33
#endif
34

    
35
#ifdef CONFIG_OS2
36
#define INCL_DOS
37
 #include <os2.h>
38
 #include <stdio.h>
39

    
40
 void MorphToPM()
41
 {
42
   PPIB pib;
43
   PTIB tib;
44

    
45
   DosGetInfoBlocks(&tib, &pib);
46

    
47
   // Change flag from VIO to PM:
48
   if (pib->pib_ultype==2) pib->pib_ultype = 3;
49
 }
50
#endif
51

    
52
//#define DEBUG_SYNC
53

    
54
#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
55
#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
56
#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
57

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

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

    
67
/* maximum audio speed change to get correct sync */
68
#define SAMPLE_CORRECTION_PERCENT_MAX 10
69

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

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

    
76
static int sws_flags = SWS_BICUBIC;
77

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

    
87
#define VIDEO_PICTURE_QUEUE_SIZE 1
88
#define SUBPICTURE_QUEUE_SIZE 4
89

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

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

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

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

    
122
    int audio_stream;
123

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

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

    
145
    int show_audio; /* if true, display audio samples */
146
    int16_t sample_array[SAMPLE_ARRAY_SIZE];
147
    int sample_array_index;
148
    int last_i_start;
149

    
150
    SDL_Thread *subtitle_tid;
151
    int subtitle_stream;
152
    int subtitle_stream_changed;
153
    AVStream *subtitle_st;
154
    PacketQueue subtitleq;
155
    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
156
    int subpq_size, subpq_rindex, subpq_windex;
157
    SDL_mutex *subpq_mutex;
158
    SDL_cond *subpq_cond;
159

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

    
174
    //    QETimer *video_timer;
175
    char filename[1024];
176
    int width, height, xleft, ytop;
177
} VideoState;
178

    
179
void show_help(void);
180
static int audio_write_get_buf_size(VideoState *is);
181

    
182
/* options specified by the user */
183
static AVInputFormat *file_iformat;
184
static const char *input_filename;
185
static int fs_screen_width;
186
static int fs_screen_height;
187
static int screen_width = 0;
188
static int screen_height = 0;
189
static int audio_disable;
190
static int video_disable;
191
static int seek_by_bytes;
192
static int display_disable;
193
static int show_status;
194
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
195
static int64_t start_time = AV_NOPTS_VALUE;
196
static int debug = 0;
197
static int debug_mv = 0;
198
static int step = 0;
199
static int thread_count = 1;
200
static int workaround_bugs = 1;
201
static int fast = 0;
202
static int genpts = 0;
203
static int lowres = 0;
204
static int idct = FF_IDCT_AUTO;
205
static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
206
static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
207
static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
208
static int error_resilience = FF_ER_CAREFUL;
209
static int error_concealment = 3;
210

    
211
/* current context */
212
static int is_full_screen;
213
static VideoState *cur_stream;
214
static int64_t audio_callback_time;
215

    
216
AVPacket flush_pkt;
217

    
218
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
219
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
220
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
221

    
222
SDL_Surface *screen;
223

    
224
/* packet queue handling */
225
static void packet_queue_init(PacketQueue *q)
226
{
227
    memset(q, 0, sizeof(PacketQueue));
228
    q->mutex = SDL_CreateMutex();
229
    q->cond = SDL_CreateCond();
230
}
231

    
232
static void packet_queue_flush(PacketQueue *q)
233
{
234
    AVPacketList *pkt, *pkt1;
235

    
236
    SDL_LockMutex(q->mutex);
237
    for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
238
        pkt1 = pkt->next;
239
        av_free_packet(&pkt->pkt);
240
        av_freep(&pkt);
241
    }
242
    q->last_pkt = NULL;
243
    q->first_pkt = NULL;
244
    q->nb_packets = 0;
245
    q->size = 0;
246
    SDL_UnlockMutex(q->mutex);
247
}
248

    
249
static void packet_queue_end(PacketQueue *q)
250
{
251
    packet_queue_flush(q);
252
    SDL_DestroyMutex(q->mutex);
253
    SDL_DestroyCond(q->cond);
254
}
255

    
256
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
257
{
258
    AVPacketList *pkt1;
259

    
260
    /* duplicate the packet */
261
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
262
        return -1;
263

    
264
    pkt1 = av_malloc(sizeof(AVPacketList));
265
    if (!pkt1)
266
        return -1;
267
    pkt1->pkt = *pkt;
268
    pkt1->next = NULL;
269

    
270

    
271
    SDL_LockMutex(q->mutex);
272

    
273
    if (!q->last_pkt)
274

    
275
        q->first_pkt = pkt1;
276
    else
277
        q->last_pkt->next = pkt1;
278
    q->last_pkt = pkt1;
279
    q->nb_packets++;
280
    q->size += pkt1->pkt.size;
281
    /* XXX: should duplicate packet data in DV case */
282
    SDL_CondSignal(q->cond);
283

    
284
    SDL_UnlockMutex(q->mutex);
285
    return 0;
286
}
287

    
288
static void packet_queue_abort(PacketQueue *q)
289
{
290
    SDL_LockMutex(q->mutex);
291

    
292
    q->abort_request = 1;
293

    
294
    SDL_CondSignal(q->cond);
295

    
296
    SDL_UnlockMutex(q->mutex);
297
}
298

    
299
/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
300
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
301
{
302
    AVPacketList *pkt1;
303
    int ret;
304

    
305
    SDL_LockMutex(q->mutex);
306

    
307
    for(;;) {
308
        if (q->abort_request) {
309
            ret = -1;
310
            break;
311
        }
312

    
313
        pkt1 = q->first_pkt;
314
        if (pkt1) {
315
            q->first_pkt = pkt1->next;
316
            if (!q->first_pkt)
317
                q->last_pkt = NULL;
318
            q->nb_packets--;
319
            q->size -= pkt1->pkt.size;
320
            *pkt = pkt1->pkt;
321
            av_free(pkt1);
322
            ret = 1;
323
            break;
324
        } else if (!block) {
325
            ret = 0;
326
            break;
327
        } else {
328
            SDL_CondWait(q->cond, q->mutex);
329
        }
330
    }
331
    SDL_UnlockMutex(q->mutex);
332
    return ret;
333
}
334

    
335
static inline void fill_rectangle(SDL_Surface *screen,
336
                                  int x, int y, int w, int h, int color)
337
{
338
    SDL_Rect rect;
339
    rect.x = x;
340
    rect.y = y;
341
    rect.w = w;
342
    rect.h = h;
343
    SDL_FillRect(screen, &rect, color);
344
}
345

    
346
#if 0
347
/* draw only the border of a rectangle */
348
void fill_border(VideoState *s, int x, int y, int w, int h, int color)
349
{
350
    int w1, w2, h1, h2;
351

352
    /* fill the background */
353
    w1 = x;
354
    if (w1 < 0)
355
        w1 = 0;
356
    w2 = s->width - (x + w);
357
    if (w2 < 0)
358
        w2 = 0;
359
    h1 = y;
360
    if (h1 < 0)
361
        h1 = 0;
362
    h2 = s->height - (y + h);
363
    if (h2 < 0)
364
        h2 = 0;
365
    fill_rectangle(screen,
366
                   s->xleft, s->ytop,
367
                   w1, s->height,
368
                   color);
369
    fill_rectangle(screen,
370
                   s->xleft + s->width - w2, s->ytop,
371
                   w2, s->height,
372
                   color);
373
    fill_rectangle(screen,
374
                   s->xleft + w1, s->ytop,
375
                   s->width - w1 - w2, h1,
376
                   color);
377
    fill_rectangle(screen,
378
                   s->xleft + w1, s->ytop + s->height - h2,
379
                   s->width - w1 - w2, h2,
380
                   color);
381
}
382
#endif
383

    
384

    
385

    
386
#define SCALEBITS 10
387
#define ONE_HALF  (1 << (SCALEBITS - 1))
388
#define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
389

    
390
#define RGB_TO_Y_CCIR(r, g, b) \
391
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
392
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
393

    
394
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
395
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
396
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
397

    
398
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
399
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
400
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
401

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

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

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

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

    
428

    
429
#define BPP 1
430

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

    
439
    lum = dst->data[0] + rect->y * dst->linesize[0];
440
    cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1];
441
    cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2];
442

    
443
    width2 = (rect->w + 1) >> 1;
444
    skip2 = rect->x >> 1;
445
    wrap = dst->linesize[0];
446
    wrap3 = rect->linesize;
447
    p = rect->bitmap;
448
    pal = rect->rgba_palette;  /* Now in YCrCb! */
449

    
450
    if (rect->y & 1) {
451
        lum += rect->x;
452
        cb += skip2;
453
        cr += skip2;
454

    
455
        if (rect->x & 1) {
456
            YUVA_IN(y, u, v, a, p, pal);
457
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
458
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
459
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
460
            cb++;
461
            cr++;
462
            lum++;
463
            p += BPP;
464
        }
465
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
466
            YUVA_IN(y, u, v, a, p, pal);
467
            u1 = u;
468
            v1 = v;
469
            a1 = a;
470
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
471

    
472
            YUVA_IN(y, u, v, a, p + BPP, pal);
473
            u1 += u;
474
            v1 += v;
475
            a1 += a;
476
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
477
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
478
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
479
            cb++;
480
            cr++;
481
            p += 2 * BPP;
482
            lum += 2;
483
        }
484
        if (w) {
485
            YUVA_IN(y, u, v, a, p, pal);
486
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
487
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
488
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
489
        }
490
        p += wrap3 + (wrap3 - rect->w * BPP);
491
        lum += wrap + (wrap - rect->w - rect->x);
492
        cb += dst->linesize[1] - width2 - skip2;
493
        cr += dst->linesize[2] - width2 - skip2;
494
    }
495
    for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) {
496
        lum += rect->x;
497
        cb += skip2;
498
        cr += skip2;
499

    
500
        if (rect->x & 1) {
501
            YUVA_IN(y, u, v, a, p, pal);
502
            u1 = u;
503
            v1 = v;
504
            a1 = a;
505
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
506
            p += wrap3;
507
            lum += wrap;
508
            YUVA_IN(y, u, v, a, p, pal);
509
            u1 += u;
510
            v1 += v;
511
            a1 += a;
512
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
513
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
514
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
515
            cb++;
516
            cr++;
517
            p += -wrap3 + BPP;
518
            lum += -wrap + 1;
519
        }
520
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
521
            YUVA_IN(y, u, v, a, p, pal);
522
            u1 = u;
523
            v1 = v;
524
            a1 = a;
525
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
526

    
527
            YUVA_IN(y, u, v, a, p, pal);
528
            u1 += u;
529
            v1 += v;
530
            a1 += a;
531
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
532
            p += wrap3;
533
            lum += wrap;
534

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

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

    
547
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
548
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
549

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

    
586
        if (rect->x & 1) {
587
            YUVA_IN(y, u, v, a, p, pal);
588
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
589
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
590
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
591
            cb++;
592
            cr++;
593
            lum++;
594
            p += BPP;
595
        }
596
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
597
            YUVA_IN(y, u, v, a, p, pal);
598
            u1 = u;
599
            v1 = v;
600
            a1 = a;
601
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
602

    
603
            YUVA_IN(y, u, v, a, p + BPP, pal);
604
            u1 += u;
605
            v1 += v;
606
            a1 += a;
607
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
608
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
609
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
610
            cb++;
611
            cr++;
612
            p += 2 * BPP;
613
            lum += 2;
614
        }
615
        if (w) {
616
            YUVA_IN(y, u, v, a, p, pal);
617
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
618
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
619
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
620
        }
621
    }
622
}
623

    
624
static void free_subpicture(SubPicture *sp)
625
{
626
    int i;
627

    
628
    for (i = 0; i < sp->sub.num_rects; i++)
629
    {
630
        av_free(sp->sub.rects[i].bitmap);
631
        av_free(sp->sub.rects[i].rgba_palette);
632
    }
633

    
634
    av_free(sp->sub.rects);
635

    
636
    memset(&sp->sub, 0, sizeof(AVSubtitle));
637
}
638

    
639
static void video_image_display(VideoState *is)
640
{
641
    VideoPicture *vp;
642
    SubPicture *sp;
643
    AVPicture pict;
644
    float aspect_ratio;
645
    int width, height, x, y;
646
    SDL_Rect rect;
647
    int i;
648

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

    
695
        if (is->subtitle_st)
696
        {
697
            if (is->subpq_size > 0)
698
            {
699
                sp = &is->subpq[is->subpq_rindex];
700

    
701
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
702
                {
703
                    SDL_LockYUVOverlay (vp->bmp);
704

    
705
                    pict.data[0] = vp->bmp->pixels[0];
706
                    pict.data[1] = vp->bmp->pixels[2];
707
                    pict.data[2] = vp->bmp->pixels[1];
708

    
709
                    pict.linesize[0] = vp->bmp->pitches[0];
710
                    pict.linesize[1] = vp->bmp->pitches[2];
711
                    pict.linesize[2] = vp->bmp->pitches[1];
712

    
713
                    for (i = 0; i < sp->sub.num_rects; i++)
714
                        blend_subrect(&pict, &sp->sub.rects[i]);
715

    
716
                    SDL_UnlockYUVOverlay (vp->bmp);
717
                }
718
            }
719
        }
720

    
721

    
722
        /* XXX: we suppose the screen has a 1.0 pixel ratio */
723
        height = is->height;
724
        width = ((int)rint(height * aspect_ratio)) & -3;
725
        if (width > is->width) {
726
            width = is->width;
727
            height = ((int)rint(width / aspect_ratio)) & -3;
728
        }
729
        x = (is->width - width) / 2;
730
        y = (is->height - height) / 2;
731
        if (!is->no_background) {
732
            /* fill the background */
733
            //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
734
        } else {
735
            is->no_background = 0;
736
        }
737
        rect.x = is->xleft + x;
738
        rect.y = is->xleft + y;
739
        rect.w = width;
740
        rect.h = height;
741
        SDL_DisplayYUVOverlay(vp->bmp, &rect);
742
    } else {
743
#if 0
744
        fill_rectangle(screen,
745
                       is->xleft, is->ytop, is->width, is->height,
746
                       QERGB(0x00, 0x00, 0x00));
747
#endif
748
    }
749
}
750

    
751
static inline int compute_mod(int a, int b)
752
{
753
    a = a % b;
754
    if (a >= 0)
755
        return a;
756
    else
757
        return a + b;
758
}
759

    
760
static void video_audio_display(VideoState *s)
761
{
762
    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
763
    int ch, channels, h, h2, bgcolor, fgcolor;
764
    int16_t time_diff;
765

    
766
    /* compute display index : center on currently output samples */
767
    channels = s->audio_st->codec->channels;
768
    nb_display_channels = channels;
769
    if (!s->paused) {
770
        n = 2 * channels;
771
        delay = audio_write_get_buf_size(s);
772
        delay /= n;
773

    
774
        /* to be more precise, we take into account the time spent since
775
           the last buffer computation */
776
        if (audio_callback_time) {
777
            time_diff = av_gettime() - audio_callback_time;
778
            delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
779
        }
780

    
781
        delay -= s->width / 2;
782
        if (delay < s->width)
783
            delay = s->width;
784
        i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
785
        s->last_i_start = i_start;
786
    } else {
787
        i_start = s->last_i_start;
788
    }
789

    
790
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
791
    fill_rectangle(screen,
792
                   s->xleft, s->ytop, s->width, s->height,
793
                   bgcolor);
794

    
795
    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
796

    
797
    /* total height for one channel */
798
    h = s->height / nb_display_channels;
799
    /* graph height / 2 */
800
    h2 = (h * 9) / 20;
801
    for(ch = 0;ch < nb_display_channels; ch++) {
802
        i = i_start + ch;
803
        y1 = s->ytop + ch * h + (h / 2); /* position of center line */
804
        for(x = 0; x < s->width; x++) {
805
            y = (s->sample_array[i] * h2) >> 15;
806
            if (y < 0) {
807
                y = -y;
808
                ys = y1 - y;
809
            } else {
810
                ys = y1;
811
            }
812
            fill_rectangle(screen,
813
                           s->xleft + x, ys, 1, y,
814
                           fgcolor);
815
            i += channels;
816
            if (i >= SAMPLE_ARRAY_SIZE)
817
                i -= SAMPLE_ARRAY_SIZE;
818
        }
819
    }
820

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

    
823
    for(ch = 1;ch < nb_display_channels; ch++) {
824
        y = s->ytop + ch * h;
825
        fill_rectangle(screen,
826
                       s->xleft, y, s->width, 1,
827
                       fgcolor);
828
    }
829
    SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
830
}
831

    
832
static int video_open(VideoState *is){
833
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
834
    int w,h;
835

    
836
    if(is_full_screen) flags |= SDL_FULLSCREEN;
837
    else               flags |= SDL_RESIZABLE;
838

    
839
    if (is_full_screen && fs_screen_width) {
840
        w = fs_screen_width;
841
        h = fs_screen_height;
842
    } else if(!is_full_screen && screen_width){
843
        w = screen_width;
844
        h = screen_height;
845
    }else if (is->video_st && is->video_st->codec->width){
846
        w = is->video_st->codec->width;
847
        h = is->video_st->codec->height;
848
    } else {
849
        w = 640;
850
        h = 480;
851
    }
852
#ifndef CONFIG_DARWIN
853
    screen = SDL_SetVideoMode(w, h, 0, flags);
854
#else
855
    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
856
    screen = SDL_SetVideoMode(w, h, 24, flags);
857
#endif
858
    if (!screen) {
859
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
860
        return -1;
861
    }
862
    SDL_WM_SetCaption("FFplay", "FFplay");
863

    
864
    is->width = screen->w;
865
    is->height = screen->h;
866

    
867
    return 0;
868
}
869

    
870
/* display the current picture, if any */
871
static void video_display(VideoState *is)
872
{
873
    if(!screen)
874
        video_open(cur_stream);
875
    if (is->audio_st && is->show_audio)
876
        video_audio_display(is);
877
    else if (is->video_st)
878
        video_image_display(is);
879
}
880

    
881
static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
882
{
883
    SDL_Event event;
884
    event.type = FF_REFRESH_EVENT;
885
    event.user.data1 = opaque;
886
    SDL_PushEvent(&event);
887
    return 0; /* 0 means stop timer */
888
}
889

    
890
/* schedule a video refresh in 'delay' ms */
891
static void schedule_refresh(VideoState *is, int delay)
892
{
893
    SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
894
}
895

    
896
/* get the current audio clock value */
897
static double get_audio_clock(VideoState *is)
898
{
899
    double pts;
900
    int hw_buf_size, bytes_per_sec;
901
    pts = is->audio_clock;
902
    hw_buf_size = audio_write_get_buf_size(is);
903
    bytes_per_sec = 0;
904
    if (is->audio_st) {
905
        bytes_per_sec = is->audio_st->codec->sample_rate *
906
            2 * is->audio_st->codec->channels;
907
    }
908
    if (bytes_per_sec)
909
        pts -= (double)hw_buf_size / bytes_per_sec;
910
    return pts;
911
}
912

    
913
/* get the current video clock value */
914
static double get_video_clock(VideoState *is)
915
{
916
    double delta;
917
    if (is->paused) {
918
        delta = 0;
919
    } else {
920
        delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
921
    }
922
    return is->video_current_pts + delta;
923
}
924

    
925
/* get the current external clock value */
926
static double get_external_clock(VideoState *is)
927
{
928
    int64_t ti;
929
    ti = av_gettime();
930
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
931
}
932

    
933
/* get the current master clock value */
934
static double get_master_clock(VideoState *is)
935
{
936
    double val;
937

    
938
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
939
        if (is->video_st)
940
            val = get_video_clock(is);
941
        else
942
            val = get_audio_clock(is);
943
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
944
        if (is->audio_st)
945
            val = get_audio_clock(is);
946
        else
947
            val = get_video_clock(is);
948
    } else {
949
        val = get_external_clock(is);
950
    }
951
    return val;
952
}
953

    
954
/* seek in the stream */
955
static void stream_seek(VideoState *is, int64_t pos, int rel)
956
{
957
    if (!is->seek_req) {
958
        is->seek_pos = pos;
959
        is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
960
        if (seek_by_bytes)
961
            is->seek_flags |= AVSEEK_FLAG_BYTE;
962
        is->seek_req = 1;
963
    }
964
}
965

    
966
/* pause or resume the video */
967
static void stream_pause(VideoState *is)
968
{
969
    is->paused = !is->paused;
970
    if (is->paused) {
971
        is->video_current_pts = get_video_clock(is);
972
    }
973
}
974

    
975
/* called to display each frame */
976
static void video_refresh_timer(void *opaque)
977
{
978
    VideoState *is = opaque;
979
    VideoPicture *vp;
980
    double actual_delay, delay, sync_threshold, ref_clock, diff;
981

    
982
    SubPicture *sp, *sp2;
983

    
984
    if (is->video_st) {
985
        if (is->pictq_size == 0) {
986
            /* if no picture, need to wait */
987
            schedule_refresh(is, 1);
988
        } else {
989
            /* dequeue the picture */
990
            vp = &is->pictq[is->pictq_rindex];
991

    
992
            /* update current video pts */
993
            is->video_current_pts = vp->pts;
994
            is->video_current_pts_time = av_gettime();
995

    
996
            /* compute nominal delay */
997
            delay = vp->pts - is->frame_last_pts;
998
            if (delay <= 0 || delay >= 1.0) {
999
                /* if incorrect delay, use previous one */
1000
                delay = is->frame_last_delay;
1001
            }
1002
            is->frame_last_delay = delay;
1003
            is->frame_last_pts = vp->pts;
1004

    
1005
            /* update delay to follow master synchronisation source */
1006
            if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1007
                 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1008
                /* if video is slave, we try to correct big delays by
1009
                   duplicating or deleting a frame */
1010
                ref_clock = get_master_clock(is);
1011
                diff = vp->pts - ref_clock;
1012

    
1013
                /* skip or repeat frame. We take into account the
1014
                   delay to compute the threshold. I still don't know
1015
                   if it is the best guess */
1016
                sync_threshold = AV_SYNC_THRESHOLD;
1017
                if (delay > sync_threshold)
1018
                    sync_threshold = delay;
1019
                if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1020
                    if (diff <= -sync_threshold)
1021
                        delay = 0;
1022
                    else if (diff >= sync_threshold)
1023
                        delay = 2 * delay;
1024
                }
1025
            }
1026

    
1027
            is->frame_timer += delay;
1028
            /* compute the REAL delay (we need to do that to avoid
1029
               long term errors */
1030
            actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1031
            if (actual_delay < 0.010) {
1032
                /* XXX: should skip picture */
1033
                actual_delay = 0.010;
1034
            }
1035
            /* launch timer for next picture */
1036
            schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
1037

    
1038
#if defined(DEBUG_SYNC)
1039
            printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1040
                   delay, actual_delay, vp->pts, -diff);
1041
#endif
1042

    
1043
            if(is->subtitle_st) {
1044
                if (is->subtitle_stream_changed) {
1045
                    SDL_LockMutex(is->subpq_mutex);
1046

    
1047
                    while (is->subpq_size) {
1048
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1049

    
1050
                        /* update queue size and signal for next picture */
1051
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1052
                            is->subpq_rindex = 0;
1053

    
1054
                        is->subpq_size--;
1055
                    }
1056
                    is->subtitle_stream_changed = 0;
1057

    
1058
                    SDL_CondSignal(is->subpq_cond);
1059
                    SDL_UnlockMutex(is->subpq_mutex);
1060
                } else {
1061
                    if (is->subpq_size > 0) {
1062
                        sp = &is->subpq[is->subpq_rindex];
1063

    
1064
                        if (is->subpq_size > 1)
1065
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1066
                        else
1067
                            sp2 = NULL;
1068

    
1069
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1070
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1071
                        {
1072
                            free_subpicture(sp);
1073

    
1074
                            /* update queue size and signal for next picture */
1075
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1076
                                is->subpq_rindex = 0;
1077

    
1078
                            SDL_LockMutex(is->subpq_mutex);
1079
                            is->subpq_size--;
1080
                            SDL_CondSignal(is->subpq_cond);
1081
                            SDL_UnlockMutex(is->subpq_mutex);
1082
                        }
1083
                    }
1084
                }
1085
            }
1086

    
1087
            /* display picture */
1088
            video_display(is);
1089

    
1090
            /* update queue size and signal for next picture */
1091
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1092
                is->pictq_rindex = 0;
1093

    
1094
            SDL_LockMutex(is->pictq_mutex);
1095
            is->pictq_size--;
1096
            SDL_CondSignal(is->pictq_cond);
1097
            SDL_UnlockMutex(is->pictq_mutex);
1098
        }
1099
    } else if (is->audio_st) {
1100
        /* draw the next audio frame */
1101

    
1102
        schedule_refresh(is, 40);
1103

    
1104
        /* if only audio stream, then display the audio bars (better
1105
           than nothing, just to test the implementation */
1106

    
1107
        /* display picture */
1108
        video_display(is);
1109
    } else {
1110
        schedule_refresh(is, 100);
1111
    }
1112
    if (show_status) {
1113
        static int64_t last_time;
1114
        int64_t cur_time;
1115
        int aqsize, vqsize, sqsize;
1116
        double av_diff;
1117

    
1118
        cur_time = av_gettime();
1119
        if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1120
            aqsize = 0;
1121
            vqsize = 0;
1122
            sqsize = 0;
1123
            if (is->audio_st)
1124
                aqsize = is->audioq.size;
1125
            if (is->video_st)
1126
                vqsize = is->videoq.size;
1127
            if (is->subtitle_st)
1128
                sqsize = is->subtitleq.size;
1129
            av_diff = 0;
1130
            if (is->audio_st && is->video_st)
1131
                av_diff = get_audio_clock(is) - get_video_clock(is);
1132
            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1133
                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1134
            fflush(stdout);
1135
            last_time = cur_time;
1136
        }
1137
    }
1138
}
1139

    
1140
/* allocate a picture (needs to do that in main thread to avoid
1141
   potential locking problems */
1142
static void alloc_picture(void *opaque)
1143
{
1144
    VideoState *is = opaque;
1145
    VideoPicture *vp;
1146

    
1147
    vp = &is->pictq[is->pictq_windex];
1148

    
1149
    if (vp->bmp)
1150
        SDL_FreeYUVOverlay(vp->bmp);
1151

    
1152
#if 0
1153
    /* XXX: use generic function */
1154
    /* XXX: disable overlay if no hardware acceleration or if RGB format */
1155
    switch(is->video_st->codec->pix_fmt) {
1156
    case PIX_FMT_YUV420P:
1157
    case PIX_FMT_YUV422P:
1158
    case PIX_FMT_YUV444P:
1159
    case PIX_FMT_YUV422:
1160
    case PIX_FMT_YUV410P:
1161
    case PIX_FMT_YUV411P:
1162
        is_yuv = 1;
1163
        break;
1164
    default:
1165
        is_yuv = 0;
1166
        break;
1167
    }
1168
#endif
1169
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1170
                                   is->video_st->codec->height,
1171
                                   SDL_YV12_OVERLAY,
1172
                                   screen);
1173
    vp->width = is->video_st->codec->width;
1174
    vp->height = is->video_st->codec->height;
1175

    
1176
    SDL_LockMutex(is->pictq_mutex);
1177
    vp->allocated = 1;
1178
    SDL_CondSignal(is->pictq_cond);
1179
    SDL_UnlockMutex(is->pictq_mutex);
1180
}
1181

    
1182
/**
1183
 *
1184
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1185
 */
1186
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1187
{
1188
    VideoPicture *vp;
1189
    int dst_pix_fmt;
1190
    AVPicture pict;
1191
    static struct SwsContext *img_convert_ctx;
1192

    
1193
    /* wait until we have space to put a new picture */
1194
    SDL_LockMutex(is->pictq_mutex);
1195
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1196
           !is->videoq.abort_request) {
1197
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1198
    }
1199
    SDL_UnlockMutex(is->pictq_mutex);
1200

    
1201
    if (is->videoq.abort_request)
1202
        return -1;
1203

    
1204
    vp = &is->pictq[is->pictq_windex];
1205

    
1206
    /* alloc or resize hardware picture buffer */
1207
    if (!vp->bmp ||
1208
        vp->width != is->video_st->codec->width ||
1209
        vp->height != is->video_st->codec->height) {
1210
        SDL_Event event;
1211

    
1212
        vp->allocated = 0;
1213

    
1214
        /* the allocation must be done in the main thread to avoid
1215
           locking problems */
1216
        event.type = FF_ALLOC_EVENT;
1217
        event.user.data1 = is;
1218
        SDL_PushEvent(&event);
1219

    
1220
        /* wait until the picture is allocated */
1221
        SDL_LockMutex(is->pictq_mutex);
1222
        while (!vp->allocated && !is->videoq.abort_request) {
1223
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1224
        }
1225
        SDL_UnlockMutex(is->pictq_mutex);
1226

    
1227
        if (is->videoq.abort_request)
1228
            return -1;
1229
    }
1230

    
1231
    /* if the frame is not skipped, then display it */
1232
    if (vp->bmp) {
1233
        /* get a pointer on the bitmap */
1234
        SDL_LockYUVOverlay (vp->bmp);
1235

    
1236
        dst_pix_fmt = PIX_FMT_YUV420P;
1237
        pict.data[0] = vp->bmp->pixels[0];
1238
        pict.data[1] = vp->bmp->pixels[2];
1239
        pict.data[2] = vp->bmp->pixels[1];
1240

    
1241
        pict.linesize[0] = vp->bmp->pitches[0];
1242
        pict.linesize[1] = vp->bmp->pitches[2];
1243
        pict.linesize[2] = vp->bmp->pitches[1];
1244
        if (img_convert_ctx == NULL) {
1245
            img_convert_ctx = sws_getContext(is->video_st->codec->width,
1246
                    is->video_st->codec->height, is->video_st->codec->pix_fmt,
1247
                    is->video_st->codec->width, is->video_st->codec->height,
1248
                    dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1249
            if (img_convert_ctx == NULL) {
1250
                fprintf(stderr, "Cannot initialize the conversion context\n");
1251
                exit(1);
1252
            }
1253
        }
1254
        sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
1255
                  0, is->video_st->codec->height, pict.data, pict.linesize);
1256
        /* update the bitmap content */
1257
        SDL_UnlockYUVOverlay(vp->bmp);
1258

    
1259
        vp->pts = pts;
1260

    
1261
        /* now we can update the picture count */
1262
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1263
            is->pictq_windex = 0;
1264
        SDL_LockMutex(is->pictq_mutex);
1265
        is->pictq_size++;
1266
        SDL_UnlockMutex(is->pictq_mutex);
1267
    }
1268
    return 0;
1269
}
1270

    
1271
/**
1272
 * compute the exact PTS for the picture if it is omitted in the stream
1273
 * @param pts1 the dts of the pkt / pts of the frame
1274
 */
1275
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1276
{
1277
    double frame_delay, pts;
1278

    
1279
    pts = pts1;
1280

    
1281
    if (pts != 0) {
1282
        /* update video clock with pts, if present */
1283
        is->video_clock = pts;
1284
    } else {
1285
        pts = is->video_clock;
1286
    }
1287
    /* update video clock for next frame */
1288
    frame_delay = av_q2d(is->video_st->codec->time_base);
1289
    /* for MPEG2, the frame can be repeated, so we update the
1290
       clock accordingly */
1291
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1292
    is->video_clock += frame_delay;
1293

    
1294
#if defined(DEBUG_SYNC) && 0
1295
    {
1296
        int ftype;
1297
        if (src_frame->pict_type == FF_B_TYPE)
1298
            ftype = 'B';
1299
        else if (src_frame->pict_type == FF_I_TYPE)
1300
            ftype = 'I';
1301
        else
1302
            ftype = 'P';
1303
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1304
               ftype, pts, pts1);
1305
    }
1306
#endif
1307
    return queue_picture(is, src_frame, pts);
1308
}
1309

    
1310
static int video_thread(void *arg)
1311
{
1312
    VideoState *is = arg;
1313
    AVPacket pkt1, *pkt = &pkt1;
1314
    int len1, got_picture;
1315
    AVFrame *frame= avcodec_alloc_frame();
1316
    double pts;
1317

    
1318
    for(;;) {
1319
        while (is->paused && !is->videoq.abort_request) {
1320
            SDL_Delay(10);
1321
        }
1322
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1323
            break;
1324

    
1325
        if(pkt->data == flush_pkt.data){
1326
            avcodec_flush_buffers(is->video_st->codec);
1327
            continue;
1328
        }
1329

    
1330
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1331
           this packet, if any */
1332
        pts = 0;
1333
        if (pkt->dts != AV_NOPTS_VALUE)
1334
            pts = av_q2d(is->video_st->time_base)*pkt->dts;
1335

    
1336
            len1 = avcodec_decode_video(is->video_st->codec,
1337
                                        frame, &got_picture,
1338
                                        pkt->data, pkt->size);
1339
//            if (len1 < 0)
1340
//                break;
1341
            if (got_picture) {
1342
                if (output_picture2(is, frame, pts) < 0)
1343
                    goto the_end;
1344
            }
1345
        av_free_packet(pkt);
1346
        if (step)
1347
            if (cur_stream)
1348
                stream_pause(cur_stream);
1349
    }
1350
 the_end:
1351
    av_free(frame);
1352
    return 0;
1353
}
1354

    
1355
static int subtitle_thread(void *arg)
1356
{
1357
    VideoState *is = arg;
1358
    SubPicture *sp;
1359
    AVPacket pkt1, *pkt = &pkt1;
1360
    int len1, got_subtitle;
1361
    double pts;
1362
    int i, j;
1363
    int r, g, b, y, u, v, a;
1364

    
1365
    for(;;) {
1366
        while (is->paused && !is->subtitleq.abort_request) {
1367
            SDL_Delay(10);
1368
        }
1369
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1370
            break;
1371

    
1372
        if(pkt->data == flush_pkt.data){
1373
            avcodec_flush_buffers(is->subtitle_st->codec);
1374
            continue;
1375
        }
1376
        SDL_LockMutex(is->subpq_mutex);
1377
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1378
               !is->subtitleq.abort_request) {
1379
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1380
        }
1381
        SDL_UnlockMutex(is->subpq_mutex);
1382

    
1383
        if (is->subtitleq.abort_request)
1384
            goto the_end;
1385

    
1386
        sp = &is->subpq[is->subpq_windex];
1387

    
1388
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1389
           this packet, if any */
1390
        pts = 0;
1391
        if (pkt->pts != AV_NOPTS_VALUE)
1392
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1393

    
1394
        len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
1395
                                    &sp->sub, &got_subtitle,
1396
                                    pkt->data, pkt->size);
1397
//            if (len1 < 0)
1398
//                break;
1399
        if (got_subtitle && sp->sub.format == 0) {
1400
            sp->pts = pts;
1401

    
1402
            for (i = 0; i < sp->sub.num_rects; i++)
1403
            {
1404
                for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
1405
                {
1406
                    RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
1407
                    y = RGB_TO_Y_CCIR(r, g, b);
1408
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1409
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1410
                    YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
1411
                }
1412
            }
1413

    
1414
            /* now we can update the picture count */
1415
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1416
                is->subpq_windex = 0;
1417
            SDL_LockMutex(is->subpq_mutex);
1418
            is->subpq_size++;
1419
            SDL_UnlockMutex(is->subpq_mutex);
1420
        }
1421
        av_free_packet(pkt);
1422
//        if (step)
1423
//            if (cur_stream)
1424
//                stream_pause(cur_stream);
1425
    }
1426
 the_end:
1427
    return 0;
1428
}
1429

    
1430
/* copy samples for viewing in editor window */
1431
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1432
{
1433
    int size, len, channels;
1434

    
1435
    channels = is->audio_st->codec->channels;
1436

    
1437
    size = samples_size / sizeof(short);
1438
    while (size > 0) {
1439
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1440
        if (len > size)
1441
            len = size;
1442
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1443
        samples += len;
1444
        is->sample_array_index += len;
1445
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1446
            is->sample_array_index = 0;
1447
        size -= len;
1448
    }
1449
}
1450

    
1451
/* return the new audio buffer size (samples can be added or deleted
1452
   to get better sync if video or external master clock) */
1453
static int synchronize_audio(VideoState *is, short *samples,
1454
                             int samples_size1, double pts)
1455
{
1456
    int n, samples_size;
1457
    double ref_clock;
1458

    
1459
    n = 2 * is->audio_st->codec->channels;
1460
    samples_size = samples_size1;
1461

    
1462
    /* if not master, then we try to remove or add samples to correct the clock */
1463
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1464
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1465
        double diff, avg_diff;
1466
        int wanted_size, min_size, max_size, nb_samples;
1467

    
1468
        ref_clock = get_master_clock(is);
1469
        diff = get_audio_clock(is) - ref_clock;
1470

    
1471
        if (diff < AV_NOSYNC_THRESHOLD) {
1472
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1473
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1474
                /* not enough measures to have a correct estimate */
1475
                is->audio_diff_avg_count++;
1476
            } else {
1477
                /* estimate the A-V difference */
1478
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1479

    
1480
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1481
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1482
                    nb_samples = samples_size / n;
1483

    
1484
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1485
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1486
                    if (wanted_size < min_size)
1487
                        wanted_size = min_size;
1488
                    else if (wanted_size > max_size)
1489
                        wanted_size = max_size;
1490

    
1491
                    /* add or remove samples to correction the synchro */
1492
                    if (wanted_size < samples_size) {
1493
                        /* remove samples */
1494
                        samples_size = wanted_size;
1495
                    } else if (wanted_size > samples_size) {
1496
                        uint8_t *samples_end, *q;
1497
                        int nb;
1498

    
1499
                        /* add samples */
1500
                        nb = (samples_size - wanted_size);
1501
                        samples_end = (uint8_t *)samples + samples_size - n;
1502
                        q = samples_end + n;
1503
                        while (nb > 0) {
1504
                            memcpy(q, samples_end, n);
1505
                            q += n;
1506
                            nb -= n;
1507
                        }
1508
                        samples_size = wanted_size;
1509
                    }
1510
                }
1511
#if 0
1512
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1513
                       diff, avg_diff, samples_size - samples_size1,
1514
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
1515
#endif
1516
            }
1517
        } else {
1518
            /* too big difference : may be initial PTS errors, so
1519
               reset A-V filter */
1520
            is->audio_diff_avg_count = 0;
1521
            is->audio_diff_cum = 0;
1522
        }
1523
    }
1524

    
1525
    return samples_size;
1526
}
1527

    
1528
/* decode one audio frame and returns its uncompressed size */
1529
static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
1530
{
1531
    AVPacket *pkt = &is->audio_pkt;
1532
    int n, len1, data_size;
1533
    double pts;
1534

    
1535
    for(;;) {
1536
        /* NOTE: the audio packet can contain several frames */
1537
        while (is->audio_pkt_size > 0) {
1538
            len1 = avcodec_decode_audio(is->audio_st->codec,
1539
                                        (int16_t *)audio_buf, &data_size,
1540
                                        is->audio_pkt_data, is->audio_pkt_size);
1541
            if (len1 < 0) {
1542
                /* if error, we skip the frame */
1543
                is->audio_pkt_size = 0;
1544
                break;
1545
            }
1546

    
1547
            is->audio_pkt_data += len1;
1548
            is->audio_pkt_size -= len1;
1549
            if (data_size <= 0)
1550
                continue;
1551
            /* if no pts, then compute it */
1552
            pts = is->audio_clock;
1553
            *pts_ptr = pts;
1554
            n = 2 * is->audio_st->codec->channels;
1555
            is->audio_clock += (double)data_size /
1556
                (double)(n * is->audio_st->codec->sample_rate);
1557
#if defined(DEBUG_SYNC)
1558
            {
1559
                static double last_clock;
1560
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1561
                       is->audio_clock - last_clock,
1562
                       is->audio_clock, pts);
1563
                last_clock = is->audio_clock;
1564
            }
1565
#endif
1566
            return data_size;
1567
        }
1568

    
1569
        /* free the current packet */
1570
        if (pkt->data)
1571
            av_free_packet(pkt);
1572

    
1573
        if (is->paused || is->audioq.abort_request) {
1574
            return -1;
1575
        }
1576

    
1577
        /* read next packet */
1578
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1579
            return -1;
1580
        if(pkt->data == flush_pkt.data){
1581
            avcodec_flush_buffers(is->audio_st->codec);
1582
            continue;
1583
        }
1584

    
1585
        is->audio_pkt_data = pkt->data;
1586
        is->audio_pkt_size = pkt->size;
1587

    
1588
        /* if update the audio clock with the pts */
1589
        if (pkt->pts != AV_NOPTS_VALUE) {
1590
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1591
        }
1592
    }
1593
}
1594

    
1595
/* get the current audio output buffer size, in samples. With SDL, we
1596
   cannot have a precise information */
1597
static int audio_write_get_buf_size(VideoState *is)
1598
{
1599
    return is->audio_hw_buf_size - is->audio_buf_index;
1600
}
1601

    
1602

    
1603
/* prepare a new audio buffer */
1604
void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1605
{
1606
    VideoState *is = opaque;
1607
    int audio_size, len1;
1608
    double pts;
1609

    
1610
    audio_callback_time = av_gettime();
1611

    
1612
    while (len > 0) {
1613
        if (is->audio_buf_index >= is->audio_buf_size) {
1614
           audio_size = audio_decode_frame(is, is->audio_buf, &pts);
1615
           if (audio_size < 0) {
1616
                /* if error, just output silence */
1617
               is->audio_buf_size = 1024;
1618
               memset(is->audio_buf, 0, is->audio_buf_size);
1619
           } else {
1620
               if (is->show_audio)
1621
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1622
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1623
                                              pts);
1624
               is->audio_buf_size = audio_size;
1625
           }
1626
           is->audio_buf_index = 0;
1627
        }
1628
        len1 = is->audio_buf_size - is->audio_buf_index;
1629
        if (len1 > len)
1630
            len1 = len;
1631
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1632
        len -= len1;
1633
        stream += len1;
1634
        is->audio_buf_index += len1;
1635
    }
1636
}
1637

    
1638
/* open a given stream. Return 0 if OK */
1639
static int stream_component_open(VideoState *is, int stream_index)
1640
{
1641
    AVFormatContext *ic = is->ic;
1642
    AVCodecContext *enc;
1643
    AVCodec *codec;
1644
    SDL_AudioSpec wanted_spec, spec;
1645

    
1646
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1647
        return -1;
1648
    enc = ic->streams[stream_index]->codec;
1649

    
1650
    /* prepare audio output */
1651
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1652
        wanted_spec.freq = enc->sample_rate;
1653
        wanted_spec.format = AUDIO_S16SYS;
1654
        /* hack for AC3. XXX: suppress that */
1655
        if (enc->channels > 2)
1656
            enc->channels = 2;
1657
        wanted_spec.channels = enc->channels;
1658
        wanted_spec.silence = 0;
1659
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1660
        wanted_spec.callback = sdl_audio_callback;
1661
        wanted_spec.userdata = is;
1662
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1663
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1664
            return -1;
1665
        }
1666
        is->audio_hw_buf_size = spec.size;
1667
    }
1668

    
1669
    codec = avcodec_find_decoder(enc->codec_id);
1670
    enc->debug_mv = debug_mv;
1671
    enc->debug = debug;
1672
    enc->workaround_bugs = workaround_bugs;
1673
    enc->lowres = lowres;
1674
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1675
    enc->idct_algo= idct;
1676
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1677
    enc->skip_frame= skip_frame;
1678
    enc->skip_idct= skip_idct;
1679
    enc->skip_loop_filter= skip_loop_filter;
1680
    enc->error_resilience= error_resilience;
1681
    enc->error_concealment= error_concealment;
1682
    if (!codec ||
1683
        avcodec_open(enc, codec) < 0)
1684
        return -1;
1685
#if defined(HAVE_THREADS)
1686
    if(thread_count>1)
1687
        avcodec_thread_init(enc, thread_count);
1688
#endif
1689
    enc->thread_count= thread_count;
1690
    switch(enc->codec_type) {
1691
    case CODEC_TYPE_AUDIO:
1692
        is->audio_stream = stream_index;
1693
        is->audio_st = ic->streams[stream_index];
1694
        is->audio_buf_size = 0;
1695
        is->audio_buf_index = 0;
1696

    
1697
        /* init averaging filter */
1698
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1699
        is->audio_diff_avg_count = 0;
1700
        /* since we do not have a precise anough audio fifo fullness,
1701
           we correct audio sync only if larger than this threshold */
1702
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1703

    
1704
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1705
        packet_queue_init(&is->audioq);
1706
        SDL_PauseAudio(0);
1707
        break;
1708
    case CODEC_TYPE_VIDEO:
1709
        is->video_stream = stream_index;
1710
        is->video_st = ic->streams[stream_index];
1711

    
1712
        is->frame_last_delay = 40e-3;
1713
        is->frame_timer = (double)av_gettime() / 1000000.0;
1714
        is->video_current_pts_time = av_gettime();
1715

    
1716
        packet_queue_init(&is->videoq);
1717
        is->video_tid = SDL_CreateThread(video_thread, is);
1718
        break;
1719
    case CODEC_TYPE_SUBTITLE:
1720
        is->subtitle_stream = stream_index;
1721
        is->subtitle_st = ic->streams[stream_index];
1722
        packet_queue_init(&is->subtitleq);
1723

    
1724
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1725
        break;
1726
    default:
1727
        break;
1728
    }
1729
    return 0;
1730
}
1731

    
1732
static void stream_component_close(VideoState *is, int stream_index)
1733
{
1734
    AVFormatContext *ic = is->ic;
1735
    AVCodecContext *enc;
1736

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

    
1741
    switch(enc->codec_type) {
1742
    case CODEC_TYPE_AUDIO:
1743
        packet_queue_abort(&is->audioq);
1744

    
1745
        SDL_CloseAudio();
1746

    
1747
        packet_queue_end(&is->audioq);
1748
        break;
1749
    case CODEC_TYPE_VIDEO:
1750
        packet_queue_abort(&is->videoq);
1751

    
1752
        /* note: we also signal this mutex to make sure we deblock the
1753
           video thread in all cases */
1754
        SDL_LockMutex(is->pictq_mutex);
1755
        SDL_CondSignal(is->pictq_cond);
1756
        SDL_UnlockMutex(is->pictq_mutex);
1757

    
1758
        SDL_WaitThread(is->video_tid, NULL);
1759

    
1760
        packet_queue_end(&is->videoq);
1761
        break;
1762
    case CODEC_TYPE_SUBTITLE:
1763
        packet_queue_abort(&is->subtitleq);
1764

    
1765
        /* note: we also signal this mutex to make sure we deblock the
1766
           video thread in all cases */
1767
        SDL_LockMutex(is->subpq_mutex);
1768
        is->subtitle_stream_changed = 1;
1769

    
1770
        SDL_CondSignal(is->subpq_cond);
1771
        SDL_UnlockMutex(is->subpq_mutex);
1772

    
1773
        SDL_WaitThread(is->subtitle_tid, NULL);
1774

    
1775
        packet_queue_end(&is->subtitleq);
1776
        break;
1777
    default:
1778
        break;
1779
    }
1780

    
1781
    avcodec_close(enc);
1782
    switch(enc->codec_type) {
1783
    case CODEC_TYPE_AUDIO:
1784
        is->audio_st = NULL;
1785
        is->audio_stream = -1;
1786
        break;
1787
    case CODEC_TYPE_VIDEO:
1788
        is->video_st = NULL;
1789
        is->video_stream = -1;
1790
        break;
1791
    case CODEC_TYPE_SUBTITLE:
1792
        is->subtitle_st = NULL;
1793
        is->subtitle_stream = -1;
1794
        break;
1795
    default:
1796
        break;
1797
    }
1798
}
1799

    
1800
static void dump_stream_info(const AVFormatContext *s)
1801
{
1802
    if (s->track != 0)
1803
        fprintf(stderr, "Track: %d\n", s->track);
1804
    if (s->title[0] != '\0')
1805
        fprintf(stderr, "Title: %s\n", s->title);
1806
    if (s->author[0] != '\0')
1807
        fprintf(stderr, "Author: %s\n", s->author);
1808
    if (s->copyright[0] != '\0')
1809
        fprintf(stderr, "Copyright: %s\n", s->copyright);
1810
    if (s->comment[0] != '\0')
1811
        fprintf(stderr, "Comment: %s\n", s->comment);
1812
    if (s->album[0] != '\0')
1813
        fprintf(stderr, "Album: %s\n", s->album);
1814
    if (s->year != 0)
1815
        fprintf(stderr, "Year: %d\n", s->year);
1816
    if (s->genre[0] != '\0')
1817
        fprintf(stderr, "Genre: %s\n", s->genre);
1818
}
1819

    
1820
/* since we have only one decoding thread, we can use a global
1821
   variable instead of a thread local variable */
1822
static VideoState *global_video_state;
1823

    
1824
static int decode_interrupt_cb(void)
1825
{
1826
    return (global_video_state && global_video_state->abort_request);
1827
}
1828

    
1829
/* this thread gets the stream from the disk or the network */
1830
static int decode_thread(void *arg)
1831
{
1832
    VideoState *is = arg;
1833
    AVFormatContext *ic;
1834
    int err, i, ret, video_index, audio_index, use_play;
1835
    AVPacket pkt1, *pkt = &pkt1;
1836
    AVFormatParameters params, *ap = &params;
1837

    
1838
    video_index = -1;
1839
    audio_index = -1;
1840
    is->video_stream = -1;
1841
    is->audio_stream = -1;
1842
    is->subtitle_stream = -1;
1843

    
1844
    global_video_state = is;
1845
    url_set_interrupt_cb(decode_interrupt_cb);
1846

    
1847
    memset(ap, 0, sizeof(*ap));
1848
    ap->initial_pause = 1; /* we force a pause when starting an RTSP
1849
                              stream */
1850

    
1851
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1852
    if (err < 0) {
1853
        print_error(is->filename, err);
1854
        ret = -1;
1855
        goto fail;
1856
    }
1857
    is->ic = ic;
1858
#ifdef CONFIG_NETWORK
1859
    use_play = (ic->iformat == &rtsp_demuxer);
1860
#else
1861
    use_play = 0;
1862
#endif
1863

    
1864
    if(genpts)
1865
        ic->flags |= AVFMT_FLAG_GENPTS;
1866

    
1867
    if (!use_play) {
1868
        err = av_find_stream_info(ic);
1869
        if (err < 0) {
1870
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1871
            ret = -1;
1872
            goto fail;
1873
        }
1874
        ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
1875
    }
1876

    
1877
    /* if seeking requested, we execute it */
1878
    if (start_time != AV_NOPTS_VALUE) {
1879
        int64_t timestamp;
1880

    
1881
        timestamp = start_time;
1882
        /* add the stream start time */
1883
        if (ic->start_time != AV_NOPTS_VALUE)
1884
            timestamp += ic->start_time;
1885
        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1886
        if (ret < 0) {
1887
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
1888
                    is->filename, (double)timestamp / AV_TIME_BASE);
1889
        }
1890
    }
1891

    
1892
    /* now we can begin to play (RTSP stream only) */
1893
    av_read_play(ic);
1894

    
1895
    if (use_play) {
1896
        err = av_find_stream_info(ic);
1897
        if (err < 0) {
1898
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1899
            ret = -1;
1900
            goto fail;
1901
        }
1902
    }
1903

    
1904
    for(i = 0; i < ic->nb_streams; i++) {
1905
        AVCodecContext *enc = ic->streams[i]->codec;
1906
        switch(enc->codec_type) {
1907
        case CODEC_TYPE_AUDIO:
1908
            if (audio_index < 0 && !audio_disable)
1909
                audio_index = i;
1910
            break;
1911
        case CODEC_TYPE_VIDEO:
1912
            if (video_index < 0 && !video_disable)
1913
                video_index = i;
1914
            break;
1915
        default:
1916
            break;
1917
        }
1918
    }
1919
    if (show_status) {
1920
        dump_format(ic, 0, is->filename, 0);
1921
        dump_stream_info(ic);
1922
    }
1923

    
1924
    /* open the streams */
1925
    if (audio_index >= 0) {
1926
        stream_component_open(is, audio_index);
1927
    }
1928

    
1929
    if (video_index >= 0) {
1930
        stream_component_open(is, video_index);
1931
    } else {
1932
        if (!display_disable)
1933
            is->show_audio = 1;
1934
    }
1935

    
1936
    if (is->video_stream < 0 && is->audio_stream < 0) {
1937
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
1938
        ret = -1;
1939
        goto fail;
1940
    }
1941

    
1942
    for(;;) {
1943
        if (is->abort_request)
1944
            break;
1945
#ifdef CONFIG_NETWORK
1946
        if (is->paused != is->last_paused) {
1947
            is->last_paused = is->paused;
1948
            if (is->paused)
1949
                av_read_pause(ic);
1950
            else
1951
                av_read_play(ic);
1952
        }
1953
        if (is->paused && ic->iformat == &rtsp_demuxer) {
1954
            /* wait 10 ms to avoid trying to get another packet */
1955
            /* XXX: horrible */
1956
            SDL_Delay(10);
1957
            continue;
1958
        }
1959
#endif
1960
        if (is->seek_req) {
1961
            ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags);
1962
            if (ret < 0) {
1963
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
1964
            }else{
1965
                if (is->audio_stream >= 0) {
1966
                    packet_queue_flush(&is->audioq);
1967
                    packet_queue_put(&is->audioq, &flush_pkt);
1968
                }
1969
                if (is->subtitle_stream >= 0) {
1970
                    packet_queue_flush(&is->subtitleq);
1971
                    packet_queue_put(&is->subtitleq, &flush_pkt);
1972
                }
1973
                if (is->video_stream >= 0) {
1974
                    packet_queue_flush(&is->videoq);
1975
                    packet_queue_put(&is->videoq, &flush_pkt);
1976
                }
1977
            }
1978
            is->seek_req = 0;
1979
        }
1980

    
1981
        /* if the queue are full, no need to read more */
1982
        if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1983
            is->videoq.size > MAX_VIDEOQ_SIZE ||
1984
            is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1985
            url_feof(&ic->pb)) {
1986
            /* wait 10 ms */
1987
            SDL_Delay(10);
1988
            continue;
1989
        }
1990
        ret = av_read_frame(ic, pkt);
1991
        if (ret < 0) {
1992
            if (url_ferror(&ic->pb) == 0) {
1993
                SDL_Delay(100); /* wait for user event */
1994
                continue;
1995
            } else
1996
                break;
1997
        }
1998
        if (pkt->stream_index == is->audio_stream) {
1999
            packet_queue_put(&is->audioq, pkt);
2000
        } else if (pkt->stream_index == is->video_stream) {
2001
            packet_queue_put(&is->videoq, pkt);
2002
        } else if (pkt->stream_index == is->subtitle_stream) {
2003
            packet_queue_put(&is->subtitleq, pkt);
2004
        } else {
2005
            av_free_packet(pkt);
2006
        }
2007
    }
2008
    /* wait until the end */
2009
    while (!is->abort_request) {
2010
        SDL_Delay(100);
2011
    }
2012

    
2013
    ret = 0;
2014
 fail:
2015
    /* disable interrupting */
2016
    global_video_state = NULL;
2017

    
2018
    /* close each stream */
2019
    if (is->audio_stream >= 0)
2020
        stream_component_close(is, is->audio_stream);
2021
    if (is->video_stream >= 0)
2022
        stream_component_close(is, is->video_stream);
2023
    if (is->subtitle_stream >= 0)
2024
        stream_component_close(is, is->subtitle_stream);
2025
    if (is->ic) {
2026
        av_close_input_file(is->ic);
2027
        is->ic = NULL; /* safety */
2028
    }
2029
    url_set_interrupt_cb(NULL);
2030

    
2031
    if (ret != 0) {
2032
        SDL_Event event;
2033

    
2034
        event.type = FF_QUIT_EVENT;
2035
        event.user.data1 = is;
2036
        SDL_PushEvent(&event);
2037
    }
2038
    return 0;
2039
}
2040

    
2041
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2042
{
2043
    VideoState *is;
2044

    
2045
    is = av_mallocz(sizeof(VideoState));
2046
    if (!is)
2047
        return NULL;
2048
    pstrcpy(is->filename, sizeof(is->filename), filename);
2049
    is->iformat = iformat;
2050
    is->ytop = 0;
2051
    is->xleft = 0;
2052

    
2053
    /* start video display */
2054
    is->pictq_mutex = SDL_CreateMutex();
2055
    is->pictq_cond = SDL_CreateCond();
2056

    
2057
    is->subpq_mutex = SDL_CreateMutex();
2058
    is->subpq_cond = SDL_CreateCond();
2059

    
2060
    /* add the refresh timer to draw the picture */
2061
    schedule_refresh(is, 40);
2062

    
2063
    is->av_sync_type = av_sync_type;
2064
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2065
    if (!is->parse_tid) {
2066
        av_free(is);
2067
        return NULL;
2068
    }
2069
    return is;
2070
}
2071

    
2072
static void stream_close(VideoState *is)
2073
{
2074
    VideoPicture *vp;
2075
    int i;
2076
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2077
    is->abort_request = 1;
2078
    SDL_WaitThread(is->parse_tid, NULL);
2079

    
2080
    /* free all pictures */
2081
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2082
        vp = &is->pictq[i];
2083
        if (vp->bmp) {
2084
            SDL_FreeYUVOverlay(vp->bmp);
2085
            vp->bmp = NULL;
2086
        }
2087
    }
2088
    SDL_DestroyMutex(is->pictq_mutex);
2089
    SDL_DestroyCond(is->pictq_cond);
2090
    SDL_DestroyMutex(is->subpq_mutex);
2091
    SDL_DestroyCond(is->subpq_cond);
2092
}
2093

    
2094
static void stream_cycle_channel(VideoState *is, int codec_type)
2095
{
2096
    AVFormatContext *ic = is->ic;
2097
    int start_index, stream_index;
2098
    AVStream *st;
2099

    
2100
    if (codec_type == CODEC_TYPE_VIDEO)
2101
        start_index = is->video_stream;
2102
    else if (codec_type == CODEC_TYPE_AUDIO)
2103
        start_index = is->audio_stream;
2104
    else
2105
        start_index = is->subtitle_stream;
2106
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2107
        return;
2108
    stream_index = start_index;
2109
    for(;;) {
2110
        if (++stream_index >= is->ic->nb_streams)
2111
        {
2112
            if (codec_type == CODEC_TYPE_SUBTITLE)
2113
            {
2114
                stream_index = -1;
2115
                goto the_end;
2116
            } else
2117
                stream_index = 0;
2118
        }
2119
        if (stream_index == start_index)
2120
            return;
2121
        st = ic->streams[stream_index];
2122
        if (st->codec->codec_type == codec_type) {
2123
            /* check that parameters are OK */
2124
            switch(codec_type) {
2125
            case CODEC_TYPE_AUDIO:
2126
                if (st->codec->sample_rate != 0 &&
2127
                    st->codec->channels != 0)
2128
                    goto the_end;
2129
                break;
2130
            case CODEC_TYPE_VIDEO:
2131
            case CODEC_TYPE_SUBTITLE:
2132
                goto the_end;
2133
            default:
2134
                break;
2135
            }
2136
        }
2137
    }
2138
 the_end:
2139
    stream_component_close(is, start_index);
2140
    stream_component_open(is, stream_index);
2141
}
2142

    
2143

    
2144
static void toggle_full_screen(void)
2145
{
2146
    is_full_screen = !is_full_screen;
2147
    if (!fs_screen_width) {
2148
        /* use default SDL method */
2149
//        SDL_WM_ToggleFullScreen(screen);
2150
    }
2151
    video_open(cur_stream);
2152
}
2153

    
2154
static void toggle_pause(void)
2155
{
2156
    if (cur_stream)
2157
        stream_pause(cur_stream);
2158
    step = 0;
2159
}
2160

    
2161
static void step_to_next_frame(void)
2162
{
2163
    if (cur_stream) {
2164
        if (cur_stream->paused)
2165
            cur_stream->paused=0;
2166
        cur_stream->video_current_pts = get_video_clock(cur_stream);
2167
    }
2168
    step = 1;
2169
}
2170

    
2171
static void do_exit(void)
2172
{
2173
    if (cur_stream) {
2174
        stream_close(cur_stream);
2175
        cur_stream = NULL;
2176
    }
2177
    if (show_status)
2178
        printf("\n");
2179
    SDL_Quit();
2180
    exit(0);
2181
}
2182

    
2183
static void toggle_audio_display(void)
2184
{
2185
    if (cur_stream) {
2186
        cur_stream->show_audio = !cur_stream->show_audio;
2187
    }
2188
}
2189

    
2190
/* handle an event sent by the GUI */
2191
static void event_loop(void)
2192
{
2193
    SDL_Event event;
2194
    double incr, pos, frac;
2195

    
2196
    for(;;) {
2197
        SDL_WaitEvent(&event);
2198
        switch(event.type) {
2199
        case SDL_KEYDOWN:
2200
            switch(event.key.keysym.sym) {
2201
            case SDLK_ESCAPE:
2202
            case SDLK_q:
2203
                do_exit();
2204
                break;
2205
            case SDLK_f:
2206
                toggle_full_screen();
2207
                break;
2208
            case SDLK_p:
2209
            case SDLK_SPACE:
2210
                toggle_pause();
2211
                break;
2212
            case SDLK_s: //S: Step to next frame
2213
                step_to_next_frame();
2214
                break;
2215
            case SDLK_a:
2216
                if (cur_stream)
2217
                    stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2218
                break;
2219
            case SDLK_v:
2220
                if (cur_stream)
2221
                    stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2222
                break;
2223
            case SDLK_t:
2224
                if (cur_stream)
2225
                    stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2226
                break;
2227
            case SDLK_w:
2228
                toggle_audio_display();
2229
                break;
2230
            case SDLK_LEFT:
2231
                incr = -10.0;
2232
                goto do_seek;
2233
            case SDLK_RIGHT:
2234
                incr = 10.0;
2235
                goto do_seek;
2236
            case SDLK_UP:
2237
                incr = 60.0;
2238
                goto do_seek;
2239
            case SDLK_DOWN:
2240
                incr = -60.0;
2241
            do_seek:
2242
                if (cur_stream) {
2243
                    if (seek_by_bytes) {
2244
                        pos = url_ftell(&cur_stream->ic->pb);
2245
                        if (cur_stream->ic->bit_rate)
2246
                            incr *= cur_stream->ic->bit_rate / 60.0;
2247
                        else
2248
                            incr *= 180000.0;
2249
                        pos += incr;
2250
                        stream_seek(cur_stream, pos, incr);
2251
                    } else {
2252
                        pos = get_master_clock(cur_stream);
2253
                        pos += incr;
2254
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
2255
                    }
2256
                }
2257
                break;
2258
            default:
2259
                break;
2260
            }
2261
            break;
2262
        case SDL_MOUSEBUTTONDOWN:
2263
            if (cur_stream) {
2264
                int ns, hh, mm, ss;
2265
                int tns, thh, tmm, tss;
2266
                tns = cur_stream->ic->duration/1000000LL;
2267
                thh = tns/3600;
2268
                tmm = (tns%3600)/60;
2269
                tss = (tns%60);
2270
                frac = (double)event.button.x/(double)cur_stream->width;
2271
                ns = frac*tns;
2272
                hh = ns/3600;
2273
                mm = (ns%3600)/60;
2274
                ss = (ns%60);
2275
                fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2276
                        hh, mm, ss, thh, tmm, tss);
2277
                stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
2278
            }
2279
            break;
2280
        case SDL_VIDEORESIZE:
2281
            if (cur_stream) {
2282
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2283
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2284
                screen_width = cur_stream->width = event.resize.w;
2285
                screen_height= cur_stream->height= event.resize.h;
2286
            }
2287
            break;
2288
        case SDL_QUIT:
2289
        case FF_QUIT_EVENT:
2290
            do_exit();
2291
            break;
2292
        case FF_ALLOC_EVENT:
2293
            video_open(event.user.data1);
2294
            alloc_picture(event.user.data1);
2295
            break;
2296
        case FF_REFRESH_EVENT:
2297
            video_refresh_timer(event.user.data1);
2298
            break;
2299
        default:
2300
            break;
2301
        }
2302
    }
2303
}
2304

    
2305
void opt_width(const char *arg)
2306
{
2307
    screen_width = atoi(arg);
2308
    if(screen_width<=0){
2309
        fprintf(stderr, "invalid width\n");
2310
        exit(1);
2311
    }
2312
}
2313

    
2314
void opt_height(const char *arg)
2315
{
2316
    screen_height = atoi(arg);
2317
    if(screen_height<=0){
2318
        fprintf(stderr, "invalid height\n");
2319
        exit(1);
2320
    }
2321
}
2322

    
2323
static void opt_format(const char *arg)
2324
{
2325
    file_iformat = av_find_input_format(arg);
2326
    if (!file_iformat) {
2327
        fprintf(stderr, "Unknown input format: %s\n", arg);
2328
        exit(1);
2329
    }
2330
}
2331

    
2332
#ifdef CONFIG_NETWORK
2333
void opt_rtp_tcp(void)
2334
{
2335
    /* only tcp protocol */
2336
    rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
2337
}
2338
#endif
2339

    
2340
void opt_sync(const char *arg)
2341
{
2342
    if (!strcmp(arg, "audio"))
2343
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2344
    else if (!strcmp(arg, "video"))
2345
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2346
    else if (!strcmp(arg, "ext"))
2347
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2348
    else
2349
        show_help();
2350
}
2351

    
2352
void opt_seek(const char *arg)
2353
{
2354
    start_time = parse_date(arg, 1);
2355
}
2356

    
2357
static void opt_debug(const char *arg)
2358
{
2359
    av_log_set_level(99);
2360
    debug = atoi(arg);
2361
}
2362

    
2363
static void opt_vismv(const char *arg)
2364
{
2365
    debug_mv = atoi(arg);
2366
}
2367

    
2368
static void opt_thread_count(const char *arg)
2369
{
2370
    thread_count= atoi(arg);
2371
#if !defined(HAVE_THREADS)
2372
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2373
#endif
2374
}
2375

    
2376
const OptionDef options[] = {
2377
    { "h", 0, {(void*)show_help}, "show help" },
2378
    { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2379
    { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
2380
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2381
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2382
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2383
    { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2384
    { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2385
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2386
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2387
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2388
    { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2389
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2390
    { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2391
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2392
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2393
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2394
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2395
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2396
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2397
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2398
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)",  "threshold" },
2399
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2400
#ifdef CONFIG_NETWORK
2401
    { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
2402
#endif
2403
    { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2404
    { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2405
    { NULL, },
2406
};
2407

    
2408
void show_help(void)
2409
{
2410
    printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003-2006 Fabrice Bellard, et al.\n"
2411
           "usage: ffplay [options] input_file\n"
2412
           "Simple media player\n");
2413
    printf("\n");
2414
    show_help_options(options, "Main options:\n",
2415
                      OPT_EXPERT, 0);
2416
    show_help_options(options, "\nAdvanced options:\n",
2417
                      OPT_EXPERT, OPT_EXPERT);
2418
    printf("\nWhile playing:\n"
2419
           "q, ESC              quit\n"
2420
           "f                   toggle full screen\n"
2421
           "p, SPC              pause\n"
2422
           "a                   cycle audio channel\n"
2423
           "v                   cycle video channel\n"
2424
           "t                   cycle subtitle channel\n"
2425
           "w                   show audio waves\n"
2426
           "left/right          seek backward/forward 10 seconds\n"
2427
           "down/up             seek backward/forward 1 minute\n"
2428
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2429
           );
2430
    exit(1);
2431
}
2432

    
2433
void parse_arg_file(const char *filename)
2434
{
2435
    if (!strcmp(filename, "-"))
2436
                    filename = "pipe:";
2437
    input_filename = filename;
2438
}
2439

    
2440
/* Called from the main */
2441
int main(int argc, char **argv)
2442
{
2443
    int flags;
2444

    
2445
    /* register all codecs, demux and protocols */
2446
    av_register_all();
2447

    
2448
    #ifdef CONFIG_OS2
2449
      MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
2450

    
2451
      // Make stdout and stderr unbuffered
2452
      setbuf( stdout, NULL );
2453
      setbuf( stderr, NULL );
2454
    #endif
2455

    
2456
    parse_options(argc, argv, options);
2457

    
2458
    if (!input_filename)
2459
        show_help();
2460

    
2461
    if (display_disable) {
2462
        video_disable = 1;
2463
    }
2464
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2465
#if !defined(__MINGW32__) && !defined(CONFIG_DARWIN)
2466
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 or darwin */
2467
#endif
2468
    if (SDL_Init (flags)) {
2469
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2470
        exit(1);
2471
    }
2472

    
2473
    if (!display_disable) {
2474
#ifdef HAVE_SDL_VIDEO_SIZE
2475
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2476
        fs_screen_width = vi->current_w;
2477
        fs_screen_height = vi->current_h;
2478
#endif
2479
    }
2480

    
2481
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2482
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2483
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2484
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2485

    
2486
    av_init_packet(&flush_pkt);
2487
    flush_pkt.data= "FLUSH";
2488

    
2489
    cur_stream = stream_open(input_filename, file_iformat);
2490

    
2491
    event_loop();
2492

    
2493
    /* never returns */
2494

    
2495
    return 0;
2496
}