Mercurial > libavformat.hg
annotate mpeg.c @ 165:e4d2f704bf80 libavformat
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
needed to detect some files produced by pvr-250/350 capture cards.
- Adds AC3 audio support to the mpegts demuxer, and makes it a little more
tolerant of bad files.
patch by (Isaac Richards <ijr at po dot cwru dot edu>)
| author | michaelni |
|---|---|
| date | Thu, 10 Jul 2003 09:04:04 +0000 |
| parents | a58a8a53eb46 |
| children | 7d56e9f83fdb |
| rev | line source |
|---|---|
| 0 | 1 /* |
| 2 * MPEG1/2 mux/demux | |
| 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. | |
| 4 * | |
| 5 * 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 * | |
| 10 * This library is distributed in the hope that it will be useful, | |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 * Lesser General Public License for more details. | |
| 14 * | |
| 15 * 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 */ | |
| 19 #include "avformat.h" | |
| 20 | |
| 21 #define MAX_PAYLOAD_SIZE 4096 | |
| 22 #define NB_STREAMS 2 | |
| 23 | |
| 24 typedef struct { | |
| 65 | 25 uint8_t buffer[MAX_PAYLOAD_SIZE]; |
| 0 | 26 int buffer_ptr; |
| 65 | 27 uint8_t id; |
| 0 | 28 int max_buffer_size; /* in bytes */ |
| 29 int packet_number; | |
| 65 | 30 int64_t start_pts; |
| 0 | 31 } StreamInfo; |
| 32 | |
| 33 typedef struct { | |
| 34 int packet_size; /* required packet size */ | |
| 35 int packet_data_max_size; /* maximum data size inside a packet */ | |
| 36 int packet_number; | |
| 37 int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ | |
| 38 int system_header_freq; | |
| 39 int mux_rate; /* bitrate in units of 50 bytes/s */ | |
| 40 /* stream info */ | |
| 41 int audio_bound; | |
| 42 int video_bound; | |
| 43 int is_mpeg2; | |
| 44 int is_vcd; | |
| 45 } MpegMuxContext; | |
| 46 | |
| 47 #define PACK_START_CODE ((unsigned int)0x000001ba) | |
| 48 #define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) | |
| 49 #define SEQUENCE_END_CODE ((unsigned int)0x000001b7) | |
| 50 #define PACKET_START_CODE_MASK ((unsigned int)0xffffff00) | |
| 51 #define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100) | |
| 52 #define ISO_11172_END_CODE ((unsigned int)0x000001b9) | |
| 53 | |
| 54 /* mpeg2 */ | |
| 55 #define PROGRAM_STREAM_MAP 0x1bc | |
| 56 #define PRIVATE_STREAM_1 0x1bd | |
| 57 #define PADDING_STREAM 0x1be | |
| 58 #define PRIVATE_STREAM_2 0x1bf | |
| 59 | |
| 60 | |
| 61 #define AUDIO_ID 0xc0 | |
| 62 #define VIDEO_ID 0xe0 | |
| 63 | |
| 64 extern AVOutputFormat mpeg1system_mux; | |
| 65 extern AVOutputFormat mpeg1vcd_mux; | |
| 66 extern AVOutputFormat mpeg2vob_mux; | |
| 67 | |
| 68 static int put_pack_header(AVFormatContext *ctx, | |
| 65 | 69 uint8_t *buf, int64_t timestamp) |
| 0 | 70 { |
| 71 MpegMuxContext *s = ctx->priv_data; | |
| 72 PutBitContext pb; | |
| 73 | |
| 74 init_put_bits(&pb, buf, 128, NULL, NULL); | |
| 75 | |
| 76 put_bits(&pb, 32, PACK_START_CODE); | |
| 77 if (s->is_mpeg2) { | |
| 78 put_bits(&pb, 2, 0x2); | |
| 79 } else { | |
| 80 put_bits(&pb, 4, 0x2); | |
| 81 } | |
| 65 | 82 put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); |
| 0 | 83 put_bits(&pb, 1, 1); |
| 65 | 84 put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); |
| 0 | 85 put_bits(&pb, 1, 1); |
| 65 | 86 put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff)); |
| 0 | 87 put_bits(&pb, 1, 1); |
| 88 if (s->is_mpeg2) { | |
| 89 /* clock extension */ | |
| 90 put_bits(&pb, 9, 0); | |
| 91 put_bits(&pb, 1, 1); | |
| 92 } | |
| 93 put_bits(&pb, 1, 1); | |
| 94 put_bits(&pb, 22, s->mux_rate); | |
| 95 put_bits(&pb, 1, 1); | |
| 96 if (s->is_mpeg2) { | |
| 97 put_bits(&pb, 5, 0x1f); /* reserved */ | |
| 98 put_bits(&pb, 3, 0); /* stuffing length */ | |
| 99 } | |
| 100 flush_put_bits(&pb); | |
| 101 return pbBufPtr(&pb) - pb.buf; | |
| 102 } | |
| 103 | |
| 65 | 104 static int put_system_header(AVFormatContext *ctx, uint8_t *buf) |
| 0 | 105 { |
| 106 MpegMuxContext *s = ctx->priv_data; | |
| 107 int size, rate_bound, i, private_stream_coded, id; | |
| 108 PutBitContext pb; | |
| 109 | |
| 110 init_put_bits(&pb, buf, 128, NULL, NULL); | |
| 111 | |
| 112 put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); | |
| 113 put_bits(&pb, 16, 0); | |
| 114 put_bits(&pb, 1, 1); | |
| 115 | |
| 116 rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */ | |
| 117 put_bits(&pb, 22, rate_bound); | |
| 118 put_bits(&pb, 1, 1); /* marker */ | |
| 119 put_bits(&pb, 6, s->audio_bound); | |
| 120 | |
| 121 put_bits(&pb, 1, 1); /* variable bitrate */ | |
| 122 put_bits(&pb, 1, 1); /* non constrainted bit stream */ | |
| 123 | |
| 124 put_bits(&pb, 1, 0); /* audio locked */ | |
| 125 put_bits(&pb, 1, 0); /* video locked */ | |
| 126 put_bits(&pb, 1, 1); /* marker */ | |
| 127 | |
| 128 put_bits(&pb, 5, s->video_bound); | |
| 129 put_bits(&pb, 8, 0xff); /* reserved byte */ | |
| 130 | |
| 131 /* audio stream info */ | |
| 132 private_stream_coded = 0; | |
| 133 for(i=0;i<ctx->nb_streams;i++) { | |
| 134 StreamInfo *stream = ctx->streams[i]->priv_data; | |
| 135 id = stream->id; | |
| 136 if (id < 0xc0) { | |
| 137 /* special case for private streams (AC3 use that) */ | |
| 138 if (private_stream_coded) | |
| 139 continue; | |
| 140 private_stream_coded = 1; | |
| 141 id = 0xbd; | |
| 142 } | |
| 143 put_bits(&pb, 8, id); /* stream ID */ | |
| 144 put_bits(&pb, 2, 3); | |
| 145 if (id < 0xe0) { | |
| 146 /* audio */ | |
| 147 put_bits(&pb, 1, 0); | |
| 148 put_bits(&pb, 13, stream->max_buffer_size / 128); | |
| 149 } else { | |
| 150 /* video */ | |
| 151 put_bits(&pb, 1, 1); | |
| 152 put_bits(&pb, 13, stream->max_buffer_size / 1024); | |
| 153 } | |
| 154 } | |
| 155 flush_put_bits(&pb); | |
| 156 size = pbBufPtr(&pb) - pb.buf; | |
| 157 /* patch packet size */ | |
| 158 buf[4] = (size - 6) >> 8; | |
| 159 buf[5] = (size - 6) & 0xff; | |
| 160 | |
| 161 return size; | |
| 162 } | |
| 163 | |
| 164 static int mpeg_mux_init(AVFormatContext *ctx) | |
| 165 { | |
| 166 MpegMuxContext *s = ctx->priv_data; | |
| 167 int bitrate, i, mpa_id, mpv_id, ac3_id; | |
| 168 AVStream *st; | |
| 169 StreamInfo *stream; | |
| 170 | |
| 171 s->packet_number = 0; | |
| 172 s->is_vcd = (ctx->oformat == &mpeg1vcd_mux); | |
| 173 s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux); | |
| 174 | |
| 175 if (s->is_vcd) | |
| 176 s->packet_size = 2324; /* VCD packet size */ | |
| 177 else | |
| 178 s->packet_size = 2048; | |
| 179 | |
| 180 /* startcode(4) + length(2) + flags(1) */ | |
| 181 s->packet_data_max_size = s->packet_size - 7; | |
| 182 s->audio_bound = 0; | |
| 183 s->video_bound = 0; | |
| 184 mpa_id = AUDIO_ID; | |
| 185 ac3_id = 0x80; | |
| 186 mpv_id = VIDEO_ID; | |
| 187 for(i=0;i<ctx->nb_streams;i++) { | |
| 188 st = ctx->streams[i]; | |
| 189 stream = av_mallocz(sizeof(StreamInfo)); | |
| 190 if (!stream) | |
| 191 goto fail; | |
| 192 st->priv_data = stream; | |
| 193 | |
| 194 switch(st->codec.codec_type) { | |
| 195 case CODEC_TYPE_AUDIO: | |
| 196 if (st->codec.codec_id == CODEC_ID_AC3) | |
| 197 stream->id = ac3_id++; | |
| 198 else | |
| 199 stream->id = mpa_id++; | |
| 200 stream->max_buffer_size = 4 * 1024; | |
| 201 s->audio_bound++; | |
| 202 break; | |
| 203 case CODEC_TYPE_VIDEO: | |
| 204 stream->id = mpv_id++; | |
| 205 stream->max_buffer_size = 46 * 1024; | |
| 206 s->video_bound++; | |
| 207 break; | |
| 208 default: | |
| 209 av_abort(); | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 /* we increase slightly the bitrate to take into account the | |
| 214 headers. XXX: compute it exactly */ | |
| 215 bitrate = 2000; | |
| 216 for(i=0;i<ctx->nb_streams;i++) { | |
| 217 st = ctx->streams[i]; | |
| 218 bitrate += st->codec.bit_rate; | |
| 219 } | |
| 220 s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); | |
| 221 | |
| 222 if (s->is_vcd || s->is_mpeg2) | |
| 223 /* every packet */ | |
| 224 s->pack_header_freq = 1; | |
| 225 else | |
| 226 /* every 2 seconds */ | |
| 227 s->pack_header_freq = 2 * bitrate / s->packet_size / 8; | |
| 228 | |
| 229 if (s->is_mpeg2) | |
| 230 /* every 200 packets. Need to look at the spec. */ | |
| 231 s->system_header_freq = s->pack_header_freq * 40; | |
| 232 else if (s->is_vcd) | |
| 233 /* every 40 packets, this is my invention */ | |
| 234 s->system_header_freq = s->pack_header_freq * 40; | |
| 235 else | |
| 236 s->system_header_freq = s->pack_header_freq * 5; | |
| 237 | |
| 238 for(i=0;i<ctx->nb_streams;i++) { | |
| 239 stream = ctx->streams[i]->priv_data; | |
| 240 stream->buffer_ptr = 0; | |
| 241 stream->packet_number = 0; | |
| 242 stream->start_pts = -1; | |
| 243 } | |
| 244 return 0; | |
| 245 fail: | |
| 246 for(i=0;i<ctx->nb_streams;i++) { | |
| 247 av_free(ctx->streams[i]->priv_data); | |
| 248 } | |
| 249 return -ENOMEM; | |
| 250 } | |
| 251 | |
| 252 /* flush the packet on stream stream_index */ | |
| 253 static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt) | |
| 254 { | |
| 255 MpegMuxContext *s = ctx->priv_data; | |
| 256 StreamInfo *stream = ctx->streams[stream_index]->priv_data; | |
| 65 | 257 uint8_t *buf_ptr; |
| 0 | 258 int size, payload_size, startcode, id, len, stuffing_size, i, header_len; |
| 65 | 259 int64_t timestamp; |
| 260 uint8_t buffer[128]; | |
| 0 | 261 int last = last_pkt ? 4 : 0; |
| 262 | |
| 263 id = stream->id; | |
| 264 timestamp = stream->start_pts; | |
| 265 | |
| 266 #if 0 | |
| 267 printf("packet ID=%2x PTS=%0.3f\n", | |
| 268 id, timestamp / 90000.0); | |
| 269 #endif | |
| 270 | |
| 271 buf_ptr = buffer; | |
| 272 if (((s->packet_number % s->pack_header_freq) == 0)) { | |
| 273 /* output pack and systems header if needed */ | |
| 274 size = put_pack_header(ctx, buf_ptr, timestamp); | |
| 275 buf_ptr += size; | |
| 276 if ((s->packet_number % s->system_header_freq) == 0) { | |
| 277 size = put_system_header(ctx, buf_ptr); | |
| 278 buf_ptr += size; | |
| 279 } | |
| 280 } | |
| 281 size = buf_ptr - buffer; | |
| 282 put_buffer(&ctx->pb, buffer, size); | |
| 283 | |
| 284 /* packet header */ | |
| 285 if (s->is_mpeg2) { | |
| 286 header_len = 8; | |
| 287 } else { | |
| 288 header_len = 5; | |
| 289 } | |
| 290 payload_size = s->packet_size - (size + 6 + header_len + last); | |
| 291 if (id < 0xc0) { | |
| 292 startcode = PRIVATE_STREAM_1; | |
| 293 payload_size -= 4; | |
| 294 } else { | |
| 295 startcode = 0x100 + id; | |
| 296 } | |
| 297 stuffing_size = payload_size - stream->buffer_ptr; | |
| 298 if (stuffing_size < 0) | |
| 299 stuffing_size = 0; | |
| 300 | |
| 301 put_be32(&ctx->pb, startcode); | |
| 302 | |
| 303 put_be16(&ctx->pb, payload_size + header_len); | |
| 304 /* stuffing */ | |
| 305 for(i=0;i<stuffing_size;i++) | |
| 306 put_byte(&ctx->pb, 0xff); | |
| 307 | |
| 308 if (s->is_mpeg2) { | |
| 309 put_byte(&ctx->pb, 0x80); /* mpeg2 id */ | |
| 310 put_byte(&ctx->pb, 0x80); /* flags */ | |
| 311 put_byte(&ctx->pb, 0x05); /* header len (only pts is included) */ | |
| 312 } | |
| 313 put_byte(&ctx->pb, | |
| 314 (0x02 << 4) | | |
| 315 (((timestamp >> 30) & 0x07) << 1) | | |
| 316 1); | |
| 65 | 317 put_be16(&ctx->pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); |
| 318 put_be16(&ctx->pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); | |
| 0 | 319 |
| 320 if (startcode == PRIVATE_STREAM_1) { | |
| 321 put_byte(&ctx->pb, id); | |
| 322 if (id >= 0x80 && id <= 0xbf) { | |
| 323 /* XXX: need to check AC3 spec */ | |
| 324 put_byte(&ctx->pb, 1); | |
| 325 put_byte(&ctx->pb, 0); | |
| 326 put_byte(&ctx->pb, 2); | |
| 327 } | |
| 328 } | |
| 329 | |
| 330 if (last_pkt) { | |
| 331 put_be32(&ctx->pb, ISO_11172_END_CODE); | |
| 332 } | |
| 333 /* output data */ | |
| 334 put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); | |
| 335 put_flush_packet(&ctx->pb); | |
| 336 | |
| 337 /* preserve remaining data */ | |
| 338 len = stream->buffer_ptr - payload_size; | |
| 339 if (len < 0) | |
| 340 len = 0; | |
| 341 memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len); | |
| 342 stream->buffer_ptr = len; | |
| 343 | |
| 344 s->packet_number++; | |
| 345 stream->packet_number++; | |
| 346 stream->start_pts = -1; | |
| 347 } | |
| 348 | |
| 349 static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, | |
| 65 | 350 uint8_t *buf, int size, int pts) |
| 0 | 351 { |
| 352 MpegMuxContext *s = ctx->priv_data; | |
| 353 AVStream *st = ctx->streams[stream_index]; | |
| 354 StreamInfo *stream = st->priv_data; | |
| 355 int len; | |
| 356 | |
| 357 while (size > 0) { | |
| 358 /* set pts */ | |
| 359 if (stream->start_pts == -1) { | |
| 360 stream->start_pts = pts; | |
| 361 } | |
| 362 len = s->packet_data_max_size - stream->buffer_ptr; | |
| 363 if (len > size) | |
| 364 len = size; | |
| 365 memcpy(stream->buffer + stream->buffer_ptr, buf, len); | |
| 366 stream->buffer_ptr += len; | |
| 367 buf += len; | |
| 368 size -= len; | |
| 369 while (stream->buffer_ptr >= s->packet_data_max_size) { | |
| 370 /* output the packet */ | |
| 371 if (stream->start_pts == -1) | |
| 372 stream->start_pts = pts; | |
| 373 flush_packet(ctx, stream_index, 0); | |
| 374 } | |
| 375 } | |
| 376 return 0; | |
| 377 } | |
| 378 | |
| 379 static int mpeg_mux_end(AVFormatContext *ctx) | |
| 380 { | |
| 381 StreamInfo *stream; | |
| 382 int i; | |
| 383 | |
| 384 /* flush each packet */ | |
| 385 for(i=0;i<ctx->nb_streams;i++) { | |
| 386 stream = ctx->streams[i]->priv_data; | |
| 387 if (stream->buffer_ptr > 0) { | |
| 388 if (i == (ctx->nb_streams - 1)) | |
| 389 flush_packet(ctx, i, 1); | |
| 390 else | |
| 391 flush_packet(ctx, i, 0); | |
| 392 } | |
| 393 } | |
| 394 | |
| 395 /* write the end header */ | |
| 396 //put_be32(&ctx->pb, ISO_11172_END_CODE); | |
| 397 //put_flush_packet(&ctx->pb); | |
| 398 return 0; | |
| 399 } | |
| 400 | |
| 401 /*********************************************/ | |
| 402 /* demux code */ | |
| 403 | |
| 404 #define MAX_SYNC_SIZE 100000 | |
| 405 | |
| 406 static int mpegps_probe(AVProbeData *p) | |
| 407 { | |
|
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
408 int code, c, i; |
| 49 | 409 const uint8_t *d; |
| 0 | 410 |
|
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
411 code = 0xff; |
| 0 | 412 /* we search the first start code. If it is a packet start code, |
| 413 then we decide it is mpeg ps. We do not send highest value to | |
| 414 give a chance to mpegts */ | |
| 49 | 415 /* NOTE: the search range was restricted to avoid too many false |
| 416 detections */ | |
| 417 | |
| 418 if (p->buf_size < 6) | |
| 419 return 0; | |
|
165
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
420 |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
421 for (i = 0; i < 20; i++) { |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
422 c = p->buf[i]; |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
423 code = (code << 8) | c; |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
424 if ((code & 0xffffff00) == 0x100) { |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
425 if (code == PACK_START_CODE || |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
426 code == SYSTEM_HEADER_START_CODE || |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
427 (code >= 0x1e0 && code <= 0x1ef) || |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
428 (code >= 0x1c0 && code <= 0x1df) || |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
429 code == PRIVATE_STREAM_2 || |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
430 code == PROGRAM_STREAM_MAP || |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
431 code == PRIVATE_STREAM_1 || |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
432 code == PADDING_STREAM) |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
433 return AVPROBE_SCORE_MAX - 1; |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
434 else |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
435 return 0; |
|
e4d2f704bf80
- Looks a tiny bit harder in mpegps_probe() for a valid start code. This is
michaelni
parents:
65
diff
changeset
|
436 } |
| 0 | 437 } |
| 438 return 0; | |
| 439 } | |
| 440 | |
| 441 | |
| 442 typedef struct MpegDemuxContext { | |
| 443 int header_state; | |
| 444 } MpegDemuxContext; | |
| 445 | |
| 446 static int find_start_code(ByteIOContext *pb, int *size_ptr, | |
| 65 | 447 uint32_t *header_state) |
| 0 | 448 { |
| 449 unsigned int state, v; | |
| 450 int val, n; | |
| 451 | |
| 452 state = *header_state; | |
| 453 n = *size_ptr; | |
| 454 while (n > 0) { | |
| 455 if (url_feof(pb)) | |
| 456 break; | |
| 457 v = get_byte(pb); | |
| 458 n--; | |
| 459 if (state == 0x000001) { | |
| 460 state = ((state << 8) | v) & 0xffffff; | |
| 461 val = state; | |
| 462 goto found; | |
| 463 } | |
| 464 state = ((state << 8) | v) & 0xffffff; | |
| 465 } | |
| 466 val = -1; | |
| 467 found: | |
| 468 *header_state = state; | |
| 469 *size_ptr = n; | |
| 470 return val; | |
| 471 } | |
| 472 | |
| 473 static int mpegps_read_header(AVFormatContext *s, | |
| 474 AVFormatParameters *ap) | |
| 475 { | |
| 476 MpegDemuxContext *m = s->priv_data; | |
| 477 m->header_state = 0xff; | |
| 478 /* no need to do more */ | |
| 479 return 0; | |
| 480 } | |
| 481 | |
| 65 | 482 static int64_t get_pts(ByteIOContext *pb, int c) |
| 0 | 483 { |
| 65 | 484 int64_t pts; |
| 0 | 485 int val; |
| 486 | |
| 487 if (c < 0) | |
| 488 c = get_byte(pb); | |
| 65 | 489 pts = (int64_t)((c >> 1) & 0x07) << 30; |
| 0 | 490 val = get_be16(pb); |
| 65 | 491 pts |= (int64_t)(val >> 1) << 15; |
| 0 | 492 val = get_be16(pb); |
| 65 | 493 pts |= (int64_t)(val >> 1); |
| 0 | 494 return pts; |
| 495 } | |
| 496 | |
| 497 static int mpegps_read_packet(AVFormatContext *s, | |
| 498 AVPacket *pkt) | |
| 499 { | |
| 500 MpegDemuxContext *m = s->priv_data; | |
| 501 AVStream *st; | |
| 502 int len, size, startcode, i, c, flags, header_len, type, codec_id; | |
| 65 | 503 int64_t pts, dts; |
| 0 | 504 |
| 505 /* next start code (should be immediately after) */ | |
| 506 redo: | |
| 507 m->header_state = 0xff; | |
| 508 size = MAX_SYNC_SIZE; | |
| 509 startcode = find_start_code(&s->pb, &size, &m->header_state); | |
| 510 //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb)); | |
| 511 if (startcode < 0) | |
| 512 return -EIO; | |
| 513 if (startcode == PACK_START_CODE) | |
| 514 goto redo; | |
| 515 if (startcode == SYSTEM_HEADER_START_CODE) | |
| 516 goto redo; | |
| 517 if (startcode == PADDING_STREAM || | |
| 518 startcode == PRIVATE_STREAM_2) { | |
| 519 /* skip them */ | |
| 520 len = get_be16(&s->pb); | |
| 521 url_fskip(&s->pb, len); | |
| 522 goto redo; | |
| 523 } | |
| 524 /* find matching stream */ | |
| 525 if (!((startcode >= 0x1c0 && startcode <= 0x1df) || | |
| 526 (startcode >= 0x1e0 && startcode <= 0x1ef) || | |
| 527 (startcode == 0x1bd))) | |
| 528 goto redo; | |
| 529 | |
| 530 len = get_be16(&s->pb); | |
| 531 pts = AV_NOPTS_VALUE; | |
| 532 dts = AV_NOPTS_VALUE; | |
| 533 /* stuffing */ | |
| 534 for(;;) { | |
| 535 c = get_byte(&s->pb); | |
| 536 len--; | |
| 537 /* XXX: for mpeg1, should test only bit 7 */ | |
| 538 if (c != 0xff) | |
| 539 break; | |
| 540 } | |
| 541 if ((c & 0xc0) == 0x40) { | |
| 542 /* buffer scale & size */ | |
| 543 get_byte(&s->pb); | |
| 544 c = get_byte(&s->pb); | |
| 545 len -= 2; | |
| 546 } | |
| 547 if ((c & 0xf0) == 0x20) { | |
| 548 pts = get_pts(&s->pb, c); | |
| 549 len -= 4; | |
| 550 } else if ((c & 0xf0) == 0x30) { | |
| 551 pts = get_pts(&s->pb, c); | |
| 552 dts = get_pts(&s->pb, -1); | |
| 553 len -= 9; | |
| 554 } else if ((c & 0xc0) == 0x80) { | |
| 555 /* mpeg 2 PES */ | |
| 556 if ((c & 0x30) != 0) { | |
| 557 fprintf(stderr, "Encrypted multiplex not handled\n"); | |
| 558 return -EIO; | |
| 559 } | |
| 560 flags = get_byte(&s->pb); | |
| 561 header_len = get_byte(&s->pb); | |
| 562 len -= 2; | |
| 563 if (header_len > len) | |
| 564 goto redo; | |
| 565 if ((flags & 0xc0) == 0x80) { | |
| 566 pts = get_pts(&s->pb, -1); | |
| 567 header_len -= 5; | |
| 568 len -= 5; | |
| 569 } if ((flags & 0xc0) == 0xc0) { | |
| 570 pts = get_pts(&s->pb, -1); | |
| 571 dts = get_pts(&s->pb, -1); | |
| 572 header_len -= 10; | |
| 573 len -= 10; | |
| 574 } | |
| 575 len -= header_len; | |
| 576 while (header_len > 0) { | |
| 577 get_byte(&s->pb); | |
| 578 header_len--; | |
| 579 } | |
| 580 } | |
| 581 if (startcode == 0x1bd) { | |
| 582 startcode = get_byte(&s->pb); | |
| 583 len--; | |
| 584 if (startcode >= 0x80 && startcode <= 0xbf) { | |
| 585 /* audio: skip header */ | |
| 586 get_byte(&s->pb); | |
| 587 get_byte(&s->pb); | |
| 588 get_byte(&s->pb); | |
| 589 len -= 3; | |
| 590 } | |
| 591 } | |
| 592 | |
| 593 /* now find stream */ | |
| 594 for(i=0;i<s->nb_streams;i++) { | |
| 595 st = s->streams[i]; | |
| 596 if (st->id == startcode) | |
| 597 goto found; | |
| 598 } | |
| 599 if (startcode >= 0x1e0 && startcode <= 0x1ef) { | |
| 600 type = CODEC_TYPE_VIDEO; | |
| 601 codec_id = CODEC_ID_MPEG1VIDEO; | |
| 602 } else if (startcode >= 0x1c0 && startcode <= 0x1df) { | |
| 603 type = CODEC_TYPE_AUDIO; | |
| 604 codec_id = CODEC_ID_MP2; | |
| 605 } else if (startcode >= 0x80 && startcode <= 0x9f) { | |
| 606 type = CODEC_TYPE_AUDIO; | |
| 607 codec_id = CODEC_ID_AC3; | |
| 41 | 608 } else if (startcode >= 0xa0 && startcode <= 0xbf) { |
| 609 type = CODEC_TYPE_AUDIO; | |
| 610 codec_id = CODEC_ID_PCM_S16BE; | |
| 0 | 611 } else { |
| 612 skip: | |
| 613 /* skip packet */ | |
| 614 url_fskip(&s->pb, len); | |
| 615 goto redo; | |
| 616 } | |
| 617 /* no stream found: add a new stream */ | |
| 618 st = av_new_stream(s, startcode); | |
| 619 if (!st) | |
| 620 goto skip; | |
| 621 st->codec.codec_type = type; | |
| 622 st->codec.codec_id = codec_id; | |
| 623 found: | |
| 41 | 624 if (startcode >= 0xa0 && startcode <= 0xbf) { |
| 625 int b1, freq; | |
| 626 static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; | |
| 627 | |
| 628 /* for LPCM, we just skip the header and consider it is raw | |
| 629 audio data */ | |
| 630 if (len <= 3) | |
| 631 goto skip; | |
| 632 get_byte(&s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ | |
| 633 b1 = get_byte(&s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ | |
| 634 get_byte(&s->pb); /* dynamic range control (0x80 = off) */ | |
| 635 len -= 3; | |
| 636 freq = (b1 >> 4) & 3; | |
| 637 st->codec.sample_rate = lpcm_freq_tab[freq]; | |
| 638 st->codec.channels = 1 + (b1 & 7); | |
| 639 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate * 2; | |
| 640 } | |
| 0 | 641 av_new_packet(pkt, len); |
| 642 //printf("\nRead Packet ID: %x PTS: %f Size: %d", startcode, | |
| 643 // (float)pts/90000, len); | |
| 644 get_buffer(&s->pb, pkt->data, pkt->size); | |
| 645 pkt->pts = pts; | |
| 646 pkt->stream_index = st->index; | |
| 647 return 0; | |
| 648 } | |
| 649 | |
| 650 static int mpegps_read_close(AVFormatContext *s) | |
| 651 { | |
| 652 return 0; | |
| 653 } | |
| 654 | |
| 655 static AVOutputFormat mpeg1system_mux = { | |
| 656 "mpeg", | |
| 657 "MPEG1 System format", | |
|
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
658 "video/mpeg", |
| 0 | 659 "mpg,mpeg", |
| 660 sizeof(MpegMuxContext), | |
| 661 CODEC_ID_MP2, | |
| 662 CODEC_ID_MPEG1VIDEO, | |
| 663 mpeg_mux_init, | |
| 664 mpeg_mux_write_packet, | |
| 665 mpeg_mux_end, | |
| 666 }; | |
| 667 | |
| 668 static AVOutputFormat mpeg1vcd_mux = { | |
| 669 "vcd", | |
| 670 "MPEG1 System format (VCD)", | |
|
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
671 "video/mpeg", |
| 0 | 672 NULL, |
| 673 sizeof(MpegMuxContext), | |
| 674 CODEC_ID_MP2, | |
| 675 CODEC_ID_MPEG1VIDEO, | |
| 676 mpeg_mux_init, | |
| 677 mpeg_mux_write_packet, | |
| 678 mpeg_mux_end, | |
| 679 }; | |
| 680 | |
| 681 static AVOutputFormat mpeg2vob_mux = { | |
| 682 "vob", | |
| 683 "MPEG2 PS format (VOB)", | |
|
14
b167760cd0aa
mimetype fixes patch by (Ryutaroh Matsumoto <ryutaroh at it dot ss dot titech dot ac dot jp>)
michaelni
parents:
0
diff
changeset
|
684 "video/mpeg", |
| 0 | 685 "vob", |
| 686 sizeof(MpegMuxContext), | |
| 687 CODEC_ID_MP2, | |
| 688 CODEC_ID_MPEG1VIDEO, | |
| 689 mpeg_mux_init, | |
| 690 mpeg_mux_write_packet, | |
| 691 mpeg_mux_end, | |
| 692 }; | |
| 693 | |
| 694 static AVInputFormat mpegps_demux = { | |
| 695 "mpeg", | |
| 696 "MPEG PS format", | |
| 697 sizeof(MpegDemuxContext), | |
| 698 mpegps_probe, | |
| 699 mpegps_read_header, | |
| 700 mpegps_read_packet, | |
| 701 mpegps_read_close, | |
| 702 .flags = AVFMT_NOHEADER, | |
| 703 }; | |
| 704 | |
| 705 int mpegps_init(void) | |
| 706 { | |
| 707 av_register_output_format(&mpeg1system_mux); | |
| 708 av_register_output_format(&mpeg1vcd_mux); | |
| 709 av_register_output_format(&mpeg2vob_mux); | |
| 710 av_register_input_format(&mpegps_demux); | |
| 711 return 0; | |
| 712 } |
