📄 mpeg.c
字号:
s->packet_number++; stream->packet_number++; stream->start_pts = -1;}static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, UINT8 *buf, int size, int pts){ MpegMuxContext *s = ctx->priv_data; AVStream *st = ctx->streams[stream_index]; StreamInfo *stream = st->priv_data; int len; while (size > 0) { /* set pts */ if (stream->start_pts == -1) { stream->start_pts = pts; } len = s->packet_data_max_size - stream->buffer_ptr; if (len > size) len = size; memcpy(stream->buffer + stream->buffer_ptr, buf, len); stream->buffer_ptr += len; buf += len; size -= len; while (stream->buffer_ptr >= s->packet_data_max_size) { /* output the packet */ if (stream->start_pts == -1) stream->start_pts = pts; flush_packet(ctx, stream_index, 0); } } return 0;}static int mpeg_mux_end(AVFormatContext *ctx){ StreamInfo *stream; int i; /* flush each packet */ for(i=0;i<ctx->nb_streams;i++) { stream = ctx->streams[i]->priv_data; if (stream->buffer_ptr > 0) { if (i == (ctx->nb_streams - 1)) flush_packet(ctx, i, 1); else flush_packet(ctx, i, 0); } } /* write the end header */ //put_be32(&ctx->pb, ISO_11172_END_CODE); //put_flush_packet(&ctx->pb); return 0;}/*********************************************//* demux code */#define MAX_SYNC_SIZE 100000static int mpegps_probe(AVProbeData *p){ int code, c, i; code = 0xff; /* we search the first start code. If it is a packet start code, then we decide it is mpeg ps. We do not send highest value to give a chance to mpegts */ for(i=0;i<p->buf_size;i++) { c = p->buf[i]; code = (code << 8) | c; if ((code & 0xffffff00) == 0x100) { if (code == PACK_START_CODE || code == SYSTEM_HEADER_START_CODE || (code >= 0x1e0 && code <= 0x1ef) || (code >= 0x1c0 && code <= 0x1df) || code == PRIVATE_STREAM_2 || code == PROGRAM_STREAM_MAP || code == PRIVATE_STREAM_1 || code == PADDING_STREAM) return AVPROBE_SCORE_MAX - 1; else return 0; } } return 0;}typedef struct MpegDemuxContext { int header_state;} MpegDemuxContext;static int find_start_code(ByteIOContext *pb, int *size_ptr, UINT32 *header_state){ unsigned int state, v; int val, n; state = *header_state; n = *size_ptr; while (n > 0) { if (url_feof(pb)) break; v = get_byte(pb); n--; if (state == 0x000001) { state = ((state << 8) | v) & 0xffffff; val = state; goto found; } state = ((state << 8) | v) & 0xffffff; } val = -1; found: *header_state = state; *size_ptr = n; return val;}static int mpegps_read_header(AVFormatContext *s, AVFormatParameters *ap){ MpegDemuxContext *m = s->priv_data; m->header_state = 0xff; /* no need to do more */ return 0;}static INT64 get_pts(ByteIOContext *pb, int c){ INT64 pts; int val; if (c < 0) c = get_byte(pb); pts = (INT64)((c >> 1) & 0x07) << 30; val = get_be16(pb); pts |= (INT64)(val >> 1) << 15; val = get_be16(pb); pts |= (INT64)(val >> 1); return pts;}static int mpegps_read_packet(AVFormatContext *s, AVPacket *pkt){ MpegDemuxContext *m = s->priv_data; AVStream *st; int len, size, startcode, i, c, flags, header_len, type, codec_id; INT64 pts, dts; /* next start code (should be immediately after) */ redo: m->header_state = 0xff; size = MAX_SYNC_SIZE; startcode = find_start_code(&s->pb, &size, &m->header_state); //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb)); if (startcode < 0) return -EIO; if (startcode == PACK_START_CODE) goto redo; if (startcode == SYSTEM_HEADER_START_CODE) goto redo; if (startcode == PADDING_STREAM || startcode == PRIVATE_STREAM_2) { /* skip them */ len = get_be16(&s->pb); url_fskip(&s->pb, len); goto redo; } /* find matching stream */ if (!((startcode >= 0x1c0 && startcode <= 0x1df) || (startcode >= 0x1e0 && startcode <= 0x1ef) || (startcode == 0x1bd))) goto redo; len = get_be16(&s->pb); pts = AV_NOPTS_VALUE; dts = AV_NOPTS_VALUE; /* stuffing */ for(;;) { c = get_byte(&s->pb); len--; /* XXX: for mpeg1, should test only bit 7 */ if (c != 0xff) break; } if ((c & 0xc0) == 0x40) { /* buffer scale & size */ get_byte(&s->pb); c = get_byte(&s->pb); len -= 2; } if ((c & 0xf0) == 0x20) { pts = get_pts(&s->pb, c); len -= 4; } else if ((c & 0xf0) == 0x30) { pts = get_pts(&s->pb, c); dts = get_pts(&s->pb, -1); len -= 9; } else if ((c & 0xc0) == 0x80) { /* mpeg 2 PES */ if ((c & 0x30) != 0) { fprintf(stderr, "Encrypted multiplex not handled\n"); return -EIO; } flags = get_byte(&s->pb); header_len = get_byte(&s->pb); len -= 2; if (header_len > len) goto redo; if ((flags & 0xc0) == 0x80) { pts = get_pts(&s->pb, -1); header_len -= 5; len -= 5; } if ((flags & 0xc0) == 0xc0) { pts = get_pts(&s->pb, -1); dts = get_pts(&s->pb, -1); header_len -= 10; len -= 10; } len -= header_len; while (header_len > 0) { get_byte(&s->pb); header_len--; } } if (startcode == 0x1bd) { startcode = get_byte(&s->pb); len--; if (startcode >= 0x80 && startcode <= 0xbf) { /* audio: skip header */ get_byte(&s->pb); get_byte(&s->pb); get_byte(&s->pb); len -= 3; } } /* now find stream */ for(i=0;i<s->nb_streams;i++) { st = s->streams[i]; if (st->id == startcode) goto found; } if (startcode >= 0x1e0 && startcode <= 0x1ef) { type = CODEC_TYPE_VIDEO; codec_id = CODEC_ID_MPEG1VIDEO; } else if (startcode >= 0x1c0 && startcode <= 0x1df) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_MP2; } else if (startcode >= 0x80 && startcode <= 0x9f) { type = CODEC_TYPE_AUDIO; codec_id = CODEC_ID_AC3; } else { skip: /* skip packet */ url_fskip(&s->pb, len); goto redo; } /* no stream found: add a new stream */ st = av_new_stream(s, startcode); if (!st) goto skip; st->codec.codec_type = type; st->codec.codec_id = codec_id; found: av_new_packet(pkt, len); //printf("\nRead Packet ID: %x PTS: %f Size: %d", startcode, // (float)pts/90000, len); get_buffer(&s->pb, pkt->data, pkt->size); pkt->pts = pts; pkt->stream_index = st->index; return 0;}static int mpegps_read_close(AVFormatContext *s){ return 0;}static AVOutputFormat mpeg1system_mux = { "mpeg", "MPEG1 System format", "video/x-mpeg", "mpg,mpeg", sizeof(MpegMuxContext), CODEC_ID_MP2, CODEC_ID_MPEG1VIDEO, mpeg_mux_init, mpeg_mux_write_packet, mpeg_mux_end,};static AVOutputFormat mpeg1vcd_mux = { "vcd", "MPEG1 System format (VCD)", "video/x-mpeg", NULL, sizeof(MpegMuxContext), CODEC_ID_MP2, CODEC_ID_MPEG1VIDEO, mpeg_mux_init, mpeg_mux_write_packet, mpeg_mux_end,};static AVOutputFormat mpeg2vob_mux = { "vob", "MPEG2 PS format (VOB)", "video/x-mpeg", "vob", sizeof(MpegMuxContext), CODEC_ID_MP2, CODEC_ID_MPEG1VIDEO, mpeg_mux_init, mpeg_mux_write_packet, mpeg_mux_end,};static AVInputFormat mpegps_demux = { "mpeg", "MPEG PS format", sizeof(MpegDemuxContext), mpegps_probe, mpegps_read_header, mpegps_read_packet, mpegps_read_close, .flags = AVFMT_NOHEADER,};int mpegps_init(void){ av_register_output_format(&mpeg1system_mux); av_register_output_format(&mpeg1vcd_mux); av_register_output_format(&mpeg2vob_mux); av_register_input_format(&mpegps_demux); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -