Statistics
| Branch: | Revision:

ffmpeg / ffplay.c @ d7c2e8e3

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

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