Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ 5f6cb6eb

History | View | Annotate | Download (78.3 KB)

1 01310af2 Fabrice Bellard
/*
2
 * FFplay : Simple Media Player based on the ffmpeg libraries
3
 * Copyright (c) 2003 Fabrice Bellard
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 01310af2 Fabrice Bellard
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 01310af2 Fabrice Bellard
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 01310af2 Fabrice Bellard
 * 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 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 01310af2 Fabrice Bellard
 */
21 364a9607 Diego Biurrun
22 ba11257e Diego Biurrun
#include "config.h"
23 0f4e8165 Ronald S. Bultje
#include <math.h>
24
#include <limits.h>
25 245976da Diego Biurrun
#include "libavutil/avstring.h"
26
#include "libavformat/avformat.h"
27
#include "libavdevice/avdevice.h"
28
#include "libswscale/swscale.h"
29 5a4476e2 Peter Ross
#include "libavcodec/audioconvert.h"
30 a7e6312b Stefano Sabatini
#include "libavcodec/colorspace.h"
31 e43d7a18 Michael Niedermayer
#include "libavcodec/opt.h"
32 01310af2 Fabrice Bellard
33
#include "cmdutils.h"
34
35
#include <SDL.h>
36
#include <SDL_thread.h>
37
38 2f30a81d Diego Biurrun
#ifdef __MINGW32__
39 31319a8c Fabrice Bellard
#undef main /* We don't want SDL to override our main() */
40
#endif
41
42 c367d067 Michael Niedermayer
#undef exit
43 813338a0 Michael Niedermayer
#undef printf
44
#undef fprintf
45 c367d067 Michael Niedermayer
46 64555bd9 Michael Niedermayer
const char program_name[] = "FFplay";
47 ea9c581f Stefano Sabatini
const int program_birth_year = 2003;
48 4cfac5bc Stefano Sabatini
49 638c9d91 Fabrice Bellard
//#define DEBUG_SYNC
50
51 01310af2 Fabrice Bellard
#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
52 9ebdf3ec Baptiste Coudurier
#define MAX_AUDIOQ_SIZE (20 * 16 * 1024)
53 72ce053b Ian Caulfield
#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
54 01310af2 Fabrice Bellard
55 638c9d91 Fabrice Bellard
/* SDL audio buffer size, in samples. Should be small to have precise
56
   A/V sync as SDL does not have hardware buffer fullness info. */
57
#define SDL_AUDIO_BUFFER_SIZE 1024
58
59
/* no AV sync correction is done if below the AV sync threshold */
60 7e0140cb Michael Niedermayer
#define AV_SYNC_THRESHOLD 0.01
61 638c9d91 Fabrice Bellard
/* no AV correction is done if too big error */
62
#define AV_NOSYNC_THRESHOLD 10.0
63
64
/* maximum audio speed change to get correct sync */
65
#define SAMPLE_CORRECTION_PERCENT_MAX 10
66
67
/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
68
#define AUDIO_DIFF_AVG_NB   20
69
70 01310af2 Fabrice Bellard
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
71
#define SAMPLE_ARRAY_SIZE (2*65536)
72
73 03ae87a3 Luca Abeni
static int sws_flags = SWS_BICUBIC;
74
75 01310af2 Fabrice Bellard
typedef struct PacketQueue {
76
    AVPacketList *first_pkt, *last_pkt;
77
    int nb_packets;
78
    int size;
79
    int abort_request;
80
    SDL_mutex *mutex;
81
    SDL_cond *cond;
82
} PacketQueue;
83
84
#define VIDEO_PICTURE_QUEUE_SIZE 1
85 72ce053b Ian Caulfield
#define SUBPICTURE_QUEUE_SIZE 4
86 01310af2 Fabrice Bellard
87
typedef struct VideoPicture {
88 267e9dfa Michael Niedermayer
    double pts;                                  ///<presentation time stamp for this picture
89 01310af2 Fabrice Bellard
    SDL_Overlay *bmp;
90
    int width, height; /* source height & width */
91
    int allocated;
92
} VideoPicture;
93
94 72ce053b Ian Caulfield
typedef struct SubPicture {
95
    double pts; /* presentation time stamp for this picture */
96
    AVSubtitle sub;
97
} SubPicture;
98
99 01310af2 Fabrice Bellard
enum {
100
    AV_SYNC_AUDIO_MASTER, /* default choice */
101
    AV_SYNC_VIDEO_MASTER,
102 638c9d91 Fabrice Bellard
    AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
103 01310af2 Fabrice Bellard
};
104
105
typedef struct VideoState {
106
    SDL_Thread *parse_tid;
107
    SDL_Thread *video_tid;
108 638c9d91 Fabrice Bellard
    AVInputFormat *iformat;
109 01310af2 Fabrice Bellard
    int no_background;
110
    int abort_request;
111
    int paused;
112 416e3508 Fabrice Bellard
    int last_paused;
113 72ea344b Fabrice Bellard
    int seek_req;
114 3ba1438d Michael Niedermayer
    int seek_flags;
115 72ea344b Fabrice Bellard
    int64_t seek_pos;
116 4ed29207 Michael Niedermayer
    int64_t seek_rel;
117 01310af2 Fabrice Bellard
    AVFormatContext *ic;
118
    int dtg_active_format;
119
120
    int audio_stream;
121 115329f1 Diego Biurrun
122 01310af2 Fabrice Bellard
    int av_sync_type;
123 638c9d91 Fabrice Bellard
    double external_clock; /* external clock base */
124
    int64_t external_clock_time;
125 115329f1 Diego Biurrun
126 638c9d91 Fabrice Bellard
    double audio_clock;
127
    double audio_diff_cum; /* used for AV difference average computation */
128
    double audio_diff_avg_coef;
129
    double audio_diff_threshold;
130
    int audio_diff_avg_count;
131 01310af2 Fabrice Bellard
    AVStream *audio_st;
132
    PacketQueue audioq;
133
    int audio_hw_buf_size;
134
    /* samples output by the codec. we reserve more space for avsync
135
       compensation */
136 5a4476e2 Peter Ross
    DECLARE_ALIGNED(16,uint8_t,audio_buf1[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]);
137
    DECLARE_ALIGNED(16,uint8_t,audio_buf2[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]);
138
    uint8_t *audio_buf;
139 7fea94ce Zdenek Kabelac
    unsigned int audio_buf_size; /* in bytes */
140 01310af2 Fabrice Bellard
    int audio_buf_index; /* in bytes */
141 bea18375 Thilo Borgmann
    AVPacket audio_pkt_temp;
142 01310af2 Fabrice Bellard
    AVPacket audio_pkt;
143 5a4476e2 Peter Ross
    enum SampleFormat audio_src_fmt;
144
    AVAudioConvert *reformat_ctx;
145 115329f1 Diego Biurrun
146 01310af2 Fabrice Bellard
    int show_audio; /* if true, display audio samples */
147
    int16_t sample_array[SAMPLE_ARRAY_SIZE];
148
    int sample_array_index;
149 5e0257e3 Fabrice Bellard
    int last_i_start;
150 115329f1 Diego Biurrun
151 72ce053b Ian Caulfield
    SDL_Thread *subtitle_tid;
152
    int subtitle_stream;
153
    int subtitle_stream_changed;
154
    AVStream *subtitle_st;
155
    PacketQueue subtitleq;
156
    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
157
    int subpq_size, subpq_rindex, subpq_windex;
158
    SDL_mutex *subpq_mutex;
159
    SDL_cond *subpq_cond;
160 115329f1 Diego Biurrun
161 638c9d91 Fabrice Bellard
    double frame_timer;
162
    double frame_last_pts;
163
    double frame_last_delay;
164 115329f1 Diego Biurrun
    double video_clock;                          ///<pts of last decoded frame / predicted pts of next decoded frame
165 01310af2 Fabrice Bellard
    int video_stream;
166
    AVStream *video_st;
167
    PacketQueue videoq;
168 267e9dfa Michael Niedermayer
    double video_current_pts;                    ///<current displayed pts (different from video_clock if frame fifos are used)
169
    int64_t video_current_pts_time;              ///<time (av_gettime) at which we updated video_current_pts - used to have running video pts
170 01310af2 Fabrice Bellard
    VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
171
    int pictq_size, pictq_rindex, pictq_windex;
172
    SDL_mutex *pictq_mutex;
173
    SDL_cond *pictq_cond;
174 3ac56e28 Martin Storsjö
    struct SwsContext *img_convert_ctx;
175 115329f1 Diego Biurrun
176 01310af2 Fabrice Bellard
    //    QETimer *video_timer;
177
    char filename[1024];
178
    int width, height, xleft, ytop;
179
} VideoState;
180
181 358061f6 Diego Pettenò
static void show_help(void);
182 638c9d91 Fabrice Bellard
static int audio_write_get_buf_size(VideoState *is);
183 01310af2 Fabrice Bellard
184
/* options specified by the user */
185
static AVInputFormat *file_iformat;
186
static const char *input_filename;
187
static int fs_screen_width;
188
static int fs_screen_height;
189 fccb19e3 Michael Niedermayer
static int screen_width = 0;
190
static int screen_height = 0;
191 e4b89522 Limin Wang
static int frame_width = 0;
192
static int frame_height = 0;
193
static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
194 01310af2 Fabrice Bellard
static int audio_disable;
195
static int video_disable;
196 a8062103 Michael Niedermayer
static int wanted_audio_stream= 0;
197 4d8243d3 Michael Niedermayer
static int wanted_video_stream= 0;
198 16a59a7b Björn Axelsson
static int wanted_subtitle_stream= -1;
199 94b594c6 Steve L'Homme
static int seek_by_bytes;
200 01310af2 Fabrice Bellard
static int display_disable;
201 1e1a0b18 Baptiste Coudurier
static int show_status = 1;
202 638c9d91 Fabrice Bellard
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
203 72ea344b Fabrice Bellard
static int64_t start_time = AV_NOPTS_VALUE;
204 e26a8335 Wolfgang Hesseler
static int debug = 0;
205 0c9bbaec Wolfgang Hesseler
static int debug_mv = 0;
206 bba04f1e Wolfgang Hesseler
static int step = 0;
207 c62c07d3 Michael Niedermayer
static int thread_count = 1;
208 6387c3e6 Michael Niedermayer
static int workaround_bugs = 1;
209 6fc5b059 Michael Niedermayer
static int fast = 0;
210 30bc6613 Michael Niedermayer
static int genpts = 0;
211 178fcca8 Michael Niedermayer
static int lowres = 0;
212
static int idct = FF_IDCT_AUTO;
213 8c3eba7c Michael Niedermayer
static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
214
static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
215
static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
216 047599a4 Michael Niedermayer
static int error_recognition = FF_ER_CAREFUL;
217 1b51e051 Michael Niedermayer
static int error_concealment = 3;
218 5039185a Michael Niedermayer
static int decoder_reorder_pts= 0;
219 01310af2 Fabrice Bellard
220
/* current context */
221
static int is_full_screen;
222
static VideoState *cur_stream;
223 5e0257e3 Fabrice Bellard
static int64_t audio_callback_time;
224 01310af2 Fabrice Bellard
225 2c676c33 Diego Pettenò
static AVPacket flush_pkt;
226 39c6a118 Michael Niedermayer
227 01310af2 Fabrice Bellard
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
228
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
229 638c9d91 Fabrice Bellard
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
230 01310af2 Fabrice Bellard
231 2c676c33 Diego Pettenò
static SDL_Surface *screen;
232 01310af2 Fabrice Bellard
233
/* packet queue handling */
234
static void packet_queue_init(PacketQueue *q)
235
{
236
    memset(q, 0, sizeof(PacketQueue));
237
    q->mutex = SDL_CreateMutex();
238
    q->cond = SDL_CreateCond();
239
}
240
241 72ea344b Fabrice Bellard
static void packet_queue_flush(PacketQueue *q)
242 01310af2 Fabrice Bellard
{
243
    AVPacketList *pkt, *pkt1;
244
245 687fae2b Ivan Wong
    SDL_LockMutex(q->mutex);
246 01310af2 Fabrice Bellard
    for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
247
        pkt1 = pkt->next;
248
        av_free_packet(&pkt->pkt);
249 da6c4573 Michael Niedermayer
        av_freep(&pkt);
250 01310af2 Fabrice Bellard
    }
251 72ea344b Fabrice Bellard
    q->last_pkt = NULL;
252
    q->first_pkt = NULL;
253
    q->nb_packets = 0;
254
    q->size = 0;
255 687fae2b Ivan Wong
    SDL_UnlockMutex(q->mutex);
256 72ea344b Fabrice Bellard
}
257
258
static void packet_queue_end(PacketQueue *q)
259
{
260
    packet_queue_flush(q);
261 01310af2 Fabrice Bellard
    SDL_DestroyMutex(q->mutex);
262
    SDL_DestroyCond(q->cond);
263
}
264
265
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
266
{
267
    AVPacketList *pkt1;
268
269 72ea344b Fabrice Bellard
    /* duplicate the packet */
270 39c6a118 Michael Niedermayer
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
271 72ea344b Fabrice Bellard
        return -1;
272 115329f1 Diego Biurrun
273 01310af2 Fabrice Bellard
    pkt1 = av_malloc(sizeof(AVPacketList));
274
    if (!pkt1)
275
        return -1;
276
    pkt1->pkt = *pkt;
277
    pkt1->next = NULL;
278
279 72ea344b Fabrice Bellard
280 01310af2 Fabrice Bellard
    SDL_LockMutex(q->mutex);
281
282
    if (!q->last_pkt)
283
284
        q->first_pkt = pkt1;
285
    else
286
        q->last_pkt->next = pkt1;
287
    q->last_pkt = pkt1;
288
    q->nb_packets++;
289 7b776589 Aurelien Jacobs
    q->size += pkt1->pkt.size + sizeof(*pkt1);
290 01310af2 Fabrice Bellard
    /* XXX: should duplicate packet data in DV case */
291
    SDL_CondSignal(q->cond);
292
293
    SDL_UnlockMutex(q->mutex);
294
    return 0;
295
}
296
297
static void packet_queue_abort(PacketQueue *q)
298
{
299
    SDL_LockMutex(q->mutex);
300
301
    q->abort_request = 1;
302 115329f1 Diego Biurrun
303 01310af2 Fabrice Bellard
    SDL_CondSignal(q->cond);
304
305
    SDL_UnlockMutex(q->mutex);
306
}
307
308
/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
309
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
310
{
311
    AVPacketList *pkt1;
312
    int ret;
313
314
    SDL_LockMutex(q->mutex);
315
316
    for(;;) {
317
        if (q->abort_request) {
318
            ret = -1;
319
            break;
320
        }
321 115329f1 Diego Biurrun
322 01310af2 Fabrice Bellard
        pkt1 = q->first_pkt;
323
        if (pkt1) {
324
            q->first_pkt = pkt1->next;
325
            if (!q->first_pkt)
326
                q->last_pkt = NULL;
327
            q->nb_packets--;
328 7b776589 Aurelien Jacobs
            q->size -= pkt1->pkt.size + sizeof(*pkt1);
329 01310af2 Fabrice Bellard
            *pkt = pkt1->pkt;
330
            av_free(pkt1);
331
            ret = 1;
332
            break;
333
        } else if (!block) {
334
            ret = 0;
335
            break;
336
        } else {
337
            SDL_CondWait(q->cond, q->mutex);
338
        }
339
    }
340
    SDL_UnlockMutex(q->mutex);
341
    return ret;
342
}
343
344 115329f1 Diego Biurrun
static inline void fill_rectangle(SDL_Surface *screen,
345 01310af2 Fabrice Bellard
                                  int x, int y, int w, int h, int color)
346
{
347
    SDL_Rect rect;
348
    rect.x = x;
349
    rect.y = y;
350
    rect.w = w;
351
    rect.h = h;
352
    SDL_FillRect(screen, &rect, color);
353
}
354
355
#if 0
356
/* draw only the border of a rectangle */
357
void fill_border(VideoState *s, int x, int y, int w, int h, int color)
358
{
359
    int w1, w2, h1, h2;
360

361
    /* fill the background */
362
    w1 = x;
363
    if (w1 < 0)
364
        w1 = 0;
365
    w2 = s->width - (x + w);
366
    if (w2 < 0)
367
        w2 = 0;
368
    h1 = y;
369
    if (h1 < 0)
370
        h1 = 0;
371
    h2 = s->height - (y + h);
372
    if (h2 < 0)
373
        h2 = 0;
374 115329f1 Diego Biurrun
    fill_rectangle(screen,
375
                   s->xleft, s->ytop,
376
                   w1, s->height,
377 01310af2 Fabrice Bellard
                   color);
378 115329f1 Diego Biurrun
    fill_rectangle(screen,
379
                   s->xleft + s->width - w2, s->ytop,
380
                   w2, s->height,
381 01310af2 Fabrice Bellard
                   color);
382 115329f1 Diego Biurrun
    fill_rectangle(screen,
383
                   s->xleft + w1, s->ytop,
384
                   s->width - w1 - w2, h1,
385 01310af2 Fabrice Bellard
                   color);
386 115329f1 Diego Biurrun
    fill_rectangle(screen,
387 01310af2 Fabrice Bellard
                   s->xleft + w1, s->ytop + s->height - h2,
388
                   s->width - w1 - w2, h2,
389
                   color);
390
}
391
#endif
392
393 72ce053b Ian Caulfield
#define ALPHA_BLEND(a, oldp, newp, s)\
394
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
395
396
#define RGBA_IN(r, g, b, a, s)\
397
{\
398
    unsigned int v = ((const uint32_t *)(s))[0];\
399
    a = (v >> 24) & 0xff;\
400
    r = (v >> 16) & 0xff;\
401
    g = (v >> 8) & 0xff;\
402
    b = v & 0xff;\
403
}
404
405
#define YUVA_IN(y, u, v, a, s, pal)\
406
{\
407 57cf99f2 Reimar Döffinger
    unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
408 72ce053b Ian Caulfield
    a = (val >> 24) & 0xff;\
409
    y = (val >> 16) & 0xff;\
410
    u = (val >> 8) & 0xff;\
411
    v = val & 0xff;\
412
}
413
414
#define YUVA_OUT(d, y, u, v, a)\
415
{\
416
    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
417
}
418
419
420
#define BPP 1
421
422 0a8cd696 Reimar Döffinger
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
423 72ce053b Ian Caulfield
{
424
    int wrap, wrap3, width2, skip2;
425
    int y, u, v, a, u1, v1, a1, w, h;
426
    uint8_t *lum, *cb, *cr;
427
    const uint8_t *p;
428
    const uint32_t *pal;
429 9cb5a11e Reimar Döffinger
    int dstx, dsty, dstw, dsth;
430
431 7cf9c6ae Michael Niedermayer
    dstw = av_clip(rect->w, 0, imgw);
432
    dsth = av_clip(rect->h, 0, imgh);
433
    dstx = av_clip(rect->x, 0, imgw - dstw);
434
    dsty = av_clip(rect->y, 0, imgh - dsth);
435 9cb5a11e Reimar Döffinger
    lum = dst->data[0] + dsty * dst->linesize[0];
436
    cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
437
    cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
438
439 f54b31b9 Björn Axelsson
    width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
440 9cb5a11e Reimar Döffinger
    skip2 = dstx >> 1;
441 72ce053b Ian Caulfield
    wrap = dst->linesize[0];
442 25b4c651 Michael Niedermayer
    wrap3 = rect->pict.linesize[0];
443
    p = rect->pict.data[0];
444
    pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
445 115329f1 Diego Biurrun
446 9cb5a11e Reimar Döffinger
    if (dsty & 1) {
447
        lum += dstx;
448 72ce053b Ian Caulfield
        cb += skip2;
449
        cr += skip2;
450 115329f1 Diego Biurrun
451 9cb5a11e Reimar Döffinger
        if (dstx & 1) {
452 72ce053b Ian Caulfield
            YUVA_IN(y, u, v, a, p, pal);
453
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
454
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
455
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
456
            cb++;
457
            cr++;
458
            lum++;
459
            p += BPP;
460
        }
461 9cb5a11e Reimar Döffinger
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
462 72ce053b Ian Caulfield
            YUVA_IN(y, u, v, a, p, pal);
463
            u1 = u;
464
            v1 = v;
465
            a1 = a;
466
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
467
468
            YUVA_IN(y, u, v, a, p + BPP, pal);
469
            u1 += u;
470
            v1 += v;
471
            a1 += a;
472
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
473
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
474
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
475
            cb++;
476
            cr++;
477
            p += 2 * BPP;
478
            lum += 2;
479
        }
480
        if (w) {
481
            YUVA_IN(y, u, v, a, p, pal);
482
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
483
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
484
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
485 676ef505 Björn Axelsson
            p++;
486
            lum++;
487 72ce053b Ian Caulfield
        }
488 4606a059 Björn Axelsson
        p += wrap3 - dstw * BPP;
489
        lum += wrap - dstw - dstx;
490 72ce053b Ian Caulfield
        cb += dst->linesize[1] - width2 - skip2;
491
        cr += dst->linesize[2] - width2 - skip2;
492
    }
493 9cb5a11e Reimar Döffinger
    for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
494
        lum += dstx;
495 72ce053b Ian Caulfield
        cb += skip2;
496
        cr += skip2;
497 115329f1 Diego Biurrun
498 9cb5a11e Reimar Döffinger
        if (dstx & 1) {
499 72ce053b Ian Caulfield
            YUVA_IN(y, u, v, a, p, pal);
500
            u1 = u;
501
            v1 = v;
502
            a1 = a;
503
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
504
            p += wrap3;
505
            lum += wrap;
506
            YUVA_IN(y, u, v, a, p, pal);
507
            u1 += u;
508
            v1 += v;
509
            a1 += a;
510
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
511
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
512
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
513
            cb++;
514
            cr++;
515
            p += -wrap3 + BPP;
516
            lum += -wrap + 1;
517
        }
518 9cb5a11e Reimar Döffinger
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
519 72ce053b Ian Caulfield
            YUVA_IN(y, u, v, a, p, pal);
520
            u1 = u;
521
            v1 = v;
522
            a1 = a;
523
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
524
525 f8ca63e8 Björn Axelsson
            YUVA_IN(y, u, v, a, p + BPP, pal);
526 72ce053b Ian Caulfield
            u1 += u;
527
            v1 += v;
528
            a1 += a;
529
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
530
            p += wrap3;
531
            lum += wrap;
532
533
            YUVA_IN(y, u, v, a, p, pal);
534
            u1 += u;
535
            v1 += v;
536
            a1 += a;
537
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
538
539 f8ca63e8 Björn Axelsson
            YUVA_IN(y, u, v, a, p + BPP, pal);
540 72ce053b Ian Caulfield
            u1 += u;
541
            v1 += v;
542
            a1 += a;
543
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
544
545
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
546
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
547
548
            cb++;
549
            cr++;
550
            p += -wrap3 + 2 * BPP;
551
            lum += -wrap + 2;
552
        }
553
        if (w) {
554
            YUVA_IN(y, u, v, a, p, pal);
555
            u1 = u;
556
            v1 = v;
557
            a1 = a;
558
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
559
            p += wrap3;
560
            lum += wrap;
561
            YUVA_IN(y, u, v, a, p, pal);
562
            u1 += u;
563
            v1 += v;
564
            a1 += a;
565
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
566
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
567
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
568
            cb++;
569
            cr++;
570
            p += -wrap3 + BPP;
571
            lum += -wrap + 1;
572
        }
573 9cb5a11e Reimar Döffinger
        p += wrap3 + (wrap3 - dstw * BPP);
574
        lum += wrap + (wrap - dstw - dstx);
575 72ce053b Ian Caulfield
        cb += dst->linesize[1] - width2 - skip2;
576
        cr += dst->linesize[2] - width2 - skip2;
577
    }
578
    /* handle odd height */
579
    if (h) {
580 9cb5a11e Reimar Döffinger
        lum += dstx;
581 72ce053b Ian Caulfield
        cb += skip2;
582
        cr += skip2;
583 115329f1 Diego Biurrun
584 9cb5a11e Reimar Döffinger
        if (dstx & 1) {
585 72ce053b Ian Caulfield
            YUVA_IN(y, u, v, a, p, pal);
586
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
587
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
588
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
589
            cb++;
590
            cr++;
591
            lum++;
592
            p += BPP;
593
        }
594 9cb5a11e Reimar Döffinger
        for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
595 72ce053b Ian Caulfield
            YUVA_IN(y, u, v, a, p, pal);
596
            u1 = u;
597
            v1 = v;
598
            a1 = a;
599
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
600
601
            YUVA_IN(y, u, v, a, p + BPP, pal);
602
            u1 += u;
603
            v1 += v;
604
            a1 += a;
605
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
606
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
607
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
608
            cb++;
609
            cr++;
610
            p += 2 * BPP;
611
            lum += 2;
612
        }
613
        if (w) {
614
            YUVA_IN(y, u, v, a, p, pal);
615
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
616
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
617
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
618
        }
619
    }
620
}
621
622
static void free_subpicture(SubPicture *sp)
623
{
624
    int i;
625 115329f1 Diego Biurrun
626 72ce053b Ian Caulfield
    for (i = 0; i < sp->sub.num_rects; i++)
627
    {
628 25b4c651 Michael Niedermayer
        av_freep(&sp->sub.rects[i]->pict.data[0]);
629
        av_freep(&sp->sub.rects[i]->pict.data[1]);
630 db4fac64 Michael Niedermayer
        av_freep(&sp->sub.rects[i]);
631 72ce053b Ian Caulfield
    }
632 115329f1 Diego Biurrun
633 72ce053b Ian Caulfield
    av_free(sp->sub.rects);
634 115329f1 Diego Biurrun
635 72ce053b Ian Caulfield
    memset(&sp->sub, 0, sizeof(AVSubtitle));
636
}
637
638 01310af2 Fabrice Bellard
static void video_image_display(VideoState *is)
639
{
640
    VideoPicture *vp;
641 72ce053b Ian Caulfield
    SubPicture *sp;
642
    AVPicture pict;
643 01310af2 Fabrice Bellard
    float aspect_ratio;
644
    int width, height, x, y;
645
    SDL_Rect rect;
646 72ce053b Ian Caulfield
    int i;
647 01310af2 Fabrice Bellard
648
    vp = &is->pictq[is->pictq_rindex];
649
    if (vp->bmp) {
650
        /* XXX: use variable in the frame */
651 c30a4489 Aurelien Jacobs
        if (is->video_st->sample_aspect_ratio.num)
652
            aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
653
        else if (is->video_st->codec->sample_aspect_ratio.num)
654
            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
655 72ea344b Fabrice Bellard
        else
656 c30a4489 Aurelien Jacobs
            aspect_ratio = 0;
657 01310af2 Fabrice Bellard
        if (aspect_ratio <= 0.0)
658 c30a4489 Aurelien Jacobs
            aspect_ratio = 1.0;
659
        aspect_ratio *= (float)is->video_st->codec->width / is->video_st->codec->height;
660 01310af2 Fabrice Bellard
        /* if an active format is indicated, then it overrides the
661
           mpeg format */
662
#if 0
663 01f4895c Michael Niedermayer
        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 01310af2 Fabrice Bellard
            printf("dtg_active_format=%d\n", is->dtg_active_format);
666
        }
667
#endif
668
#if 0
669 01f4895c Michael Niedermayer
        switch(is->video_st->codec->dtg_active_format) {
670 01310af2 Fabrice Bellard
        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 72ce053b Ian Caulfield
        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 db4fac64 Michael Niedermayer
                        blend_subrect(&pict, sp->sub.rects[i],
715 0a8cd696 Reimar Döffinger
                                      vp->bmp->w, vp->bmp->h);
716 72ce053b Ian Caulfield
717
                    SDL_UnlockYUVOverlay (vp->bmp);
718
                }
719
            }
720
        }
721
722
723 01310af2 Fabrice Bellard
        /* XXX: we suppose the screen has a 1.0 pixel ratio */
724
        height = is->height;
725 bb6c34e5 Michael Niedermayer
        width = ((int)rint(height * aspect_ratio)) & ~1;
726 01310af2 Fabrice Bellard
        if (width > is->width) {
727
            width = is->width;
728 bb6c34e5 Michael Niedermayer
            height = ((int)rint(width / aspect_ratio)) & ~1;
729 01310af2 Fabrice Bellard
        }
730
        x = (is->width - width) / 2;
731
        y = (is->height - height) / 2;
732
        if (!is->no_background) {
733
            /* fill the background */
734
            //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
735
        } else {
736
            is->no_background = 0;
737
        }
738
        rect.x = is->xleft + x;
739 2f6547fb Baptiste Coudurier
        rect.y = is->ytop  + y;
740 01310af2 Fabrice Bellard
        rect.w = width;
741
        rect.h = height;
742
        SDL_DisplayYUVOverlay(vp->bmp, &rect);
743
    } else {
744
#if 0
745 115329f1 Diego Biurrun
        fill_rectangle(screen,
746
                       is->xleft, is->ytop, is->width, is->height,
747 01310af2 Fabrice Bellard
                       QERGB(0x00, 0x00, 0x00));
748
#endif
749
    }
750
}
751
752
static inline int compute_mod(int a, int b)
753
{
754
    a = a % b;
755 115329f1 Diego Biurrun
    if (a >= 0)
756 01310af2 Fabrice Bellard
        return a;
757
    else
758
        return a + b;
759
}
760
761
static void video_audio_display(VideoState *s)
762
{
763
    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
764
    int ch, channels, h, h2, bgcolor, fgcolor;
765
    int16_t time_diff;
766 115329f1 Diego Biurrun
767 01310af2 Fabrice Bellard
    /* compute display index : center on currently output samples */
768 01f4895c Michael Niedermayer
    channels = s->audio_st->codec->channels;
769 01310af2 Fabrice Bellard
    nb_display_channels = channels;
770 5e0257e3 Fabrice Bellard
    if (!s->paused) {
771
        n = 2 * channels;
772
        delay = audio_write_get_buf_size(s);
773
        delay /= n;
774 115329f1 Diego Biurrun
775 5e0257e3 Fabrice Bellard
        /* to be more precise, we take into account the time spent since
776
           the last buffer computation */
777
        if (audio_callback_time) {
778
            time_diff = av_gettime() - audio_callback_time;
779 01f4895c Michael Niedermayer
            delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
780 5e0257e3 Fabrice Bellard
        }
781 115329f1 Diego Biurrun
782 5e0257e3 Fabrice Bellard
        delay -= s->width / 2;
783
        if (delay < s->width)
784
            delay = s->width;
785 ac50bcc8 Michael Niedermayer
786
        i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
787
788
        h= INT_MIN;
789
        for(i=0; i<1000; i+=channels){
790
            int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
791
            int a= s->sample_array[idx];
792
            int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
793
            int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
794
            int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
795
            int score= a-d;
796
            if(h<score && (b^c)<0){
797
                h= score;
798
                i_start= idx;
799
            }
800
        }
801
802 5e0257e3 Fabrice Bellard
        s->last_i_start = i_start;
803
    } else {
804
        i_start = s->last_i_start;
805 01310af2 Fabrice Bellard
    }
806
807
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
808 115329f1 Diego Biurrun
    fill_rectangle(screen,
809
                   s->xleft, s->ytop, s->width, s->height,
810 01310af2 Fabrice Bellard
                   bgcolor);
811
812
    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
813
814
    /* total height for one channel */
815
    h = s->height / nb_display_channels;
816
    /* graph height / 2 */
817
    h2 = (h * 9) / 20;
818
    for(ch = 0;ch < nb_display_channels; ch++) {
819
        i = i_start + ch;
820
        y1 = s->ytop + ch * h + (h / 2); /* position of center line */
821
        for(x = 0; x < s->width; x++) {
822
            y = (s->sample_array[i] * h2) >> 15;
823
            if (y < 0) {
824
                y = -y;
825
                ys = y1 - y;
826
            } else {
827
                ys = y1;
828
            }
829 115329f1 Diego Biurrun
            fill_rectangle(screen,
830
                           s->xleft + x, ys, 1, y,
831 01310af2 Fabrice Bellard
                           fgcolor);
832
            i += channels;
833
            if (i >= SAMPLE_ARRAY_SIZE)
834
                i -= SAMPLE_ARRAY_SIZE;
835
        }
836
    }
837
838
    fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
839
840
    for(ch = 1;ch < nb_display_channels; ch++) {
841
        y = s->ytop + ch * h;
842 115329f1 Diego Biurrun
        fill_rectangle(screen,
843
                       s->xleft, y, s->width, 1,
844 01310af2 Fabrice Bellard
                       fgcolor);
845
    }
846
    SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
847
}
848
849 990c8438 Michael Niedermayer
static int video_open(VideoState *is){
850
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
851
    int w,h;
852
853 fb84155b Michael Niedermayer
    if(is_full_screen) flags |= SDL_FULLSCREEN;
854
    else               flags |= SDL_RESIZABLE;
855
856 990c8438 Michael Niedermayer
    if (is_full_screen && fs_screen_width) {
857
        w = fs_screen_width;
858
        h = fs_screen_height;
859 fb84155b Michael Niedermayer
    } else if(!is_full_screen && screen_width){
860
        w = screen_width;
861
        h = screen_height;
862
    }else if (is->video_st && is->video_st->codec->width){
863
        w = is->video_st->codec->width;
864
        h = is->video_st->codec->height;
865 990c8438 Michael Niedermayer
    } else {
866 fb84155b Michael Niedermayer
        w = 640;
867
        h = 480;
868 990c8438 Michael Niedermayer
    }
869 c97f5402 Diego Biurrun
#ifndef __APPLE__
870 990c8438 Michael Niedermayer
    screen = SDL_SetVideoMode(w, h, 0, flags);
871
#else
872
    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
873
    screen = SDL_SetVideoMode(w, h, 24, flags);
874
#endif
875
    if (!screen) {
876
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
877
        return -1;
878
    }
879
    SDL_WM_SetCaption("FFplay", "FFplay");
880
881
    is->width = screen->w;
882
    is->height = screen->h;
883
884
    return 0;
885
}
886 8c982c5d Michael Niedermayer
887 01310af2 Fabrice Bellard
/* display the current picture, if any */
888
static void video_display(VideoState *is)
889
{
890 8c982c5d Michael Niedermayer
    if(!screen)
891
        video_open(cur_stream);
892 115329f1 Diego Biurrun
    if (is->audio_st && is->show_audio)
893 01310af2 Fabrice Bellard
        video_audio_display(is);
894
    else if (is->video_st)
895
        video_image_display(is);
896
}
897
898
static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
899
{
900
    SDL_Event event;
901
    event.type = FF_REFRESH_EVENT;
902
    event.user.data1 = opaque;
903
    SDL_PushEvent(&event);
904
    return 0; /* 0 means stop timer */
905
}
906
907
/* schedule a video refresh in 'delay' ms */
908
static void schedule_refresh(VideoState *is, int delay)
909
{
910 cc1f91d7 Michael Niedermayer
    if(!delay) delay=1; //SDL seems to be buggy when the delay is 0
911 01310af2 Fabrice Bellard
    SDL_AddTimer(delay, sdl_refresh_timer_cb, is);
912
}
913
914 638c9d91 Fabrice Bellard
/* get the current audio clock value */
915
static double get_audio_clock(VideoState *is)
916
{
917
    double pts;
918
    int hw_buf_size, bytes_per_sec;
919
    pts = is->audio_clock;
920
    hw_buf_size = audio_write_get_buf_size(is);
921
    bytes_per_sec = 0;
922
    if (is->audio_st) {
923 115329f1 Diego Biurrun
        bytes_per_sec = is->audio_st->codec->sample_rate *
924 01f4895c Michael Niedermayer
            2 * is->audio_st->codec->channels;
925 638c9d91 Fabrice Bellard
    }
926
    if (bytes_per_sec)
927
        pts -= (double)hw_buf_size / bytes_per_sec;
928
    return pts;
929
}
930
931
/* get the current video clock value */
932
static double get_video_clock(VideoState *is)
933
{
934
    double delta;
935 04108619 Michael Niedermayer
    if (is->paused) {
936 72ea344b Fabrice Bellard
        delta = 0;
937
    } else {
938
        delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
939
    }
940 638c9d91 Fabrice Bellard
    return is->video_current_pts + delta;
941
}
942
943
/* get the current external clock value */
944
static double get_external_clock(VideoState *is)
945
{
946
    int64_t ti;
947
    ti = av_gettime();
948
    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
949
}
950
951
/* get the current master clock value */
952
static double get_master_clock(VideoState *is)
953
{
954
    double val;
955
956 72ea344b Fabrice Bellard
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
957
        if (is->video_st)
958
            val = get_video_clock(is);
959
        else
960
            val = get_audio_clock(is);
961
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
962
        if (is->audio_st)
963
            val = get_audio_clock(is);
964
        else
965
            val = get_video_clock(is);
966
    } else {
967 638c9d91 Fabrice Bellard
        val = get_external_clock(is);
968 72ea344b Fabrice Bellard
    }
969 638c9d91 Fabrice Bellard
    return val;
970
}
971
972 72ea344b Fabrice Bellard
/* seek in the stream */
973 4ed29207 Michael Niedermayer
static void stream_seek(VideoState *is, int64_t pos, int64_t rel)
974 72ea344b Fabrice Bellard
{
975 687fae2b Ivan Wong
    if (!is->seek_req) {
976
        is->seek_pos = pos;
977 4ed29207 Michael Niedermayer
        is->seek_rel = rel;
978 94b594c6 Steve L'Homme
        if (seek_by_bytes)
979
            is->seek_flags |= AVSEEK_FLAG_BYTE;
980 687fae2b Ivan Wong
        is->seek_req = 1;
981
    }
982 72ea344b Fabrice Bellard
}
983
984
/* pause or resume the video */
985
static void stream_pause(VideoState *is)
986
{
987
    is->paused = !is->paused;
988 917fa192 Michael McConnell
    if (!is->paused) {
989 72ea344b Fabrice Bellard
        is->video_current_pts = get_video_clock(is);
990 917fa192 Michael McConnell
        is->frame_timer += (av_gettime() - is->video_current_pts_time) / 1000000.0;
991 72ea344b Fabrice Bellard
    }
992
}
993
994 49410784 Tomer Barletz
static double compute_frame_delay(double frame_current_pts, VideoState *is)
995
{
996
    double actual_delay, delay, sync_threshold, ref_clock, diff;
997
998
    /* compute nominal delay */
999
    delay = frame_current_pts - is->frame_last_pts;
1000
    if (delay <= 0 || delay >= 10.0) {
1001
        /* if incorrect delay, use previous one */
1002
        delay = is->frame_last_delay;
1003 443658fd Tomer Barletz
    } else {
1004 712de377 Benoit Fouet
        is->frame_last_delay = delay;
1005 443658fd Tomer Barletz
    }
1006 49410784 Tomer Barletz
    is->frame_last_pts = frame_current_pts;
1007
1008
    /* update delay to follow master synchronisation source */
1009
    if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
1010
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1011
        /* if video is slave, we try to correct big delays by
1012
           duplicating or deleting a frame */
1013
        ref_clock = get_master_clock(is);
1014
        diff = frame_current_pts - ref_clock;
1015
1016
        /* skip or repeat frame. We take into account the
1017
           delay to compute the threshold. I still don't know
1018
           if it is the best guess */
1019
        sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
1020
        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
1021
            if (diff <= -sync_threshold)
1022
                delay = 0;
1023
            else if (diff >= sync_threshold)
1024
                delay = 2 * delay;
1025
        }
1026
    }
1027
1028
    is->frame_timer += delay;
1029
    /* compute the REAL delay (we need to do that to avoid
1030
       long term errors */
1031
    actual_delay = is->frame_timer - (av_gettime() / 1000000.0);
1032
    if (actual_delay < 0.010) {
1033
        /* XXX: should skip picture */
1034
        actual_delay = 0.010;
1035
    }
1036
1037 eecc17a7 Tomer Barletz
#if defined(DEBUG_SYNC)
1038
    printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
1039
            delay, actual_delay, frame_current_pts, -diff);
1040
#endif
1041
1042 49410784 Tomer Barletz
    return actual_delay;
1043
}
1044
1045 01310af2 Fabrice Bellard
/* called to display each frame */
1046
static void video_refresh_timer(void *opaque)
1047
{
1048
    VideoState *is = opaque;
1049
    VideoPicture *vp;
1050 638c9d91 Fabrice Bellard
1051 72ce053b Ian Caulfield
    SubPicture *sp, *sp2;
1052 01310af2 Fabrice Bellard
1053
    if (is->video_st) {
1054
        if (is->pictq_size == 0) {
1055
            /* if no picture, need to wait */
1056 7e0140cb Michael Niedermayer
            schedule_refresh(is, 1);
1057 01310af2 Fabrice Bellard
        } else {
1058 638c9d91 Fabrice Bellard
            /* dequeue the picture */
1059 01310af2 Fabrice Bellard
            vp = &is->pictq[is->pictq_rindex];
1060 638c9d91 Fabrice Bellard
1061
            /* update current video pts */
1062
            is->video_current_pts = vp->pts;
1063
            is->video_current_pts_time = av_gettime();
1064
1065 01310af2 Fabrice Bellard
            /* launch timer for next picture */
1066 49410784 Tomer Barletz
            schedule_refresh(is, (int)(compute_frame_delay(vp->pts, is) * 1000 + 0.5));
1067 638c9d91 Fabrice Bellard
1068 72ce053b Ian Caulfield
            if(is->subtitle_st) {
1069
                if (is->subtitle_stream_changed) {
1070
                    SDL_LockMutex(is->subpq_mutex);
1071 115329f1 Diego Biurrun
1072 72ce053b Ian Caulfield
                    while (is->subpq_size) {
1073
                        free_subpicture(&is->subpq[is->subpq_rindex]);
1074 115329f1 Diego Biurrun
1075 72ce053b Ian Caulfield
                        /* update queue size and signal for next picture */
1076
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1077
                            is->subpq_rindex = 0;
1078 115329f1 Diego Biurrun
1079 72ce053b Ian Caulfield
                        is->subpq_size--;
1080
                    }
1081
                    is->subtitle_stream_changed = 0;
1082
1083
                    SDL_CondSignal(is->subpq_cond);
1084
                    SDL_UnlockMutex(is->subpq_mutex);
1085
                } else {
1086
                    if (is->subpq_size > 0) {
1087
                        sp = &is->subpq[is->subpq_rindex];
1088
1089
                        if (is->subpq_size > 1)
1090
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
1091
                        else
1092
                            sp2 = NULL;
1093
1094
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
1095
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
1096
                        {
1097
                            free_subpicture(sp);
1098
1099
                            /* update queue size and signal for next picture */
1100
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
1101
                                is->subpq_rindex = 0;
1102
1103
                            SDL_LockMutex(is->subpq_mutex);
1104
                            is->subpq_size--;
1105
                            SDL_CondSignal(is->subpq_cond);
1106
                            SDL_UnlockMutex(is->subpq_mutex);
1107
                        }
1108
                    }
1109
                }
1110
            }
1111
1112 01310af2 Fabrice Bellard
            /* display picture */
1113
            video_display(is);
1114 115329f1 Diego Biurrun
1115 01310af2 Fabrice Bellard
            /* update queue size and signal for next picture */
1116
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
1117
                is->pictq_rindex = 0;
1118 115329f1 Diego Biurrun
1119 01310af2 Fabrice Bellard
            SDL_LockMutex(is->pictq_mutex);
1120
            is->pictq_size--;
1121
            SDL_CondSignal(is->pictq_cond);
1122
            SDL_UnlockMutex(is->pictq_mutex);
1123
        }
1124
    } else if (is->audio_st) {
1125
        /* draw the next audio frame */
1126
1127
        schedule_refresh(is, 40);
1128
1129
        /* if only audio stream, then display the audio bars (better
1130
           than nothing, just to test the implementation */
1131 115329f1 Diego Biurrun
1132 01310af2 Fabrice Bellard
        /* display picture */
1133
        video_display(is);
1134
    } else {
1135
        schedule_refresh(is, 100);
1136
    }
1137
    if (show_status) {
1138
        static int64_t last_time;
1139
        int64_t cur_time;
1140 72ce053b Ian Caulfield
        int aqsize, vqsize, sqsize;
1141 638c9d91 Fabrice Bellard
        double av_diff;
1142 115329f1 Diego Biurrun
1143 01310af2 Fabrice Bellard
        cur_time = av_gettime();
1144 1e1a0b18 Baptiste Coudurier
        if (!last_time || (cur_time - last_time) >= 30000) {
1145 01310af2 Fabrice Bellard
            aqsize = 0;
1146
            vqsize = 0;
1147 72ce053b Ian Caulfield
            sqsize = 0;
1148 01310af2 Fabrice Bellard
            if (is->audio_st)
1149
                aqsize = is->audioq.size;
1150
            if (is->video_st)
1151
                vqsize = is->videoq.size;
1152 72ce053b Ian Caulfield
            if (is->subtitle_st)
1153
                sqsize = is->subtitleq.size;
1154 638c9d91 Fabrice Bellard
            av_diff = 0;
1155
            if (is->audio_st && is->video_st)
1156
                av_diff = get_audio_clock(is) - get_video_clock(is);
1157 115329f1 Diego Biurrun
            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
1158 72ce053b Ian Caulfield
                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
1159 01310af2 Fabrice Bellard
            fflush(stdout);
1160
            last_time = cur_time;
1161
        }
1162
    }
1163
}
1164
1165
/* allocate a picture (needs to do that in main thread to avoid
1166
   potential locking problems */
1167
static void alloc_picture(void *opaque)
1168
{
1169
    VideoState *is = opaque;
1170
    VideoPicture *vp;
1171
1172
    vp = &is->pictq[is->pictq_windex];
1173
1174
    if (vp->bmp)
1175
        SDL_FreeYUVOverlay(vp->bmp);
1176
1177 01f4895c Michael Niedermayer
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
1178
                                   is->video_st->codec->height,
1179 115329f1 Diego Biurrun
                                   SDL_YV12_OVERLAY,
1180 61890b02 Fabrice Bellard
                                   screen);
1181 01f4895c Michael Niedermayer
    vp->width = is->video_st->codec->width;
1182
    vp->height = is->video_st->codec->height;
1183 01310af2 Fabrice Bellard
1184
    SDL_LockMutex(is->pictq_mutex);
1185
    vp->allocated = 1;
1186
    SDL_CondSignal(is->pictq_cond);
1187
    SDL_UnlockMutex(is->pictq_mutex);
1188
}
1189
1190 267e9dfa Michael Niedermayer
/**
1191
 *
1192
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
1193
 */
1194 638c9d91 Fabrice Bellard
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
1195 01310af2 Fabrice Bellard
{
1196
    VideoPicture *vp;
1197
    int dst_pix_fmt;
1198 115329f1 Diego Biurrun
1199 01310af2 Fabrice Bellard
    /* wait until we have space to put a new picture */
1200
    SDL_LockMutex(is->pictq_mutex);
1201
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
1202
           !is->videoq.abort_request) {
1203
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1204
    }
1205
    SDL_UnlockMutex(is->pictq_mutex);
1206 115329f1 Diego Biurrun
1207 01310af2 Fabrice Bellard
    if (is->videoq.abort_request)
1208
        return -1;
1209
1210
    vp = &is->pictq[is->pictq_windex];
1211
1212
    /* alloc or resize hardware picture buffer */
1213 115329f1 Diego Biurrun
    if (!vp->bmp ||
1214 01f4895c Michael Niedermayer
        vp->width != is->video_st->codec->width ||
1215
        vp->height != is->video_st->codec->height) {
1216 01310af2 Fabrice Bellard
        SDL_Event event;
1217
1218
        vp->allocated = 0;
1219
1220
        /* the allocation must be done in the main thread to avoid
1221
           locking problems */
1222
        event.type = FF_ALLOC_EVENT;
1223
        event.user.data1 = is;
1224
        SDL_PushEvent(&event);
1225 115329f1 Diego Biurrun
1226 01310af2 Fabrice Bellard
        /* wait until the picture is allocated */
1227
        SDL_LockMutex(is->pictq_mutex);
1228
        while (!vp->allocated && !is->videoq.abort_request) {
1229
            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
1230
        }
1231
        SDL_UnlockMutex(is->pictq_mutex);
1232
1233
        if (is->videoq.abort_request)
1234
            return -1;
1235
    }
1236
1237 638c9d91 Fabrice Bellard
    /* if the frame is not skipped, then display it */
1238 01310af2 Fabrice Bellard
    if (vp->bmp) {
1239 fbf1b885 avcoder
        AVPicture pict;
1240
1241 01310af2 Fabrice Bellard
        /* get a pointer on the bitmap */
1242
        SDL_LockYUVOverlay (vp->bmp);
1243
1244
        dst_pix_fmt = PIX_FMT_YUV420P;
1245 fbf1b885 avcoder
        memset(&pict,0,sizeof(AVPicture));
1246 01310af2 Fabrice Bellard
        pict.data[0] = vp->bmp->pixels[0];
1247
        pict.data[1] = vp->bmp->pixels[2];
1248
        pict.data[2] = vp->bmp->pixels[1];
1249
1250
        pict.linesize[0] = vp->bmp->pitches[0];
1251
        pict.linesize[1] = vp->bmp->pitches[2];
1252
        pict.linesize[2] = vp->bmp->pitches[1];
1253 e43d7a18 Michael Niedermayer
        sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
1254 3ac56e28 Martin Storsjö
        is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
1255 feb7bc67 Alex Beregszaszi
            is->video_st->codec->width, is->video_st->codec->height,
1256
            is->video_st->codec->pix_fmt,
1257
            is->video_st->codec->width, is->video_st->codec->height,
1258
            dst_pix_fmt, sws_flags, NULL, NULL, NULL);
1259 3ac56e28 Martin Storsjö
        if (is->img_convert_ctx == NULL) {
1260 26ba8235 Alex Beregszaszi
            fprintf(stderr, "Cannot initialize the conversion context\n");
1261
            exit(1);
1262
        }
1263 3ac56e28 Martin Storsjö
        sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
1264 03ae87a3 Luca Abeni
                  0, is->video_st->codec->height, pict.data, pict.linesize);
1265 01310af2 Fabrice Bellard
        /* update the bitmap content */
1266
        SDL_UnlockYUVOverlay(vp->bmp);
1267
1268 638c9d91 Fabrice Bellard
        vp->pts = pts;
1269 01310af2 Fabrice Bellard
1270
        /* now we can update the picture count */
1271
        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
1272
            is->pictq_windex = 0;
1273
        SDL_LockMutex(is->pictq_mutex);
1274
        is->pictq_size++;
1275
        SDL_UnlockMutex(is->pictq_mutex);
1276
    }
1277 638c9d91 Fabrice Bellard
    return 0;
1278
}
1279
1280 115329f1 Diego Biurrun
/**
1281
 * compute the exact PTS for the picture if it is omitted in the stream
1282 267e9dfa Michael Niedermayer
 * @param pts1 the dts of the pkt / pts of the frame
1283
 */
1284 638c9d91 Fabrice Bellard
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
1285
{
1286
    double frame_delay, pts;
1287 115329f1 Diego Biurrun
1288 638c9d91 Fabrice Bellard
    pts = pts1;
1289
1290 01310af2 Fabrice Bellard
    if (pts != 0) {
1291 638c9d91 Fabrice Bellard
        /* update video clock with pts, if present */
1292 01310af2 Fabrice Bellard
        is->video_clock = pts;
1293
    } else {
1294 72ea344b Fabrice Bellard
        pts = is->video_clock;
1295
    }
1296
    /* update video clock for next frame */
1297 01f4895c Michael Niedermayer
    frame_delay = av_q2d(is->video_st->codec->time_base);
1298 72ea344b Fabrice Bellard
    /* for MPEG2, the frame can be repeated, so we update the
1299
       clock accordingly */
1300 267e9dfa Michael Niedermayer
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1301 72ea344b Fabrice Bellard
    is->video_clock += frame_delay;
1302 638c9d91 Fabrice Bellard
1303
#if defined(DEBUG_SYNC) && 0
1304
    {
1305
        int ftype;
1306
        if (src_frame->pict_type == FF_B_TYPE)
1307
            ftype = 'B';
1308
        else if (src_frame->pict_type == FF_I_TYPE)
1309
            ftype = 'I';
1310
        else
1311
            ftype = 'P';
1312 115329f1 Diego Biurrun
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
1313 72ea344b Fabrice Bellard
               ftype, pts, pts1);
1314 638c9d91 Fabrice Bellard
    }
1315
#endif
1316 72ea344b Fabrice Bellard
    return queue_picture(is, src_frame, pts);
1317 01310af2 Fabrice Bellard
}
1318
1319
static int video_thread(void *arg)
1320
{
1321
    VideoState *is = arg;
1322
    AVPacket pkt1, *pkt = &pkt1;
1323 72ea344b Fabrice Bellard
    int len1, got_picture;
1324 c6b1edc9 Michael Niedermayer
    AVFrame *frame= avcodec_alloc_frame();
1325 01310af2 Fabrice Bellard
    double pts;
1326
1327
    for(;;) {
1328
        while (is->paused && !is->videoq.abort_request) {
1329
            SDL_Delay(10);
1330
        }
1331
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
1332
            break;
1333 39c6a118 Michael Niedermayer
1334
        if(pkt->data == flush_pkt.data){
1335
            avcodec_flush_buffers(is->video_st->codec);
1336
            continue;
1337
        }
1338
1339 638c9d91 Fabrice Bellard
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
1340
           this packet, if any */
1341 7fb262b5 Michael Niedermayer
        is->video_st->codec->reordered_opaque= pkt->pts;
1342 bea18375 Thilo Borgmann
        len1 = avcodec_decode_video2(is->video_st->codec,
1343 620e8baf Michael Niedermayer
                                    frame, &got_picture,
1344 bea18375 Thilo Borgmann
                                    pkt);
1345 620e8baf Michael Niedermayer
1346
        if(   (decoder_reorder_pts || pkt->dts == AV_NOPTS_VALUE)
1347 7fb262b5 Michael Niedermayer
           && frame->reordered_opaque != AV_NOPTS_VALUE)
1348
            pts= frame->reordered_opaque;
1349 620e8baf Michael Niedermayer
        else if(pkt->dts != AV_NOPTS_VALUE)
1350
            pts= pkt->dts;
1351
        else
1352
            pts= 0;
1353
        pts *= av_q2d(is->video_st->time_base);
1354 5039185a Michael Niedermayer
1355 fb966f99 Michael Niedermayer
//            if (len1 < 0)
1356
//                break;
1357 620e8baf Michael Niedermayer
        if (got_picture) {
1358
            if (output_picture2(is, frame, pts) < 0)
1359
                goto the_end;
1360
        }
1361 01310af2 Fabrice Bellard
        av_free_packet(pkt);
1362 115329f1 Diego Biurrun
        if (step)
1363 bba04f1e Wolfgang Hesseler
            if (cur_stream)
1364
                stream_pause(cur_stream);
1365 01310af2 Fabrice Bellard
    }
1366
 the_end:
1367 c6b1edc9 Michael Niedermayer
    av_free(frame);
1368 01310af2 Fabrice Bellard
    return 0;
1369
}
1370
1371 72ce053b Ian Caulfield
static int subtitle_thread(void *arg)
1372
{
1373
    VideoState *is = arg;
1374
    SubPicture *sp;
1375
    AVPacket pkt1, *pkt = &pkt1;
1376
    int len1, got_subtitle;
1377
    double pts;
1378
    int i, j;
1379
    int r, g, b, y, u, v, a;
1380
1381
    for(;;) {
1382
        while (is->paused && !is->subtitleq.abort_request) {
1383
            SDL_Delay(10);
1384
        }
1385
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
1386
            break;
1387 115329f1 Diego Biurrun
1388 39c6a118 Michael Niedermayer
        if(pkt->data == flush_pkt.data){
1389
            avcodec_flush_buffers(is->subtitle_st->codec);
1390
            continue;
1391
        }
1392 72ce053b Ian Caulfield
        SDL_LockMutex(is->subpq_mutex);
1393
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
1394
               !is->subtitleq.abort_request) {
1395
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
1396
        }
1397
        SDL_UnlockMutex(is->subpq_mutex);
1398 115329f1 Diego Biurrun
1399 72ce053b Ian Caulfield
        if (is->subtitleq.abort_request)
1400
            goto the_end;
1401 115329f1 Diego Biurrun
1402 72ce053b Ian Caulfield
        sp = &is->subpq[is->subpq_windex];
1403
1404
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
1405
           this packet, if any */
1406
        pts = 0;
1407
        if (pkt->pts != AV_NOPTS_VALUE)
1408
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
1409
1410 bea18375 Thilo Borgmann
        len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
1411 115329f1 Diego Biurrun
                                    &sp->sub, &got_subtitle,
1412 bea18375 Thilo Borgmann
                                    pkt);
1413 72ce053b Ian Caulfield
//            if (len1 < 0)
1414
//                break;
1415
        if (got_subtitle && sp->sub.format == 0) {
1416
            sp->pts = pts;
1417 115329f1 Diego Biurrun
1418 72ce053b Ian Caulfield
            for (i = 0; i < sp->sub.num_rects; i++)
1419
            {
1420 db4fac64 Michael Niedermayer
                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
1421 72ce053b Ian Caulfield
                {
1422 25b4c651 Michael Niedermayer
                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
1423 72ce053b Ian Caulfield
                    y = RGB_TO_Y_CCIR(r, g, b);
1424
                    u = RGB_TO_U_CCIR(r, g, b, 0);
1425
                    v = RGB_TO_V_CCIR(r, g, b, 0);
1426 25b4c651 Michael Niedermayer
                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
1427 72ce053b Ian Caulfield
                }
1428
            }
1429
1430
            /* now we can update the picture count */
1431
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
1432
                is->subpq_windex = 0;
1433
            SDL_LockMutex(is->subpq_mutex);
1434
            is->subpq_size++;
1435
            SDL_UnlockMutex(is->subpq_mutex);
1436
        }
1437
        av_free_packet(pkt);
1438 115329f1 Diego Biurrun
//        if (step)
1439 72ce053b Ian Caulfield
//            if (cur_stream)
1440
//                stream_pause(cur_stream);
1441
    }
1442
 the_end:
1443
    return 0;
1444
}
1445
1446 01310af2 Fabrice Bellard
/* copy samples for viewing in editor window */
1447
static void update_sample_display(VideoState *is, short *samples, int samples_size)
1448
{
1449
    int size, len, channels;
1450
1451 01f4895c Michael Niedermayer
    channels = is->audio_st->codec->channels;
1452 01310af2 Fabrice Bellard
1453
    size = samples_size / sizeof(short);
1454
    while (size > 0) {
1455
        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
1456
        if (len > size)
1457
            len = size;
1458
        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
1459
        samples += len;
1460
        is->sample_array_index += len;
1461
        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
1462
            is->sample_array_index = 0;
1463
        size -= len;
1464
    }
1465
}
1466
1467
/* return the new audio buffer size (samples can be added or deleted
1468
   to get better sync if video or external master clock) */
1469 115329f1 Diego Biurrun
static int synchronize_audio(VideoState *is, short *samples,
1470 638c9d91 Fabrice Bellard
                             int samples_size1, double pts)
1471 01310af2 Fabrice Bellard
{
1472 638c9d91 Fabrice Bellard
    int n, samples_size;
1473 01310af2 Fabrice Bellard
    double ref_clock;
1474 115329f1 Diego Biurrun
1475 01f4895c Michael Niedermayer
    n = 2 * is->audio_st->codec->channels;
1476 638c9d91 Fabrice Bellard
    samples_size = samples_size1;
1477 01310af2 Fabrice Bellard
1478
    /* if not master, then we try to remove or add samples to correct the clock */
1479
    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
1480 638c9d91 Fabrice Bellard
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
1481
        double diff, avg_diff;
1482 01310af2 Fabrice Bellard
        int wanted_size, min_size, max_size, nb_samples;
1483 115329f1 Diego Biurrun
1484 638c9d91 Fabrice Bellard
        ref_clock = get_master_clock(is);
1485
        diff = get_audio_clock(is) - ref_clock;
1486 115329f1 Diego Biurrun
1487 638c9d91 Fabrice Bellard
        if (diff < AV_NOSYNC_THRESHOLD) {
1488
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
1489
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
1490
                /* not enough measures to have a correct estimate */
1491
                is->audio_diff_avg_count++;
1492
            } else {
1493
                /* estimate the A-V difference */
1494
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
1495
1496
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
1497 01f4895c Michael Niedermayer
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
1498 638c9d91 Fabrice Bellard
                    nb_samples = samples_size / n;
1499 115329f1 Diego Biurrun
1500 638c9d91 Fabrice Bellard
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1501
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
1502
                    if (wanted_size < min_size)
1503
                        wanted_size = min_size;
1504
                    else if (wanted_size > max_size)
1505
                        wanted_size = max_size;
1506 115329f1 Diego Biurrun
1507 638c9d91 Fabrice Bellard
                    /* add or remove samples to correction the synchro */
1508
                    if (wanted_size < samples_size) {
1509
                        /* remove samples */
1510
                        samples_size = wanted_size;
1511
                    } else if (wanted_size > samples_size) {
1512
                        uint8_t *samples_end, *q;
1513
                        int nb;
1514 115329f1 Diego Biurrun
1515 638c9d91 Fabrice Bellard
                        /* add samples */
1516
                        nb = (samples_size - wanted_size);
1517
                        samples_end = (uint8_t *)samples + samples_size - n;
1518
                        q = samples_end + n;
1519
                        while (nb > 0) {
1520
                            memcpy(q, samples_end, n);
1521
                            q += n;
1522
                            nb -= n;
1523
                        }
1524
                        samples_size = wanted_size;
1525
                    }
1526
                }
1527
#if 0
1528 115329f1 Diego Biurrun
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
1529
                       diff, avg_diff, samples_size - samples_size1,
1530 638c9d91 Fabrice Bellard
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
1531
#endif
1532 01310af2 Fabrice Bellard
            }
1533 638c9d91 Fabrice Bellard
        } else {
1534
            /* too big difference : may be initial PTS errors, so
1535
               reset A-V filter */
1536
            is->audio_diff_avg_count = 0;
1537
            is->audio_diff_cum = 0;
1538 01310af2 Fabrice Bellard
        }
1539
    }
1540
1541
    return samples_size;
1542
}
1543
1544
/* decode one audio frame and returns its uncompressed size */
1545 5a4476e2 Peter Ross
static int audio_decode_frame(VideoState *is, double *pts_ptr)
1546 01310af2 Fabrice Bellard
{
1547 bea18375 Thilo Borgmann
    AVPacket *pkt_temp = &is->audio_pkt_temp;
1548 01310af2 Fabrice Bellard
    AVPacket *pkt = &is->audio_pkt;
1549 abdff646 Peter Ross
    AVCodecContext *dec= is->audio_st->codec;
1550 72ea344b Fabrice Bellard
    int n, len1, data_size;
1551 01310af2 Fabrice Bellard
    double pts;
1552
1553
    for(;;) {
1554 72ea344b Fabrice Bellard
        /* NOTE: the audio packet can contain several frames */
1555 bea18375 Thilo Borgmann
        while (pkt_temp->size > 0) {
1556 5a4476e2 Peter Ross
            data_size = sizeof(is->audio_buf1);
1557 bea18375 Thilo Borgmann
            len1 = avcodec_decode_audio3(dec,
1558 5a4476e2 Peter Ross
                                        (int16_t *)is->audio_buf1, &data_size,
1559 bea18375 Thilo Borgmann
                                        pkt_temp);
1560 72ea344b Fabrice Bellard
            if (len1 < 0) {
1561
                /* if error, we skip the frame */
1562 bea18375 Thilo Borgmann
                pkt_temp->size = 0;
1563 01310af2 Fabrice Bellard
                break;
1564 72ea344b Fabrice Bellard
            }
1565 115329f1 Diego Biurrun
1566 bea18375 Thilo Borgmann
            pkt_temp->data += len1;
1567
            pkt_temp->size -= len1;
1568 72ea344b Fabrice Bellard
            if (data_size <= 0)
1569
                continue;
1570 5a4476e2 Peter Ross
1571
            if (dec->sample_fmt != is->audio_src_fmt) {
1572
                if (is->reformat_ctx)
1573
                    av_audio_convert_free(is->reformat_ctx);
1574
                is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1,
1575
                                                         dec->sample_fmt, 1, NULL, 0);
1576
                if (!is->reformat_ctx) {
1577
                    fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
1578
                        avcodec_get_sample_fmt_name(dec->sample_fmt),
1579
                        avcodec_get_sample_fmt_name(SAMPLE_FMT_S16));
1580
                        break;
1581
                }
1582
                is->audio_src_fmt= dec->sample_fmt;
1583
            }
1584
1585
            if (is->reformat_ctx) {
1586
                const void *ibuf[6]= {is->audio_buf1};
1587
                void *obuf[6]= {is->audio_buf2};
1588
                int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8};
1589
                int ostride[6]= {2};
1590
                int len= data_size/istride[0];
1591
                if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
1592
                    printf("av_audio_convert() failed\n");
1593
                    break;
1594
                }
1595
                is->audio_buf= is->audio_buf2;
1596
                /* FIXME: existing code assume that data_size equals framesize*channels*2
1597
                          remove this legacy cruft */
1598
                data_size= len*2;
1599
            }else{
1600
                is->audio_buf= is->audio_buf1;
1601
            }
1602
1603 72ea344b Fabrice Bellard
            /* if no pts, then compute it */
1604
            pts = is->audio_clock;
1605
            *pts_ptr = pts;
1606 abdff646 Peter Ross
            n = 2 * dec->channels;
1607 115329f1 Diego Biurrun
            is->audio_clock += (double)data_size /
1608 abdff646 Peter Ross
                (double)(n * dec->sample_rate);
1609 638c9d91 Fabrice Bellard
#if defined(DEBUG_SYNC)
1610 72ea344b Fabrice Bellard
            {
1611
                static double last_clock;
1612
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1613
                       is->audio_clock - last_clock,
1614
                       is->audio_clock, pts);
1615
                last_clock = is->audio_clock;
1616 01310af2 Fabrice Bellard
            }
1617 72ea344b Fabrice Bellard
#endif
1618
            return data_size;
1619 01310af2 Fabrice Bellard
        }
1620
1621 72ea344b Fabrice Bellard
        /* free the current packet */
1622
        if (pkt->data)
1623 01310af2 Fabrice Bellard
            av_free_packet(pkt);
1624 115329f1 Diego Biurrun
1625 72ea344b Fabrice Bellard
        if (is->paused || is->audioq.abort_request) {
1626
            return -1;
1627
        }
1628 115329f1 Diego Biurrun
1629 01310af2 Fabrice Bellard
        /* read next packet */
1630
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1631
            return -1;
1632 39c6a118 Michael Niedermayer
        if(pkt->data == flush_pkt.data){
1633 abdff646 Peter Ross
            avcodec_flush_buffers(dec);
1634 39c6a118 Michael Niedermayer
            continue;
1635
        }
1636
1637 bea18375 Thilo Borgmann
        pkt_temp->data = pkt->data;
1638
        pkt_temp->size = pkt->size;
1639 115329f1 Diego Biurrun
1640 72ea344b Fabrice Bellard
        /* if update the audio clock with the pts */
1641
        if (pkt->pts != AV_NOPTS_VALUE) {
1642 c0df9d75 Michael Niedermayer
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
1643 72ea344b Fabrice Bellard
        }
1644 01310af2 Fabrice Bellard
    }
1645
}
1646
1647 638c9d91 Fabrice Bellard
/* get the current audio output buffer size, in samples. With SDL, we
1648
   cannot have a precise information */
1649
static int audio_write_get_buf_size(VideoState *is)
1650 01310af2 Fabrice Bellard
{
1651 b09b580b Ryan Martell
    return is->audio_buf_size - is->audio_buf_index;
1652 01310af2 Fabrice Bellard
}
1653
1654
1655
/* prepare a new audio buffer */
1656 358061f6 Diego Pettenò
static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
1657 01310af2 Fabrice Bellard
{
1658
    VideoState *is = opaque;
1659
    int audio_size, len1;
1660
    double pts;
1661
1662
    audio_callback_time = av_gettime();
1663 115329f1 Diego Biurrun
1664 01310af2 Fabrice Bellard
    while (len > 0) {
1665
        if (is->audio_buf_index >= is->audio_buf_size) {
1666 5a4476e2 Peter Ross
           audio_size = audio_decode_frame(is, &pts);
1667 01310af2 Fabrice Bellard
           if (audio_size < 0) {
1668
                /* if error, just output silence */
1669 1a1078fa Baptiste Coudurier
               is->audio_buf = is->audio_buf1;
1670 01310af2 Fabrice Bellard
               is->audio_buf_size = 1024;
1671
               memset(is->audio_buf, 0, is->audio_buf_size);
1672
           } else {
1673
               if (is->show_audio)
1674
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1675 115329f1 Diego Biurrun
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1676 01310af2 Fabrice Bellard
                                              pts);
1677
               is->audio_buf_size = audio_size;
1678
           }
1679
           is->audio_buf_index = 0;
1680
        }
1681
        len1 = is->audio_buf_size - is->audio_buf_index;
1682
        if (len1 > len)
1683
            len1 = len;
1684
        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
1685
        len -= len1;
1686
        stream += len1;
1687
        is->audio_buf_index += len1;
1688
    }
1689
}
1690
1691
/* open a given stream. Return 0 if OK */
1692
static int stream_component_open(VideoState *is, int stream_index)
1693
{
1694
    AVFormatContext *ic = is->ic;
1695
    AVCodecContext *enc;
1696
    AVCodec *codec;
1697
    SDL_AudioSpec wanted_spec, spec;
1698
1699
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1700
        return -1;
1701 01f4895c Michael Niedermayer
    enc = ic->streams[stream_index]->codec;
1702 115329f1 Diego Biurrun
1703 01310af2 Fabrice Bellard
    /* prepare audio output */
1704
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1705 51b73087 Justin Ruggles
        if (enc->channels > 0) {
1706
            enc->request_channels = FFMIN(2, enc->channels);
1707 94eadc8b Andreas Öman
        } else {
1708 51b73087 Justin Ruggles
            enc->request_channels = 2;
1709 638c9d91 Fabrice Bellard
        }
1710 01310af2 Fabrice Bellard
    }
1711
1712
    codec = avcodec_find_decoder(enc->codec_id);
1713 13d1512c Michael Niedermayer
    enc->debug_mv = debug_mv;
1714
    enc->debug = debug;
1715 6387c3e6 Michael Niedermayer
    enc->workaround_bugs = workaround_bugs;
1716 178fcca8 Michael Niedermayer
    enc->lowres = lowres;
1717 61846e9a Michael Niedermayer
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
1718 178fcca8 Michael Niedermayer
    enc->idct_algo= idct;
1719 6fc5b059 Michael Niedermayer
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
1720 8c3eba7c Michael Niedermayer
    enc->skip_frame= skip_frame;
1721
    enc->skip_idct= skip_idct;
1722
    enc->skip_loop_filter= skip_loop_filter;
1723 047599a4 Michael Niedermayer
    enc->error_recognition= error_recognition;
1724 1b51e051 Michael Niedermayer
    enc->error_concealment= error_concealment;
1725 e43d7a18 Michael Niedermayer
1726 636f1c4c Stefano Sabatini
    set_context_opts(enc, avcodec_opts[enc->codec_type], 0);
1727 e43d7a18 Michael Niedermayer
1728 01310af2 Fabrice Bellard
    if (!codec ||
1729
        avcodec_open(enc, codec) < 0)
1730
        return -1;
1731 51b73087 Justin Ruggles
1732
    /* prepare audio output */
1733
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1734
        wanted_spec.freq = enc->sample_rate;
1735
        wanted_spec.format = AUDIO_S16SYS;
1736
        wanted_spec.channels = enc->channels;
1737
        wanted_spec.silence = 0;
1738
        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1739
        wanted_spec.callback = sdl_audio_callback;
1740
        wanted_spec.userdata = is;
1741
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
1742
            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
1743
            return -1;
1744
        }
1745
        is->audio_hw_buf_size = spec.size;
1746 5a4476e2 Peter Ross
        is->audio_src_fmt= SAMPLE_FMT_S16;
1747 51b73087 Justin Ruggles
    }
1748
1749 c62c07d3 Michael Niedermayer
    if(thread_count>1)
1750
        avcodec_thread_init(enc, thread_count);
1751
    enc->thread_count= thread_count;
1752 3f3fe38d Ronald S. Bultje
    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
1753 638c9d91 Fabrice Bellard
    switch(enc->codec_type) {
1754 01310af2 Fabrice Bellard
    case CODEC_TYPE_AUDIO:
1755
        is->audio_stream = stream_index;
1756
        is->audio_st = ic->streams[stream_index];
1757
        is->audio_buf_size = 0;
1758
        is->audio_buf_index = 0;
1759 638c9d91 Fabrice Bellard
1760
        /* init averaging filter */
1761
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1762
        is->audio_diff_avg_count = 0;
1763
        /* since we do not have a precise anough audio fifo fullness,
1764
           we correct audio sync only if larger than this threshold */
1765
        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1766
1767 01310af2 Fabrice Bellard
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1768
        packet_queue_init(&is->audioq);
1769 bb270c08 Diego Biurrun
        SDL_PauseAudio(0);
1770 01310af2 Fabrice Bellard
        break;
1771
    case CODEC_TYPE_VIDEO:
1772
        is->video_stream = stream_index;
1773
        is->video_st = ic->streams[stream_index];
1774
1775 638c9d91 Fabrice Bellard
        is->frame_last_delay = 40e-3;
1776
        is->frame_timer = (double)av_gettime() / 1000000.0;
1777
        is->video_current_pts_time = av_gettime();
1778
1779 01310af2 Fabrice Bellard
        packet_queue_init(&is->videoq);
1780
        is->video_tid = SDL_CreateThread(video_thread, is);
1781
        break;
1782 72ce053b Ian Caulfield
    case CODEC_TYPE_SUBTITLE:
1783
        is->subtitle_stream = stream_index;
1784
        is->subtitle_st = ic->streams[stream_index];
1785
        packet_queue_init(&is->subtitleq);
1786 115329f1 Diego Biurrun
1787 72ce053b Ian Caulfield
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
1788
        break;
1789 01310af2 Fabrice Bellard
    default:
1790
        break;
1791
    }
1792
    return 0;
1793
}
1794
1795
static void stream_component_close(VideoState *is, int stream_index)
1796
{
1797
    AVFormatContext *ic = is->ic;
1798
    AVCodecContext *enc;
1799 115329f1 Diego Biurrun
1800 72ce053b Ian Caulfield
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1801
        return;
1802 01f4895c Michael Niedermayer
    enc = ic->streams[stream_index]->codec;
1803 01310af2 Fabrice Bellard
1804
    switch(enc->codec_type) {
1805
    case CODEC_TYPE_AUDIO:
1806
        packet_queue_abort(&is->audioq);
1807
1808
        SDL_CloseAudio();
1809
1810
        packet_queue_end(&is->audioq);
1811 5a4476e2 Peter Ross
        if (is->reformat_ctx)
1812
            av_audio_convert_free(is->reformat_ctx);
1813 01310af2 Fabrice Bellard
        break;
1814
    case CODEC_TYPE_VIDEO:
1815
        packet_queue_abort(&is->videoq);
1816
1817
        /* note: we also signal this mutex to make sure we deblock the
1818
           video thread in all cases */
1819
        SDL_LockMutex(is->pictq_mutex);
1820
        SDL_CondSignal(is->pictq_cond);
1821
        SDL_UnlockMutex(is->pictq_mutex);
1822
1823
        SDL_WaitThread(is->video_tid, NULL);
1824
1825
        packet_queue_end(&is->videoq);
1826
        break;
1827 72ce053b Ian Caulfield
    case CODEC_TYPE_SUBTITLE:
1828
        packet_queue_abort(&is->subtitleq);
1829 115329f1 Diego Biurrun
1830 72ce053b Ian Caulfield
        /* note: we also signal this mutex to make sure we deblock the
1831
           video thread in all cases */
1832
        SDL_LockMutex(is->subpq_mutex);
1833
        is->subtitle_stream_changed = 1;
1834 115329f1 Diego Biurrun
1835 72ce053b Ian Caulfield
        SDL_CondSignal(is->subpq_cond);
1836
        SDL_UnlockMutex(is->subpq_mutex);
1837
1838
        SDL_WaitThread(is->subtitle_tid, NULL);
1839
1840
        packet_queue_end(&is->subtitleq);
1841
        break;
1842 01310af2 Fabrice Bellard
    default:
1843
        break;
1844
    }
1845
1846 3f3fe38d Ronald S. Bultje
    ic->streams[stream_index]->discard = AVDISCARD_ALL;
1847 01310af2 Fabrice Bellard
    avcodec_close(enc);
1848
    switch(enc->codec_type) {
1849
    case CODEC_TYPE_AUDIO:
1850
        is->audio_st = NULL;
1851
        is->audio_stream = -1;
1852
        break;
1853
    case CODEC_TYPE_VIDEO:
1854
        is->video_st = NULL;
1855
        is->video_stream = -1;
1856
        break;
1857 72ce053b Ian Caulfield
    case CODEC_TYPE_SUBTITLE:
1858
        is->subtitle_st = NULL;
1859
        is->subtitle_stream = -1;
1860
        break;
1861 01310af2 Fabrice Bellard
    default:
1862
        break;
1863
    }
1864
}
1865
1866 416e3508 Fabrice Bellard
/* since we have only one decoding thread, we can use a global
1867
   variable instead of a thread local variable */
1868
static VideoState *global_video_state;
1869
1870
static int decode_interrupt_cb(void)
1871
{
1872
    return (global_video_state && global_video_state->abort_request);
1873
}
1874 01310af2 Fabrice Bellard
1875
/* this thread gets the stream from the disk or the network */
1876
static int decode_thread(void *arg)
1877
{
1878
    VideoState *is = arg;
1879
    AVFormatContext *ic;
1880 16a59a7b Björn Axelsson
    int err, i, ret, video_index, audio_index, subtitle_index;
1881 01310af2 Fabrice Bellard
    AVPacket pkt1, *pkt = &pkt1;
1882 61890b02 Fabrice Bellard
    AVFormatParameters params, *ap = &params;
1883 75bb7b0a Michael Niedermayer
    int eof=0;
1884 01310af2 Fabrice Bellard
1885
    video_index = -1;
1886
    audio_index = -1;
1887 16a59a7b Björn Axelsson
    subtitle_index = -1;
1888 01310af2 Fabrice Bellard
    is->video_stream = -1;
1889
    is->audio_stream = -1;
1890 72ce053b Ian Caulfield
    is->subtitle_stream = -1;
1891 01310af2 Fabrice Bellard
1892 416e3508 Fabrice Bellard
    global_video_state = is;
1893
    url_set_interrupt_cb(decode_interrupt_cb);
1894
1895 61890b02 Fabrice Bellard
    memset(ap, 0, sizeof(*ap));
1896 115329f1 Diego Biurrun
1897 e4b89522 Limin Wang
    ap->width = frame_width;
1898
    ap->height= frame_height;
1899 7e042912 Michael Niedermayer
    ap->time_base= (AVRational){1, 25};
1900 e4b89522 Limin Wang
    ap->pix_fmt = frame_pix_fmt;
1901 7e042912 Michael Niedermayer
1902 61890b02 Fabrice Bellard
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1903 638c9d91 Fabrice Bellard
    if (err < 0) {
1904
        print_error(is->filename, err);
1905
        ret = -1;
1906
        goto fail;
1907
    }
1908 01310af2 Fabrice Bellard
    is->ic = ic;
1909 30bc6613 Michael Niedermayer
1910
    if(genpts)
1911
        ic->flags |= AVFMT_FLAG_GENPTS;
1912
1913 24c07998 Luca Abeni
    err = av_find_stream_info(ic);
1914
    if (err < 0) {
1915
        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1916
        ret = -1;
1917
        goto fail;
1918
    }
1919 899681cd Björn Axelsson
    if(ic->pb)
1920
        ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end
1921 72ea344b Fabrice Bellard
1922
    /* if seeking requested, we execute it */
1923
    if (start_time != AV_NOPTS_VALUE) {
1924
        int64_t timestamp;
1925
1926
        timestamp = start_time;
1927
        /* add the stream start time */
1928
        if (ic->start_time != AV_NOPTS_VALUE)
1929
            timestamp += ic->start_time;
1930 4ed29207 Michael Niedermayer
        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
1931 72ea344b Fabrice Bellard
        if (ret < 0) {
1932 115329f1 Diego Biurrun
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
1933 72ea344b Fabrice Bellard
                    is->filename, (double)timestamp / AV_TIME_BASE);
1934
        }
1935
    }
1936
1937 01310af2 Fabrice Bellard
    for(i = 0; i < ic->nb_streams; i++) {
1938 01f4895c Michael Niedermayer
        AVCodecContext *enc = ic->streams[i]->codec;
1939 3f3fe38d Ronald S. Bultje
        ic->streams[i]->discard = AVDISCARD_ALL;
1940 01310af2 Fabrice Bellard
        switch(enc->codec_type) {
1941
        case CODEC_TYPE_AUDIO:
1942 5dbb63fe Stefano Sabatini
            if (wanted_audio_stream-- >= 0 && !audio_disable)
1943 01310af2 Fabrice Bellard
                audio_index = i;
1944
            break;
1945
        case CODEC_TYPE_VIDEO:
1946 5dbb63fe Stefano Sabatini
            if (wanted_video_stream-- >= 0 && !video_disable)
1947 01310af2 Fabrice Bellard
                video_index = i;
1948
            break;
1949 16a59a7b Björn Axelsson
        case CODEC_TYPE_SUBTITLE:
1950 5ad4f0d4 Stefano Sabatini
            if (wanted_subtitle_stream-- >= 0 && !video_disable)
1951 16a59a7b Björn Axelsson
                subtitle_index = i;
1952
            break;
1953 01310af2 Fabrice Bellard
        default:
1954
            break;
1955
        }
1956
    }
1957
    if (show_status) {
1958
        dump_format(ic, 0, is->filename, 0);
1959
    }
1960
1961
    /* open the streams */
1962
    if (audio_index >= 0) {
1963
        stream_component_open(is, audio_index);
1964
    }
1965
1966
    if (video_index >= 0) {
1967
        stream_component_open(is, video_index);
1968
    } else {
1969
        if (!display_disable)
1970
            is->show_audio = 1;
1971
    }
1972
1973 16a59a7b Björn Axelsson
    if (subtitle_index >= 0) {
1974
        stream_component_open(is, subtitle_index);
1975
    }
1976
1977 01310af2 Fabrice Bellard
    if (is->video_stream < 0 && is->audio_stream < 0) {
1978 638c9d91 Fabrice Bellard
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
1979
        ret = -1;
1980 01310af2 Fabrice Bellard
        goto fail;
1981
    }
1982
1983
    for(;;) {
1984
        if (is->abort_request)
1985
            break;
1986 416e3508 Fabrice Bellard
        if (is->paused != is->last_paused) {
1987
            is->last_paused = is->paused;
1988 72ea344b Fabrice Bellard
            if (is->paused)
1989
                av_read_pause(ic);
1990
            else
1991
                av_read_play(ic);
1992 416e3508 Fabrice Bellard
        }
1993 2f642393 Aurelien Jacobs
#if CONFIG_RTSP_DEMUXER
1994
        if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
1995 416e3508 Fabrice Bellard
            /* wait 10 ms to avoid trying to get another packet */
1996
            /* XXX: horrible */
1997
            SDL_Delay(10);
1998
            continue;
1999
        }
2000 400738b1 Michael Niedermayer
#endif
2001 72ea344b Fabrice Bellard
        if (is->seek_req) {
2002 8e606cc8 Michael Niedermayer
            int64_t seek_target= is->seek_pos;
2003 4ed29207 Michael Niedermayer
            int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
2004
            int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
2005
//FIXME the +-2 is due to rounding being not done in the correct direction in generation
2006
//      of the seek_pos/seek_rel variables
2007 8e606cc8 Michael Niedermayer
2008 4ed29207 Michael Niedermayer
            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
2009 72ea344b Fabrice Bellard
            if (ret < 0) {
2010
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
2011 e6c0297f Michael Niedermayer
            }else{
2012
                if (is->audio_stream >= 0) {
2013
                    packet_queue_flush(&is->audioq);
2014 39c6a118 Michael Niedermayer
                    packet_queue_put(&is->audioq, &flush_pkt);
2015 e6c0297f Michael Niedermayer
                }
2016 72ce053b Ian Caulfield
                if (is->subtitle_stream >= 0) {
2017
                    packet_queue_flush(&is->subtitleq);
2018 39c6a118 Michael Niedermayer
                    packet_queue_put(&is->subtitleq, &flush_pkt);
2019 72ce053b Ian Caulfield
                }
2020 e6c0297f Michael Niedermayer
                if (is->video_stream >= 0) {
2021
                    packet_queue_flush(&is->videoq);
2022 39c6a118 Michael Niedermayer
                    packet_queue_put(&is->videoq, &flush_pkt);
2023 e6c0297f Michael Niedermayer
                }
2024 72ea344b Fabrice Bellard
            }
2025
            is->seek_req = 0;
2026 e45aeb38 Michael Niedermayer
            eof= 0;
2027 72ea344b Fabrice Bellard
        }
2028 416e3508 Fabrice Bellard
2029 01310af2 Fabrice Bellard
        /* if the queue are full, no need to read more */
2030
        if (is->audioq.size > MAX_AUDIOQ_SIZE ||
2031 115329f1 Diego Biurrun
            is->videoq.size > MAX_VIDEOQ_SIZE ||
2032 600a331c Michael Niedermayer
            is->subtitleq.size > MAX_SUBTITLEQ_SIZE) {
2033 01310af2 Fabrice Bellard
            /* wait 10 ms */
2034
            SDL_Delay(10);
2035
            continue;
2036
        }
2037 75bb7b0a Michael Niedermayer
        if(url_feof(ic->pb) || eof) {
2038 9dc41767 Michael Niedermayer
            if(is->video_stream >= 0){
2039 26534fe8 Michael Niedermayer
                av_init_packet(pkt);
2040
                pkt->data=NULL;
2041
                pkt->size=0;
2042
                pkt->stream_index= is->video_stream;
2043
                packet_queue_put(&is->videoq, pkt);
2044 9dc41767 Michael Niedermayer
            }
2045 b4083171 Michael Niedermayer
            SDL_Delay(10);
2046 600a331c Michael Niedermayer
            continue;
2047
        }
2048 72ea344b Fabrice Bellard
        ret = av_read_frame(ic, pkt);
2049 01310af2 Fabrice Bellard
        if (ret < 0) {
2050 75bb7b0a Michael Niedermayer
            if (ret == AVERROR_EOF)
2051
                eof=1;
2052
            if (url_ferror(ic->pb))
2053 bb270c08 Diego Biurrun
                break;
2054 75bb7b0a Michael Niedermayer
            SDL_Delay(100); /* wait for user event */
2055
            continue;
2056 01310af2 Fabrice Bellard
        }
2057
        if (pkt->stream_index == is->audio_stream) {
2058
            packet_queue_put(&is->audioq, pkt);
2059
        } else if (pkt->stream_index == is->video_stream) {
2060
            packet_queue_put(&is->videoq, pkt);
2061 72ce053b Ian Caulfield
        } else if (pkt->stream_index == is->subtitle_stream) {
2062
            packet_queue_put(&is->subtitleq, pkt);
2063 01310af2 Fabrice Bellard
        } else {
2064
            av_free_packet(pkt);
2065
        }
2066
    }
2067
    /* wait until the end */
2068
    while (!is->abort_request) {
2069
        SDL_Delay(100);
2070
    }
2071
2072 638c9d91 Fabrice Bellard
    ret = 0;
2073 01310af2 Fabrice Bellard
 fail:
2074 416e3508 Fabrice Bellard
    /* disable interrupting */
2075
    global_video_state = NULL;
2076
2077 01310af2 Fabrice Bellard
    /* close each stream */
2078
    if (is->audio_stream >= 0)
2079
        stream_component_close(is, is->audio_stream);
2080
    if (is->video_stream >= 0)
2081
        stream_component_close(is, is->video_stream);
2082 72ce053b Ian Caulfield
    if (is->subtitle_stream >= 0)
2083
        stream_component_close(is, is->subtitle_stream);
2084 638c9d91 Fabrice Bellard
    if (is->ic) {
2085
        av_close_input_file(is->ic);
2086
        is->ic = NULL; /* safety */
2087
    }
2088 416e3508 Fabrice Bellard
    url_set_interrupt_cb(NULL);
2089
2090 638c9d91 Fabrice Bellard
    if (ret != 0) {
2091
        SDL_Event event;
2092 115329f1 Diego Biurrun
2093 638c9d91 Fabrice Bellard
        event.type = FF_QUIT_EVENT;
2094
        event.user.data1 = is;
2095
        SDL_PushEvent(&event);
2096
    }
2097 01310af2 Fabrice Bellard
    return 0;
2098
}
2099
2100 638c9d91 Fabrice Bellard
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
2101 01310af2 Fabrice Bellard
{
2102
    VideoState *is;
2103
2104
    is = av_mallocz(sizeof(VideoState));
2105
    if (!is)
2106
        return NULL;
2107 f7d78f36 Måns Rullgård
    av_strlcpy(is->filename, filename, sizeof(is->filename));
2108 638c9d91 Fabrice Bellard
    is->iformat = iformat;
2109 01310af2 Fabrice Bellard
    is->ytop = 0;
2110
    is->xleft = 0;
2111
2112
    /* start video display */
2113
    is->pictq_mutex = SDL_CreateMutex();
2114
    is->pictq_cond = SDL_CreateCond();
2115 115329f1 Diego Biurrun
2116 72ce053b Ian Caulfield
    is->subpq_mutex = SDL_CreateMutex();
2117
    is->subpq_cond = SDL_CreateCond();
2118 115329f1 Diego Biurrun
2119 01310af2 Fabrice Bellard
    /* add the refresh timer to draw the picture */
2120
    schedule_refresh(is, 40);
2121
2122 638c9d91 Fabrice Bellard
    is->av_sync_type = av_sync_type;
2123 01310af2 Fabrice Bellard
    is->parse_tid = SDL_CreateThread(decode_thread, is);
2124
    if (!is->parse_tid) {
2125
        av_free(is);
2126
        return NULL;
2127
    }
2128
    return is;
2129
}
2130
2131
static void stream_close(VideoState *is)
2132
{
2133
    VideoPicture *vp;
2134
    int i;
2135
    /* XXX: use a special url_shutdown call to abort parse cleanly */
2136
    is->abort_request = 1;
2137
    SDL_WaitThread(is->parse_tid, NULL);
2138
2139
    /* free all pictures */
2140
    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
2141
        vp = &is->pictq[i];
2142
        if (vp->bmp) {
2143
            SDL_FreeYUVOverlay(vp->bmp);
2144
            vp->bmp = NULL;
2145
        }
2146
    }
2147
    SDL_DestroyMutex(is->pictq_mutex);
2148
    SDL_DestroyCond(is->pictq_cond);
2149 72ce053b Ian Caulfield
    SDL_DestroyMutex(is->subpq_mutex);
2150
    SDL_DestroyCond(is->subpq_cond);
2151 3ac56e28 Martin Storsjö
    if (is->img_convert_ctx)
2152
        sws_freeContext(is->img_convert_ctx);
2153 7c5ab145 Martin Storsjö
    av_free(is);
2154 01310af2 Fabrice Bellard
}
2155
2156 7b49ce2e Stefan Huehner
static void stream_cycle_channel(VideoState *is, int codec_type)
2157 638c9d91 Fabrice Bellard
{
2158
    AVFormatContext *ic = is->ic;
2159
    int start_index, stream_index;
2160
    AVStream *st;
2161
2162
    if (codec_type == CODEC_TYPE_VIDEO)
2163
        start_index = is->video_stream;
2164 72ce053b Ian Caulfield
    else if (codec_type == CODEC_TYPE_AUDIO)
2165 638c9d91 Fabrice Bellard
        start_index = is->audio_stream;
2166 72ce053b Ian Caulfield
    else
2167
        start_index = is->subtitle_stream;
2168
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
2169 638c9d91 Fabrice Bellard
        return;
2170
    stream_index = start_index;
2171
    for(;;) {
2172
        if (++stream_index >= is->ic->nb_streams)
2173 72ce053b Ian Caulfield
        {
2174
            if (codec_type == CODEC_TYPE_SUBTITLE)
2175
            {
2176
                stream_index = -1;
2177
                goto the_end;
2178
            } else
2179
                stream_index = 0;
2180
        }
2181 638c9d91 Fabrice Bellard
        if (stream_index == start_index)
2182
            return;
2183
        st = ic->streams[stream_index];
2184 01f4895c Michael Niedermayer
        if (st->codec->codec_type == codec_type) {
2185 638c9d91 Fabrice Bellard
            /* check that parameters are OK */
2186
            switch(codec_type) {
2187
            case CODEC_TYPE_AUDIO:
2188 01f4895c Michael Niedermayer
                if (st->codec->sample_rate != 0 &&
2189
                    st->codec->channels != 0)
2190 638c9d91 Fabrice Bellard
                    goto the_end;
2191
                break;
2192
            case CODEC_TYPE_VIDEO:
2193 72ce053b Ian Caulfield
            case CODEC_TYPE_SUBTITLE:
2194 638c9d91 Fabrice Bellard
                goto the_end;
2195
            default:
2196
                break;
2197
            }
2198
        }
2199
    }
2200
 the_end:
2201
    stream_component_close(is, start_index);
2202
    stream_component_open(is, stream_index);
2203
}
2204
2205
2206 7b49ce2e Stefan Huehner
static void toggle_full_screen(void)
2207 01310af2 Fabrice Bellard
{
2208
    is_full_screen = !is_full_screen;
2209 29f3b38a Måns Rullgård
    if (!fs_screen_width) {
2210
        /* use default SDL method */
2211 fb84155b Michael Niedermayer
//        SDL_WM_ToggleFullScreen(screen);
2212 01310af2 Fabrice Bellard
    }
2213 fb84155b Michael Niedermayer
    video_open(cur_stream);
2214 01310af2 Fabrice Bellard
}
2215
2216 7b49ce2e Stefan Huehner
static void toggle_pause(void)
2217 01310af2 Fabrice Bellard
{
2218
    if (cur_stream)
2219
        stream_pause(cur_stream);
2220 bba04f1e Wolfgang Hesseler
    step = 0;
2221
}
2222
2223 7b49ce2e Stefan Huehner
static void step_to_next_frame(void)
2224 bba04f1e Wolfgang Hesseler
{
2225
    if (cur_stream) {
2226 19cc524a Craig Nicol
        /* if the stream is paused unpause it, then step */
2227 bba04f1e Wolfgang Hesseler
        if (cur_stream->paused)
2228 19cc524a Craig Nicol
            stream_pause(cur_stream);
2229 bba04f1e Wolfgang Hesseler
    }
2230
    step = 1;
2231 01310af2 Fabrice Bellard
}
2232
2233 7b49ce2e Stefan Huehner
static void do_exit(void)
2234 01310af2 Fabrice Bellard
{
2235 7c5ab145 Martin Storsjö
    int i;
2236 01310af2 Fabrice Bellard
    if (cur_stream) {
2237
        stream_close(cur_stream);
2238
        cur_stream = NULL;
2239
    }
2240 7c5ab145 Martin Storsjö
    for (i = 0; i < CODEC_TYPE_NB; i++)
2241
        av_free(avcodec_opts[i]);
2242
    av_free(avformat_opts);
2243
    av_free(sws_opts);
2244 01310af2 Fabrice Bellard
    if (show_status)
2245
        printf("\n");
2246
    SDL_Quit();
2247
    exit(0);
2248
}
2249
2250 7b49ce2e Stefan Huehner
static void toggle_audio_display(void)
2251 01310af2 Fabrice Bellard
{
2252
    if (cur_stream) {
2253
        cur_stream->show_audio = !cur_stream->show_audio;
2254
    }
2255
}
2256
2257
/* handle an event sent by the GUI */
2258 7b49ce2e Stefan Huehner
static void event_loop(void)
2259 01310af2 Fabrice Bellard
{
2260
    SDL_Event event;
2261 a11d11aa Michel Bardiaux
    double incr, pos, frac;
2262 01310af2 Fabrice Bellard
2263
    for(;;) {
2264
        SDL_WaitEvent(&event);
2265
        switch(event.type) {
2266
        case SDL_KEYDOWN:
2267
            switch(event.key.keysym.sym) {
2268
            case SDLK_ESCAPE:
2269
            case SDLK_q:
2270
                do_exit();
2271
                break;
2272
            case SDLK_f:
2273
                toggle_full_screen();
2274
                break;
2275
            case SDLK_p:
2276
            case SDLK_SPACE:
2277
                toggle_pause();
2278
                break;
2279 bba04f1e Wolfgang Hesseler
            case SDLK_s: //S: Step to next frame
2280
                step_to_next_frame();
2281
                break;
2282 01310af2 Fabrice Bellard
            case SDLK_a:
2283 115329f1 Diego Biurrun
                if (cur_stream)
2284 638c9d91 Fabrice Bellard
                    stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
2285
                break;
2286
            case SDLK_v:
2287 115329f1 Diego Biurrun
                if (cur_stream)
2288 638c9d91 Fabrice Bellard
                    stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
2289
                break;
2290 72ce053b Ian Caulfield
            case SDLK_t:
2291 115329f1 Diego Biurrun
                if (cur_stream)
2292 72ce053b Ian Caulfield
                    stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
2293
                break;
2294 638c9d91 Fabrice Bellard
            case SDLK_w:
2295 01310af2 Fabrice Bellard
                toggle_audio_display();
2296
                break;
2297 72ea344b Fabrice Bellard
            case SDLK_LEFT:
2298
                incr = -10.0;
2299
                goto do_seek;
2300
            case SDLK_RIGHT:
2301
                incr = 10.0;
2302
                goto do_seek;
2303
            case SDLK_UP:
2304
                incr = 60.0;
2305
                goto do_seek;
2306
            case SDLK_DOWN:
2307
                incr = -60.0;
2308
            do_seek:
2309
                if (cur_stream) {
2310 94b594c6 Steve L'Homme
                    if (seek_by_bytes) {
2311 899681cd Björn Axelsson
                        pos = url_ftell(cur_stream->ic->pb);
2312 94b594c6 Steve L'Homme
                        if (cur_stream->ic->bit_rate)
2313
                            incr *= cur_stream->ic->bit_rate / 60.0;
2314
                        else
2315
                            incr *= 180000.0;
2316
                        pos += incr;
2317
                        stream_seek(cur_stream, pos, incr);
2318
                    } else {
2319
                        pos = get_master_clock(cur_stream);
2320
                        pos += incr;
2321 4ed29207 Michael Niedermayer
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE));
2322 94b594c6 Steve L'Homme
                    }
2323 72ea344b Fabrice Bellard
                }
2324
                break;
2325 01310af2 Fabrice Bellard
            default:
2326
                break;
2327
            }
2328
            break;
2329 a11d11aa Michel Bardiaux
        case SDL_MOUSEBUTTONDOWN:
2330 bb270c08 Diego Biurrun
            if (cur_stream) {
2331 c2b4c859 Baptiste Coudurier
                int64_t ts;
2332 bb270c08 Diego Biurrun
                int ns, hh, mm, ss;
2333
                int tns, thh, tmm, tss;
2334
                tns = cur_stream->ic->duration/1000000LL;
2335
                thh = tns/3600;
2336
                tmm = (tns%3600)/60;
2337
                tss = (tns%60);
2338
                frac = (double)event.button.x/(double)cur_stream->width;
2339
                ns = frac*tns;
2340
                hh = ns/3600;
2341
                mm = (ns%3600)/60;
2342
                ss = (ns%60);
2343
                fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
2344
                        hh, mm, ss, thh, tmm, tss);
2345 c2b4c859 Baptiste Coudurier
                ts = frac*cur_stream->ic->duration;
2346
                if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
2347
                    ts += cur_stream->ic->start_time;
2348
                stream_seek(cur_stream, ts, 0);
2349 bb270c08 Diego Biurrun
            }
2350
            break;
2351 01310af2 Fabrice Bellard
        case SDL_VIDEORESIZE:
2352
            if (cur_stream) {
2353 115329f1 Diego Biurrun
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
2354 01310af2 Fabrice Bellard
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
2355 c57d3469 Michael Niedermayer
                screen_width = cur_stream->width = event.resize.w;
2356
                screen_height= cur_stream->height= event.resize.h;
2357 01310af2 Fabrice Bellard
            }
2358
            break;
2359
        case SDL_QUIT:
2360 638c9d91 Fabrice Bellard
        case FF_QUIT_EVENT:
2361 01310af2 Fabrice Bellard
            do_exit();
2362
            break;
2363
        case FF_ALLOC_EVENT:
2364 fccb19e3 Michael Niedermayer
            video_open(event.user.data1);
2365 01310af2 Fabrice Bellard
            alloc_picture(event.user.data1);
2366
            break;
2367
        case FF_REFRESH_EVENT:
2368
            video_refresh_timer(event.user.data1);
2369
            break;
2370
        default:
2371
            break;
2372
        }
2373
    }
2374
}
2375
2376 e4b89522 Limin Wang
static void opt_frame_size(const char *arg)
2377
{
2378 b33ece16 Stefano Sabatini
    if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
2379 e4b89522 Limin Wang
        fprintf(stderr, "Incorrect frame size\n");
2380
        exit(1);
2381
    }
2382
    if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
2383
        fprintf(stderr, "Frame size must be a multiple of 2\n");
2384
        exit(1);
2385
    }
2386
}
2387
2388 a5b3b5f6 Stefano Sabatini
static int opt_width(const char *opt, const char *arg)
2389 01310af2 Fabrice Bellard
{
2390 a5b3b5f6 Stefano Sabatini
    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2391
    return 0;
2392 01310af2 Fabrice Bellard
}
2393
2394 a5b3b5f6 Stefano Sabatini
static int opt_height(const char *opt, const char *arg)
2395 01310af2 Fabrice Bellard
{
2396 a5b3b5f6 Stefano Sabatini
    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
2397
    return 0;
2398 01310af2 Fabrice Bellard
}
2399
2400
static void opt_format(const char *arg)
2401
{
2402
    file_iformat = av_find_input_format(arg);
2403
    if (!file_iformat) {
2404
        fprintf(stderr, "Unknown input format: %s\n", arg);
2405
        exit(1);
2406
    }
2407
}
2408 61890b02 Fabrice Bellard
2409 e4b89522 Limin Wang
static void opt_frame_pix_fmt(const char *arg)
2410
{
2411
    frame_pix_fmt = avcodec_get_pix_fmt(arg);
2412
}
2413
2414 b81d6235 Stefano Sabatini
static int opt_sync(const char *opt, const char *arg)
2415 638c9d91 Fabrice Bellard
{
2416
    if (!strcmp(arg, "audio"))
2417
        av_sync_type = AV_SYNC_AUDIO_MASTER;
2418
    else if (!strcmp(arg, "video"))
2419
        av_sync_type = AV_SYNC_VIDEO_MASTER;
2420
    else if (!strcmp(arg, "ext"))
2421
        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
2422 aab1b7e5 Stefano Sabatini
    else {
2423 b81d6235 Stefano Sabatini
        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
2424 aab1b7e5 Stefano Sabatini
        exit(1);
2425
    }
2426 b81d6235 Stefano Sabatini
    return 0;
2427 638c9d91 Fabrice Bellard
}
2428
2429 e11bc2c6 Stefano Sabatini
static int opt_seek(const char *opt, const char *arg)
2430 72ea344b Fabrice Bellard
{
2431 e11bc2c6 Stefano Sabatini
    start_time = parse_time_or_die(opt, arg, 1);
2432
    return 0;
2433 72ea344b Fabrice Bellard
}
2434
2435 a5b3b5f6 Stefano Sabatini
static int opt_debug(const char *opt, const char *arg)
2436 e26a8335 Wolfgang Hesseler
{
2437 a309073b Måns Rullgård
    av_log_set_level(99);
2438 a5b3b5f6 Stefano Sabatini
    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2439
    return 0;
2440 e26a8335 Wolfgang Hesseler
}
2441 115329f1 Diego Biurrun
2442 a5b3b5f6 Stefano Sabatini
static int opt_vismv(const char *opt, const char *arg)
2443 0c9bbaec Wolfgang Hesseler
{
2444 a5b3b5f6 Stefano Sabatini
    debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2445
    return 0;
2446 0c9bbaec Wolfgang Hesseler
}
2447 c62c07d3 Michael Niedermayer
2448 a5b3b5f6 Stefano Sabatini
static int opt_thread_count(const char *opt, const char *arg)
2449 c62c07d3 Michael Niedermayer
{
2450 a5b3b5f6 Stefano Sabatini
    thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
2451 b250f9c6 Aurelien Jacobs
#if !HAVE_THREADS
2452 c62c07d3 Michael Niedermayer
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
2453
#endif
2454 a5b3b5f6 Stefano Sabatini
    return 0;
2455 c62c07d3 Michael Niedermayer
}
2456 115329f1 Diego Biurrun
2457 358061f6 Diego Pettenò
static const OptionDef options[] = {
2458 992f8eae Stefano Sabatini
#include "cmdutils_common_opts.h"
2459 a5b3b5f6 Stefano Sabatini
    { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" },
2460
    { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" },
2461 e4b89522 Limin Wang
    { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
2462 638c9d91 Fabrice Bellard
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
2463 01310af2 Fabrice Bellard
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2464
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
2465 4b037567 Stefano Sabatini
    { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "select desired audio stream", "stream_number" },
2466
    { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_video_stream}, "select desired video stream", "stream_number" },
2467
    { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_subtitle_stream}, "select desired subtitle stream", "stream_number" },
2468 e11bc2c6 Stefano Sabatini
    { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
2469 94b594c6 Steve L'Homme
    { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
2470 01310af2 Fabrice Bellard
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
2471
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
2472 e4b89522 Limin Wang
    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
2473 98ae6acf Benoit Fouet
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
2474 a5b3b5f6 Stefano Sabatini
    { "debug", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
2475 6387c3e6 Michael Niedermayer
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
2476 a5b3b5f6 Stefano Sabatini
    { "vismv", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
2477 6fc5b059 Michael Niedermayer
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
2478 30bc6613 Michael Niedermayer
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
2479 5039185a Michael Niedermayer
    { "drp", OPT_BOOL |OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts", ""},
2480 178fcca8 Michael Niedermayer
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
2481 8c3eba7c Michael Niedermayer
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
2482
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
2483
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
2484 178fcca8 Michael Niedermayer
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
2485 047599a4 Michael Niedermayer
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_recognition}, "set error detection threshold (0-4)",  "threshold" },
2486 1b51e051 Michael Niedermayer
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
2487 b81d6235 Stefano Sabatini
    { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
2488 a5b3b5f6 Stefano Sabatini
    { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
2489 e43d7a18 Michael Niedermayer
    { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
2490 01310af2 Fabrice Bellard
    { NULL, },
2491
};
2492
2493 0c2a18cb Ramiro Polla
static void show_usage(void)
2494 01310af2 Fabrice Bellard
{
2495 27daa420 Ramiro Polla
    printf("Simple media player\n");
2496
    printf("usage: ffplay [options] input_file\n");
2497 01310af2 Fabrice Bellard
    printf("\n");
2498 0c2a18cb Ramiro Polla
}
2499
2500
static void show_help(void)
2501
{
2502
    show_usage();
2503 02d504a7 Fabrice Bellard
    show_help_options(options, "Main options:\n",
2504
                      OPT_EXPERT, 0);
2505
    show_help_options(options, "\nAdvanced options:\n",
2506
                      OPT_EXPERT, OPT_EXPERT);
2507 01310af2 Fabrice Bellard
    printf("\nWhile playing:\n"
2508
           "q, ESC              quit\n"
2509
           "f                   toggle full screen\n"
2510
           "p, SPC              pause\n"
2511 638c9d91 Fabrice Bellard
           "a                   cycle audio channel\n"
2512
           "v                   cycle video channel\n"
2513 72ce053b Ian Caulfield
           "t                   cycle subtitle channel\n"
2514 638c9d91 Fabrice Bellard
           "w                   show audio waves\n"
2515 72ea344b Fabrice Bellard
           "left/right          seek backward/forward 10 seconds\n"
2516
           "down/up             seek backward/forward 1 minute\n"
2517 a11d11aa Michel Bardiaux
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
2518 01310af2 Fabrice Bellard
           );
2519
}
2520
2521 358061f6 Diego Pettenò
static void opt_input_file(const char *filename)
2522 01310af2 Fabrice Bellard
{
2523 e8d83e1c Michael Niedermayer
    if (!strcmp(filename, "-"))
2524 9fcfc0b7 Diego Biurrun
        filename = "pipe:";
2525 01310af2 Fabrice Bellard
    input_filename = filename;
2526
}
2527
2528
/* Called from the main */
2529
int main(int argc, char **argv)
2530
{
2531 e43d7a18 Michael Niedermayer
    int flags, i;
2532 115329f1 Diego Biurrun
2533 01310af2 Fabrice Bellard
    /* register all codecs, demux and protocols */
2534 c721d803 Luca Abeni
    avcodec_register_all();
2535
    avdevice_register_all();
2536 01310af2 Fabrice Bellard
    av_register_all();
2537
2538 e43d7a18 Michael Niedermayer
    for(i=0; i<CODEC_TYPE_NB; i++){
2539 636f1c4c Stefano Sabatini
        avcodec_opts[i]= avcodec_alloc_context2(i);
2540 e43d7a18 Michael Niedermayer
    }
2541 8e2fd8e1 Stefano Sabatini
    avformat_opts = avformat_alloc_context();
2542 e43d7a18 Michael Niedermayer
    sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
2543
2544 ea9c581f Stefano Sabatini
    show_banner();
2545 4cfac5bc Stefano Sabatini
2546 f5da5c93 Stefano Sabatini
    parse_options(argc, argv, options, opt_input_file);
2547 01310af2 Fabrice Bellard
2548 aab1b7e5 Stefano Sabatini
    if (!input_filename) {
2549 7f11e745 Ramiro Polla
        show_usage();
2550 7a7da6b4 Stefano Sabatini
        fprintf(stderr, "An input file must be specified\n");
2551 7f11e745 Ramiro Polla
        fprintf(stderr, "Use -h to get full help or, even better, run 'man ffplay'\n");
2552 aab1b7e5 Stefano Sabatini
        exit(1);
2553
    }
2554 01310af2 Fabrice Bellard
2555
    if (display_disable) {
2556
        video_disable = 1;
2557
    }
2558 31319a8c Fabrice Bellard
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
2559 c97f5402 Diego Biurrun
#if !defined(__MINGW32__) && !defined(__APPLE__)
2560
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
2561 31319a8c Fabrice Bellard
#endif
2562 01310af2 Fabrice Bellard
    if (SDL_Init (flags)) {
2563 05ab0b76 Glenn Maynard
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
2564 01310af2 Fabrice Bellard
        exit(1);
2565
    }
2566
2567
    if (!display_disable) {
2568 b250f9c6 Aurelien Jacobs
#if HAVE_SDL_VIDEO_SIZE
2569 3ef17d62 Måns Rullgård
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
2570
        fs_screen_width = vi->current_w;
2571
        fs_screen_height = vi->current_h;
2572 29f3b38a Måns Rullgård
#endif
2573 01310af2 Fabrice Bellard
    }
2574
2575
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
2576
    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
2577
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
2578
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
2579
2580 39c6a118 Michael Niedermayer
    av_init_packet(&flush_pkt);
2581
    flush_pkt.data= "FLUSH";
2582
2583 638c9d91 Fabrice Bellard
    cur_stream = stream_open(input_filename, file_iformat);
2584 01310af2 Fabrice Bellard
2585
    event_loop();
2586
2587
    /* never returns */
2588
2589
    return 0;
2590
}