Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpeg.c @ a7eb3c8d

History | View | Annotate | Download (34.5 KB)

1 de6d9b64 Fabrice Bellard
/*
2 fb7566d0 Fabrice Bellard
 * MPEG1/2 mux/demux
3 19720f15 Fabrice Bellard
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4 de6d9b64 Fabrice Bellard
 *
5 19720f15 Fabrice Bellard
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9 de6d9b64 Fabrice Bellard
 *
10 19720f15 Fabrice Bellard
 * This library is distributed in the hope that it will be useful,
11 de6d9b64 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 19720f15 Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14 de6d9b64 Fabrice Bellard
 *
15 19720f15 Fabrice Bellard
 * 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 de6d9b64 Fabrice Bellard
 */
19
#include "avformat.h"
20
21
#define MAX_PAYLOAD_SIZE 4096
22 27f388aa Fabrice Bellard
//#define DEBUG_SEEK
23 de6d9b64 Fabrice Bellard
24
typedef struct {
25 0c1a9eda Zdenek Kabelac
    uint8_t buffer[MAX_PAYLOAD_SIZE];
26 de6d9b64 Fabrice Bellard
    int buffer_ptr;
27 0dbb48d9 Fabrice Bellard
    int nb_frames;    /* number of starting frame encountered (AC3) */
28
    int frame_start_offset; /* starting offset of the frame + 1 (0 if none) */
29 0c1a9eda Zdenek Kabelac
    uint8_t id;
30 de6d9b64 Fabrice Bellard
    int max_buffer_size; /* in bytes */
31
    int packet_number;
32 0c1a9eda Zdenek Kabelac
    int64_t start_pts;
33 27a206e0 Michel Bardiaux
    int64_t start_dts;
34 044007c2 Fabrice Bellard
    uint8_t lpcm_header[3];
35
    int lpcm_align;
36 de6d9b64 Fabrice Bellard
} StreamInfo;
37
38
typedef struct {
39
    int packet_size; /* required packet size */
40
    int packet_number;
41
    int pack_header_freq;     /* frequency (in packets^-1) at which we send pack headers */
42
    int system_header_freq;
43 0dbb48d9 Fabrice Bellard
    int system_header_size;
44 de6d9b64 Fabrice Bellard
    int mux_rate; /* bitrate in units of 50 bytes/s */
45
    /* stream info */
46
    int audio_bound;
47
    int video_bound;
48 fb7566d0 Fabrice Bellard
    int is_mpeg2;
49
    int is_vcd;
50 27a206e0 Michel Bardiaux
    int scr_stream_index; /* stream from which the system clock is
51
                             computed (VBR case) */
52
    int64_t last_scr; /* current system clock */
53 de6d9b64 Fabrice Bellard
} MpegMuxContext;
54
55
#define PACK_START_CODE             ((unsigned int)0x000001ba)
56
#define SYSTEM_HEADER_START_CODE    ((unsigned int)0x000001bb)
57 92b3e125 Juanjo
#define SEQUENCE_END_CODE           ((unsigned int)0x000001b7)
58 de6d9b64 Fabrice Bellard
#define PACKET_START_CODE_MASK      ((unsigned int)0xffffff00)
59
#define PACKET_START_CODE_PREFIX    ((unsigned int)0x00000100)
60
#define ISO_11172_END_CODE          ((unsigned int)0x000001b9)
61
  
62
/* mpeg2 */
63
#define PROGRAM_STREAM_MAP 0x1bc
64
#define PRIVATE_STREAM_1   0x1bd
65
#define PADDING_STREAM     0x1be
66
#define PRIVATE_STREAM_2   0x1bf
67
68
69
#define AUDIO_ID 0xc0
70
#define VIDEO_ID 0xe0
71 044007c2 Fabrice Bellard
#define AC3_ID   0x80
72
#define LPCM_ID  0xa0
73 de6d9b64 Fabrice Bellard
74 764ef400 Mike Melanson
#ifdef CONFIG_ENCODERS
75 fb7566d0 Fabrice Bellard
extern AVOutputFormat mpeg1system_mux;
76
extern AVOutputFormat mpeg1vcd_mux;
77
extern AVOutputFormat mpeg2vob_mux;
78
79 044007c2 Fabrice Bellard
static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };
80
81 de6d9b64 Fabrice Bellard
static int put_pack_header(AVFormatContext *ctx, 
82 0c1a9eda Zdenek Kabelac
                           uint8_t *buf, int64_t timestamp)
83 de6d9b64 Fabrice Bellard
{
84
    MpegMuxContext *s = ctx->priv_data;
85
    PutBitContext pb;
86
    
87 117a5490 Alex Beregszaszi
    init_put_bits(&pb, buf, 128);
88 de6d9b64 Fabrice Bellard
89
    put_bits(&pb, 32, PACK_START_CODE);
90 b2cac184 Fabrice Bellard
    if (s->is_mpeg2) {
91 8683e4a0 Måns Rullgård
        put_bits(&pb, 2, 0x1);
92 b2cac184 Fabrice Bellard
    } else {
93
        put_bits(&pb, 4, 0x2);
94
    }
95 0c1a9eda Zdenek Kabelac
    put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07));
96 de6d9b64 Fabrice Bellard
    put_bits(&pb, 1, 1);
97 0c1a9eda Zdenek Kabelac
    put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff));
98 de6d9b64 Fabrice Bellard
    put_bits(&pb, 1, 1);
99 0c1a9eda Zdenek Kabelac
    put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff));
100 de6d9b64 Fabrice Bellard
    put_bits(&pb, 1, 1);
101 b2cac184 Fabrice Bellard
    if (s->is_mpeg2) {
102
        /* clock extension */
103
        put_bits(&pb, 9, 0);
104
        put_bits(&pb, 1, 1);
105
    }
106 de6d9b64 Fabrice Bellard
    put_bits(&pb, 1, 1);
107
    put_bits(&pb, 22, s->mux_rate);
108
    put_bits(&pb, 1, 1);
109 b2cac184 Fabrice Bellard
    if (s->is_mpeg2) {
110
        put_bits(&pb, 5, 0x1f); /* reserved */
111
        put_bits(&pb, 3, 0); /* stuffing length */
112
    }
113 de6d9b64 Fabrice Bellard
    flush_put_bits(&pb);
114 17592475 Michael Niedermayer
    return pbBufPtr(&pb) - pb.buf;
115 de6d9b64 Fabrice Bellard
}
116
117 0c1a9eda Zdenek Kabelac
static int put_system_header(AVFormatContext *ctx, uint8_t *buf)
118 de6d9b64 Fabrice Bellard
{
119
    MpegMuxContext *s = ctx->priv_data;
120
    int size, rate_bound, i, private_stream_coded, id;
121
    PutBitContext pb;
122
123 117a5490 Alex Beregszaszi
    init_put_bits(&pb, buf, 128);
124 de6d9b64 Fabrice Bellard
125
    put_bits(&pb, 32, SYSTEM_HEADER_START_CODE);
126
    put_bits(&pb, 16, 0);
127
    put_bits(&pb, 1, 1);
128
    
129
    rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */
130
    put_bits(&pb, 22, rate_bound);
131
    put_bits(&pb, 1, 1); /* marker */
132
    put_bits(&pb, 6, s->audio_bound);
133
134
    put_bits(&pb, 1, 1); /* variable bitrate */
135
    put_bits(&pb, 1, 1); /* non constrainted bit stream */
136
    
137
    put_bits(&pb, 1, 0); /* audio locked */
138
    put_bits(&pb, 1, 0); /* video locked */
139
    put_bits(&pb, 1, 1); /* marker */
140
141
    put_bits(&pb, 5, s->video_bound);
142
    put_bits(&pb, 8, 0xff); /* reserved byte */
143
    
144
    /* audio stream info */
145
    private_stream_coded = 0;
146
    for(i=0;i<ctx->nb_streams;i++) {
147
        StreamInfo *stream = ctx->streams[i]->priv_data;
148
        id = stream->id;
149
        if (id < 0xc0) {
150
            /* special case for private streams (AC3 use that) */
151
            if (private_stream_coded)
152
                continue;
153
            private_stream_coded = 1;
154
            id = 0xbd;
155
        }
156
        put_bits(&pb, 8, id); /* stream ID */
157
        put_bits(&pb, 2, 3);
158
        if (id < 0xe0) {
159
            /* audio */
160
            put_bits(&pb, 1, 0);
161
            put_bits(&pb, 13, stream->max_buffer_size / 128);
162
        } else {
163
            /* video */
164
            put_bits(&pb, 1, 1);
165
            put_bits(&pb, 13, stream->max_buffer_size / 1024);
166
        }
167
    }
168
    flush_put_bits(&pb);
169 17592475 Michael Niedermayer
    size = pbBufPtr(&pb) - pb.buf;
170 de6d9b64 Fabrice Bellard
    /* patch packet size */
171
    buf[4] = (size - 6) >> 8;
172
    buf[5] = (size - 6) & 0xff;
173
174
    return size;
175
}
176
177 0dbb48d9 Fabrice Bellard
static int get_system_header_size(AVFormatContext *ctx)
178
{
179
    int buf_index, i, private_stream_coded;
180
    StreamInfo *stream;
181
182
    buf_index = 12;
183
    private_stream_coded = 0;
184
    for(i=0;i<ctx->nb_streams;i++) {
185
        stream = ctx->streams[i]->priv_data;
186
        if (stream->id < 0xc0) {
187
            if (private_stream_coded)
188
                continue;
189
            private_stream_coded = 1;
190
        }
191
        buf_index += 3;
192
    }
193
    return buf_index;
194
}
195
196 de6d9b64 Fabrice Bellard
static int mpeg_mux_init(AVFormatContext *ctx)
197
{
198 db7f1f95 Fabrice Bellard
    MpegMuxContext *s = ctx->priv_data;
199 044007c2 Fabrice Bellard
    int bitrate, i, mpa_id, mpv_id, ac3_id, lpcm_id, j;
200 de6d9b64 Fabrice Bellard
    AVStream *st;
201
    StreamInfo *stream;
202
203
    s->packet_number = 0;
204 fb7566d0 Fabrice Bellard
    s->is_vcd = (ctx->oformat == &mpeg1vcd_mux);
205
    s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux);
206
    
207
    if (s->is_vcd)
208 92b3e125 Juanjo
        s->packet_size = 2324; /* VCD packet size */
209
    else
210
        s->packet_size = 2048;
211
        
212 de6d9b64 Fabrice Bellard
    s->audio_bound = 0;
213
    s->video_bound = 0;
214
    mpa_id = AUDIO_ID;
215 044007c2 Fabrice Bellard
    ac3_id = AC3_ID;
216 de6d9b64 Fabrice Bellard
    mpv_id = VIDEO_ID;
217 044007c2 Fabrice Bellard
    lpcm_id = LPCM_ID;
218 27a206e0 Michel Bardiaux
    s->scr_stream_index = -1;
219 de6d9b64 Fabrice Bellard
    for(i=0;i<ctx->nb_streams;i++) {
220
        st = ctx->streams[i];
221
        stream = av_mallocz(sizeof(StreamInfo));
222
        if (!stream)
223
            goto fail;
224
        st->priv_data = stream;
225
226
        switch(st->codec.codec_type) {
227
        case CODEC_TYPE_AUDIO:
228 044007c2 Fabrice Bellard
            if (st->codec.codec_id == CODEC_ID_AC3) {
229 de6d9b64 Fabrice Bellard
                stream->id = ac3_id++;
230 044007c2 Fabrice Bellard
            } else if (st->codec.codec_id == CODEC_ID_PCM_S16BE) {
231
                stream->id = lpcm_id++;
232
                for(j = 0; j < 4; j++) {
233
                    if (lpcm_freq_tab[j] == st->codec.sample_rate)
234
                        break;
235
                }
236
                if (j == 4)
237
                    goto fail;
238
                if (st->codec.channels > 8)
239
                    return -1;
240
                stream->lpcm_header[0] = 0x0c;
241
                stream->lpcm_header[1] = (st->codec.channels - 1) | (j << 4);
242
                stream->lpcm_header[2] = 0x80;
243
                stream->lpcm_align = st->codec.channels * 2;
244
            } else {
245 de6d9b64 Fabrice Bellard
                stream->id = mpa_id++;
246 044007c2 Fabrice Bellard
            }
247 de6d9b64 Fabrice Bellard
            stream->max_buffer_size = 4 * 1024; 
248
            s->audio_bound++;
249
            break;
250
        case CODEC_TYPE_VIDEO:
251 27a206e0 Michel Bardiaux
            /* by default, video is used for the SCR computation */
252
            if (s->scr_stream_index == -1)
253
                s->scr_stream_index = i;
254 de6d9b64 Fabrice Bellard
            stream->id = mpv_id++;
255
            stream->max_buffer_size = 46 * 1024; 
256
            s->video_bound++;
257
            break;
258 ac5e6a5b Philip Gladstone
        default:
259 42343f7e Philip Gladstone
            av_abort();
260 de6d9b64 Fabrice Bellard
        }
261
    }
262 27a206e0 Michel Bardiaux
    /* if no SCR, use first stream (audio) */
263
    if (s->scr_stream_index == -1)
264
        s->scr_stream_index = 0;
265 de6d9b64 Fabrice Bellard
266
    /* we increase slightly the bitrate to take into account the
267
       headers. XXX: compute it exactly */
268
    bitrate = 2000;
269
    for(i=0;i<ctx->nb_streams;i++) {
270
        st = ctx->streams[i];
271
        bitrate += st->codec.bit_rate;
272
    }
273
    s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
274 92b3e125 Juanjo
    
275 fb7566d0 Fabrice Bellard
    if (s->is_vcd || s->is_mpeg2)
276 92b3e125 Juanjo
        /* every packet */
277
        s->pack_header_freq = 1;
278
    else
279
        /* every 2 seconds */
280
        s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
281 b623bbcb Michael Niedermayer
282
    /* the above seems to make pack_header_freq zero sometimes */
283
    if (s->pack_header_freq == 0)
284
       s->pack_header_freq = 1;
285 92b3e125 Juanjo
    
286 b2cac184 Fabrice Bellard
    if (s->is_mpeg2)
287
        /* every 200 packets. Need to look at the spec.  */
288
        s->system_header_freq = s->pack_header_freq * 40;
289
    else if (s->is_vcd)
290 92b3e125 Juanjo
        /* every 40 packets, this is my invention */
291
        s->system_header_freq = s->pack_header_freq * 40;
292
    else
293
        s->system_header_freq = s->pack_header_freq * 5;
294
    
295 de6d9b64 Fabrice Bellard
    for(i=0;i<ctx->nb_streams;i++) {
296
        stream = ctx->streams[i]->priv_data;
297
        stream->buffer_ptr = 0;
298
        stream->packet_number = 0;
299 27a206e0 Michel Bardiaux
        stream->start_pts = AV_NOPTS_VALUE;
300
        stream->start_dts = AV_NOPTS_VALUE;
301 de6d9b64 Fabrice Bellard
    }
302 0dbb48d9 Fabrice Bellard
    s->system_header_size = get_system_header_size(ctx);
303 27a206e0 Michel Bardiaux
    s->last_scr = 0;
304 de6d9b64 Fabrice Bellard
    return 0;
305
 fail:
306
    for(i=0;i<ctx->nb_streams;i++) {
307 1ea4f593 Fabrice Bellard
        av_free(ctx->streams[i]->priv_data);
308 de6d9b64 Fabrice Bellard
    }
309
    return -ENOMEM;
310
}
311
312 27a206e0 Michel Bardiaux
static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp)
313
{
314
    put_byte(pb, 
315
             (id << 4) | 
316
             (((timestamp >> 30) & 0x07) << 1) | 
317
             1);
318
    put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1));
319
    put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1));
320
}
321
322 0dbb48d9 Fabrice Bellard
323
/* return the exact available payload size for the next packet for
324
   stream 'stream_index'. 'pts' and 'dts' are only used to know if
325
   timestamps are needed in the packet header. */
326
static int get_packet_payload_size(AVFormatContext *ctx, int stream_index,
327
                                   int64_t pts, int64_t dts)
328
{
329
    MpegMuxContext *s = ctx->priv_data;
330
    int buf_index;
331
    StreamInfo *stream;
332
333
    buf_index = 0;
334
    if (((s->packet_number % s->pack_header_freq) == 0)) {
335
        /* pack header size */
336
        if (s->is_mpeg2) 
337
            buf_index += 14;
338
        else
339
            buf_index += 12;
340
        if ((s->packet_number % s->system_header_freq) == 0)
341
            buf_index += s->system_header_size;
342
    }
343
344
    /* packet header size */
345
    buf_index += 6;
346
    if (s->is_mpeg2)
347
        buf_index += 3;
348
    if (pts != AV_NOPTS_VALUE) {
349 e45f1943 Fabrice Bellard
        if (dts != pts)
350 0dbb48d9 Fabrice Bellard
            buf_index += 5 + 5;
351
        else
352
            buf_index += 5;
353
    } else {
354
        if (!s->is_mpeg2)
355
            buf_index++;
356
    }
357
    
358
    stream = ctx->streams[stream_index]->priv_data;
359
    if (stream->id < 0xc0) {
360 044007c2 Fabrice Bellard
        /* AC3/LPCM private data header */
361 0dbb48d9 Fabrice Bellard
        buf_index += 4;
362 044007c2 Fabrice Bellard
        if (stream->id >= 0xa0) {
363
            int n;
364
            buf_index += 3;
365
            /* NOTE: we round the payload size to an integer number of
366
               LPCM samples */
367
            n = (s->packet_size - buf_index) % stream->lpcm_align;
368
            if (n)
369
                buf_index += (stream->lpcm_align - n);
370
        }
371 0dbb48d9 Fabrice Bellard
    }
372
    return s->packet_size - buf_index; 
373
}
374
375 de6d9b64 Fabrice Bellard
/* flush the packet on stream stream_index */
376 27a206e0 Michel Bardiaux
static void flush_packet(AVFormatContext *ctx, int stream_index, 
377
                         int64_t pts, int64_t dts, int64_t scr)
378 de6d9b64 Fabrice Bellard
{
379
    MpegMuxContext *s = ctx->priv_data;
380
    StreamInfo *stream = ctx->streams[stream_index]->priv_data;
381 0c1a9eda Zdenek Kabelac
    uint8_t *buf_ptr;
382 0dbb48d9 Fabrice Bellard
    int size, payload_size, startcode, id, stuffing_size, i, header_len;
383
    int packet_size;
384 0c1a9eda Zdenek Kabelac
    uint8_t buffer[128];
385 92b3e125 Juanjo
    
386 de6d9b64 Fabrice Bellard
    id = stream->id;
387 27a206e0 Michel Bardiaux
    
388 de6d9b64 Fabrice Bellard
#if 0
389
    printf("packet ID=%2x PTS=%0.3f\n", 
390 27a206e0 Michel Bardiaux
           id, pts / 90000.0);
391 de6d9b64 Fabrice Bellard
#endif
392
393
    buf_ptr = buffer;
394 92b3e125 Juanjo
    if (((s->packet_number % s->pack_header_freq) == 0)) {
395 de6d9b64 Fabrice Bellard
        /* output pack and systems header if needed */
396 27a206e0 Michel Bardiaux
        size = put_pack_header(ctx, buf_ptr, scr);
397 de6d9b64 Fabrice Bellard
        buf_ptr += size;
398
        if ((s->packet_number % s->system_header_freq) == 0) {
399
            size = put_system_header(ctx, buf_ptr);
400
            buf_ptr += size;
401
        }
402
    }
403
    size = buf_ptr - buffer;
404
    put_buffer(&ctx->pb, buffer, size);
405
406
    /* packet header */
407 fb7566d0 Fabrice Bellard
    if (s->is_mpeg2) {
408 27a206e0 Michel Bardiaux
        header_len = 3;
409 fb7566d0 Fabrice Bellard
    } else {
410 27a206e0 Michel Bardiaux
        header_len = 0;
411 fb7566d0 Fabrice Bellard
    }
412 27a206e0 Michel Bardiaux
    if (pts != AV_NOPTS_VALUE) {
413 e45f1943 Fabrice Bellard
        if (dts != pts)
414 27a206e0 Michel Bardiaux
            header_len += 5 + 5;
415
        else
416
            header_len += 5;
417
    } else {
418
        if (!s->is_mpeg2)
419
            header_len++;
420
    }
421
422 0dbb48d9 Fabrice Bellard
    packet_size = s->packet_size - (size + 6);
423
    payload_size = packet_size - header_len;
424 de6d9b64 Fabrice Bellard
    if (id < 0xc0) {
425
        startcode = PRIVATE_STREAM_1;
426
        payload_size -= 4;
427 044007c2 Fabrice Bellard
        if (id >= 0xa0)
428
            payload_size -= 3;
429 de6d9b64 Fabrice Bellard
    } else {
430
        startcode = 0x100 + id;
431
    }
432 0dbb48d9 Fabrice Bellard
433 de6d9b64 Fabrice Bellard
    stuffing_size = payload_size - stream->buffer_ptr;
434
    if (stuffing_size < 0)
435
        stuffing_size = 0;
436
    put_be32(&ctx->pb, startcode);
437
438 0dbb48d9 Fabrice Bellard
    put_be16(&ctx->pb, packet_size);
439 de6d9b64 Fabrice Bellard
    /* stuffing */
440
    for(i=0;i<stuffing_size;i++)
441
        put_byte(&ctx->pb, 0xff);
442 fb7566d0 Fabrice Bellard
443
    if (s->is_mpeg2) {
444
        put_byte(&ctx->pb, 0x80); /* mpeg2 id */
445 27a206e0 Michel Bardiaux
446
        if (pts != AV_NOPTS_VALUE) {
447 e45f1943 Fabrice Bellard
            if (dts != pts) {
448 27a206e0 Michel Bardiaux
                put_byte(&ctx->pb, 0xc0); /* flags */
449
                put_byte(&ctx->pb, header_len - 3);
450
                put_timestamp(&ctx->pb, 0x03, pts);
451
                put_timestamp(&ctx->pb, 0x01, dts);
452
            } else {
453
                put_byte(&ctx->pb, 0x80); /* flags */
454
                put_byte(&ctx->pb, header_len - 3);
455
                put_timestamp(&ctx->pb, 0x02, pts);
456
            }
457
        } else {
458
            put_byte(&ctx->pb, 0x00); /* flags */
459
            put_byte(&ctx->pb, header_len - 3);
460
        }
461
    } else {
462
        if (pts != AV_NOPTS_VALUE) {
463 e45f1943 Fabrice Bellard
            if (dts != pts) {
464 27a206e0 Michel Bardiaux
                put_timestamp(&ctx->pb, 0x03, pts);
465
                put_timestamp(&ctx->pb, 0x01, dts);
466
            } else {
467
                put_timestamp(&ctx->pb, 0x02, pts);
468
            }
469
        } else {
470
            put_byte(&ctx->pb, 0x0f);
471
        }
472 fb7566d0 Fabrice Bellard
    }
473 de6d9b64 Fabrice Bellard
474
    if (startcode == PRIVATE_STREAM_1) {
475
        put_byte(&ctx->pb, id);
476 044007c2 Fabrice Bellard
        if (id >= 0xa0) {
477
            /* LPCM (XXX: check nb_frames) */
478
            put_byte(&ctx->pb, 7);
479
            put_be16(&ctx->pb, 4); /* skip 3 header bytes */
480
            put_byte(&ctx->pb, stream->lpcm_header[0]);
481
            put_byte(&ctx->pb, stream->lpcm_header[1]);
482
            put_byte(&ctx->pb, stream->lpcm_header[2]);
483
        } else {
484
            /* AC3 */
485 0dbb48d9 Fabrice Bellard
            put_byte(&ctx->pb, stream->nb_frames);
486
            put_be16(&ctx->pb, stream->frame_start_offset);
487 de6d9b64 Fabrice Bellard
        }
488
    }
489
490
    /* output data */
491
    put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size);
492
    put_flush_packet(&ctx->pb);
493
    
494
    s->packet_number++;
495
    stream->packet_number++;
496 0dbb48d9 Fabrice Bellard
    stream->nb_frames = 0;
497
    stream->frame_start_offset = 0;
498 de6d9b64 Fabrice Bellard
}
499
500 e45f1943 Fabrice Bellard
/* XXX: move that to upper layer */
501
/* XXX: we assume that there are always 'max_b_frames' between
502
   reference frames. A better solution would be to use the AVFrame pts
503
   field */
504
static void compute_pts_dts(AVStream *st, int64_t *ppts, int64_t *pdts, 
505
                            int64_t timestamp)
506
{
507
    int frame_delay;
508
    int64_t pts, dts;
509
510
    if (st->codec.codec_type == CODEC_TYPE_VIDEO && 
511
        st->codec.max_b_frames != 0) {
512
        frame_delay = (st->codec.frame_rate_base * 90000LL) / 
513
            st->codec.frame_rate;
514
        if (timestamp == 0) {
515
            /* specific case for first frame : DTS just before */
516
            pts = timestamp;
517
            dts = timestamp - frame_delay;
518
        } else {
519
            timestamp -= frame_delay;
520
            if (st->codec.coded_frame->pict_type == FF_B_TYPE) {
521
                /* B frames has identical pts/dts */
522
                pts = timestamp;
523
                dts = timestamp;
524
            } else {
525
                /* a reference frame has a pts equal to the dts of the
526
                   _next_ one */
527
                dts = timestamp;
528
                pts = timestamp + (st->codec.max_b_frames + 1) * frame_delay;
529
            }
530
        }
531
#if 1
532
        printf("pts=%0.3f dts=%0.3f pict_type=%c\n", 
533
               pts / 90000.0, dts / 90000.0, 
534
               av_get_pict_type_char(st->codec.coded_frame->pict_type));
535
#endif
536
    } else {
537
        pts = timestamp;
538
        dts = timestamp;
539
    }
540
    *ppts = pts & ((1LL << 33) - 1);
541
    *pdts = dts & ((1LL << 33) - 1);
542
}
543
544 10bb7023 Juanjo
static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
545 e45f1943 Fabrice Bellard
                                 const uint8_t *buf, int size, 
546
                                 int64_t timestamp)
547 de6d9b64 Fabrice Bellard
{
548
    MpegMuxContext *s = ctx->priv_data;
549
    AVStream *st = ctx->streams[stream_index];
550
    StreamInfo *stream = st->priv_data;
551 e45f1943 Fabrice Bellard
    int64_t pts, dts, new_start_pts, new_start_dts;
552 0dbb48d9 Fabrice Bellard
    int len, avail_size;
553 27a206e0 Michel Bardiaux
554 e45f1943 Fabrice Bellard
    compute_pts_dts(st, &pts, &dts, timestamp);
555
556 27a206e0 Michel Bardiaux
    /* XXX: system clock should be computed precisely, especially for
557
       CBR case. The current mode gives at least something coherent */
558
    if (stream_index == s->scr_stream_index)
559
        s->last_scr = pts;
560 10bb7023 Juanjo
    
561 27a206e0 Michel Bardiaux
#if 0
562 e45f1943 Fabrice Bellard
    printf("%d: pts=%0.3f dts=%0.3f scr=%0.3f\n", 
563
           stream_index, 
564
           pts / 90000.0, 
565
           dts / 90000.0, 
566
           s->last_scr / 90000.0);
567 27a206e0 Michel Bardiaux
#endif
568
    
569
    /* we assume here that pts != AV_NOPTS_VALUE */
570 0dbb48d9 Fabrice Bellard
    new_start_pts = stream->start_pts;
571
    new_start_dts = stream->start_dts;
572
    
573 27a206e0 Michel Bardiaux
    if (stream->start_pts == AV_NOPTS_VALUE) {
574 0dbb48d9 Fabrice Bellard
        new_start_pts = pts;
575
        new_start_dts = dts;
576
    }
577
    avail_size = get_packet_payload_size(ctx, stream_index,
578
                                         new_start_pts, 
579
                                         new_start_dts);
580
    if (stream->buffer_ptr >= avail_size) {
581
        /* unlikely case: outputing the pts or dts increase the packet
582
           size so that we cannot write the start of the next
583
           packet. In this case, we must flush the current packet with
584
           padding */
585
        flush_packet(ctx, stream_index,
586
                     stream->start_pts, stream->start_dts, s->last_scr);
587
        stream->buffer_ptr = 0;
588 27a206e0 Michel Bardiaux
    }
589 0dbb48d9 Fabrice Bellard
    stream->start_pts = new_start_pts;
590
    stream->start_dts = new_start_dts;
591
    stream->nb_frames++;
592
    if (stream->frame_start_offset == 0)
593
        stream->frame_start_offset = stream->buffer_ptr;
594 de6d9b64 Fabrice Bellard
    while (size > 0) {
595 0dbb48d9 Fabrice Bellard
        avail_size = get_packet_payload_size(ctx, stream_index,
596
                                             stream->start_pts, 
597
                                             stream->start_dts);
598
        len = avail_size - stream->buffer_ptr;
599 de6d9b64 Fabrice Bellard
        if (len > size)
600
            len = size;
601
        memcpy(stream->buffer + stream->buffer_ptr, buf, len);
602
        stream->buffer_ptr += len;
603
        buf += len;
604
        size -= len;
605 0dbb48d9 Fabrice Bellard
        if (stream->buffer_ptr >= avail_size) {
606
            /* if packet full, we send it now */
607 27a206e0 Michel Bardiaux
            flush_packet(ctx, stream_index,
608
                         stream->start_pts, stream->start_dts, s->last_scr);
609 0dbb48d9 Fabrice Bellard
            stream->buffer_ptr = 0;
610 27a206e0 Michel Bardiaux
            /* Make sure only the FIRST pes packet for this frame has
611
               a timestamp */
612
            stream->start_pts = AV_NOPTS_VALUE;
613
            stream->start_dts = AV_NOPTS_VALUE;
614 de6d9b64 Fabrice Bellard
        }
615
    }
616 0dbb48d9 Fabrice Bellard
617 de6d9b64 Fabrice Bellard
    return 0;
618
}
619
620
static int mpeg_mux_end(AVFormatContext *ctx)
621
{
622 27a206e0 Michel Bardiaux
    MpegMuxContext *s = ctx->priv_data;
623 de6d9b64 Fabrice Bellard
    StreamInfo *stream;
624
    int i;
625
626
    /* flush each packet */
627
    for(i=0;i<ctx->nb_streams;i++) {
628
        stream = ctx->streams[i]->priv_data;
629 0dbb48d9 Fabrice Bellard
        if (stream->buffer_ptr > 0) {
630
            /* NOTE: we can always write the remaining data as it was
631
               tested before in mpeg_mux_write_packet() */
632
            flush_packet(ctx, i, stream->start_pts, stream->start_dts, 
633
                         s->last_scr);
634 92b3e125 Juanjo
        }
635 de6d9b64 Fabrice Bellard
    }
636
637 fa0f62c3 Fabrice Bellard
    /* End header according to MPEG1 systems standard. We do not write
638
       it as it is usually not needed by decoders and because it
639
       complicates MPEG stream concatenation. */
640 92b3e125 Juanjo
    //put_be32(&ctx->pb, ISO_11172_END_CODE);
641
    //put_flush_packet(&ctx->pb);
642 9d90c37f Michael Niedermayer
643
    for(i=0;i<ctx->nb_streams;i++)
644
        av_freep(&ctx->streams[i]->priv_data);
645
646 de6d9b64 Fabrice Bellard
    return 0;
647
}
648 764ef400 Mike Melanson
#endif //CONFIG_ENCODERS
649 de6d9b64 Fabrice Bellard
650
/*********************************************/
651
/* demux code */
652
653
#define MAX_SYNC_SIZE 100000
654
655 db7f1f95 Fabrice Bellard
static int mpegps_probe(AVProbeData *p)
656
{
657 ec23a472 Isaac Richards
    int code, c, i;
658 db7f1f95 Fabrice Bellard
659 ec23a472 Isaac Richards
    code = 0xff;
660 db7f1f95 Fabrice Bellard
    /* we search the first start code. If it is a packet start code,
661
       then we decide it is mpeg ps. We do not send highest value to
662
       give a chance to mpegts */
663 fa777321 Fabrice Bellard
    /* NOTE: the search range was restricted to avoid too many false
664
       detections */
665
666
    if (p->buf_size < 6)
667
        return 0;
668 ec23a472 Isaac Richards
669
    for (i = 0; i < 20; i++) {
670
        c = p->buf[i];
671
        code = (code << 8) | c;
672
        if ((code & 0xffffff00) == 0x100) {
673
            if (code == PACK_START_CODE ||
674
                code == SYSTEM_HEADER_START_CODE ||
675
                (code >= 0x1e0 && code <= 0x1ef) ||
676
                (code >= 0x1c0 && code <= 0x1df) ||
677
                code == PRIVATE_STREAM_2 ||
678
                code == PROGRAM_STREAM_MAP ||
679
                code == PRIVATE_STREAM_1 ||
680
                code == PADDING_STREAM)
681 149f7c02 Michael Niedermayer
                return AVPROBE_SCORE_MAX - 2;
682 ec23a472 Isaac Richards
            else
683
                return 0;
684
        }
685 db7f1f95 Fabrice Bellard
    }
686
    return 0;
687
}
688
689
690 de6d9b64 Fabrice Bellard
typedef struct MpegDemuxContext {
691
    int header_state;
692
} MpegDemuxContext;
693
694 27f388aa Fabrice Bellard
static int mpegps_read_header(AVFormatContext *s,
695
                              AVFormatParameters *ap)
696
{
697
    MpegDemuxContext *m = s->priv_data;
698
    m->header_state = 0xff;
699
    s->ctx_flags |= AVFMTCTX_NOHEADER;
700
701
    /* no need to do more */
702
    return 0;
703
}
704
705
static int64_t get_pts(ByteIOContext *pb, int c)
706
{
707
    int64_t pts;
708
    int val;
709
710
    if (c < 0)
711
        c = get_byte(pb);
712
    pts = (int64_t)((c >> 1) & 0x07) << 30;
713
    val = get_be16(pb);
714
    pts |= (int64_t)(val >> 1) << 15;
715
    val = get_be16(pb);
716
    pts |= (int64_t)(val >> 1);
717
    return pts;
718
}
719
720
static int find_next_start_code(ByteIOContext *pb, int *size_ptr, 
721
                                uint32_t *header_state)
722 de6d9b64 Fabrice Bellard
{
723
    unsigned int state, v;
724
    int val, n;
725
726
    state = *header_state;
727
    n = *size_ptr;
728
    while (n > 0) {
729
        if (url_feof(pb))
730
            break;
731
        v = get_byte(pb);
732
        n--;
733
        if (state == 0x000001) {
734
            state = ((state << 8) | v) & 0xffffff;
735
            val = state;
736
            goto found;
737
        }
738
        state = ((state << 8) | v) & 0xffffff;
739
    }
740
    val = -1;
741
 found:
742
    *header_state = state;
743
    *size_ptr = n;
744
    return val;
745
}
746
747 27f388aa Fabrice Bellard
/* XXX: optimize */
748
static int find_prev_start_code(ByteIOContext *pb, int *size_ptr)
749 de6d9b64 Fabrice Bellard
{
750 27f388aa Fabrice Bellard
    int64_t pos, pos_start;
751
    int max_size, start_code;
752 da24c5e3 Fabrice Bellard
753 27f388aa Fabrice Bellard
    max_size = *size_ptr;
754
    pos_start = url_ftell(pb);
755 de6d9b64 Fabrice Bellard
756 27f388aa Fabrice Bellard
    /* in order to go faster, we fill the buffer */
757
    pos = pos_start - 16386;
758
    if (pos < 0)
759
        pos = 0;
760
    url_fseek(pb, pos, SEEK_SET);
761
    get_byte(pb);
762 de6d9b64 Fabrice Bellard
763 27f388aa Fabrice Bellard
    pos = pos_start;
764
    for(;;) {
765
        pos--;
766
        if (pos < 0 || (pos_start - pos) >= max_size) {
767
            start_code = -1;
768
            goto the_end;
769
        }
770
        url_fseek(pb, pos, SEEK_SET);
771
        start_code = get_be32(pb);
772
        if ((start_code & 0xffffff00) == 0x100)
773
            break;
774
    }
775
 the_end:
776
    *size_ptr = pos_start - pos;
777
    return start_code;
778 de6d9b64 Fabrice Bellard
}
779
780 27f388aa Fabrice Bellard
/* read the next (or previous) PES header. Return its position in ppos 
781
   (if not NULL), and its start code, pts and dts.
782
 */
783
static int mpegps_read_pes_header(AVFormatContext *s,
784
                                  int64_t *ppos, int *pstart_code, 
785
                                  int64_t *ppts, int64_t *pdts, int find_next)
786 de6d9b64 Fabrice Bellard
{
787
    MpegDemuxContext *m = s->priv_data;
788 27f388aa Fabrice Bellard
    int len, size, startcode, c, flags, header_len;
789
    int64_t pts, dts, last_pos;
790 de6d9b64 Fabrice Bellard
791 27f388aa Fabrice Bellard
    last_pos = -1;
792 de6d9b64 Fabrice Bellard
 redo:
793 27f388aa Fabrice Bellard
    if (find_next) {
794
        /* next start code (should be immediately after) */
795
        m->header_state = 0xff;
796
        size = MAX_SYNC_SIZE;
797
        startcode = find_next_start_code(&s->pb, &size, &m->header_state);
798
    } else {
799
        if (last_pos >= 0)
800
            url_fseek(&s->pb, last_pos, SEEK_SET);
801
        size = MAX_SYNC_SIZE;
802
        startcode = find_prev_start_code(&s->pb, &size);
803
        last_pos = url_ftell(&s->pb) - 4;
804
    }
805 001e3f55 Juanjo
    //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb));
806 de6d9b64 Fabrice Bellard
    if (startcode < 0)
807
        return -EIO;
808
    if (startcode == PACK_START_CODE)
809
        goto redo;
810
    if (startcode == SYSTEM_HEADER_START_CODE)
811
        goto redo;
812
    if (startcode == PADDING_STREAM ||
813
        startcode == PRIVATE_STREAM_2) {
814
        /* skip them */
815
        len = get_be16(&s->pb);
816
        url_fskip(&s->pb, len);
817
        goto redo;
818
    }
819
    /* find matching stream */
820
    if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
821
          (startcode >= 0x1e0 && startcode <= 0x1ef) ||
822
          (startcode == 0x1bd)))
823
        goto redo;
824 27f388aa Fabrice Bellard
    if (ppos) {
825
        *ppos = url_ftell(&s->pb) - 4;
826
    }
827 de6d9b64 Fabrice Bellard
    len = get_be16(&s->pb);
828 b2cac184 Fabrice Bellard
    pts = AV_NOPTS_VALUE;
829
    dts = AV_NOPTS_VALUE;
830 de6d9b64 Fabrice Bellard
    /* stuffing */
831
    for(;;) {
832 27f388aa Fabrice Bellard
        if (len < 1)
833
            goto redo;
834 de6d9b64 Fabrice Bellard
        c = get_byte(&s->pb);
835
        len--;
836
        /* XXX: for mpeg1, should test only bit 7 */
837
        if (c != 0xff) 
838
            break;
839
    }
840
    if ((c & 0xc0) == 0x40) {
841
        /* buffer scale & size */
842 27f388aa Fabrice Bellard
        if (len < 2)
843
            goto redo;
844 de6d9b64 Fabrice Bellard
        get_byte(&s->pb);
845
        c = get_byte(&s->pb);
846
        len -= 2;
847
    }
848
    if ((c & 0xf0) == 0x20) {
849 27f388aa Fabrice Bellard
        if (len < 4)
850
            goto redo;
851
        dts = pts = get_pts(&s->pb, c);
852 de6d9b64 Fabrice Bellard
        len -= 4;
853
    } else if ((c & 0xf0) == 0x30) {
854 27f388aa Fabrice Bellard
        if (len < 9)
855
            goto redo;
856 de6d9b64 Fabrice Bellard
        pts = get_pts(&s->pb, c);
857
        dts = get_pts(&s->pb, -1);
858
        len -= 9;
859
    } else if ((c & 0xc0) == 0x80) {
860
        /* mpeg 2 PES */
861
        if ((c & 0x30) != 0) {
862 27f388aa Fabrice Bellard
            /* Encrypted multiplex not handled */
863
            goto redo;
864 de6d9b64 Fabrice Bellard
        }
865
        flags = get_byte(&s->pb);
866
        header_len = get_byte(&s->pb);
867
        len -= 2;
868
        if (header_len > len)
869
            goto redo;
870 1e5c667c Fabrice Bellard
        if ((flags & 0xc0) == 0x80) {
871 27f388aa Fabrice Bellard
            dts = pts = get_pts(&s->pb, -1);
872
            if (header_len < 5)
873
                goto redo;
874 de6d9b64 Fabrice Bellard
            header_len -= 5;
875
            len -= 5;
876
        } if ((flags & 0xc0) == 0xc0) {
877
            pts = get_pts(&s->pb, -1);
878
            dts = get_pts(&s->pb, -1);
879 27f388aa Fabrice Bellard
            if (header_len < 10)
880
                goto redo;
881 de6d9b64 Fabrice Bellard
            header_len -= 10;
882
            len -= 10;
883
        }
884
        len -= header_len;
885
        while (header_len > 0) {
886
            get_byte(&s->pb);
887
            header_len--;
888
        }
889
    }
890
    if (startcode == 0x1bd) {
891 27f388aa Fabrice Bellard
        if (len < 1)
892
            goto redo;
893 de6d9b64 Fabrice Bellard
        startcode = get_byte(&s->pb);
894
        len--;
895
        if (startcode >= 0x80 && startcode <= 0xbf) {
896
            /* audio: skip header */
897 27f388aa Fabrice Bellard
            if (len < 3)
898
                goto redo;
899 de6d9b64 Fabrice Bellard
            get_byte(&s->pb);
900
            get_byte(&s->pb);
901
            get_byte(&s->pb);
902
            len -= 3;
903
        }
904
    }
905 27f388aa Fabrice Bellard
    *pstart_code = startcode;
906
    *ppts = pts;
907
    *pdts = dts;
908
    return len;
909
}
910
911
static int mpegps_read_packet(AVFormatContext *s,
912
                              AVPacket *pkt)
913
{
914
    AVStream *st;
915
    int len, startcode, i, type, codec_id;
916
    int64_t pts, dts;
917
918
 redo:
919
    len = mpegps_read_pes_header(s, NULL, &startcode, &pts, &dts, 1);
920
    if (len < 0)
921
        return len;
922 27a206e0 Michel Bardiaux
    
923 de6d9b64 Fabrice Bellard
    /* now find stream */
924
    for(i=0;i<s->nb_streams;i++) {
925
        st = s->streams[i];
926
        if (st->id == startcode)
927
            goto found;
928
    }
929 db7f1f95 Fabrice Bellard
    if (startcode >= 0x1e0 && startcode <= 0x1ef) {
930
        type = CODEC_TYPE_VIDEO;
931 0dbb48d9 Fabrice Bellard
        codec_id = CODEC_ID_MPEG2VIDEO;
932 db7f1f95 Fabrice Bellard
    } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
933
        type = CODEC_TYPE_AUDIO;
934
        codec_id = CODEC_ID_MP2;
935
    } else if (startcode >= 0x80 && startcode <= 0x9f) {
936
        type = CODEC_TYPE_AUDIO;
937
        codec_id = CODEC_ID_AC3;
938 9ec05e36 Fabrice Bellard
    } else if (startcode >= 0xa0 && startcode <= 0xbf) {
939
        type = CODEC_TYPE_AUDIO;
940
        codec_id = CODEC_ID_PCM_S16BE;
941 db7f1f95 Fabrice Bellard
    } else {
942
    skip:
943
        /* skip packet */
944
        url_fskip(&s->pb, len);
945
        goto redo;
946
    }
947 1e5c667c Fabrice Bellard
    /* no stream found: add a new stream */
948
    st = av_new_stream(s, startcode);
949
    if (!st) 
950
        goto skip;
951 db7f1f95 Fabrice Bellard
    st->codec.codec_type = type;
952
    st->codec.codec_id = codec_id;
953 27f388aa Fabrice Bellard
    if (codec_id != CODEC_ID_PCM_S16BE)
954
        st->need_parsing = 1;
955 de6d9b64 Fabrice Bellard
 found:
956 9ec05e36 Fabrice Bellard
    if (startcode >= 0xa0 && startcode <= 0xbf) {
957
        int b1, freq;
958
959
        /* for LPCM, we just skip the header and consider it is raw
960
           audio data */
961
        if (len <= 3)
962
            goto skip;
963
        get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */
964
        b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */
965
        get_byte(&s->pb); /* dynamic range control (0x80 = off) */
966
        len -= 3;
967
        freq = (b1 >> 4) & 3;
968
        st->codec.sample_rate = lpcm_freq_tab[freq];
969
        st->codec.channels = 1 + (b1 & 7);
970
        st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2;
971
    }
972 de6d9b64 Fabrice Bellard
    av_new_packet(pkt, len);
973
    get_buffer(&s->pb, pkt->data, pkt->size);
974
    pkt->pts = pts;
975 27f388aa Fabrice Bellard
    pkt->dts = dts;
976 db7f1f95 Fabrice Bellard
    pkt->stream_index = st->index;
977 27a206e0 Michel Bardiaux
#if 0
978
    printf("%d: pts=%0.3f dts=%0.3f\n",
979
           pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0);
980
#endif
981 de6d9b64 Fabrice Bellard
    return 0;
982
}
983
984 db7f1f95 Fabrice Bellard
static int mpegps_read_close(AVFormatContext *s)
985 de6d9b64 Fabrice Bellard
{
986
    return 0;
987
}
988
989 27f388aa Fabrice Bellard
static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, 
990
                               int64_t *ppos, int find_next)
991
{
992
    int len, startcode;
993
    int64_t pos, pts, dts;
994
995
    pos = *ppos;
996
#ifdef DEBUG_SEEK
997
    printf("read_dts: pos=0x%llx next=%d -> ", pos, find_next);
998
#endif
999
    url_fseek(&s->pb, pos, SEEK_SET);
1000
    for(;;) {
1001
        len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts, find_next);
1002
        if (len < 0) {
1003
#ifdef DEBUG_SEEK
1004
            printf("none (ret=%d)\n", len);
1005
#endif
1006
            return AV_NOPTS_VALUE;
1007
        }
1008
        if (startcode == s->streams[stream_index]->id && 
1009
            dts != AV_NOPTS_VALUE) {
1010
            break;
1011
        }
1012
        if (find_next) {
1013
            url_fskip(&s->pb, len);
1014
        } else {
1015
            url_fseek(&s->pb, pos, SEEK_SET);
1016
        }
1017
    }
1018
#ifdef DEBUG_SEEK
1019
    printf("pos=0x%llx dts=0x%llx %0.3f\n", pos, dts, dts / 90000.0);
1020
#endif
1021
    *ppos = pos;
1022
    return dts;
1023
}
1024
1025
static int find_stream_index(AVFormatContext *s)
1026
{
1027
    int i;
1028
    AVStream *st;
1029
1030
    if (s->nb_streams <= 0)
1031
        return -1;
1032
    for(i = 0; i < s->nb_streams; i++) {
1033
        st = s->streams[i];
1034
        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
1035
            return i;
1036
        }
1037
    }
1038
    return 0;
1039
}
1040
1041
static int mpegps_read_seek(AVFormatContext *s, 
1042
                            int stream_index, int64_t timestamp)
1043
{
1044
    int64_t pos_min, pos_max, pos;
1045
    int64_t dts_min, dts_max, dts;
1046
1047
    timestamp = (timestamp * 90000) / AV_TIME_BASE;
1048
1049
#ifdef DEBUG_SEEK
1050
    printf("read_seek: %d %0.3f\n", stream_index, timestamp / 90000.0);
1051
#endif
1052
1053
    /* XXX: find stream_index by looking at the first PES packet found */
1054
    if (stream_index < 0) {
1055
        stream_index = find_stream_index(s);
1056
        if (stream_index < 0)
1057
            return -1;
1058
    }
1059
    pos_min = 0;
1060
    dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1);
1061
    if (dts_min == AV_NOPTS_VALUE) {
1062
        /* we can reach this case only if no PTS are present in
1063
           the whole stream */
1064
        return -1;
1065
    }
1066
    pos_max = url_filesize(url_fileno(&s->pb)) - 1;
1067
    dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0);
1068
    
1069
    while (pos_min <= pos_max) {
1070
#ifdef DEBUG_SEEK
1071
        printf("pos_min=0x%llx pos_max=0x%llx dts_min=%0.3f dts_max=%0.3f\n", 
1072
               pos_min, pos_max,
1073
               dts_min / 90000.0, dts_max / 90000.0);
1074
#endif
1075
        if (timestamp <= dts_min) {
1076
            pos = pos_min;
1077
            goto found;
1078
        } else if (timestamp >= dts_max) {
1079
            pos = pos_max;
1080
            goto found;
1081
        } else {
1082
            /* interpolate position (better than dichotomy) */
1083
            pos = (int64_t)((double)(pos_max - pos_min) * 
1084
                            (double)(timestamp - dts_min) /
1085
                            (double)(dts_max - dts_min)) + pos_min;
1086
        }
1087
#ifdef DEBUG_SEEK
1088
        printf("pos=0x%llx\n", pos);
1089
#endif
1090
        /* read the next timestamp */
1091
        dts = mpegps_read_dts(s, stream_index, &pos, 1);
1092
        /* check if we are lucky */
1093
        if (dts == AV_NOPTS_VALUE) {
1094
            /* should never happen */
1095
            pos = pos_min;
1096
            goto found;
1097
        } else if (timestamp == dts) {
1098
            goto found;
1099
        } else if (timestamp < dts) {
1100
            pos_max = pos;
1101
            dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0);
1102
            if (dts_max == AV_NOPTS_VALUE) {
1103
                /* should never happen */
1104
                break;
1105
            } else if (timestamp >= dts_max) {
1106
                pos = pos_max;
1107
                goto found;
1108
            }
1109
        } else {
1110
            pos_min = pos + 1;
1111
            dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1);
1112
            if (dts_min == AV_NOPTS_VALUE) {
1113
                /* should never happen */
1114
                goto found;
1115
            } else if (timestamp <= dts_min) {
1116
                goto found;
1117
            }
1118
        }
1119
    }
1120
    pos = pos_min;
1121
 found:
1122
#ifdef DEBUG_SEEK
1123
    pos_min = pos;
1124
    dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1);
1125
    pos_min++;
1126
    dts_max = mpegps_read_dts(s, stream_index, &pos_min, 1);
1127
    printf("pos=0x%llx %0.3f<=%0.3f<=%0.3f\n", 
1128
           pos, dts_min / 90000.0, timestamp / 90000.0, dts_max / 90000.0);
1129
#endif
1130
    /* do the seek */
1131
    url_fseek(&s->pb, pos, SEEK_SET);
1132
    return 0;
1133
}
1134
1135 764ef400 Mike Melanson
#ifdef CONFIG_ENCODERS
1136 fb7566d0 Fabrice Bellard
static AVOutputFormat mpeg1system_mux = {
1137 de6d9b64 Fabrice Bellard
    "mpeg",
1138 fb7566d0 Fabrice Bellard
    "MPEG1 System format",
1139 c6c11cb6 Ryutaroh Matsumoto
    "video/mpeg",
1140 fb7566d0 Fabrice Bellard
    "mpg,mpeg",
1141
    sizeof(MpegMuxContext),
1142
    CODEC_ID_MP2,
1143
    CODEC_ID_MPEG1VIDEO,
1144
    mpeg_mux_init,
1145
    mpeg_mux_write_packet,
1146
    mpeg_mux_end,
1147
};
1148
1149
static AVOutputFormat mpeg1vcd_mux = {
1150
    "vcd",
1151
    "MPEG1 System format (VCD)",
1152 c6c11cb6 Ryutaroh Matsumoto
    "video/mpeg",
1153 fb7566d0 Fabrice Bellard
    NULL,
1154
    sizeof(MpegMuxContext),
1155
    CODEC_ID_MP2,
1156
    CODEC_ID_MPEG1VIDEO,
1157
    mpeg_mux_init,
1158
    mpeg_mux_write_packet,
1159
    mpeg_mux_end,
1160
};
1161
1162
static AVOutputFormat mpeg2vob_mux = {
1163
    "vob",
1164
    "MPEG2 PS format (VOB)",
1165 c6c11cb6 Ryutaroh Matsumoto
    "video/mpeg",
1166 fb7566d0 Fabrice Bellard
    "vob",
1167 db7f1f95 Fabrice Bellard
    sizeof(MpegMuxContext),
1168 de6d9b64 Fabrice Bellard
    CODEC_ID_MP2,
1169 0dbb48d9 Fabrice Bellard
    CODEC_ID_MPEG2VIDEO,
1170 de6d9b64 Fabrice Bellard
    mpeg_mux_init,
1171
    mpeg_mux_write_packet,
1172
    mpeg_mux_end,
1173 db7f1f95 Fabrice Bellard
};
1174 764ef400 Mike Melanson
#endif //CONFIG_ENCODERS
1175 de6d9b64 Fabrice Bellard
1176 32f38cb4 Fabrice Bellard
AVInputFormat mpegps_demux = {
1177 db7f1f95 Fabrice Bellard
    "mpeg",
1178
    "MPEG PS format",
1179
    sizeof(MpegDemuxContext),
1180
    mpegps_probe,
1181
    mpegps_read_header,
1182
    mpegps_read_packet,
1183
    mpegps_read_close,
1184 27f388aa Fabrice Bellard
    mpegps_read_seek,
1185 de6d9b64 Fabrice Bellard
};
1186 db7f1f95 Fabrice Bellard
1187
int mpegps_init(void)
1188
{
1189 764ef400 Mike Melanson
#ifdef CONFIG_ENCODERS
1190 fb7566d0 Fabrice Bellard
    av_register_output_format(&mpeg1system_mux);
1191
    av_register_output_format(&mpeg1vcd_mux);
1192
    av_register_output_format(&mpeg2vob_mux);
1193 764ef400 Mike Melanson
#endif //CONFIG_ENCODERS
1194 db7f1f95 Fabrice Bellard
    av_register_input_format(&mpegps_demux);
1195
    return 0;
1196
}