~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/ffplay.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * FFplay : Simple Media Player based on the ffmpeg libraries
3
3
 * Copyright (c) 2003 Fabrice Bellard
4
4
 *
5
 
 * This library is free software; you can redistribute it and/or
 
5
 * This file is part of FFmpeg.
 
6
 *
 
7
 * FFmpeg is free software; you can redistribute it and/or
6
8
 * modify it under the terms of the GNU Lesser General Public
7
9
 * License as published by the Free Software Foundation; either
8
 
 * version 2 of the License, or (at your option) any later version.
 
10
 * version 2.1 of the License, or (at your option) any later version.
9
11
 *
10
 
 * This library is distributed in the hope that it will be useful,
 
12
 * FFmpeg is distributed in the hope that it will be useful,
11
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
15
 * Lesser General Public License for more details.
14
16
 *
15
17
 * You should have received a copy of the GNU Lesser General Public
16
 
 * License along with this library; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 * License along with FFmpeg; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
20
 */
19
21
#define HAVE_AV_CONFIG_H
20
22
#include "avformat.h"
 
23
#include "swscale.h"
21
24
 
 
25
#include "version.h"
22
26
#include "cmdutils.h"
23
27
 
24
28
#include <SDL.h>
25
29
#include <SDL_thread.h>
26
30
 
27
 
#ifdef CONFIG_WIN32
 
31
#ifdef __MINGW32__
28
32
#undef main /* We don't want SDL to override our main() */
29
33
#endif
30
34
 
31
 
#if defined(__linux__)
32
 
#define HAVE_X11
33
 
#endif
34
 
 
35
 
#ifdef HAVE_X11
36
 
#include <X11/Xlib.h>
 
35
#ifdef CONFIG_OS2
 
36
#define INCL_DOS
 
37
 #include <os2.h>
 
38
 #include <stdio.h>
 
39
 
 
40
 void MorphToPM()
 
41
 {
 
42
   PPIB pib;
 
43
   PTIB tib;
 
44
 
 
45
   DosGetInfoBlocks(&tib, &pib);
 
46
 
 
47
   // Change flag from VIO to PM:
 
48
   if (pib->pib_ultype==2) pib->pib_ultype = 3;
 
49
 }
37
50
#endif
38
51
 
39
52
//#define DEBUG_SYNC
40
53
 
41
54
#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
42
55
#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
 
56
#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
43
57
 
44
58
/* SDL audio buffer size, in samples. Should be small to have precise
45
59
   A/V sync as SDL does not have hardware buffer fullness info. */
46
60
#define SDL_AUDIO_BUFFER_SIZE 1024
47
61
 
48
62
/* no AV sync correction is done if below the AV sync threshold */
49
 
#define AV_SYNC_THRESHOLD 0.08
 
63
#define AV_SYNC_THRESHOLD 0.01
50
64
/* no AV correction is done if too big error */
51
65
#define AV_NOSYNC_THRESHOLD 10.0
52
66
 
59
73
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
60
74
#define SAMPLE_ARRAY_SIZE (2*65536)
61
75
 
 
76
static int sws_flags = SWS_BICUBIC;
 
77
 
62
78
typedef struct PacketQueue {
63
79
    AVPacketList *first_pkt, *last_pkt;
64
80
    int nb_packets;
69
85
} PacketQueue;
70
86
 
71
87
#define VIDEO_PICTURE_QUEUE_SIZE 1
 
88
#define SUBPICTURE_QUEUE_SIZE 4
72
89
 
73
90
typedef struct VideoPicture {
74
 
    double pts; /* presentation time stamp for this picture */
 
91
    double pts;                                  ///<presentation time stamp for this picture
75
92
    SDL_Overlay *bmp;
76
93
    int width, height; /* source height & width */
77
94
    int allocated;
78
95
} VideoPicture;
79
96
 
 
97
typedef struct SubPicture {
 
98
    double pts; /* presentation time stamp for this picture */
 
99
    AVSubtitle sub;
 
100
} SubPicture;
 
101
 
80
102
enum {
81
103
    AV_SYNC_AUDIO_MASTER, /* default choice */
82
104
    AV_SYNC_VIDEO_MASTER,
91
113
    int abort_request;
92
114
    int paused;
93
115
    int last_paused;
 
116
    int seek_req;
 
117
    int seek_flags;
 
118
    int64_t seek_pos;
94
119
    AVFormatContext *ic;
95
120
    int dtg_active_format;
96
121
 
97
122
    int audio_stream;
98
 
    
 
123
 
99
124
    int av_sync_type;
100
125
    double external_clock; /* external clock base */
101
126
    int64_t external_clock_time;
102
 
    
 
127
 
103
128
    double audio_clock;
104
129
    double audio_diff_cum; /* used for AV difference average computation */
105
130
    double audio_diff_avg_coef;
110
135
    int audio_hw_buf_size;
111
136
    /* samples output by the codec. we reserve more space for avsync
112
137
       compensation */
113
 
    uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; 
114
 
    int audio_buf_size; /* in bytes */
 
138
    DECLARE_ALIGNED(16,uint8_t,audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]);
 
139
    unsigned int audio_buf_size; /* in bytes */
115
140
    int audio_buf_index; /* in bytes */
116
141
    AVPacket audio_pkt;
117
142
    uint8_t *audio_pkt_data;
118
143
    int audio_pkt_size;
119
 
    int64_t audio_pkt_ipts;
120
 
    
 
144
 
121
145
    int show_audio; /* if true, display audio samples */
122
146
    int16_t sample_array[SAMPLE_ARRAY_SIZE];
123
147
    int sample_array_index;
124
148
    int last_i_start;
125
 
    
 
149
 
 
150
    SDL_Thread *subtitle_tid;
 
151
    int subtitle_stream;
 
152
    int subtitle_stream_changed;
 
153
    AVStream *subtitle_st;
 
154
    PacketQueue subtitleq;
 
155
    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
 
156
    int subpq_size, subpq_rindex, subpq_windex;
 
157
    SDL_mutex *subpq_mutex;
 
158
    SDL_cond *subpq_cond;
 
159
 
126
160
    double frame_timer;
127
161
    double frame_last_pts;
128
162
    double frame_last_delay;
129
 
    double video_clock;
 
163
    double video_clock;                          ///<pts of last decoded frame / predicted pts of next decoded frame
130
164
    int video_stream;
131
165
    AVStream *video_st;
132
166
    PacketQueue videoq;
133
 
    int64_t ipts;
134
 
    int picture_start; /* true if picture starts */
135
 
    double video_last_P_pts; /* pts of the last P picture (needed if B
136
 
                                frames are present) */
137
 
    double video_current_pts; /* current displayed pts (different from
138
 
                                 video_clock if frame fifos are used) */
139
 
    int64_t video_current_pts_time; /* time at which we updated
140
 
                                       video_current_pts - used to
141
 
                                       have running video pts */
 
167
    double video_current_pts;                    ///<current displayed pts (different from video_clock if frame fifos are used)
 
168
    int64_t video_current_pts_time;              ///<time (av_gettime) at which we updated video_current_pts - used to have running video pts
142
169
    VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
143
170
    int pictq_size, pictq_rindex, pictq_windex;
144
171
    SDL_mutex *pictq_mutex;
145
172
    SDL_cond *pictq_cond;
146
 
    
 
173
 
147
174
    //    QETimer *video_timer;
148
175
    char filename[1024];
149
176
    int width, height, xleft, ytop;
154
181
 
155
182
/* options specified by the user */
156
183
static AVInputFormat *file_iformat;
157
 
static AVImageFormat *image_format;
158
184
static const char *input_filename;
159
185
static int fs_screen_width;
160
186
static int fs_screen_height;
161
 
static int screen_width = 640;
162
 
static int screen_height = 480;
 
187
static int screen_width = 0;
 
188
static int screen_height = 0;
 
189
static int frame_width = 0;
 
190
static int frame_height = 0;
 
191
static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
163
192
static int audio_disable;
164
193
static int video_disable;
 
194
static int wanted_audio_stream= 0;
 
195
static int seek_by_bytes;
165
196
static int display_disable;
166
197
static int show_status;
167
198
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
 
199
static int64_t start_time = AV_NOPTS_VALUE;
 
200
static int debug = 0;
 
201
static int debug_mv = 0;
 
202
static int step = 0;
 
203
static int thread_count = 1;
 
204
static int workaround_bugs = 1;
 
205
static int fast = 0;
 
206
static int genpts = 0;
 
207
static int lowres = 0;
 
208
static int idct = FF_IDCT_AUTO;
 
209
static enum AVDiscard skip_frame= AVDISCARD_DEFAULT;
 
210
static enum AVDiscard skip_idct= AVDISCARD_DEFAULT;
 
211
static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT;
 
212
static int error_resilience = FF_ER_CAREFUL;
 
213
static int error_concealment = 3;
168
214
 
169
215
/* current context */
170
216
static int is_full_screen;
171
217
static VideoState *cur_stream;
172
218
static int64_t audio_callback_time;
173
219
 
 
220
AVPacket flush_pkt;
 
221
 
174
222
#define FF_ALLOC_EVENT   (SDL_USEREVENT)
175
223
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
176
224
#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
185
233
    q->cond = SDL_CreateCond();
186
234
}
187
235
 
188
 
static void packet_queue_end(PacketQueue *q)
 
236
static void packet_queue_flush(PacketQueue *q)
189
237
{
190
238
    AVPacketList *pkt, *pkt1;
191
239
 
 
240
    SDL_LockMutex(q->mutex);
192
241
    for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
193
242
        pkt1 = pkt->next;
194
243
        av_free_packet(&pkt->pkt);
 
244
        av_freep(&pkt);
195
245
    }
 
246
    q->last_pkt = NULL;
 
247
    q->first_pkt = NULL;
 
248
    q->nb_packets = 0;
 
249
    q->size = 0;
 
250
    SDL_UnlockMutex(q->mutex);
 
251
}
 
252
 
 
253
static void packet_queue_end(PacketQueue *q)
 
254
{
 
255
    packet_queue_flush(q);
196
256
    SDL_DestroyMutex(q->mutex);
197
257
    SDL_DestroyCond(q->cond);
198
258
}
201
261
{
202
262
    AVPacketList *pkt1;
203
263
 
 
264
    /* duplicate the packet */
 
265
    if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
 
266
        return -1;
 
267
 
204
268
    pkt1 = av_malloc(sizeof(AVPacketList));
205
269
    if (!pkt1)
206
270
        return -1;
207
271
    pkt1->pkt = *pkt;
208
272
    pkt1->next = NULL;
209
273
 
 
274
 
210
275
    SDL_LockMutex(q->mutex);
211
276
 
212
277
    if (!q->last_pkt)
229
294
    SDL_LockMutex(q->mutex);
230
295
 
231
296
    q->abort_request = 1;
232
 
    
 
297
 
233
298
    SDL_CondSignal(q->cond);
234
299
 
235
300
    SDL_UnlockMutex(q->mutex);
248
313
            ret = -1;
249
314
            break;
250
315
        }
251
 
            
 
316
 
252
317
        pkt1 = q->first_pkt;
253
318
        if (pkt1) {
254
319
            q->first_pkt = pkt1->next;
271
336
    return ret;
272
337
}
273
338
 
274
 
static inline void fill_rectangle(SDL_Surface *screen, 
 
339
static inline void fill_rectangle(SDL_Surface *screen,
275
340
                                  int x, int y, int w, int h, int color)
276
341
{
277
342
    SDL_Rect rect;
301
366
    h2 = s->height - (y + h);
302
367
    if (h2 < 0)
303
368
        h2 = 0;
304
 
    fill_rectangle(screen, 
305
 
                   s->xleft, s->ytop, 
306
 
                   w1, s->height, 
307
 
                   color);
308
 
    fill_rectangle(screen, 
309
 
                   s->xleft + s->width - w2, s->ytop, 
310
 
                   w2, s->height, 
311
 
                   color);
312
 
    fill_rectangle(screen, 
313
 
                   s->xleft + w1, s->ytop, 
314
 
                   s->width - w1 - w2, h1, 
315
 
                   color);
316
 
    fill_rectangle(screen, 
 
369
    fill_rectangle(screen,
 
370
                   s->xleft, s->ytop,
 
371
                   w1, s->height,
 
372
                   color);
 
373
    fill_rectangle(screen,
 
374
                   s->xleft + s->width - w2, s->ytop,
 
375
                   w2, s->height,
 
376
                   color);
 
377
    fill_rectangle(screen,
 
378
                   s->xleft + w1, s->ytop,
 
379
                   s->width - w1 - w2, h1,
 
380
                   color);
 
381
    fill_rectangle(screen,
317
382
                   s->xleft + w1, s->ytop + s->height - h2,
318
383
                   s->width - w1 - w2, h2,
319
384
                   color);
320
385
}
321
386
#endif
322
387
 
 
388
 
 
389
 
 
390
#define SCALEBITS 10
 
391
#define ONE_HALF  (1 << (SCALEBITS - 1))
 
392
#define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
 
393
 
 
394
#define RGB_TO_Y_CCIR(r, g, b) \
 
395
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
 
396
  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
 
397
 
 
398
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
 
399
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
 
400
     FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
 
401
 
 
402
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
 
403
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
 
404
   FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
 
405
 
 
406
#define ALPHA_BLEND(a, oldp, newp, s)\
 
407
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
 
408
 
 
409
#define RGBA_IN(r, g, b, a, s)\
 
410
{\
 
411
    unsigned int v = ((const uint32_t *)(s))[0];\
 
412
    a = (v >> 24) & 0xff;\
 
413
    r = (v >> 16) & 0xff;\
 
414
    g = (v >> 8) & 0xff;\
 
415
    b = v & 0xff;\
 
416
}
 
417
 
 
418
#define YUVA_IN(y, u, v, a, s, pal)\
 
419
{\
 
420
    unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)s];\
 
421
    a = (val >> 24) & 0xff;\
 
422
    y = (val >> 16) & 0xff;\
 
423
    u = (val >> 8) & 0xff;\
 
424
    v = val & 0xff;\
 
425
}
 
426
 
 
427
#define YUVA_OUT(d, y, u, v, a)\
 
428
{\
 
429
    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
 
430
}
 
431
 
 
432
 
 
433
#define BPP 1
 
434
 
 
435
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect)
 
436
{
 
437
    int wrap, wrap3, width2, skip2;
 
438
    int y, u, v, a, u1, v1, a1, w, h;
 
439
    uint8_t *lum, *cb, *cr;
 
440
    const uint8_t *p;
 
441
    const uint32_t *pal;
 
442
 
 
443
    lum = dst->data[0] + rect->y * dst->linesize[0];
 
444
    cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1];
 
445
    cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2];
 
446
 
 
447
    width2 = (rect->w + 1) >> 1;
 
448
    skip2 = rect->x >> 1;
 
449
    wrap = dst->linesize[0];
 
450
    wrap3 = rect->linesize;
 
451
    p = rect->bitmap;
 
452
    pal = rect->rgba_palette;  /* Now in YCrCb! */
 
453
 
 
454
    if (rect->y & 1) {
 
455
        lum += rect->x;
 
456
        cb += skip2;
 
457
        cr += skip2;
 
458
 
 
459
        if (rect->x & 1) {
 
460
            YUVA_IN(y, u, v, a, p, pal);
 
461
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
462
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
 
463
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
 
464
            cb++;
 
465
            cr++;
 
466
            lum++;
 
467
            p += BPP;
 
468
        }
 
469
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
 
470
            YUVA_IN(y, u, v, a, p, pal);
 
471
            u1 = u;
 
472
            v1 = v;
 
473
            a1 = a;
 
474
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
475
 
 
476
            YUVA_IN(y, u, v, a, p + BPP, pal);
 
477
            u1 += u;
 
478
            v1 += v;
 
479
            a1 += a;
 
480
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
 
481
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
 
482
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
 
483
            cb++;
 
484
            cr++;
 
485
            p += 2 * BPP;
 
486
            lum += 2;
 
487
        }
 
488
        if (w) {
 
489
            YUVA_IN(y, u, v, a, p, pal);
 
490
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
491
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
 
492
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
 
493
        }
 
494
        p += wrap3 + (wrap3 - rect->w * BPP);
 
495
        lum += wrap + (wrap - rect->w - rect->x);
 
496
        cb += dst->linesize[1] - width2 - skip2;
 
497
        cr += dst->linesize[2] - width2 - skip2;
 
498
    }
 
499
    for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) {
 
500
        lum += rect->x;
 
501
        cb += skip2;
 
502
        cr += skip2;
 
503
 
 
504
        if (rect->x & 1) {
 
505
            YUVA_IN(y, u, v, a, p, pal);
 
506
            u1 = u;
 
507
            v1 = v;
 
508
            a1 = a;
 
509
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
510
            p += wrap3;
 
511
            lum += wrap;
 
512
            YUVA_IN(y, u, v, a, p, pal);
 
513
            u1 += u;
 
514
            v1 += v;
 
515
            a1 += a;
 
516
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
517
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
 
518
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
 
519
            cb++;
 
520
            cr++;
 
521
            p += -wrap3 + BPP;
 
522
            lum += -wrap + 1;
 
523
        }
 
524
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
 
525
            YUVA_IN(y, u, v, a, p, pal);
 
526
            u1 = u;
 
527
            v1 = v;
 
528
            a1 = a;
 
529
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
530
 
 
531
            YUVA_IN(y, u, v, a, p, pal);
 
532
            u1 += u;
 
533
            v1 += v;
 
534
            a1 += a;
 
535
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
 
536
            p += wrap3;
 
537
            lum += wrap;
 
538
 
 
539
            YUVA_IN(y, u, v, a, p, pal);
 
540
            u1 += u;
 
541
            v1 += v;
 
542
            a1 += a;
 
543
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
544
 
 
545
            YUVA_IN(y, u, v, a, p, pal);
 
546
            u1 += u;
 
547
            v1 += v;
 
548
            a1 += a;
 
549
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
 
550
 
 
551
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
 
552
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
 
553
 
 
554
            cb++;
 
555
            cr++;
 
556
            p += -wrap3 + 2 * BPP;
 
557
            lum += -wrap + 2;
 
558
        }
 
559
        if (w) {
 
560
            YUVA_IN(y, u, v, a, p, pal);
 
561
            u1 = u;
 
562
            v1 = v;
 
563
            a1 = a;
 
564
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
565
            p += wrap3;
 
566
            lum += wrap;
 
567
            YUVA_IN(y, u, v, a, p, pal);
 
568
            u1 += u;
 
569
            v1 += v;
 
570
            a1 += a;
 
571
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
572
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
 
573
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
 
574
            cb++;
 
575
            cr++;
 
576
            p += -wrap3 + BPP;
 
577
            lum += -wrap + 1;
 
578
        }
 
579
        p += wrap3 + (wrap3 - rect->w * BPP);
 
580
        lum += wrap + (wrap - rect->w - rect->x);
 
581
        cb += dst->linesize[1] - width2 - skip2;
 
582
        cr += dst->linesize[2] - width2 - skip2;
 
583
    }
 
584
    /* handle odd height */
 
585
    if (h) {
 
586
        lum += rect->x;
 
587
        cb += skip2;
 
588
        cr += skip2;
 
589
 
 
590
        if (rect->x & 1) {
 
591
            YUVA_IN(y, u, v, a, p, pal);
 
592
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
593
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
 
594
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
 
595
            cb++;
 
596
            cr++;
 
597
            lum++;
 
598
            p += BPP;
 
599
        }
 
600
        for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) {
 
601
            YUVA_IN(y, u, v, a, p, pal);
 
602
            u1 = u;
 
603
            v1 = v;
 
604
            a1 = a;
 
605
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
606
 
 
607
            YUVA_IN(y, u, v, a, p + BPP, pal);
 
608
            u1 += u;
 
609
            v1 += v;
 
610
            a1 += a;
 
611
            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
 
612
            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
 
613
            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
 
614
            cb++;
 
615
            cr++;
 
616
            p += 2 * BPP;
 
617
            lum += 2;
 
618
        }
 
619
        if (w) {
 
620
            YUVA_IN(y, u, v, a, p, pal);
 
621
            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
 
622
            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
 
623
            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
 
624
        }
 
625
    }
 
626
}
 
627
 
 
628
static void free_subpicture(SubPicture *sp)
 
629
{
 
630
    int i;
 
631
 
 
632
    for (i = 0; i < sp->sub.num_rects; i++)
 
633
    {
 
634
        av_free(sp->sub.rects[i].bitmap);
 
635
        av_free(sp->sub.rects[i].rgba_palette);
 
636
    }
 
637
 
 
638
    av_free(sp->sub.rects);
 
639
 
 
640
    memset(&sp->sub, 0, sizeof(AVSubtitle));
 
641
}
 
642
 
323
643
static void video_image_display(VideoState *is)
324
644
{
325
645
    VideoPicture *vp;
 
646
    SubPicture *sp;
 
647
    AVPicture pict;
326
648
    float aspect_ratio;
327
649
    int width, height, x, y;
328
650
    SDL_Rect rect;
 
651
    int i;
329
652
 
330
653
    vp = &is->pictq[is->pictq_rindex];
331
654
    if (vp->bmp) {
332
655
        /* XXX: use variable in the frame */
333
 
        aspect_ratio = is->video_st->codec.aspect_ratio;
 
656
        if (is->video_st->codec->sample_aspect_ratio.num == 0)
 
657
            aspect_ratio = 0;
 
658
        else
 
659
            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio)
 
660
                * is->video_st->codec->width / is->video_st->codec->height;;
334
661
        if (aspect_ratio <= 0.0)
335
 
            aspect_ratio = (float)is->video_st->codec.width / 
336
 
                (float)is->video_st->codec.height;
 
662
            aspect_ratio = (float)is->video_st->codec->width /
 
663
                (float)is->video_st->codec->height;
337
664
        /* if an active format is indicated, then it overrides the
338
665
           mpeg format */
339
666
#if 0
340
 
        if (is->video_st->codec.dtg_active_format != is->dtg_active_format) {
341
 
            is->dtg_active_format = is->video_st->codec.dtg_active_format;
 
667
        if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
 
668
            is->dtg_active_format = is->video_st->codec->dtg_active_format;
342
669
            printf("dtg_active_format=%d\n", is->dtg_active_format);
343
670
        }
344
671
#endif
345
672
#if 0
346
 
        switch(is->video_st->codec.dtg_active_format) {
 
673
        switch(is->video_st->codec->dtg_active_format) {
347
674
        case FF_DTG_AFD_SAME:
348
675
        default:
349
676
            /* nothing to do */
369
696
        }
370
697
#endif
371
698
 
 
699
        if (is->subtitle_st)
 
700
        {
 
701
            if (is->subpq_size > 0)
 
702
            {
 
703
                sp = &is->subpq[is->subpq_rindex];
 
704
 
 
705
                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
 
706
                {
 
707
                    SDL_LockYUVOverlay (vp->bmp);
 
708
 
 
709
                    pict.data[0] = vp->bmp->pixels[0];
 
710
                    pict.data[1] = vp->bmp->pixels[2];
 
711
                    pict.data[2] = vp->bmp->pixels[1];
 
712
 
 
713
                    pict.linesize[0] = vp->bmp->pitches[0];
 
714
                    pict.linesize[1] = vp->bmp->pitches[2];
 
715
                    pict.linesize[2] = vp->bmp->pitches[1];
 
716
 
 
717
                    for (i = 0; i < sp->sub.num_rects; i++)
 
718
                        blend_subrect(&pict, &sp->sub.rects[i]);
 
719
 
 
720
                    SDL_UnlockYUVOverlay (vp->bmp);
 
721
                }
 
722
            }
 
723
        }
 
724
 
 
725
 
372
726
        /* XXX: we suppose the screen has a 1.0 pixel ratio */
373
727
        height = is->height;
374
728
        width = ((int)rint(height * aspect_ratio)) & -3;
385
739
            is->no_background = 0;
386
740
        }
387
741
        rect.x = is->xleft + x;
388
 
        rect.y = is->xleft + y;
 
742
        rect.y = is->ytop  + y;
389
743
        rect.w = width;
390
744
        rect.h = height;
391
745
        SDL_DisplayYUVOverlay(vp->bmp, &rect);
392
746
    } else {
393
747
#if 0
394
 
        fill_rectangle(screen, 
395
 
                       is->xleft, is->ytop, is->width, is->height, 
 
748
        fill_rectangle(screen,
 
749
                       is->xleft, is->ytop, is->width, is->height,
396
750
                       QERGB(0x00, 0x00, 0x00));
397
751
#endif
398
752
    }
401
755
static inline int compute_mod(int a, int b)
402
756
{
403
757
    a = a % b;
404
 
    if (a >= 0) 
 
758
    if (a >= 0)
405
759
        return a;
406
760
    else
407
761
        return a + b;
412
766
    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
413
767
    int ch, channels, h, h2, bgcolor, fgcolor;
414
768
    int16_t time_diff;
415
 
    
 
769
 
416
770
    /* compute display index : center on currently output samples */
417
 
    channels = s->audio_st->codec.channels;
 
771
    channels = s->audio_st->codec->channels;
418
772
    nb_display_channels = channels;
419
773
    if (!s->paused) {
420
774
        n = 2 * channels;
421
775
        delay = audio_write_get_buf_size(s);
422
776
        delay /= n;
423
 
        
 
777
 
424
778
        /* to be more precise, we take into account the time spent since
425
779
           the last buffer computation */
426
780
        if (audio_callback_time) {
427
781
            time_diff = av_gettime() - audio_callback_time;
428
 
            delay += (time_diff * s->audio_st->codec.sample_rate) / 1000000;
 
782
            delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;
429
783
        }
430
 
        
 
784
 
431
785
        delay -= s->width / 2;
432
786
        if (delay < s->width)
433
787
            delay = s->width;
434
 
        i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
 
788
 
 
789
        i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
 
790
 
 
791
        h= INT_MIN;
 
792
        for(i=0; i<1000; i+=channels){
 
793
            int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
 
794
            int a= s->sample_array[idx];
 
795
            int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE];
 
796
            int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE];
 
797
            int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE];
 
798
            int score= a-d;
 
799
            if(h<score && (b^c)<0){
 
800
                h= score;
 
801
                i_start= idx;
 
802
            }
 
803
        }
 
804
 
435
805
        s->last_i_start = i_start;
436
806
    } else {
437
807
        i_start = s->last_i_start;
438
808
    }
439
809
 
440
810
    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
441
 
    fill_rectangle(screen, 
442
 
                   s->xleft, s->ytop, s->width, s->height, 
 
811
    fill_rectangle(screen,
 
812
                   s->xleft, s->ytop, s->width, s->height,
443
813
                   bgcolor);
444
814
 
445
815
    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
459
829
            } else {
460
830
                ys = y1;
461
831
            }
462
 
            fill_rectangle(screen, 
463
 
                           s->xleft + x, ys, 1, y, 
 
832
            fill_rectangle(screen,
 
833
                           s->xleft + x, ys, 1, y,
464
834
                           fgcolor);
465
835
            i += channels;
466
836
            if (i >= SAMPLE_ARRAY_SIZE)
472
842
 
473
843
    for(ch = 1;ch < nb_display_channels; ch++) {
474
844
        y = s->ytop + ch * h;
475
 
        fill_rectangle(screen, 
476
 
                       s->xleft, y, s->width, 1, 
 
845
        fill_rectangle(screen,
 
846
                       s->xleft, y, s->width, 1,
477
847
                       fgcolor);
478
848
    }
479
849
    SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
480
850
}
481
851
 
 
852
static int video_open(VideoState *is){
 
853
    int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
 
854
    int w,h;
 
855
 
 
856
    if(is_full_screen) flags |= SDL_FULLSCREEN;
 
857
    else               flags |= SDL_RESIZABLE;
 
858
 
 
859
    if (is_full_screen && fs_screen_width) {
 
860
        w = fs_screen_width;
 
861
        h = fs_screen_height;
 
862
    } else if(!is_full_screen && screen_width){
 
863
        w = screen_width;
 
864
        h = screen_height;
 
865
    }else if (is->video_st && is->video_st->codec->width){
 
866
        w = is->video_st->codec->width;
 
867
        h = is->video_st->codec->height;
 
868
    } else {
 
869
        w = 640;
 
870
        h = 480;
 
871
    }
 
872
#ifndef CONFIG_DARWIN
 
873
    screen = SDL_SetVideoMode(w, h, 0, flags);
 
874
#else
 
875
    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */
 
876
    screen = SDL_SetVideoMode(w, h, 24, flags);
 
877
#endif
 
878
    if (!screen) {
 
879
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
 
880
        return -1;
 
881
    }
 
882
    SDL_WM_SetCaption("FFplay", "FFplay");
 
883
 
 
884
    is->width = screen->w;
 
885
    is->height = screen->h;
 
886
 
 
887
    return 0;
 
888
}
 
889
 
482
890
/* display the current picture, if any */
483
891
static void video_display(VideoState *is)
484
892
{
485
 
    if (is->audio_st && is->show_audio) 
 
893
    if(!screen)
 
894
        video_open(cur_stream);
 
895
    if (is->audio_st && is->show_audio)
486
896
        video_audio_display(is);
487
897
    else if (is->video_st)
488
898
        video_image_display(is);
512
922
    hw_buf_size = audio_write_get_buf_size(is);
513
923
    bytes_per_sec = 0;
514
924
    if (is->audio_st) {
515
 
        bytes_per_sec = is->audio_st->codec.sample_rate * 
516
 
            2 * is->audio_st->codec.channels;
 
925
        bytes_per_sec = is->audio_st->codec->sample_rate *
 
926
            2 * is->audio_st->codec->channels;
517
927
    }
518
928
    if (bytes_per_sec)
519
929
        pts -= (double)hw_buf_size / bytes_per_sec;
524
934
static double get_video_clock(VideoState *is)
525
935
{
526
936
    double delta;
527
 
    delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
 
937
    if (is->paused) {
 
938
        delta = 0;
 
939
    } else {
 
940
        delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
 
941
    }
528
942
    return is->video_current_pts + delta;
529
943
}
530
944
 
541
955
{
542
956
    double val;
543
957
 
544
 
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st)
545
 
        val = get_video_clock(is);
546
 
    else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st)
547
 
        val = get_audio_clock(is);
548
 
    else
 
958
    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
 
959
        if (is->video_st)
 
960
            val = get_video_clock(is);
 
961
        else
 
962
            val = get_audio_clock(is);
 
963
    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
 
964
        if (is->audio_st)
 
965
            val = get_audio_clock(is);
 
966
        else
 
967
            val = get_video_clock(is);
 
968
    } else {
549
969
        val = get_external_clock(is);
 
970
    }
550
971
    return val;
551
972
}
552
973
 
 
974
/* seek in the stream */
 
975
static void stream_seek(VideoState *is, int64_t pos, int rel)
 
976
{
 
977
    if (!is->seek_req) {
 
978
        is->seek_pos = pos;
 
979
        is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
 
980
        if (seek_by_bytes)
 
981
            is->seek_flags |= AVSEEK_FLAG_BYTE;
 
982
        is->seek_req = 1;
 
983
    }
 
984
}
 
985
 
 
986
/* pause or resume the video */
 
987
static void stream_pause(VideoState *is)
 
988
{
 
989
    is->paused = !is->paused;
 
990
    if (!is->paused) {
 
991
        is->video_current_pts = get_video_clock(is);
 
992
        is->frame_timer += (av_gettime() - is->video_current_pts_time) / 1000000.0;
 
993
    }
 
994
}
 
995
 
553
996
/* called to display each frame */
554
997
static void video_refresh_timer(void *opaque)
555
998
{
557
1000
    VideoPicture *vp;
558
1001
    double actual_delay, delay, sync_threshold, ref_clock, diff;
559
1002
 
 
1003
    SubPicture *sp, *sp2;
560
1004
 
561
1005
    if (is->video_st) {
562
1006
        if (is->pictq_size == 0) {
563
1007
            /* if no picture, need to wait */
564
 
            schedule_refresh(is, 40);
 
1008
            schedule_refresh(is, 1);
565
1009
        } else {
566
1010
            /* dequeue the picture */
567
1011
            vp = &is->pictq[is->pictq_rindex];
586
1030
                   duplicating or deleting a frame */
587
1031
                ref_clock = get_master_clock(is);
588
1032
                diff = vp->pts - ref_clock;
589
 
                
 
1033
 
590
1034
                /* skip or repeat frame. We take into account the
591
1035
                   delay to compute the threshold. I still don't know
592
1036
                   if it is the best guess */
613
1057
            schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));
614
1058
 
615
1059
#if defined(DEBUG_SYNC)
616
 
            printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n", 
 
1060
            printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",
617
1061
                   delay, actual_delay, vp->pts, -diff);
618
1062
#endif
619
1063
 
 
1064
            if(is->subtitle_st) {
 
1065
                if (is->subtitle_stream_changed) {
 
1066
                    SDL_LockMutex(is->subpq_mutex);
 
1067
 
 
1068
                    while (is->subpq_size) {
 
1069
                        free_subpicture(&is->subpq[is->subpq_rindex]);
 
1070
 
 
1071
                        /* update queue size and signal for next picture */
 
1072
                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
 
1073
                            is->subpq_rindex = 0;
 
1074
 
 
1075
                        is->subpq_size--;
 
1076
                    }
 
1077
                    is->subtitle_stream_changed = 0;
 
1078
 
 
1079
                    SDL_CondSignal(is->subpq_cond);
 
1080
                    SDL_UnlockMutex(is->subpq_mutex);
 
1081
                } else {
 
1082
                    if (is->subpq_size > 0) {
 
1083
                        sp = &is->subpq[is->subpq_rindex];
 
1084
 
 
1085
                        if (is->subpq_size > 1)
 
1086
                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
 
1087
                        else
 
1088
                            sp2 = NULL;
 
1089
 
 
1090
                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
 
1091
                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
 
1092
                        {
 
1093
                            free_subpicture(sp);
 
1094
 
 
1095
                            /* update queue size and signal for next picture */
 
1096
                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
 
1097
                                is->subpq_rindex = 0;
 
1098
 
 
1099
                            SDL_LockMutex(is->subpq_mutex);
 
1100
                            is->subpq_size--;
 
1101
                            SDL_CondSignal(is->subpq_cond);
 
1102
                            SDL_UnlockMutex(is->subpq_mutex);
 
1103
                        }
 
1104
                    }
 
1105
                }
 
1106
            }
 
1107
 
620
1108
            /* display picture */
621
1109
            video_display(is);
622
 
            
 
1110
 
623
1111
            /* update queue size and signal for next picture */
624
1112
            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
625
1113
                is->pictq_rindex = 0;
626
 
            
 
1114
 
627
1115
            SDL_LockMutex(is->pictq_mutex);
628
1116
            is->pictq_size--;
629
1117
            SDL_CondSignal(is->pictq_cond);
636
1124
 
637
1125
        /* if only audio stream, then display the audio bars (better
638
1126
           than nothing, just to test the implementation */
639
 
        
 
1127
 
640
1128
        /* display picture */
641
1129
        video_display(is);
642
1130
    } else {
645
1133
    if (show_status) {
646
1134
        static int64_t last_time;
647
1135
        int64_t cur_time;
648
 
        int aqsize, vqsize;
 
1136
        int aqsize, vqsize, sqsize;
649
1137
        double av_diff;
650
 
        
 
1138
 
651
1139
        cur_time = av_gettime();
652
1140
        if (!last_time || (cur_time - last_time) >= 500 * 1000) {
653
1141
            aqsize = 0;
654
1142
            vqsize = 0;
 
1143
            sqsize = 0;
655
1144
            if (is->audio_st)
656
1145
                aqsize = is->audioq.size;
657
1146
            if (is->video_st)
658
1147
                vqsize = is->videoq.size;
 
1148
            if (is->subtitle_st)
 
1149
                sqsize = is->subtitleq.size;
659
1150
            av_diff = 0;
660
1151
            if (is->audio_st && is->video_st)
661
1152
                av_diff = get_audio_clock(is) - get_video_clock(is);
662
 
            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB    \r", 
663
 
                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024);
 
1153
            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",
 
1154
                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);
664
1155
            fflush(stdout);
665
1156
            last_time = cur_time;
666
1157
        }
682
1173
#if 0
683
1174
    /* XXX: use generic function */
684
1175
    /* XXX: disable overlay if no hardware acceleration or if RGB format */
685
 
    switch(is->video_st->codec.pix_fmt) {
 
1176
    switch(is->video_st->codec->pix_fmt) {
686
1177
    case PIX_FMT_YUV420P:
687
1178
    case PIX_FMT_YUV422P:
688
1179
    case PIX_FMT_YUV444P:
689
 
    case PIX_FMT_YUV422:
 
1180
    case PIX_FMT_YUYV422:
690
1181
    case PIX_FMT_YUV410P:
691
1182
    case PIX_FMT_YUV411P:
692
1183
        is_yuv = 1;
696
1187
        break;
697
1188
    }
698
1189
#endif
699
 
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec.width,
700
 
                                   is->video_st->codec.height,
701
 
                                   SDL_YV12_OVERLAY, 
 
1190
    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
 
1191
                                   is->video_st->codec->height,
 
1192
                                   SDL_YV12_OVERLAY,
702
1193
                                   screen);
703
 
    vp->width = is->video_st->codec.width;
704
 
    vp->height = is->video_st->codec.height;
 
1194
    vp->width = is->video_st->codec->width;
 
1195
    vp->height = is->video_st->codec->height;
705
1196
 
706
1197
    SDL_LockMutex(is->pictq_mutex);
707
1198
    vp->allocated = 1;
709
1200
    SDL_UnlockMutex(is->pictq_mutex);
710
1201
}
711
1202
 
 
1203
/**
 
1204
 *
 
1205
 * @param pts the dts of the pkt / pts of the frame and guessed if not known
 
1206
 */
712
1207
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
713
1208
{
714
1209
    VideoPicture *vp;
715
1210
    int dst_pix_fmt;
716
1211
    AVPicture pict;
717
 
    
 
1212
    static struct SwsContext *img_convert_ctx;
 
1213
 
718
1214
    /* wait until we have space to put a new picture */
719
1215
    SDL_LockMutex(is->pictq_mutex);
720
1216
    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
722
1218
        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
723
1219
    }
724
1220
    SDL_UnlockMutex(is->pictq_mutex);
725
 
    
 
1221
 
726
1222
    if (is->videoq.abort_request)
727
1223
        return -1;
728
1224
 
729
1225
    vp = &is->pictq[is->pictq_windex];
730
1226
 
731
1227
    /* alloc or resize hardware picture buffer */
732
 
    if (!vp->bmp || 
733
 
        vp->width != is->video_st->codec.width ||
734
 
        vp->height != is->video_st->codec.height) {
 
1228
    if (!vp->bmp ||
 
1229
        vp->width != is->video_st->codec->width ||
 
1230
        vp->height != is->video_st->codec->height) {
735
1231
        SDL_Event event;
736
1232
 
737
1233
        vp->allocated = 0;
741
1237
        event.type = FF_ALLOC_EVENT;
742
1238
        event.user.data1 = is;
743
1239
        SDL_PushEvent(&event);
744
 
        
 
1240
 
745
1241
        /* wait until the picture is allocated */
746
1242
        SDL_LockMutex(is->pictq_mutex);
747
1243
        while (!vp->allocated && !is->videoq.abort_request) {
766
1262
        pict.linesize[0] = vp->bmp->pitches[0];
767
1263
        pict.linesize[1] = vp->bmp->pitches[2];
768
1264
        pict.linesize[2] = vp->bmp->pitches[1];
769
 
        
770
 
        img_convert(&pict, dst_pix_fmt, 
771
 
                    (AVPicture *)src_frame, is->video_st->codec.pix_fmt, 
772
 
                    is->video_st->codec.width, is->video_st->codec.height);
 
1265
        if (img_convert_ctx == NULL) {
 
1266
            img_convert_ctx = sws_getContext(is->video_st->codec->width,
 
1267
                    is->video_st->codec->height, is->video_st->codec->pix_fmt,
 
1268
                    is->video_st->codec->width, is->video_st->codec->height,
 
1269
                    dst_pix_fmt, sws_flags, NULL, NULL, NULL);
 
1270
            if (img_convert_ctx == NULL) {
 
1271
                fprintf(stderr, "Cannot initialize the conversion context\n");
 
1272
                exit(1);
 
1273
            }
 
1274
        }
 
1275
        sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
 
1276
                  0, is->video_st->codec->height, pict.data, pict.linesize);
773
1277
        /* update the bitmap content */
774
1278
        SDL_UnlockYUVOverlay(vp->bmp);
775
1279
 
785
1289
    return 0;
786
1290
}
787
1291
 
788
 
/* compute the exact PTS for the picture if it is omitted in the stream */
 
1292
/**
 
1293
 * compute the exact PTS for the picture if it is omitted in the stream
 
1294
 * @param pts1 the dts of the pkt / pts of the frame
 
1295
 */
789
1296
static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
790
1297
{
791
1298
    double frame_delay, pts;
792
 
    
 
1299
 
793
1300
    pts = pts1;
794
1301
 
795
 
    /* if B frames are present, and if the current picture is a I
796
 
       or P frame, we use the last pts */
797
 
    if (is->video_st->codec.has_b_frames && 
798
 
        src_frame->pict_type != FF_B_TYPE) {
799
 
        /* use last pts */
800
 
        pts = is->video_last_P_pts;
801
 
        /* get the pts for the next I or P frame if present */
802
 
        is->video_last_P_pts = pts1;
803
 
    }
804
 
 
805
1302
    if (pts != 0) {
806
1303
        /* update video clock with pts, if present */
807
1304
        is->video_clock = pts;
808
1305
    } else {
809
 
        frame_delay = (double)is->video_st->codec.frame_rate_base / 
810
 
            (double)is->video_st->codec.frame_rate;
811
 
        is->video_clock += frame_delay;
812
 
        /* for MPEG2, the frame can be repeated, so we update the
813
 
           clock accordingly */
814
 
        if (src_frame->repeat_pict) {
815
 
            is->video_clock += src_frame->repeat_pict * (frame_delay * 0.5);
816
 
        }
 
1306
        pts = is->video_clock;
817
1307
    }
 
1308
    /* update video clock for next frame */
 
1309
    frame_delay = av_q2d(is->video_st->codec->time_base);
 
1310
    /* for MPEG2, the frame can be repeated, so we update the
 
1311
       clock accordingly */
 
1312
    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
 
1313
    is->video_clock += frame_delay;
818
1314
 
819
1315
#if defined(DEBUG_SYNC) && 0
820
1316
    {
825
1321
            ftype = 'I';
826
1322
        else
827
1323
            ftype = 'P';
828
 
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n", 
829
 
               ftype, is->video_clock, pts1);
 
1324
        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",
 
1325
               ftype, pts, pts1);
830
1326
    }
831
1327
#endif
832
 
    return queue_picture(is, src_frame, is->video_clock);
 
1328
    return queue_picture(is, src_frame, pts);
833
1329
}
834
1330
 
835
1331
static int video_thread(void *arg)
836
1332
{
837
1333
    VideoState *is = arg;
838
1334
    AVPacket pkt1, *pkt = &pkt1;
839
 
    unsigned char *ptr;
840
 
    int len, len1, got_picture;
841
 
    AVFrame frame;
842
 
    int64_t ipts;
 
1335
    int len1, got_picture;
 
1336
    AVFrame *frame= avcodec_alloc_frame();
843
1337
    double pts;
844
1338
 
845
1339
    for(;;) {
848
1342
        }
849
1343
        if (packet_queue_get(&is->videoq, pkt, 1) < 0)
850
1344
            break;
 
1345
 
 
1346
        if(pkt->data == flush_pkt.data){
 
1347
            avcodec_flush_buffers(is->video_st->codec);
 
1348
            continue;
 
1349
        }
 
1350
 
851
1351
        /* NOTE: ipts is the PTS of the _first_ picture beginning in
852
1352
           this packet, if any */
853
 
        ipts = pkt->pts;
854
 
        ptr = pkt->data;
855
 
        if (is->video_st->codec.codec_id == CODEC_ID_RAWVIDEO) {
856
 
            avpicture_fill((AVPicture *)&frame, ptr, 
857
 
                           is->video_st->codec.pix_fmt,
858
 
                           is->video_st->codec.width,
859
 
                           is->video_st->codec.height);
860
 
            pts = 0;
861
 
            if (ipts != AV_NOPTS_VALUE)
862
 
                pts = (double)ipts * is->ic->pts_num / is->ic->pts_den;
863
 
            frame.pict_type = FF_I_TYPE;
864
 
            if (output_picture2(is, &frame, pts) < 0)
865
 
                goto the_end;
866
 
        } else {
867
 
            len = pkt->size;
868
 
            while (len > 0) {
869
 
                if (is->picture_start) {
870
 
                    is->ipts = ipts;
871
 
                    is->picture_start = 0;
872
 
                    ipts = AV_NOPTS_VALUE;
873
 
                }
874
 
                len1 = avcodec_decode_video(&is->video_st->codec, 
875
 
                                            &frame, &got_picture, ptr, len);
876
 
                if (len1 < 0)
877
 
                    break;
878
 
                if (got_picture) {
879
 
                    pts = 0;
880
 
                    if (is->ipts != AV_NOPTS_VALUE)
881
 
                        pts = (double)is->ipts * is->ic->pts_num / is->ic->pts_den;
882
 
                    if (output_picture2(is, &frame, pts) < 0)
883
 
                        goto the_end;
884
 
                    is->picture_start = 1;
885
 
                }
886
 
                ptr += len1;
887
 
                len -= len1;
888
 
            }
889
 
        }
890
 
        av_free_packet(pkt);
 
1353
        pts = 0;
 
1354
        if (pkt->dts != AV_NOPTS_VALUE)
 
1355
            pts = av_q2d(is->video_st->time_base)*pkt->dts;
 
1356
 
 
1357
            len1 = avcodec_decode_video(is->video_st->codec,
 
1358
                                        frame, &got_picture,
 
1359
                                        pkt->data, pkt->size);
 
1360
//            if (len1 < 0)
 
1361
//                break;
 
1362
            if (got_picture) {
 
1363
                if (output_picture2(is, frame, pts) < 0)
 
1364
                    goto the_end;
 
1365
            }
 
1366
        av_free_packet(pkt);
 
1367
        if (step)
 
1368
            if (cur_stream)
 
1369
                stream_pause(cur_stream);
 
1370
    }
 
1371
 the_end:
 
1372
    av_free(frame);
 
1373
    return 0;
 
1374
}
 
1375
 
 
1376
static int subtitle_thread(void *arg)
 
1377
{
 
1378
    VideoState *is = arg;
 
1379
    SubPicture *sp;
 
1380
    AVPacket pkt1, *pkt = &pkt1;
 
1381
    int len1, got_subtitle;
 
1382
    double pts;
 
1383
    int i, j;
 
1384
    int r, g, b, y, u, v, a;
 
1385
 
 
1386
    for(;;) {
 
1387
        while (is->paused && !is->subtitleq.abort_request) {
 
1388
            SDL_Delay(10);
 
1389
        }
 
1390
        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
 
1391
            break;
 
1392
 
 
1393
        if(pkt->data == flush_pkt.data){
 
1394
            avcodec_flush_buffers(is->subtitle_st->codec);
 
1395
            continue;
 
1396
        }
 
1397
        SDL_LockMutex(is->subpq_mutex);
 
1398
        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
 
1399
               !is->subtitleq.abort_request) {
 
1400
            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
 
1401
        }
 
1402
        SDL_UnlockMutex(is->subpq_mutex);
 
1403
 
 
1404
        if (is->subtitleq.abort_request)
 
1405
            goto the_end;
 
1406
 
 
1407
        sp = &is->subpq[is->subpq_windex];
 
1408
 
 
1409
       /* NOTE: ipts is the PTS of the _first_ picture beginning in
 
1410
           this packet, if any */
 
1411
        pts = 0;
 
1412
        if (pkt->pts != AV_NOPTS_VALUE)
 
1413
            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
 
1414
 
 
1415
        len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
 
1416
                                    &sp->sub, &got_subtitle,
 
1417
                                    pkt->data, pkt->size);
 
1418
//            if (len1 < 0)
 
1419
//                break;
 
1420
        if (got_subtitle && sp->sub.format == 0) {
 
1421
            sp->pts = pts;
 
1422
 
 
1423
            for (i = 0; i < sp->sub.num_rects; i++)
 
1424
            {
 
1425
                for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
 
1426
                {
 
1427
                    RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
 
1428
                    y = RGB_TO_Y_CCIR(r, g, b);
 
1429
                    u = RGB_TO_U_CCIR(r, g, b, 0);
 
1430
                    v = RGB_TO_V_CCIR(r, g, b, 0);
 
1431
                    YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
 
1432
                }
 
1433
            }
 
1434
 
 
1435
            /* now we can update the picture count */
 
1436
            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
 
1437
                is->subpq_windex = 0;
 
1438
            SDL_LockMutex(is->subpq_mutex);
 
1439
            is->subpq_size++;
 
1440
            SDL_UnlockMutex(is->subpq_mutex);
 
1441
        }
 
1442
        av_free_packet(pkt);
 
1443
//        if (step)
 
1444
//            if (cur_stream)
 
1445
//                stream_pause(cur_stream);
891
1446
    }
892
1447
 the_end:
893
1448
    return 0;
898
1453
{
899
1454
    int size, len, channels;
900
1455
 
901
 
    channels = is->audio_st->codec.channels;
 
1456
    channels = is->audio_st->codec->channels;
902
1457
 
903
1458
    size = samples_size / sizeof(short);
904
1459
    while (size > 0) {
916
1471
 
917
1472
/* return the new audio buffer size (samples can be added or deleted
918
1473
   to get better sync if video or external master clock) */
919
 
static int synchronize_audio(VideoState *is, short *samples, 
 
1474
static int synchronize_audio(VideoState *is, short *samples,
920
1475
                             int samples_size1, double pts)
921
1476
{
922
1477
    int n, samples_size;
923
1478
    double ref_clock;
924
 
    
925
 
    n = 2 * is->audio_st->codec.channels;
 
1479
 
 
1480
    n = 2 * is->audio_st->codec->channels;
926
1481
    samples_size = samples_size1;
927
1482
 
928
1483
    /* if not master, then we try to remove or add samples to correct the clock */
930
1485
         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
931
1486
        double diff, avg_diff;
932
1487
        int wanted_size, min_size, max_size, nb_samples;
933
 
            
 
1488
 
934
1489
        ref_clock = get_master_clock(is);
935
1490
        diff = get_audio_clock(is) - ref_clock;
936
 
        
 
1491
 
937
1492
        if (diff < AV_NOSYNC_THRESHOLD) {
938
1493
            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
939
1494
            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
944
1499
                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
945
1500
 
946
1501
                if (fabs(avg_diff) >= is->audio_diff_threshold) {
947
 
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec.sample_rate) * n);
 
1502
                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
948
1503
                    nb_samples = samples_size / n;
949
 
                
 
1504
 
950
1505
                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
951
1506
                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
952
1507
                    if (wanted_size < min_size)
953
1508
                        wanted_size = min_size;
954
1509
                    else if (wanted_size > max_size)
955
1510
                        wanted_size = max_size;
956
 
                    
 
1511
 
957
1512
                    /* add or remove samples to correction the synchro */
958
1513
                    if (wanted_size < samples_size) {
959
1514
                        /* remove samples */
961
1516
                    } else if (wanted_size > samples_size) {
962
1517
                        uint8_t *samples_end, *q;
963
1518
                        int nb;
964
 
                        
 
1519
 
965
1520
                        /* add samples */
966
1521
                        nb = (samples_size - wanted_size);
967
1522
                        samples_end = (uint8_t *)samples + samples_size - n;
975
1530
                    }
976
1531
                }
977
1532
#if 0
978
 
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n", 
979
 
                       diff, avg_diff, samples_size - samples_size1, 
 
1533
                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
 
1534
                       diff, avg_diff, samples_size - samples_size1,
980
1535
                       is->audio_clock, is->video_clock, is->audio_diff_threshold);
981
1536
#endif
982
1537
            }
995
1550
static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
996
1551
{
997
1552
    AVPacket *pkt = &is->audio_pkt;
998
 
    int len1, data_size;
 
1553
    int n, len1, data_size;
999
1554
    double pts;
1000
1555
 
1001
1556
    for(;;) {
1002
 
        if (is->paused || is->audioq.abort_request) {
1003
 
            return -1;
1004
 
        }
 
1557
        /* NOTE: the audio packet can contain several frames */
1005
1558
        while (is->audio_pkt_size > 0) {
1006
 
            len1 = avcodec_decode_audio(&is->audio_st->codec, 
1007
 
                                        (int16_t *)audio_buf, &data_size, 
 
1559
            len1 = avcodec_decode_audio(is->audio_st->codec,
 
1560
                                        (int16_t *)audio_buf, &data_size,
1008
1561
                                        is->audio_pkt_data, is->audio_pkt_size);
1009
 
            if (len1 < 0)
 
1562
            if (len1 < 0) {
 
1563
                /* if error, we skip the frame */
 
1564
                is->audio_pkt_size = 0;
1010
1565
                break;
 
1566
            }
 
1567
 
1011
1568
            is->audio_pkt_data += len1;
1012
1569
            is->audio_pkt_size -= len1;
1013
 
            if (data_size > 0) {
1014
 
                pts = 0;
1015
 
                if (is->audio_pkt_ipts != AV_NOPTS_VALUE)
1016
 
                    pts = (double)is->audio_pkt_ipts * is->ic->pts_num / is->ic->pts_den;
1017
 
                /* if no pts, then compute it */
1018
 
                if (pts != 0) {
1019
 
                    is->audio_clock = pts;
1020
 
                } else {
1021
 
                    int n;
1022
 
                    n = 2 * is->audio_st->codec.channels;
1023
 
                    is->audio_clock += (double)data_size / (double)(n * is->audio_st->codec.sample_rate);
1024
 
                }
 
1570
            if (data_size <= 0)
 
1571
                continue;
 
1572
            /* if no pts, then compute it */
 
1573
            pts = is->audio_clock;
 
1574
            *pts_ptr = pts;
 
1575
            n = 2 * is->audio_st->codec->channels;
 
1576
            is->audio_clock += (double)data_size /
 
1577
                (double)(n * is->audio_st->codec->sample_rate);
1025
1578
#if defined(DEBUG_SYNC)
1026
 
                {
1027
 
                    static double last_clock;
1028
 
                    printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
1029
 
                           is->audio_clock - last_clock,
1030
 
                           is->audio_clock, pts);
1031
 
                    last_clock = is->audio_clock;
1032
 
                }
 
1579
            {
 
1580
                static double last_clock;
 
1581
                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
 
1582
                       is->audio_clock - last_clock,
 
1583
                       is->audio_clock, pts);
 
1584
                last_clock = is->audio_clock;
 
1585
            }
1033
1586
#endif
1034
 
                *pts_ptr = is->audio_clock;
1035
 
                is->audio_pkt_ipts = AV_NOPTS_VALUE;
1036
 
                /* we got samples : we can exit now */
1037
 
                return data_size;
1038
 
            }
 
1587
            return data_size;
1039
1588
        }
1040
1589
 
1041
 
        /* free previous packet if any */
1042
 
        if (pkt->destruct)
 
1590
        /* free the current packet */
 
1591
        if (pkt->data)
1043
1592
            av_free_packet(pkt);
1044
1593
 
 
1594
        if (is->paused || is->audioq.abort_request) {
 
1595
            return -1;
 
1596
        }
 
1597
 
1045
1598
        /* read next packet */
1046
1599
        if (packet_queue_get(&is->audioq, pkt, 1) < 0)
1047
1600
            return -1;
 
1601
        if(pkt->data == flush_pkt.data){
 
1602
            avcodec_flush_buffers(is->audio_st->codec);
 
1603
            continue;
 
1604
        }
 
1605
 
1048
1606
        is->audio_pkt_data = pkt->data;
1049
1607
        is->audio_pkt_size = pkt->size;
1050
 
        is->audio_pkt_ipts = pkt->pts;
 
1608
 
 
1609
        /* if update the audio clock with the pts */
 
1610
        if (pkt->pts != AV_NOPTS_VALUE) {
 
1611
            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
 
1612
        }
1051
1613
    }
1052
1614
}
1053
1615
 
1055
1617
   cannot have a precise information */
1056
1618
static int audio_write_get_buf_size(VideoState *is)
1057
1619
{
1058
 
    return is->audio_hw_buf_size - is->audio_buf_index;
 
1620
    return is->audio_buf_size - is->audio_buf_index;
1059
1621
}
1060
1622
 
1061
1623
 
1067
1629
    double pts;
1068
1630
 
1069
1631
    audio_callback_time = av_gettime();
1070
 
    
 
1632
 
1071
1633
    while (len > 0) {
1072
1634
        if (is->audio_buf_index >= is->audio_buf_size) {
1073
1635
           audio_size = audio_decode_frame(is, is->audio_buf, &pts);
1078
1640
           } else {
1079
1641
               if (is->show_audio)
1080
1642
                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
1081
 
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size, 
 
1643
               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
1082
1644
                                              pts);
1083
1645
               is->audio_buf_size = audio_size;
1084
1646
           }
1094
1656
    }
1095
1657
}
1096
1658
 
1097
 
 
1098
1659
/* open a given stream. Return 0 if OK */
1099
1660
static int stream_component_open(VideoState *is, int stream_index)
1100
1661
{
1105
1666
 
1106
1667
    if (stream_index < 0 || stream_index >= ic->nb_streams)
1107
1668
        return -1;
1108
 
    enc = &ic->streams[stream_index]->codec;
1109
 
    
 
1669
    enc = ic->streams[stream_index]->codec;
 
1670
 
1110
1671
    /* prepare audio output */
1111
1672
    if (enc->codec_type == CODEC_TYPE_AUDIO) {
1112
1673
        wanted_spec.freq = enc->sample_rate;
1127
1688
    }
1128
1689
 
1129
1690
    codec = avcodec_find_decoder(enc->codec_id);
 
1691
    enc->debug_mv = debug_mv;
 
1692
    enc->debug = debug;
 
1693
    enc->workaround_bugs = workaround_bugs;
 
1694
    enc->lowres = lowres;
 
1695
    if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
 
1696
    enc->idct_algo= idct;
 
1697
    if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
 
1698
    enc->skip_frame= skip_frame;
 
1699
    enc->skip_idct= skip_idct;
 
1700
    enc->skip_loop_filter= skip_loop_filter;
 
1701
    enc->error_resilience= error_resilience;
 
1702
    enc->error_concealment= error_concealment;
1130
1703
    if (!codec ||
1131
1704
        avcodec_open(enc, codec) < 0)
1132
1705
        return -1;
 
1706
#if defined(HAVE_THREADS)
 
1707
    if(thread_count>1)
 
1708
        avcodec_thread_init(enc, thread_count);
 
1709
#endif
 
1710
    enc->thread_count= thread_count;
1133
1711
    switch(enc->codec_type) {
1134
1712
    case CODEC_TYPE_AUDIO:
1135
1713
        is->audio_stream = stream_index;
1136
1714
        is->audio_st = ic->streams[stream_index];
1137
1715
        is->audio_buf_size = 0;
1138
1716
        is->audio_buf_index = 0;
1139
 
        is->audio_pkt_size = 0;
1140
1717
 
1141
1718
        /* init averaging filter */
1142
1719
        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1147
1724
 
1148
1725
        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1149
1726
        packet_queue_init(&is->audioq);
1150
 
        SDL_PauseAudio(0);
 
1727
        SDL_PauseAudio(0);
1151
1728
        break;
1152
1729
    case CODEC_TYPE_VIDEO:
1153
1730
        is->video_stream = stream_index;
1155
1732
 
1156
1733
        is->frame_last_delay = 40e-3;
1157
1734
        is->frame_timer = (double)av_gettime() / 1000000.0;
1158
 
        is->picture_start = 1;
1159
1735
        is->video_current_pts_time = av_gettime();
1160
1736
 
1161
1737
        packet_queue_init(&is->videoq);
1162
1738
        is->video_tid = SDL_CreateThread(video_thread, is);
1163
1739
        break;
 
1740
    case CODEC_TYPE_SUBTITLE:
 
1741
        is->subtitle_stream = stream_index;
 
1742
        is->subtitle_st = ic->streams[stream_index];
 
1743
        packet_queue_init(&is->subtitleq);
 
1744
 
 
1745
        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
 
1746
        break;
1164
1747
    default:
1165
1748
        break;
1166
1749
    }
1171
1754
{
1172
1755
    AVFormatContext *ic = is->ic;
1173
1756
    AVCodecContext *enc;
1174
 
    
1175
 
    enc = &ic->streams[stream_index]->codec;
 
1757
 
 
1758
    if (stream_index < 0 || stream_index >= ic->nb_streams)
 
1759
        return;
 
1760
    enc = ic->streams[stream_index]->codec;
1176
1761
 
1177
1762
    switch(enc->codec_type) {
1178
1763
    case CODEC_TYPE_AUDIO:
1195
1780
 
1196
1781
        packet_queue_end(&is->videoq);
1197
1782
        break;
 
1783
    case CODEC_TYPE_SUBTITLE:
 
1784
        packet_queue_abort(&is->subtitleq);
 
1785
 
 
1786
        /* note: we also signal this mutex to make sure we deblock the
 
1787
           video thread in all cases */
 
1788
        SDL_LockMutex(is->subpq_mutex);
 
1789
        is->subtitle_stream_changed = 1;
 
1790
 
 
1791
        SDL_CondSignal(is->subpq_cond);
 
1792
        SDL_UnlockMutex(is->subpq_mutex);
 
1793
 
 
1794
        SDL_WaitThread(is->subtitle_tid, NULL);
 
1795
 
 
1796
        packet_queue_end(&is->subtitleq);
 
1797
        break;
1198
1798
    default:
1199
1799
        break;
1200
1800
    }
1209
1809
        is->video_st = NULL;
1210
1810
        is->video_stream = -1;
1211
1811
        break;
 
1812
    case CODEC_TYPE_SUBTITLE:
 
1813
        is->subtitle_st = NULL;
 
1814
        is->subtitle_stream = -1;
 
1815
        break;
1212
1816
    default:
1213
1817
        break;
1214
1818
    }
1215
1819
}
1216
1820
 
1217
 
void dump_stream_info(AVFormatContext *s)
 
1821
static void dump_stream_info(const AVFormatContext *s)
1218
1822
{
1219
1823
    if (s->track != 0)
1220
1824
        fprintf(stderr, "Track: %d\n", s->track);
1222
1826
        fprintf(stderr, "Title: %s\n", s->title);
1223
1827
    if (s->author[0] != '\0')
1224
1828
        fprintf(stderr, "Author: %s\n", s->author);
 
1829
    if (s->copyright[0] != '\0')
 
1830
        fprintf(stderr, "Copyright: %s\n", s->copyright);
 
1831
    if (s->comment[0] != '\0')
 
1832
        fprintf(stderr, "Comment: %s\n", s->comment);
1225
1833
    if (s->album[0] != '\0')
1226
1834
        fprintf(stderr, "Album: %s\n", s->album);
1227
1835
    if (s->year != 0)
1244
1852
{
1245
1853
    VideoState *is = arg;
1246
1854
    AVFormatContext *ic;
1247
 
    int err, i, ret, video_index, audio_index;
 
1855
    int err, i, ret, video_index, audio_index, use_play;
1248
1856
    AVPacket pkt1, *pkt = &pkt1;
1249
1857
    AVFormatParameters params, *ap = &params;
1250
1858
 
1252
1860
    audio_index = -1;
1253
1861
    is->video_stream = -1;
1254
1862
    is->audio_stream = -1;
 
1863
    is->subtitle_stream = -1;
1255
1864
 
1256
1865
    global_video_state = is;
1257
1866
    url_set_interrupt_cb(decode_interrupt_cb);
1258
1867
 
1259
1868
    memset(ap, 0, sizeof(*ap));
1260
 
    ap->image_format = image_format;
 
1869
    ap->initial_pause = 1; /* we force a pause when starting an RTSP
 
1870
                              stream */
 
1871
 
 
1872
    ap->width = frame_width;
 
1873
    ap->height= frame_height;
 
1874
    ap->time_base= (AVRational){1, 25};
 
1875
    ap->pix_fmt = frame_pix_fmt;
1261
1876
 
1262
1877
    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
1263
1878
    if (err < 0) {
1266
1881
        goto fail;
1267
1882
    }
1268
1883
    is->ic = ic;
1269
 
    err = av_find_stream_info(ic);
1270
 
    if (err < 0) {
1271
 
        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
1272
 
        ret = -1;
1273
 
        goto fail;
1274
 
    }
1275
 
    
 
1884
#ifdef CONFIG_NETWORK
 
1885
    use_play = (ic->iformat == &rtsp_demuxer);
 
1886
#else
 
1887
    use_play = 0;
 
1888
#endif
 
1889
 
 
1890
    if(genpts)
 
1891
        ic->flags |= AVFMT_FLAG_GENPTS;
 
1892
 
 
1893
    if (!use_play) {
 
1894
        err = av_find_stream_info(ic);
 
1895
        if (err < 0) {
 
1896
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
 
1897
            ret = -1;
 
1898
            goto fail;
 
1899
        }
 
1900
        ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end
 
1901
    }
 
1902
 
 
1903
    /* if seeking requested, we execute it */
 
1904
    if (start_time != AV_NOPTS_VALUE) {
 
1905
        int64_t timestamp;
 
1906
 
 
1907
        timestamp = start_time;
 
1908
        /* add the stream start time */
 
1909
        if (ic->start_time != AV_NOPTS_VALUE)
 
1910
            timestamp += ic->start_time;
 
1911
        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
 
1912
        if (ret < 0) {
 
1913
            fprintf(stderr, "%s: could not seek to position %0.3f\n",
 
1914
                    is->filename, (double)timestamp / AV_TIME_BASE);
 
1915
        }
 
1916
    }
 
1917
 
 
1918
    /* now we can begin to play (RTSP stream only) */
 
1919
    av_read_play(ic);
 
1920
 
 
1921
    if (use_play) {
 
1922
        err = av_find_stream_info(ic);
 
1923
        if (err < 0) {
 
1924
            fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
 
1925
            ret = -1;
 
1926
            goto fail;
 
1927
        }
 
1928
    }
 
1929
 
1276
1930
    for(i = 0; i < ic->nb_streams; i++) {
1277
 
        AVCodecContext *enc = &ic->streams[i]->codec;
 
1931
        AVCodecContext *enc = ic->streams[i]->codec;
1278
1932
        switch(enc->codec_type) {
1279
1933
        case CODEC_TYPE_AUDIO:
1280
 
            if (audio_index < 0 && !audio_disable)
 
1934
            if ((audio_index < 0 || wanted_audio_stream-- > 0) && !audio_disable)
1281
1935
                audio_index = i;
1282
1936
            break;
1283
1937
        case CODEC_TYPE_VIDEO:
1317
1971
#ifdef CONFIG_NETWORK
1318
1972
        if (is->paused != is->last_paused) {
1319
1973
            is->last_paused = is->paused;
1320
 
            if (ic->iformat == &rtsp_demux) {
1321
 
                if (is->paused)
1322
 
                    rtsp_pause(ic);
1323
 
                else
1324
 
                    rtsp_resume(ic);
1325
 
            }
 
1974
            if (is->paused)
 
1975
                av_read_pause(ic);
 
1976
            else
 
1977
                av_read_play(ic);
1326
1978
        }
1327
 
        if (is->paused && ic->iformat == &rtsp_demux) {
 
1979
        if (is->paused && ic->iformat == &rtsp_demuxer) {
1328
1980
            /* wait 10 ms to avoid trying to get another packet */
1329
1981
            /* XXX: horrible */
1330
1982
            SDL_Delay(10);
1331
1983
            continue;
1332
1984
        }
1333
1985
#endif
 
1986
        if (is->seek_req) {
 
1987
            int stream_index= -1;
 
1988
            int64_t seek_target= is->seek_pos;
 
1989
 
 
1990
            if     (is->   video_stream >= 0) stream_index= is->   video_stream;
 
1991
            else if(is->   audio_stream >= 0) stream_index= is->   audio_stream;
 
1992
            else if(is->subtitle_stream >= 0) stream_index= is->subtitle_stream;
 
1993
 
 
1994
            if(stream_index>=0){
 
1995
                seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, ic->streams[stream_index]->time_base);
 
1996
            }
 
1997
 
 
1998
            ret = av_seek_frame(is->ic, stream_index, seek_target, is->seek_flags);
 
1999
            if (ret < 0) {
 
2000
                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
 
2001
            }else{
 
2002
                if (is->audio_stream >= 0) {
 
2003
                    packet_queue_flush(&is->audioq);
 
2004
                    packet_queue_put(&is->audioq, &flush_pkt);
 
2005
                }
 
2006
                if (is->subtitle_stream >= 0) {
 
2007
                    packet_queue_flush(&is->subtitleq);
 
2008
                    packet_queue_put(&is->subtitleq, &flush_pkt);
 
2009
                }
 
2010
                if (is->video_stream >= 0) {
 
2011
                    packet_queue_flush(&is->videoq);
 
2012
                    packet_queue_put(&is->videoq, &flush_pkt);
 
2013
                }
 
2014
            }
 
2015
            is->seek_req = 0;
 
2016
        }
1334
2017
 
1335
2018
        /* if the queue are full, no need to read more */
1336
2019
        if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1337
 
            is->videoq.size > MAX_VIDEOQ_SIZE) {
 
2020
            is->videoq.size > MAX_VIDEOQ_SIZE ||
 
2021
            is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
 
2022
            url_feof(&ic->pb)) {
1338
2023
            /* wait 10 ms */
1339
2024
            SDL_Delay(10);
1340
2025
            continue;
1341
2026
        }
1342
 
        ret = av_read_packet(ic, pkt);
 
2027
        ret = av_read_frame(ic, pkt);
1343
2028
        if (ret < 0) {
1344
 
            break;
 
2029
            if (url_ferror(&ic->pb) == 0) {
 
2030
                SDL_Delay(100); /* wait for user event */
 
2031
                continue;
 
2032
            } else
 
2033
                break;
1345
2034
        }
1346
2035
        if (pkt->stream_index == is->audio_stream) {
1347
2036
            packet_queue_put(&is->audioq, pkt);
1348
2037
        } else if (pkt->stream_index == is->video_stream) {
1349
2038
            packet_queue_put(&is->videoq, pkt);
 
2039
        } else if (pkt->stream_index == is->subtitle_stream) {
 
2040
            packet_queue_put(&is->subtitleq, pkt);
1350
2041
        } else {
1351
2042
            av_free_packet(pkt);
1352
2043
        }
1366
2057
        stream_component_close(is, is->audio_stream);
1367
2058
    if (is->video_stream >= 0)
1368
2059
        stream_component_close(is, is->video_stream);
 
2060
    if (is->subtitle_stream >= 0)
 
2061
        stream_component_close(is, is->subtitle_stream);
1369
2062
    if (is->ic) {
1370
2063
        av_close_input_file(is->ic);
1371
2064
        is->ic = NULL; /* safety */
1374
2067
 
1375
2068
    if (ret != 0) {
1376
2069
        SDL_Event event;
1377
 
        
 
2070
 
1378
2071
        event.type = FF_QUIT_EVENT;
1379
2072
        event.user.data1 = is;
1380
2073
        SDL_PushEvent(&event);
1382
2075
    return 0;
1383
2076
}
1384
2077
 
1385
 
/* pause or resume the video */
1386
 
static void stream_pause(VideoState *is)
1387
 
{
1388
 
    is->paused = !is->paused;
1389
 
}
1390
 
 
1391
2078
static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
1392
2079
{
1393
2080
    VideoState *is;
1397
2084
        return NULL;
1398
2085
    pstrcpy(is->filename, sizeof(is->filename), filename);
1399
2086
    is->iformat = iformat;
1400
 
    if (screen) {
1401
 
        is->width = screen->w;
1402
 
        is->height = screen->h;
1403
 
    }
1404
2087
    is->ytop = 0;
1405
2088
    is->xleft = 0;
1406
2089
 
1408
2091
    is->pictq_mutex = SDL_CreateMutex();
1409
2092
    is->pictq_cond = SDL_CreateCond();
1410
2093
 
 
2094
    is->subpq_mutex = SDL_CreateMutex();
 
2095
    is->subpq_cond = SDL_CreateCond();
 
2096
 
1411
2097
    /* add the refresh timer to draw the picture */
1412
2098
    schedule_refresh(is, 40);
1413
2099
 
1438
2124
    }
1439
2125
    SDL_DestroyMutex(is->pictq_mutex);
1440
2126
    SDL_DestroyCond(is->pictq_cond);
 
2127
    SDL_DestroyMutex(is->subpq_mutex);
 
2128
    SDL_DestroyCond(is->subpq_cond);
1441
2129
}
1442
2130
 
1443
 
void stream_cycle_channel(VideoState *is, int codec_type)
 
2131
static void stream_cycle_channel(VideoState *is, int codec_type)
1444
2132
{
1445
2133
    AVFormatContext *ic = is->ic;
1446
2134
    int start_index, stream_index;
1448
2136
 
1449
2137
    if (codec_type == CODEC_TYPE_VIDEO)
1450
2138
        start_index = is->video_stream;
1451
 
    else
 
2139
    else if (codec_type == CODEC_TYPE_AUDIO)
1452
2140
        start_index = is->audio_stream;
1453
 
    if (start_index < 0)
 
2141
    else
 
2142
        start_index = is->subtitle_stream;
 
2143
    if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0))
1454
2144
        return;
1455
2145
    stream_index = start_index;
1456
2146
    for(;;) {
1457
2147
        if (++stream_index >= is->ic->nb_streams)
1458
 
            stream_index = 0;
 
2148
        {
 
2149
            if (codec_type == CODEC_TYPE_SUBTITLE)
 
2150
            {
 
2151
                stream_index = -1;
 
2152
                goto the_end;
 
2153
            } else
 
2154
                stream_index = 0;
 
2155
        }
1459
2156
        if (stream_index == start_index)
1460
2157
            return;
1461
2158
        st = ic->streams[stream_index];
1462
 
        if (st->codec.codec_type == codec_type) {
 
2159
        if (st->codec->codec_type == codec_type) {
1463
2160
            /* check that parameters are OK */
1464
2161
            switch(codec_type) {
1465
2162
            case CODEC_TYPE_AUDIO:
1466
 
                if (st->codec.sample_rate != 0 &&
1467
 
                    st->codec.channels != 0)
 
2163
                if (st->codec->sample_rate != 0 &&
 
2164
                    st->codec->channels != 0)
1468
2165
                    goto the_end;
1469
2166
                break;
1470
2167
            case CODEC_TYPE_VIDEO:
 
2168
            case CODEC_TYPE_SUBTITLE:
1471
2169
                goto the_end;
1472
2170
            default:
1473
2171
                break;
1480
2178
}
1481
2179
 
1482
2180
 
1483
 
void toggle_full_screen(void)
 
2181
static void toggle_full_screen(void)
1484
2182
{
1485
 
    int w, h, flags;
1486
2183
    is_full_screen = !is_full_screen;
1487
2184
    if (!fs_screen_width) {
1488
2185
        /* use default SDL method */
1489
 
        SDL_WM_ToggleFullScreen(screen);
1490
 
    } else {
1491
 
        /* use the recorded resolution */
1492
 
        flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
1493
 
        if (is_full_screen) {
1494
 
            w = fs_screen_width;
1495
 
            h = fs_screen_height;
1496
 
            flags |= SDL_FULLSCREEN;
1497
 
        } else {
1498
 
            w = screen_width;
1499
 
            h = screen_height;
1500
 
            flags |= SDL_RESIZABLE;
1501
 
        }
1502
 
        screen = SDL_SetVideoMode(w, h, 0, flags);
1503
 
        cur_stream->width = w;
1504
 
        cur_stream->height = h;
 
2186
//        SDL_WM_ToggleFullScreen(screen);
1505
2187
    }
 
2188
    video_open(cur_stream);
1506
2189
}
1507
2190
 
1508
 
void toggle_pause(void)
 
2191
static void toggle_pause(void)
1509
2192
{
1510
2193
    if (cur_stream)
1511
2194
        stream_pause(cur_stream);
1512
 
}
1513
 
 
1514
 
void do_exit(void)
 
2195
    step = 0;
 
2196
}
 
2197
 
 
2198
static void step_to_next_frame(void)
 
2199
{
 
2200
    if (cur_stream) {
 
2201
        if (cur_stream->paused)
 
2202
            cur_stream->paused=0;
 
2203
        cur_stream->video_current_pts = get_video_clock(cur_stream);
 
2204
    }
 
2205
    step = 1;
 
2206
}
 
2207
 
 
2208
static void do_exit(void)
1515
2209
{
1516
2210
    if (cur_stream) {
1517
2211
        stream_close(cur_stream);
1523
2217
    exit(0);
1524
2218
}
1525
2219
 
1526
 
void toggle_audio_display(void)
 
2220
static void toggle_audio_display(void)
1527
2221
{
1528
2222
    if (cur_stream) {
1529
2223
        cur_stream->show_audio = !cur_stream->show_audio;
1531
2225
}
1532
2226
 
1533
2227
/* handle an event sent by the GUI */
1534
 
void event_loop(void)
 
2228
static void event_loop(void)
1535
2229
{
1536
2230
    SDL_Event event;
 
2231
    double incr, pos, frac;
1537
2232
 
1538
2233
    for(;;) {
1539
2234
        SDL_WaitEvent(&event);
1551
2246
            case SDLK_SPACE:
1552
2247
                toggle_pause();
1553
2248
                break;
 
2249
            case SDLK_s: //S: Step to next frame
 
2250
                step_to_next_frame();
 
2251
                break;
1554
2252
            case SDLK_a:
1555
 
                if (cur_stream) 
 
2253
                if (cur_stream)
1556
2254
                    stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);
1557
2255
                break;
1558
2256
            case SDLK_v:
1559
 
                if (cur_stream) 
 
2257
                if (cur_stream)
1560
2258
                    stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);
1561
2259
                break;
 
2260
            case SDLK_t:
 
2261
                if (cur_stream)
 
2262
                    stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE);
 
2263
                break;
1562
2264
            case SDLK_w:
1563
2265
                toggle_audio_display();
1564
2266
                break;
 
2267
            case SDLK_LEFT:
 
2268
                incr = -10.0;
 
2269
                goto do_seek;
 
2270
            case SDLK_RIGHT:
 
2271
                incr = 10.0;
 
2272
                goto do_seek;
 
2273
            case SDLK_UP:
 
2274
                incr = 60.0;
 
2275
                goto do_seek;
 
2276
            case SDLK_DOWN:
 
2277
                incr = -60.0;
 
2278
            do_seek:
 
2279
                if (cur_stream) {
 
2280
                    if (seek_by_bytes) {
 
2281
                        pos = url_ftell(&cur_stream->ic->pb);
 
2282
                        if (cur_stream->ic->bit_rate)
 
2283
                            incr *= cur_stream->ic->bit_rate / 60.0;
 
2284
                        else
 
2285
                            incr *= 180000.0;
 
2286
                        pos += incr;
 
2287
                        stream_seek(cur_stream, pos, incr);
 
2288
                    } else {
 
2289
                        pos = get_master_clock(cur_stream);
 
2290
                        pos += incr;
 
2291
                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr);
 
2292
                    }
 
2293
                }
 
2294
                break;
1565
2295
            default:
1566
2296
                break;
1567
2297
            }
1568
2298
            break;
 
2299
        case SDL_MOUSEBUTTONDOWN:
 
2300
            if (cur_stream) {
 
2301
                int ns, hh, mm, ss;
 
2302
                int tns, thh, tmm, tss;
 
2303
                tns = cur_stream->ic->duration/1000000LL;
 
2304
                thh = tns/3600;
 
2305
                tmm = (tns%3600)/60;
 
2306
                tss = (tns%60);
 
2307
                frac = (double)event.button.x/(double)cur_stream->width;
 
2308
                ns = frac*tns;
 
2309
                hh = ns/3600;
 
2310
                mm = (ns%3600)/60;
 
2311
                ss = (ns%60);
 
2312
                fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
 
2313
                        hh, mm, ss, thh, tmm, tss);
 
2314
                stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
 
2315
            }
 
2316
            break;
1569
2317
        case SDL_VIDEORESIZE:
1570
2318
            if (cur_stream) {
1571
 
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0, 
 
2319
                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
1572
2320
                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
1573
 
                cur_stream->width = event.resize.w;
1574
 
                cur_stream->height = event.resize.h;
 
2321
                screen_width = cur_stream->width = event.resize.w;
 
2322
                screen_height= cur_stream->height= event.resize.h;
1575
2323
            }
1576
2324
            break;
1577
2325
        case SDL_QUIT:
1579
2327
            do_exit();
1580
2328
            break;
1581
2329
        case FF_ALLOC_EVENT:
 
2330
            video_open(event.user.data1);
1582
2331
            alloc_picture(event.user.data1);
1583
2332
            break;
1584
2333
        case FF_REFRESH_EVENT:
1590
2339
    }
1591
2340
}
1592
2341
 
 
2342
static void opt_frame_size(const char *arg)
 
2343
{
 
2344
    if (parse_image_size(&frame_width, &frame_height, arg) < 0) {
 
2345
        fprintf(stderr, "Incorrect frame size\n");
 
2346
        exit(1);
 
2347
    }
 
2348
    if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
 
2349
        fprintf(stderr, "Frame size must be a multiple of 2\n");
 
2350
        exit(1);
 
2351
    }
 
2352
}
 
2353
 
1593
2354
void opt_width(const char *arg)
1594
2355
{
1595
2356
    screen_width = atoi(arg);
 
2357
    if(screen_width<=0){
 
2358
        fprintf(stderr, "invalid width\n");
 
2359
        exit(1);
 
2360
    }
1596
2361
}
1597
2362
 
1598
2363
void opt_height(const char *arg)
1599
2364
{
1600
2365
    screen_height = atoi(arg);
 
2366
    if(screen_height<=0){
 
2367
        fprintf(stderr, "invalid height\n");
 
2368
        exit(1);
 
2369
    }
1601
2370
}
1602
2371
 
1603
2372
static void opt_format(const char *arg)
1609
2378
    }
1610
2379
}
1611
2380
 
1612
 
static void opt_image_format(const char *arg)
 
2381
static void opt_frame_pix_fmt(const char *arg)
1613
2382
{
1614
 
    AVImageFormat *f;
1615
 
    
1616
 
    for(f = first_image_format; f != NULL; f = f->next) {
1617
 
        if (!strcmp(arg, f->name))
1618
 
            break;
1619
 
    }
1620
 
    if (!f) {
1621
 
        fprintf(stderr, "Unknown image format: '%s'\n", arg);
1622
 
        exit(1);
1623
 
    }
1624
 
    image_format = f;
 
2383
    frame_pix_fmt = avcodec_get_pix_fmt(arg);
1625
2384
}
1626
2385
 
1627
2386
#ifdef CONFIG_NETWORK
1644
2403
        show_help();
1645
2404
}
1646
2405
 
 
2406
void opt_seek(const char *arg)
 
2407
{
 
2408
    start_time = parse_date(arg, 1);
 
2409
}
 
2410
 
 
2411
static void opt_debug(const char *arg)
 
2412
{
 
2413
    av_log_level = 99;
 
2414
    debug = atoi(arg);
 
2415
}
 
2416
 
 
2417
static void opt_vismv(const char *arg)
 
2418
{
 
2419
    debug_mv = atoi(arg);
 
2420
}
 
2421
 
 
2422
static void opt_thread_count(const char *arg)
 
2423
{
 
2424
    thread_count= atoi(arg);
 
2425
#if !defined(HAVE_THREADS)
 
2426
    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
 
2427
#endif
 
2428
}
 
2429
 
1647
2430
const OptionDef options[] = {
1648
2431
    { "h", 0, {(void*)show_help}, "show help" },
1649
2432
    { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },
1650
2433
    { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },
1651
 
#if 0
1652
 
    /* disabled as SDL/X11 does not support it correctly on application launch */
 
2434
    { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
1653
2435
    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },
1654
 
#endif
1655
2436
    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
1656
2437
    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },
 
2438
    { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_audio_stream}, "", "" },
 
2439
    { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },
 
2440
    { "bytes", OPT_BOOL, {(void*)&seek_by_bytes}, "seek by bytes" },
1657
2441
    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },
1658
2442
    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
1659
 
    { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" },
 
2443
    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
1660
2444
    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },
 
2445
    { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },
 
2446
    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },
 
2447
    { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },
 
2448
    { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" },
 
2449
    { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" },
 
2450
    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" },
 
2451
    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" },
 
2452
    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" },
 
2453
    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" },
 
2454
    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo",  "algo" },
 
2455
    { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)",  "threshold" },
 
2456
    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options",  "bit_mask" },
1661
2457
#ifdef CONFIG_NETWORK
1662
2458
    { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },
1663
2459
#endif
1664
 
    { "sync", HAS_ARG | OPT_EXPERT, {(void*)&opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
 
2460
    { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
 
2461
    { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
1665
2462
    { NULL, },
1666
2463
};
1667
2464
 
1668
2465
void show_help(void)
1669
2466
{
1670
 
    printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
 
2467
    printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003-2006 Fabrice Bellard, et al.\n"
1671
2468
           "usage: ffplay [options] input_file\n"
1672
2469
           "Simple media player\n");
1673
2470
    printf("\n");
1681
2478
           "p, SPC              pause\n"
1682
2479
           "a                   cycle audio channel\n"
1683
2480
           "v                   cycle video channel\n"
 
2481
           "t                   cycle subtitle channel\n"
1684
2482
           "w                   show audio waves\n"
 
2483
           "left/right          seek backward/forward 10 seconds\n"
 
2484
           "down/up             seek backward/forward 1 minute\n"
 
2485
           "mouse click         seek to percentage in file corresponding to fraction of width\n"
1685
2486
           );
1686
2487
    exit(1);
1687
2488
}
1696
2497
/* Called from the main */
1697
2498
int main(int argc, char **argv)
1698
2499
{
1699
 
    int flags, w, h;
1700
 
    
 
2500
    int flags;
 
2501
 
1701
2502
    /* register all codecs, demux and protocols */
1702
2503
    av_register_all();
1703
2504
 
 
2505
    #ifdef CONFIG_OS2
 
2506
      MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions
 
2507
 
 
2508
      // Make stdout and stderr unbuffered
 
2509
      setbuf( stdout, NULL );
 
2510
      setbuf( stderr, NULL );
 
2511
    #endif
 
2512
 
1704
2513
    parse_options(argc, argv, options);
1705
2514
 
1706
2515
    if (!input_filename)
1710
2519
        video_disable = 1;
1711
2520
    }
1712
2521
    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
1713
 
#ifndef CONFIG_WIN32
1714
 
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 */
 
2522
#if !defined(__MINGW32__) && !defined(CONFIG_DARWIN)
 
2523
    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 or darwin */
1715
2524
#endif
1716
2525
    if (SDL_Init (flags)) {
1717
 
        fprintf(stderr, "Could not initialize SDL - exiting\n");
 
2526
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
1718
2527
        exit(1);
1719
2528
    }
1720
2529
 
1721
2530
    if (!display_disable) {
1722
 
#ifdef HAVE_X11
1723
 
        /* save the screen resolution... SDL should allow full screen
1724
 
           by resizing the window */
1725
 
        {
1726
 
            Display *dpy;
1727
 
            dpy = XOpenDisplay(NULL);
1728
 
            if (dpy) {
1729
 
                fs_screen_width = DisplayWidth(dpy, DefaultScreen(dpy));
1730
 
                fs_screen_height = DisplayHeight(dpy, DefaultScreen(dpy));
1731
 
                XCloseDisplay(dpy);
1732
 
            }
1733
 
        }
 
2531
#ifdef HAVE_SDL_VIDEO_SIZE
 
2532
        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
 
2533
        fs_screen_width = vi->current_w;
 
2534
        fs_screen_height = vi->current_h;
1734
2535
#endif
1735
 
        flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
1736
 
        if (is_full_screen && fs_screen_width) {
1737
 
            w = fs_screen_width;
1738
 
            h = fs_screen_height;
1739
 
            flags |= SDL_FULLSCREEN;
1740
 
        } else {
1741
 
            w = screen_width;
1742
 
            h = screen_height;
1743
 
            flags |= SDL_RESIZABLE;
1744
 
        }
1745
 
        screen = SDL_SetVideoMode(w, h, 0, flags);
1746
 
        if (!screen) {
1747
 
            fprintf(stderr, "SDL: could not set video mode - exiting\n");
1748
 
            exit(1);
1749
 
        }
1750
 
        SDL_WM_SetCaption("FFplay", "FFplay");
1751
2536
    }
1752
2537
 
1753
2538
    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
1755
2540
    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
1756
2541
    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
1757
2542
 
 
2543
    av_init_packet(&flush_pkt);
 
2544
    flush_pkt.data= "FLUSH";
 
2545
 
1758
2546
    cur_stream = stream_open(input_filename, file_iformat);
1759
2547
 
1760
2548
    event_loop();