Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 0bc5ccb8

History | View | Annotate | Download (74.3 KB)

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

    
178
    //    QETimer *video_timer;
179
    char filename[1024];
180
    int width, height, xleft, ytop;
181
} VideoState;
182

    
183
void show_help(void);
184
static int audio_write_get_buf_size(VideoState *is);
185

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

    
215
/* current context */
216
static int is_full_screen;
217
static VideoState *cur_stream;
218
static int64_t audio_callback_time;
219

    
220
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
221
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
222
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
223

    
224
SDL_Surface *screen;
225

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

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

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

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

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

    
262
    /* duplicate the packet */
263
    if (av_dup_packet(pkt) < 0)
264
        return -1;
265

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

    
272

    
273
    SDL_LockMutex(q->mutex);
274

    
275
    if (!q->last_pkt)
276

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

    
286
    SDL_UnlockMutex(q->mutex);
287
    return 0;
288
}
289

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

    
294
    q->abort_request = 1;
295

    
296
    SDL_CondSignal(q->cond);
297

    
298
    SDL_UnlockMutex(q->mutex);
299
}
300

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

    
307
    SDL_LockMutex(q->mutex);
308

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

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

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

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

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

    
386

    
387

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

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

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

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

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

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

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

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

    
430

    
431
#define BPP 1
432

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
626
static void free_subpicture(SubPicture *sp)
627
{
628
    int i;
629

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

    
636
    av_free(sp->sub.rects);
637

    
638
    memset(&sp->sub, 0, sizeof(AVSubtitle));
639
}
640

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

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

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

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

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

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

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

    
718
                    SDL_UnlockYUVOverlay (vp->bmp);
719
                }
720
            }
721
        }
722

    
723

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

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

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

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

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

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

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

    
797
    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
798

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

    
823
    fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
824

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

    
834
/* display the current picture, if any */
835
static void video_display(VideoState *is)
836
{
837
    if (is->audio_st && is->show_audio)
838
        video_audio_display(is);
839
    else if (is->video_st)
840
        video_image_display(is);
841
}
842

    
843
static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
844
{
845
    SDL_Event event;
846
    event.type = FF_REFRESH_EVENT;
847
    event.user.data1 = opaque;
848
    SDL_PushEvent(&event);
849
    return 0; /* 0 means stop timer */
850
}
851

    
852
/* schedule a video refresh in 'delay' ms */
853
static void schedule_refresh(VideoState *is, int delay)
854
{
855
    SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
856
}
857

    
858
/* get the current audio clock value */
859
static double get_audio_clock(VideoState *is)
860
{
861
    double pts;
862
    int hw_buf_size, bytes_per_sec;
863
    pts = is->audio_clock;
864
    hw_buf_size = audio_write_get_buf_size(is);
865
    bytes_per_sec = 0;
866
    if (is->audio_st) {
867
        bytes_per_sec = is->audio_st->codec->sample_rate *
868
            2 * is->audio_st->codec->channels;
869
    }
870
    if (bytes_per_sec)
871
        pts -= (double)hw_buf_size / bytes_per_sec;
872
    return pts;
873
}
874

    
875
/* get the current video clock value */
876
static double get_video_clock(VideoState *is)
877
{
878
    double delta;
879
    if (is->paused) {
880
        delta = 0;
881
    } else {
882
        delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
883
    }
884
    return is->video_current_pts + delta;
885
}
886

    
887
/* get the current external clock value */
888
static double get_external_clock(VideoState *is)
889
{
890
    int64_t ti;
891
    ti = av_gettime();
892
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
893
}
894

    
895
/* get the current master clock value */
896
static double get_master_clock(VideoState *is)
897
{
898
    double val;
899

    
900
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
901
        if (is->video_st)
902
            val = get_video_clock(is);
903
        else
904
            val = get_audio_clock(is);
905
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
906
        if (is->audio_st)
907
            val = get_audio_clock(is);
908
        else
909
            val = get_video_clock(is);
910
    } else {
911
        val = get_external_clock(is);
912
    }
913
    return val;
914
}
915

    
916
/* seek in the stream */
917
static void stream_seek(VideoState *is, int64_t pos, int rel)
918
{
919
    if (!is->seek_req) {
920
        is->seek_pos = pos;
921
        is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
922
        if (seek_by_bytes)
923
            is->seek_flags |= AVSEEK_FLAG_BYTE;
924
        is->seek_req = 1;
925
    }
926
}
927

    
928
/* pause or resume the video */
929
static void stream_pause(VideoState *is)
930
{
931
    is->paused = !is->paused;
932
    if (is->paused) {
933
        is->video_current_pts = get_video_clock(is);
934
    }
935
}
936

    
937
/* called to display each frame */
938
static void video_refresh_timer(void *opaque)
939
{
940
    VideoState *is = opaque;
941
    VideoPicture *vp;
942
    double actual_delay, delay, sync_threshold, ref_clock, diff;
943

    
944
    SubPicture *sp, *sp2;
945

    
946
    if (is->video_st) {
947
        if (is->pictq_size == 0) {
948
            /* if no picture, need to wait */
949
            schedule_refresh(is, 1);
950
        } else {
951
            /* dequeue the picture */
952
            vp = &is->pictq[is->pictq_rindex];
953

    
954
            /* update current video pts */
955
            is->video_current_pts = vp->pts;
956
            is->video_current_pts_time = av_gettime();
957

    
958
            /* compute nominal delay */
959
            delay = vp->pts - is->frame_last_pts;
960
            if (delay <= 0 || delay >= 1.0) {
961
                /* if incorrect delay, use previous one */
962
                delay = is->frame_last_delay;
963
            }
964
            is->frame_last_delay = delay;
965
            is->frame_last_pts = vp->pts;
966

    
967
            /* update delay to follow master synchronisation source */
968
            if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
969
                 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
970
                /* if video is slave, we try to correct big delays by
971
                   duplicating or deleting a frame */
972
                ref_clock = get_master_clock(is);
973
                diff = vp->pts - ref_clock;
974

    
975
                /* skip or repeat frame. We take into account the
976
                   delay to compute the threshold. I still don't know
977
                   if it is the best guess */
978
                sync_threshold = AV_SYNC_THRESHOLD;
979
                if (delay > sync_threshold)
980
                    sync_threshold = delay;
981
                if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
982
                    if (diff <= -sync_threshold)
983
                        delay = 0;
984
                    else if (diff >= sync_threshold)
985
                        delay = 2 * delay;
986
                }
987
            }
988

    
989
            is->frame_timer += delay;
990
            /* compute the REAL delay (we need to do that to avoid
991
               long term errors */
992
            actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
993
            if (actual_delay < 0.010) {
994
                /* XXX: should skip picture */
995
                actual_delay = 0.010;
996
            }
997
            /* launch timer for next picture */
998
            schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
999

    
1000
#if defined(DEBUG_SYNC)
1001
            printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1002
                   delay, actual_delay, vp->pts, -diff);
1003
#endif
1004

    
1005
            if(is->subtitle_st) {
1006
                if (is->subtitle_stream_changed) {
1007
                    SDL_LockMutex(is->subpq_mutex);
1008

    
1009
                    while (is->subpq_size) {
1010
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1011

    
1012
                        /* update queue size and signal for next picture */
1013
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1014
                            is->subpq_rindex = 0;
1015

    
1016
                        is->subpq_size--;
1017
                    }
1018
                    is->subtitle_stream_changed = 0;
1019

    
1020
                    SDL_CondSignal(is->subpq_cond);
1021
                    SDL_UnlockMutex(is->subpq_mutex);
1022
                } else {
1023
                    if (is->subpq_size > 0) {
1024
                        sp = &is->subpq[is->subpq_rindex];
1025

    
1026
                        if (is->subpq_size > 1)
1027
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1028
                        else
1029
                            sp2 = NULL;
1030

    
1031
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1032
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1033
                        {
1034
                            free_subpicture(sp);
1035

    
1036
                            /* update queue size and signal for next picture */
1037
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1038
                                is->subpq_rindex = 0;
1039

    
1040
                            SDL_LockMutex(is->subpq_mutex);
1041
                            is->subpq_size--;
1042
                            SDL_CondSignal(is->subpq_cond);
1043
                            SDL_UnlockMutex(is->subpq_mutex);
1044
                        }
1045
                    }
1046
                }
1047
            }
1048

    
1049
            /* display picture */
1050
            video_display(is);
1051

    
1052
            /* update queue size and signal for next picture */
1053
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1054
                is->pictq_rindex = 0;
1055

    
1056
            SDL_LockMutex(is->pictq_mutex);
1057
            is->pictq_size--;
1058
            SDL_CondSignal(is->pictq_cond);
1059
            SDL_UnlockMutex(is->pictq_mutex);
1060
        }
1061
    } else if (is->audio_st) {
1062
        /* draw the next audio frame */
1063

    
1064
        schedule_refresh(is, 40);
1065

    
1066
        /* if only audio stream, then display the audio bars (better
1067
           than nothing, just to test the implementation */
1068

    
1069
        /* display picture */
1070
        video_display(is);
1071
    } else {
1072
        schedule_refresh(is, 100);
1073
    }
1074
    if (show_status) {
1075
        static int64_t last_time;
1076
        int64_t cur_time;
1077
        int aqsize, vqsize, sqsize;
1078
        double av_diff;
1079

    
1080
        cur_time = av_gettime();
1081
        if (!last_time || (cur_time - last_time) >= 500 * 1000) {
1082
            aqsize = 0;
1083
            vqsize = 0;
1084
            sqsize = 0;
1085
            if (is->audio_st)
1086
                aqsize = is->audioq.size;
1087
            if (is->video_st)
1088
                vqsize = is->videoq.size;
1089
            if (is->subtitle_st)
1090
                sqsize = is->subtitleq.size;
1091
            av_diff = 0;
1092
            if (is->audio_st && is->video_st)
1093
                av_diff = get_audio_clock(is) - get_video_clock(is);
1094
            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1095
                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1096
            fflush(stdout);
1097
            last_time = cur_time;
1098
        }
1099
    }
1100
}
1101

    
1102
/* allocate a picture (needs to do that in main thread to avoid
1103
   potential locking problems */
1104
static void alloc_picture(void *opaque)
1105
{
1106
    VideoState *is = opaque;
1107
    VideoPicture *vp;
1108

    
1109
    vp = &is->pictq[is->pictq_windex];
1110

    
1111
    if (vp->bmp)
1112
        SDL_FreeYUVOverlay(vp->bmp);
1113

    
1114
#if 0
1115
    /* XXX: use generic function */
1116
    /* XXX: disable overlay if no hardware acceleration or if RGB format */
1117
    switch(is->video_st->codec->pix_fmt) {
1118
    case PIX_FMT_YUV420P:
1119
    case PIX_FMT_YUV422P:
1120
    case PIX_FMT_YUV444P:
1121
    case PIX_FMT_YUV422:
1122
    case PIX_FMT_YUV410P:
1123
    case PIX_FMT_YUV411P:
1124
        is_yuv = 1;
1125
        break;
1126
    default:
1127
        is_yuv = 0;
1128
        break;
1129
    }
1130
#endif
1131
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1132
                                   is->video_st->codec->height,
1133
                                   SDL_YV12_OVERLAY,
1134
                                   screen);
1135
    vp->width = is->video_st->codec->width;
1136
    vp->height = is->video_st->codec->height;
1137

    
1138
    SDL_LockMutex(is->pictq_mutex);
1139
    vp->allocated = 1;
1140
    SDL_CondSignal(is->pictq_cond);
1141
    SDL_UnlockMutex(is->pictq_mutex);
1142
}
1143

    
1144
/**
1145
 *
1146
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1147
 */
1148
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1149
{
1150
    VideoPicture *vp;
1151
    int dst_pix_fmt;
1152
    AVPicture pict;
1153
    static struct SwsContext *img_convert_ctx;
1154

    
1155
    /* wait until we have space to put a new picture */
1156
    SDL_LockMutex(is->pictq_mutex);
1157
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1158
           !is->videoq.abort_request) {
1159
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1160
    }
1161
    SDL_UnlockMutex(is->pictq_mutex);
1162

    
1163
    if (is->videoq.abort_request)
1164
        return -1;
1165

    
1166
    vp = &is->pictq[is->pictq_windex];
1167

    
1168
    /* alloc or resize hardware picture buffer */
1169
    if (!vp->bmp ||
1170
        vp->width != is->video_st->codec->width ||
1171
        vp->height != is->video_st->codec->height) {
1172
        SDL_Event event;
1173

    
1174
        vp->allocated = 0;
1175

    
1176
        /* the allocation must be done in the main thread to avoid
1177
           locking problems */
1178
        event.type = FF_ALLOC_EVENT;
1179
        event.user.data1 = is;
1180
        SDL_PushEvent(&event);
1181

    
1182
        /* wait until the picture is allocated */
1183
        SDL_LockMutex(is->pictq_mutex);
1184
        while (!vp->allocated && !is->videoq.abort_request) {
1185
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1186
        }
1187
        SDL_UnlockMutex(is->pictq_mutex);
1188

    
1189
        if (is->videoq.abort_request)
1190
            return -1;
1191
    }
1192

    
1193
    /* if the frame is not skipped, then display it */
1194
    if (vp->bmp) {
1195
        /* get a pointer on the bitmap */
1196
        SDL_LockYUVOverlay (vp->bmp);
1197

    
1198
        dst_pix_fmt = PIX_FMT_YUV420P;
1199
        pict.data[0] = vp->bmp->pixels[0];
1200
        pict.data[1] = vp->bmp->pixels[2];
1201
        pict.data[2] = vp->bmp->pixels[1];
1202

    
1203
        pict.linesize[0] = vp->bmp->pitches[0];
1204
        pict.linesize[1] = vp->bmp->pitches[2];
1205
        pict.linesize[2] = vp->bmp->pitches[1];
1206
        if (img_convert_ctx == NULL) {
1207
            img_convert_ctx = sws_getContext(is->video_st->codec->width,
1208
                    is->video_st->codec->height, is->video_st->codec->pix_fmt,
1209
                    is->video_st->codec->width, is->video_st->codec->height,
1210
                    dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1211
            if (img_convert_ctx == NULL) {
1212
                fprintf(stderr, "Cannot initialize the conversion context\n");
1213
                exit(1);
1214
            }
1215
        }
1216
        sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
1217
                  0, is->video_st->codec->height, pict.data, pict.linesize);
1218
        /* update the bitmap content */
1219
        SDL_UnlockYUVOverlay(vp->bmp);
1220

    
1221
        vp->pts = pts;
1222

    
1223
        /* now we can update the picture count */
1224
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1225
            is->pictq_windex = 0;
1226
        SDL_LockMutex(is->pictq_mutex);
1227
        is->pictq_size++;
1228
        SDL_UnlockMutex(is->pictq_mutex);
1229
    }
1230
    return 0;
1231
}
1232

    
1233
/**
1234
 * compute the exact PTS for the picture if it is omitted in the stream
1235
 * @param pts1 the dts of the pkt / pts of the frame
1236
 */
1237
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1238
{
1239
    double frame_delay, pts;
1240

    
1241
    pts = pts1;
1242

    
1243
    if (pts != 0) {
1244
        /* update video clock with pts, if present */
1245
        is->video_clock = pts;
1246
    } else {
1247
        pts = is->video_clock;
1248
    }
1249
    /* update video clock for next frame */
1250
    frame_delay = av_q2d(is->video_st->codec->time_base);
1251
    /* for MPEG2, the frame can be repeated, so we update the
1252
       clock accordingly */
1253
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1254
    is->video_clock += frame_delay;
1255

    
1256
#if defined(DEBUG_SYNC) && 0
1257
    {
1258
        int ftype;
1259
        if (src_frame->pict_type == FF_B_TYPE)
1260
            ftype = 'B';
1261
        else if (src_frame->pict_type == FF_I_TYPE)
1262
            ftype = 'I';
1263
        else
1264
            ftype = 'P';
1265
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1266
               ftype, pts, pts1);
1267
    }
1268
#endif
1269
    return queue_picture(is, src_frame, pts);
1270
}
1271

    
1272
static int video_thread(void *arg)
1273
{
1274
    VideoState *is = arg;
1275
    AVPacket pkt1, *pkt = &pkt1;
1276
    int len1, got_picture;
1277
    AVFrame *frame= avcodec_alloc_frame();
1278
    double pts;
1279

    
1280
    for(;;) {
1281
        while (is->paused && !is->videoq.abort_request) {
1282
            SDL_Delay(10);
1283
        }
1284
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1285
            break;
1286
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1287
           this packet, if any */
1288
        pts = 0;
1289
        if (pkt->dts != AV_NOPTS_VALUE)
1290
            pts = av_q2d(is->video_st->time_base)*pkt->dts;
1291

    
1292
            SDL_LockMutex(is->video_decoder_mutex);
1293
            len1 = avcodec_decode_video(is->video_st->codec,
1294
                                        frame, &got_picture,
1295
                                        pkt->data, pkt->size);
1296
            SDL_UnlockMutex(is->video_decoder_mutex);
1297
//            if (len1 < 0)
1298
//                break;
1299
            if (got_picture) {
1300
                if (output_picture2(is, frame, pts) < 0)
1301
                    goto the_end;
1302
            }
1303
        av_free_packet(pkt);
1304
        if (step)
1305
            if (cur_stream)
1306
                stream_pause(cur_stream);
1307
    }
1308
 the_end:
1309
    av_free(frame);
1310
    return 0;
1311
}
1312

    
1313
static int subtitle_thread(void *arg)
1314
{
1315
    VideoState *is = arg;
1316
    SubPicture *sp;
1317
    AVPacket pkt1, *pkt = &pkt1;
1318
    int len1, got_subtitle;
1319
    double pts;
1320
    int i, j;
1321
    int r, g, b, y, u, v, a;
1322

    
1323
    for(;;) {
1324
        while (is->paused && !is->subtitleq.abort_request) {
1325
            SDL_Delay(10);
1326
        }
1327
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1328
            break;
1329

    
1330
        SDL_LockMutex(is->subpq_mutex);
1331
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1332
               !is->subtitleq.abort_request) {
1333
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1334
        }
1335
        SDL_UnlockMutex(is->subpq_mutex);
1336

    
1337
        if (is->subtitleq.abort_request)
1338
            goto the_end;
1339

    
1340
        sp = &is->subpq[is->subpq_windex];
1341

    
1342
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1343
           this packet, if any */
1344
        pts = 0;
1345
        if (pkt->pts != AV_NOPTS_VALUE)
1346
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1347

    
1348
        SDL_LockMutex(is->subtitle_decoder_mutex);
1349
        len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
1350
                                    &sp->sub, &got_subtitle,
1351
                                    pkt->data, pkt->size);
1352
        SDL_UnlockMutex(is->subtitle_decoder_mutex);
1353
//            if (len1 < 0)
1354
//                break;
1355
        if (got_subtitle && sp->sub.format == 0) {
1356
            sp->pts = pts;
1357

    
1358
            for (i = 0; i < sp->sub.num_rects; i++)
1359
            {
1360
                for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
1361
                {
1362
                    RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
1363
                    y = RGB_TO_Y_CCIR(r, g, b);
1364
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1365
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1366
                    YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
1367
                }
1368
            }
1369

    
1370
            /* now we can update the picture count */
1371
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1372
                is->subpq_windex = 0;
1373
            SDL_LockMutex(is->subpq_mutex);
1374
            is->subpq_size++;
1375
            SDL_UnlockMutex(is->subpq_mutex);
1376
        }
1377
        av_free_packet(pkt);
1378
//        if (step)
1379
//            if (cur_stream)
1380
//                stream_pause(cur_stream);
1381
    }
1382
 the_end:
1383
    return 0;
1384
}
1385

    
1386
/* copy samples for viewing in editor window */
1387
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1388
{
1389
    int size, len, channels;
1390

    
1391
    channels = is->audio_st->codec->channels;
1392

    
1393
    size = samples_size / sizeof(short);
1394
    while (size > 0) {
1395
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1396
        if (len > size)
1397
            len = size;
1398
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1399
        samples += len;
1400
        is->sample_array_index += len;
1401
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1402
            is->sample_array_index = 0;
1403
        size -= len;
1404
    }
1405
}
1406

    
1407
/* return the new audio buffer size (samples can be added or deleted
1408
   to get better sync if video or external master clock) */
1409
static int synchronize_audio(VideoState *is, short *samples,
1410
                             int samples_size1, double pts)
1411
{
1412
    int n, samples_size;
1413
    double ref_clock;
1414

    
1415
    n = 2 * is->audio_st->codec->channels;
1416
    samples_size = samples_size1;
1417

    
1418
    /* if not master, then we try to remove or add samples to correct the clock */
1419
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1420
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1421
        double diff, avg_diff;
1422
        int wanted_size, min_size, max_size, nb_samples;
1423

    
1424
        ref_clock = get_master_clock(is);
1425
        diff = get_audio_clock(is) - ref_clock;
1426

    
1427
        if (diff < AV_NOSYNC_THRESHOLD) {
1428
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1429
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1430
                /* not enough measures to have a correct estimate */
1431
                is->audio_diff_avg_count++;
1432
            } else {
1433
                /* estimate the A-V difference */
1434
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1435

    
1436
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1437
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1438
                    nb_samples = samples_size / n;
1439

    
1440
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1441
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1442
                    if (wanted_size < min_size)
1443
                        wanted_size = min_size;
1444
                    else if (wanted_size > max_size)
1445
                        wanted_size = max_size;
1446

    
1447
                    /* add or remove samples to correction the synchro */
1448
                    if (wanted_size < samples_size) {
1449
                        /* remove samples */
1450
                        samples_size = wanted_size;
1451
                    } else if (wanted_size > samples_size) {
1452
                        uint8_t *samples_end, *q;
1453
                        int nb;
1454

    
1455
                        /* add samples */
1456
                        nb = (samples_size - wanted_size);
1457
                        samples_end = (uint8_t *)samples + samples_size - n;
1458
                        q = samples_end + n;
1459
                        while (nb > 0) {
1460
                            memcpy(q, samples_end, n);
1461
                            q += n;
1462
                            nb -= n;
1463
                        }
1464
                        samples_size = wanted_size;
1465
                    }
1466
                }
1467
#if 0
1468
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1469
                       diff, avg_diff, samples_size - samples_size1,
1470
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
1471
#endif
1472
            }
1473
        } else {
1474
            /* too big difference : may be initial PTS errors, so
1475
               reset A-V filter */
1476
            is->audio_diff_avg_count = 0;
1477
            is->audio_diff_cum = 0;
1478
        }
1479
    }
1480

    
1481
    return samples_size;
1482
}
1483

    
1484
/* decode one audio frame and returns its uncompressed size */
1485
static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
1486
{
1487
    AVPacket *pkt = &is->audio_pkt;
1488
    int n, len1, data_size;
1489
    double pts;
1490

    
1491
    for(;;) {
1492
        /* NOTE: the audio packet can contain several frames */
1493
        while (is->audio_pkt_size > 0) {
1494
            SDL_LockMutex(is->audio_decoder_mutex);
1495
            len1 = avcodec_decode_audio(is->audio_st->codec,
1496
                                        (int16_t *)audio_buf, &data_size,
1497
                                        is->audio_pkt_data, is->audio_pkt_size);
1498
            SDL_UnlockMutex(is->audio_decoder_mutex);
1499
            if (len1 < 0) {
1500
                /* if error, we skip the frame */
1501
                is->audio_pkt_size = 0;
1502
                break;
1503
            }
1504

    
1505
            is->audio_pkt_data += len1;
1506
            is->audio_pkt_size -= len1;
1507
            if (data_size <= 0)
1508
                continue;
1509
            /* if no pts, then compute it */
1510
            pts = is->audio_clock;
1511
            *pts_ptr = pts;
1512
            n = 2 * is->audio_st->codec->channels;
1513
            is->audio_clock += (double)data_size /
1514
                (double)(n * is->audio_st->codec->sample_rate);
1515
#if defined(DEBUG_SYNC)
1516
            {
1517
                static double last_clock;
1518
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1519
                       is->audio_clock - last_clock,
1520
                       is->audio_clock, pts);
1521
                last_clock = is->audio_clock;
1522
            }
1523
#endif
1524
            return data_size;
1525
        }
1526

    
1527
        /* free the current packet */
1528
        if (pkt->data)
1529
            av_free_packet(pkt);
1530

    
1531
        if (is->paused || is->audioq.abort_request) {
1532
            return -1;
1533
        }
1534

    
1535
        /* read next packet */
1536
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1537
            return -1;
1538
        is->audio_pkt_data = pkt->data;
1539
        is->audio_pkt_size = pkt->size;
1540

    
1541
        /* if update the audio clock with the pts */
1542
        if (pkt->pts != AV_NOPTS_VALUE) {
1543
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1544
        }
1545
    }
1546
}
1547

    
1548
/* get the current audio output buffer size, in samples. With SDL, we
1549
   cannot have a precise information */
1550
static int audio_write_get_buf_size(VideoState *is)
1551
{
1552
    return is->audio_hw_buf_size - is->audio_buf_index;
1553
}
1554

    
1555

    
1556
/* prepare a new audio buffer */
1557
void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1558
{
1559
    VideoState *is = opaque;
1560
    int audio_size, len1;
1561
    double pts;
1562

    
1563
    audio_callback_time = av_gettime();
1564

    
1565
    while (len > 0) {
1566
        if (is->audio_buf_index >= is->audio_buf_size) {
1567
           audio_size = audio_decode_frame(is, is->audio_buf, &pts);
1568
           if (audio_size < 0) {
1569
                /* if error, just output silence */
1570
               is->audio_buf_size = 1024;
1571
               memset(is->audio_buf, 0, is->audio_buf_size);
1572
           } else {
1573
               if (is->show_audio)
1574
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1575
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1576
                                              pts);
1577
               is->audio_buf_size = audio_size;
1578
           }
1579
           is->audio_buf_index = 0;
1580
        }
1581
        len1 = is->audio_buf_size - is->audio_buf_index;
1582
        if (len1 > len)
1583
            len1 = len;
1584
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1585
        len -= len1;
1586
        stream += len1;
1587
        is->audio_buf_index += len1;
1588
    }
1589
}
1590

    
1591

    
1592
/* open a given stream. Return 0 if OK */
1593
static int stream_component_open(VideoState *is, int stream_index)
1594
{
1595
    AVFormatContext *ic = is->ic;
1596
    AVCodecContext *enc;
1597
    AVCodec *codec;
1598
    SDL_AudioSpec wanted_spec, spec;
1599

    
1600
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1601
        return -1;
1602
    enc = ic->streams[stream_index]->codec;
1603

    
1604
    /* prepare audio output */
1605
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1606
        wanted_spec.freq = enc->sample_rate;
1607
        wanted_spec.format = AUDIO_S16SYS;
1608
        /* hack for AC3. XXX: suppress that */
1609
        if (enc->channels > 2)
1610
            enc->channels = 2;
1611
        wanted_spec.channels = enc->channels;
1612
        wanted_spec.silence = 0;
1613
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1614
        wanted_spec.callback = sdl_audio_callback;
1615
        wanted_spec.userdata = is;
1616
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1617
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1618
            return -1;
1619
        }
1620
        is->audio_hw_buf_size = spec.size;
1621
    }
1622

    
1623
    codec = avcodec_find_decoder(enc->codec_id);
1624
    enc->debug_mv = debug_mv;
1625
    enc->debug = debug;
1626
    enc->workaround_bugs = workaround_bugs;
1627
    enc->lowres = lowres;
1628
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1629
    enc->idct_algo= idct;
1630
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1631
    enc->skip_frame= skip_frame;
1632
    enc->skip_idct= skip_idct;
1633
    enc->skip_loop_filter= skip_loop_filter;
1634
    enc->error_resilience= error_resilience;
1635
    enc->error_concealment= error_concealment;
1636
    if (!codec ||
1637
        avcodec_open(enc, codec) < 0)
1638
        return -1;
1639
#if defined(HAVE_THREADS)
1640
    if(thread_count>1)
1641
        avcodec_thread_init(enc, thread_count);
1642
#endif
1643
    enc->thread_count= thread_count;
1644
    switch(enc->codec_type) {
1645
    case CODEC_TYPE_AUDIO:
1646
        is->audio_stream = stream_index;
1647
        is->audio_st = ic->streams[stream_index];
1648
        is->audio_buf_size = 0;
1649
        is->audio_buf_index = 0;
1650

    
1651
        /* init averaging filter */
1652
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1653
        is->audio_diff_avg_count = 0;
1654
        /* since we do not have a precise anough audio fifo fullness,
1655
           we correct audio sync only if larger than this threshold */
1656
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1657

    
1658
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1659
        packet_queue_init(&is->audioq);
1660
        SDL_PauseAudio(0);
1661
        break;
1662
    case CODEC_TYPE_VIDEO:
1663
        is->video_stream = stream_index;
1664
        is->video_st = ic->streams[stream_index];
1665

    
1666
        is->frame_last_delay = 40e-3;
1667
        is->frame_timer = (double)av_gettime() / 1000000.0;
1668
        is->video_current_pts_time = av_gettime();
1669

    
1670
        packet_queue_init(&is->videoq);
1671
        is->video_tid = SDL_CreateThread(video_thread, is);
1672
        break;
1673
    case CODEC_TYPE_SUBTITLE:
1674
        is->subtitle_stream = stream_index;
1675
        is->subtitle_st = ic->streams[stream_index];
1676
        packet_queue_init(&is->subtitleq);
1677

    
1678
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1679
        break;
1680
    default:
1681
        break;
1682
    }
1683
    return 0;
1684
}
1685

    
1686
static void stream_component_close(VideoState *is, int stream_index)
1687
{
1688
    AVFormatContext *ic = is->ic;
1689
    AVCodecContext *enc;
1690

    
1691
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1692
        return;
1693
    enc = ic->streams[stream_index]->codec;
1694

    
1695
    switch(enc->codec_type) {
1696
    case CODEC_TYPE_AUDIO:
1697
        packet_queue_abort(&is->audioq);
1698

    
1699
        SDL_CloseAudio();
1700

    
1701
        packet_queue_end(&is->audioq);
1702
        break;
1703
    case CODEC_TYPE_VIDEO:
1704
        packet_queue_abort(&is->videoq);
1705

    
1706
        /* note: we also signal this mutex to make sure we deblock the
1707
           video thread in all cases */
1708
        SDL_LockMutex(is->pictq_mutex);
1709
        SDL_CondSignal(is->pictq_cond);
1710
        SDL_UnlockMutex(is->pictq_mutex);
1711

    
1712
        SDL_WaitThread(is->video_tid, NULL);
1713

    
1714
        packet_queue_end(&is->videoq);
1715
        break;
1716
    case CODEC_TYPE_SUBTITLE:
1717
        packet_queue_abort(&is->subtitleq);
1718

    
1719
        /* note: we also signal this mutex to make sure we deblock the
1720
           video thread in all cases */
1721
        SDL_LockMutex(is->subpq_mutex);
1722
        is->subtitle_stream_changed = 1;
1723

    
1724
        SDL_CondSignal(is->subpq_cond);
1725
        SDL_UnlockMutex(is->subpq_mutex);
1726

    
1727
        SDL_WaitThread(is->subtitle_tid, NULL);
1728

    
1729
        packet_queue_end(&is->subtitleq);
1730
        break;
1731
    default:
1732
        break;
1733
    }
1734

    
1735
    avcodec_close(enc);
1736
    switch(enc->codec_type) {
1737
    case CODEC_TYPE_AUDIO:
1738
        is->audio_st = NULL;
1739
        is->audio_stream = -1;
1740
        break;
1741
    case CODEC_TYPE_VIDEO:
1742
        is->video_st = NULL;
1743
        is->video_stream = -1;
1744
        break;
1745
    case CODEC_TYPE_SUBTITLE:
1746
        is->subtitle_st = NULL;
1747
        is->subtitle_stream = -1;
1748
        break;
1749
    default:
1750
        break;
1751
    }
1752
}
1753

    
1754
static void dump_stream_info(const AVFormatContext *s)
1755
{
1756
    if (s->track != 0)
1757
        fprintf(stderr, "Track: %d\n", s->track);
1758
    if (s->title[0] != '\0')
1759
        fprintf(stderr, "Title: %s\n", s->title);
1760
    if (s->author[0] != '\0')
1761
        fprintf(stderr, "Author: %s\n", s->author);
1762
    if (s->copyright[0] != '\0')
1763
        fprintf(stderr, "Copyright: %s\n", s->copyright);
1764
    if (s->comment[0] != '\0')
1765
        fprintf(stderr, "Comment: %s\n", s->comment);
1766
    if (s->album[0] != '\0')
1767
        fprintf(stderr, "Album: %s\n", s->album);
1768
    if (s->year != 0)
1769
        fprintf(stderr, "Year: %d\n", s->year);
1770
    if (s->genre[0] != '\0')
1771
        fprintf(stderr, "Genre: %s\n", s->genre);
1772
}
1773

    
1774
/* since we have only one decoding thread, we can use a global
1775
   variable instead of a thread local variable */
1776
static VideoState *global_video_state;
1777

    
1778
static int decode_interrupt_cb(void)
1779
{
1780
    return (global_video_state && global_video_state->abort_request);
1781
}
1782

    
1783
/* this thread gets the stream from the disk or the network */
1784
static int decode_thread(void *arg)
1785
{
1786
    VideoState *is = arg;
1787
    AVFormatContext *ic;
1788
    int err, i, ret, video_index, audio_index, use_play;
1789
    AVPacket pkt1, *pkt = &pkt1;
1790
    AVFormatParameters params, *ap = &params;
1791

    
1792
    video_index = -1;
1793
    audio_index = -1;
1794
    is->video_stream = -1;
1795
    is->audio_stream = -1;
1796
    is->subtitle_stream = -1;
1797

    
1798
    global_video_state = is;
1799
    url_set_interrupt_cb(decode_interrupt_cb);
1800

    
1801
    memset(ap, 0, sizeof(*ap));
1802
    ap->initial_pause = 1; /* we force a pause when starting an RTSP
1803
                              stream */
1804

    
1805
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1806
    if (err < 0) {
1807
        print_error(is->filename, err);
1808
        ret = -1;
1809
        goto fail;
1810
    }
1811
    is->ic = ic;
1812
#ifdef CONFIG_NETWORK
1813
    use_play = (ic->iformat == &rtsp_demuxer);
1814
#else
1815
    use_play = 0;
1816
#endif
1817

    
1818
    if(genpts)
1819
        ic->flags |= AVFMT_FLAG_GENPTS;
1820

    
1821
    if (!use_play) {
1822
        err = av_find_stream_info(ic);
1823
        if (err < 0) {
1824
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1825
            ret = -1;
1826
            goto fail;
1827
        }
1828
        ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
1829
    }
1830

    
1831
    /* if seeking requested, we execute it */
1832
    if (start_time != AV_NOPTS_VALUE) {
1833
        int64_t timestamp;
1834

    
1835
        timestamp = start_time;
1836
        /* add the stream start time */
1837
        if (ic->start_time != AV_NOPTS_VALUE)
1838
            timestamp += ic->start_time;
1839
        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1840
        if (ret < 0) {
1841
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
1842
                    is->filename, (double)timestamp / AV_TIME_BASE);
1843
        }
1844
    }
1845

    
1846
    /* now we can begin to play (RTSP stream only) */
1847
    av_read_play(ic);
1848

    
1849
    if (use_play) {
1850
        err = av_find_stream_info(ic);
1851
        if (err < 0) {
1852
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1853
            ret = -1;
1854
            goto fail;
1855
        }
1856
    }
1857

    
1858
    for(i = 0; i < ic->nb_streams; i++) {
1859
        AVCodecContext *enc = ic->streams[i]->codec;
1860
        switch(enc->codec_type) {
1861
        case CODEC_TYPE_AUDIO:
1862
            if (audio_index < 0 && !audio_disable)
1863
                audio_index = i;
1864
            break;
1865
        case CODEC_TYPE_VIDEO:
1866
            if (video_index < 0 && !video_disable)
1867
                video_index = i;
1868
            break;
1869
        default:
1870
            break;
1871
        }
1872
    }
1873
    if (show_status) {
1874
        dump_format(ic, 0, is->filename, 0);
1875
        dump_stream_info(ic);
1876
    }
1877

    
1878
    /* open the streams */
1879
    if (audio_index >= 0) {
1880
        stream_component_open(is, audio_index);
1881
    }
1882

    
1883
    if (video_index >= 0) {
1884
        stream_component_open(is, video_index);
1885
    } else {
1886
        if (!display_disable)
1887
            is->show_audio = 1;
1888
    }
1889

    
1890
    if (is->video_stream < 0 && is->audio_stream < 0) {
1891
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
1892
        ret = -1;
1893
        goto fail;
1894
    }
1895

    
1896
    for(;;) {
1897
        if (is->abort_request)
1898
            break;
1899
#ifdef CONFIG_NETWORK
1900
        if (is->paused != is->last_paused) {
1901
            is->last_paused = is->paused;
1902
            if (is->paused)
1903
                av_read_pause(ic);
1904
            else
1905
                av_read_play(ic);
1906
        }
1907
        if (is->paused && ic->iformat == &rtsp_demuxer) {
1908
            /* wait 10 ms to avoid trying to get another packet */
1909
            /* XXX: horrible */
1910
            SDL_Delay(10);
1911
            continue;
1912
        }
1913
#endif
1914
        if (is->seek_req) {
1915
            /* XXX: must lock decoder threads */
1916
            SDL_LockMutex(is->video_decoder_mutex);
1917
            SDL_LockMutex(is->audio_decoder_mutex);
1918
            SDL_LockMutex(is->subtitle_decoder_mutex);
1919
            ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags);
1920
            if (ret < 0) {
1921
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
1922
            }else{
1923
                if (is->audio_stream >= 0) {
1924
                    packet_queue_flush(&is->audioq);
1925
                    avcodec_flush_buffers(ic->streams[audio_index]->codec);
1926
                }
1927
                if (is->subtitle_stream >= 0) {
1928
                    packet_queue_flush(&is->subtitleq);
1929
                }
1930
                if (is->video_stream >= 0) {
1931
                    packet_queue_flush(&is->videoq);
1932
                    avcodec_flush_buffers(ic->streams[video_index]->codec);
1933
                }
1934
            }
1935
            SDL_UnlockMutex(is->subtitle_decoder_mutex);
1936
            SDL_UnlockMutex(is->audio_decoder_mutex);
1937
            SDL_UnlockMutex(is->video_decoder_mutex);
1938
            is->seek_req = 0;
1939
        }
1940

    
1941
        /* if the queue are full, no need to read more */
1942
        if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1943
            is->videoq.size > MAX_VIDEOQ_SIZE ||
1944
            is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1945
            url_feof(&ic->pb)) {
1946
            /* wait 10 ms */
1947
            SDL_Delay(10);
1948
            continue;
1949
        }
1950
        ret = av_read_frame(ic, pkt);
1951
        if (ret < 0) {
1952
            if (url_ferror(&ic->pb) == 0) {
1953
                SDL_Delay(100); /* wait for user event */
1954
                continue;
1955
            } else
1956
                break;
1957
        }
1958
        if (pkt->stream_index == is->audio_stream) {
1959
            packet_queue_put(&is->audioq, pkt);
1960
        } else if (pkt->stream_index == is->video_stream) {
1961
            packet_queue_put(&is->videoq, pkt);
1962
        } else if (pkt->stream_index == is->subtitle_stream) {
1963
            packet_queue_put(&is->subtitleq, pkt);
1964
        } else {
1965
            av_free_packet(pkt);
1966
        }
1967
    }
1968
    /* wait until the end */
1969
    while (!is->abort_request) {
1970
        SDL_Delay(100);
1971
    }
1972

    
1973
    ret = 0;
1974
 fail:
1975
    /* disable interrupting */
1976
    global_video_state = NULL;
1977

    
1978
    /* close each stream */
1979
    if (is->audio_stream >= 0)
1980
        stream_component_close(is, is->audio_stream);
1981
    if (is->video_stream >= 0)
1982
        stream_component_close(is, is->video_stream);
1983
    if (is->subtitle_stream >= 0)
1984
        stream_component_close(is, is->subtitle_stream);
1985
    if (is->ic) {
1986
        av_close_input_file(is->ic);
1987
        is->ic = NULL; /* safety */
1988
    }
1989
    url_set_interrupt_cb(NULL);
1990

    
1991
    if (ret != 0) {
1992
        SDL_Event event;
1993

    
1994
        event.type = FF_QUIT_EVENT;
1995
        event.user.data1 = is;
1996
        SDL_PushEvent(&event);
1997
    }
1998
    return 0;
1999
}
2000

    
2001
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2002
{
2003
    VideoState *is;
2004

    
2005
    is = av_mallocz(sizeof(VideoState));
2006
    if (!is)
2007
        return NULL;
2008
    pstrcpy(is->filename, sizeof(is->filename), filename);
2009
    is->iformat = iformat;
2010
    if (screen) {
2011
        is->width = screen->w;
2012
        is->height = screen->h;
2013
    }
2014
    is->ytop = 0;
2015
    is->xleft = 0;
2016

    
2017
    /* start video display */
2018
    is->pictq_mutex = SDL_CreateMutex();
2019
    is->pictq_cond = SDL_CreateCond();
2020

    
2021
    is->subpq_mutex = SDL_CreateMutex();
2022
    is->subpq_cond = SDL_CreateCond();
2023

    
2024
    is->subtitle_decoder_mutex = SDL_CreateMutex();
2025
    is->audio_decoder_mutex = SDL_CreateMutex();
2026
    is->video_decoder_mutex = SDL_CreateMutex();
2027

    
2028
    /* add the refresh timer to draw the picture */
2029
    schedule_refresh(is, 40);
2030

    
2031
    is->av_sync_type = av_sync_type;
2032
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2033
    if (!is->parse_tid) {
2034
        av_free(is);
2035
        return NULL;
2036
    }
2037
    return is;
2038
}
2039

    
2040
static void stream_close(VideoState *is)
2041
{
2042
    VideoPicture *vp;
2043
    int i;
2044
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2045
    is->abort_request = 1;
2046
    SDL_WaitThread(is->parse_tid, NULL);
2047

    
2048
    /* free all pictures */
2049
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2050
        vp = &is->pictq[i];
2051
        if (vp->bmp) {
2052
            SDL_FreeYUVOverlay(vp->bmp);
2053
            vp->bmp = NULL;
2054
        }
2055
    }
2056
    SDL_DestroyMutex(is->pictq_mutex);
2057
    SDL_DestroyCond(is->pictq_cond);
2058
    SDL_DestroyMutex(is->subpq_mutex);
2059
    SDL_DestroyCond(is->subpq_cond);
2060
    SDL_DestroyMutex(is->subtitle_decoder_mutex);
2061
    SDL_DestroyMutex(is->audio_decoder_mutex);
2062
    SDL_DestroyMutex(is->video_decoder_mutex);
2063
}
2064

    
2065
static void stream_cycle_channel(VideoState *is, int codec_type)
2066
{
2067
    AVFormatContext *ic = is->ic;
2068
    int start_index, stream_index;
2069
    AVStream *st;
2070

    
2071
    if (codec_type == CODEC_TYPE_VIDEO)
2072
        start_index = is->video_stream;
2073
    else if (codec_type == CODEC_TYPE_AUDIO)
2074
        start_index = is->audio_stream;
2075
    else
2076
        start_index = is->subtitle_stream;
2077
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2078
        return;
2079
    stream_index = start_index;
2080
    for(;;) {
2081
        if (++stream_index >= is->ic->nb_streams)
2082
        {
2083
            if (codec_type == CODEC_TYPE_SUBTITLE)
2084
            {
2085
                stream_index = -1;
2086
                goto the_end;
2087
            } else
2088
                stream_index = 0;
2089
        }
2090
        if (stream_index == start_index)
2091
            return;
2092
        st = ic->streams[stream_index];
2093
        if (st->codec->codec_type == codec_type) {
2094
            /* check that parameters are OK */
2095
            switch(codec_type) {
2096
            case CODEC_TYPE_AUDIO:
2097
                if (st->codec->sample_rate != 0 &&
2098
                    st->codec->channels != 0)
2099
                    goto the_end;
2100
                break;
2101
            case CODEC_TYPE_VIDEO:
2102
            case CODEC_TYPE_SUBTITLE:
2103
                goto the_end;
2104
            default:
2105
                break;
2106
            }
2107
        }
2108
    }
2109
 the_end:
2110
    stream_component_close(is, start_index);
2111
    stream_component_open(is, stream_index);
2112
}
2113

    
2114

    
2115
static void toggle_full_screen(void)
2116
{
2117
    int w, h, flags;
2118
    is_full_screen = !is_full_screen;
2119
    if (!fs_screen_width) {
2120
        /* use default SDL method */
2121
        SDL_WM_ToggleFullScreen(screen);
2122
    } else {
2123
        /* use the recorded resolution */
2124
        flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
2125
        if (is_full_screen) {
2126
            w = fs_screen_width;
2127
            h = fs_screen_height;
2128
            flags |= SDL_FULLSCREEN;
2129
        } else {
2130
            w = screen_width;
2131
            h = screen_height;
2132
            flags |= SDL_RESIZABLE;
2133
        }
2134
        screen = SDL_SetVideoMode(w, h, 0, flags);
2135
        cur_stream->width = w;
2136
        cur_stream->height = h;
2137
    }
2138
}
2139

    
2140
static void toggle_pause(void)
2141
{
2142
    if (cur_stream)
2143
        stream_pause(cur_stream);
2144
    step = 0;
2145
}
2146

    
2147
static void step_to_next_frame(void)
2148
{
2149
    if (cur_stream) {
2150
        if (cur_stream->paused)
2151
            cur_stream->paused=0;
2152
        cur_stream->video_current_pts = get_video_clock(cur_stream);
2153
    }
2154
    step = 1;
2155
}
2156

    
2157
static void do_exit(void)
2158
{
2159
    if (cur_stream) {
2160
        stream_close(cur_stream);
2161
        cur_stream = NULL;
2162
    }
2163
    if (show_status)
2164
        printf("\n");
2165
    SDL_Quit();
2166
    exit(0);
2167
}
2168

    
2169
static void toggle_audio_display(void)
2170
{
2171
    if (cur_stream) {
2172
        cur_stream->show_audio = !cur_stream->show_audio;
2173
    }
2174
}
2175

    
2176
/* handle an event sent by the GUI */
2177
static void event_loop(void)
2178
{
2179
    SDL_Event event;
2180
    double incr, pos, frac;
2181

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

    
2290
void opt_width(const char *arg)
2291
{
2292
    screen_width = atoi(arg);
2293
}
2294

    
2295
void opt_height(const char *arg)
2296
{
2297
    screen_height = atoi(arg);
2298
}
2299

    
2300
static void opt_format(const char *arg)
2301
{
2302
    file_iformat = av_find_input_format(arg);
2303
    if (!file_iformat) {
2304
        fprintf(stderr, "Unknown input format: %s\n", arg);
2305
        exit(1);
2306
    }
2307
}
2308

    
2309
#ifdef CONFIG_NETWORK
2310
void opt_rtp_tcp(void)
2311
{
2312
    /* only tcp protocol */
2313
    rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
2314
}
2315
#endif
2316

    
2317
void opt_sync(const char *arg)
2318
{
2319
    if (!strcmp(arg, "audio"))
2320
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2321
    else if (!strcmp(arg, "video"))
2322
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2323
    else if (!strcmp(arg, "ext"))
2324
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2325
    else
2326
        show_help();
2327
}
2328

    
2329
void opt_seek(const char *arg)
2330
{
2331
    start_time = parse_date(arg, 1);
2332
}
2333

    
2334
static void opt_debug(const char *arg)
2335
{
2336
    av_log_set_level(99);
2337
    debug = atoi(arg);
2338
}
2339

    
2340
static void opt_vismv(const char *arg)
2341
{
2342
    debug_mv = atoi(arg);
2343
}
2344

    
2345
static void opt_thread_count(const char *arg)
2346
{
2347
    thread_count= atoi(arg);
2348
#if !defined(HAVE_THREADS)
2349
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2350
#endif
2351
}
2352

    
2353
const OptionDef options[] = {
2354
    { "h", 0, {(void*)show_help}, "show help" },
2355
    { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
2356
    { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
2357
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2358
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2359
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2360
    { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2361
    { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2362
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2363
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2364
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2365
    { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2366
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2367
    { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2368
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2369
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2370
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2371
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2372
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2373
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2374
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2375
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)",  "threshold" },
2376
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2377
#ifdef CONFIG_NETWORK
2378
    { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
2379
#endif
2380
    { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2381
    { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2382
    { NULL, },
2383
};
2384

    
2385
void show_help(void)
2386
{
2387
    printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003-2006 Fabrice Bellard, et al.\n"
2388
           "usage: ffplay [options] input_file\n"
2389
           "Simple media player\n");
2390
    printf("\n");
2391
    show_help_options(options, "Main options:\n",
2392
                      OPT_EXPERT, 0);
2393
    show_help_options(options, "\nAdvanced options:\n",
2394
                      OPT_EXPERT, OPT_EXPERT);
2395
    printf("\nWhile playing:\n"
2396
           "q, ESC              quit\n"
2397
           "f                   toggle full screen\n"
2398
           "p, SPC              pause\n"
2399
           "a                   cycle audio channel\n"
2400
           "v                   cycle video channel\n"
2401
           "t                   cycle subtitle channel\n"
2402
           "w                   show audio waves\n"
2403
           "left/right          seek backward/forward 10 seconds\n"
2404
           "down/up             seek backward/forward 1 minute\n"
2405
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2406
           );
2407
    exit(1);
2408
}
2409

    
2410
void parse_arg_file(const char *filename)
2411
{
2412
    if (!strcmp(filename, "-"))
2413
                    filename = "pipe:";
2414
    input_filename = filename;
2415
}
2416

    
2417
/* Called from the main */
2418
int main(int argc, char **argv)
2419
{
2420
    int flags, w, h;
2421

    
2422
    /* register all codecs, demux and protocols */
2423
    av_register_all();
2424

    
2425
    #ifdef CONFIG_OS2
2426
      MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
2427

    
2428
      // Make stdout and stderr unbuffered
2429
      setbuf( stdout, NULL );
2430
      setbuf( stderr, NULL );
2431
    #endif
2432

    
2433
    parse_options(argc, argv, options);
2434

    
2435
    if (!input_filename)
2436
        show_help();
2437

    
2438
    if (display_disable) {
2439
        video_disable = 1;
2440
    }
2441
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2442
#if !defined(__MINGW32__) && !defined(CONFIG_DARWIN)
2443
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 or darwin */
2444
#endif
2445
    if (SDL_Init (flags)) {
2446
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2447
        exit(1);
2448
    }
2449

    
2450
    if (!display_disable) {
2451
#ifdef HAVE_SDL_VIDEO_SIZE
2452
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2453
        fs_screen_width = vi->current_w;
2454
        fs_screen_height = vi->current_h;
2455
#endif
2456
        flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
2457
        if (is_full_screen && fs_screen_width) {
2458
            w = fs_screen_width;
2459
            h = fs_screen_height;
2460
            flags |= SDL_FULLSCREEN;
2461
        } else {
2462
            w = screen_width;
2463
            h = screen_height;
2464
            flags |= SDL_RESIZABLE;
2465
        }
2466
#ifndef CONFIG_DARWIN
2467
        screen = SDL_SetVideoMode(w, h, 0, flags);
2468
#else
2469
        /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
2470
        screen = SDL_SetVideoMode(w, h, 24, flags);
2471
#endif
2472
        if (!screen) {
2473
            fprintf(stderr, "SDL: could not set video mode - exiting\n");
2474
            exit(1);
2475
        }
2476
        SDL_WM_SetCaption("FFplay", "FFplay");
2477
    }
2478

    
2479
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2480
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2481
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2482
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2483

    
2484
    cur_stream = stream_open(input_filename, file_iformat);
2485

    
2486
    event_loop();
2487

    
2488
    /* never returns */
2489

    
2490
    return 0;
2491
}