📄 mpeg.c
字号:
/* * MPEG1/2 mux/demux * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "avformat.h"#include "bitstream.h"#define MAX_PAYLOAD_SIZE 4096//#define DEBUG_SEEK#undef NDEBUG#include <assert.h>typedef struct PacketDesc { int64_t pts; int64_t dts; int size; int unwritten_size; int flags; struct PacketDesc *next;} PacketDesc;typedef struct { FifoBuffer fifo; uint8_t id; int max_buffer_size; /* in bytes */ int buffer_index; PacketDesc *predecode_packet; PacketDesc *premux_packet; PacketDesc **next_packet; int packet_number; uint8_t lpcm_header[3]; int lpcm_align; uint8_t *fifo_iframe_ptr; int align_iframe; int64_t vobu_start_pts;} StreamInfo;typedef struct { int packet_size; /* required packet size */ int packet_number; int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ int system_header_freq; int system_header_size; int mux_rate; /* bitrate in units of 50 bytes/s */ /* stream info */ int audio_bound; int video_bound; int is_mpeg2; int is_vcd; int is_svcd; int is_dvd; int64_t last_scr; /* current system clock */ double vcd_padding_bitrate; //FIXME floats int64_t vcd_padding_bytes_written;} MpegMuxContext;#define PACK_START_CODE ((unsigned int)0x000001ba)#define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb)#define SEQUENCE_END_CODE ((unsigned int)0x000001b7)#define PACKET_START_CODE_MASK ((unsigned int)0xffffff00)#define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100)#define ISO_11172_END_CODE ((unsigned int)0x000001b9)/* mpeg2 */#define PROGRAM_STREAM_MAP 0x1bc#define PRIVATE_STREAM_1 0x1bd#define PADDING_STREAM 0x1be#define PRIVATE_STREAM_2 0x1bf#define AUDIO_ID 0xc0#define VIDEO_ID 0xe0#define AC3_ID 0x80#define DTS_ID 0x8a#define LPCM_ID 0xa0#define SUB_ID 0x20#define STREAM_TYPE_VIDEO_MPEG1 0x01#define STREAM_TYPE_VIDEO_MPEG2 0x02#define STREAM_TYPE_AUDIO_MPEG1 0x03#define STREAM_TYPE_AUDIO_MPEG2 0x04#define STREAM_TYPE_PRIVATE_SECTION 0x05#define STREAM_TYPE_PRIVATE_DATA 0x06#define STREAM_TYPE_AUDIO_AAC 0x0f#define STREAM_TYPE_VIDEO_MPEG4 0x10#define STREAM_TYPE_VIDEO_H264 0x1b#define STREAM_TYPE_AUDIO_AC3 0x81#define STREAM_TYPE_AUDIO_DTS 0x8astatic const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };#ifdef CONFIG_MUXERSstatic AVOutputFormat mpeg1system_mux;static AVOutputFormat mpeg1vcd_mux;static AVOutputFormat mpeg2vob_mux;static AVOutputFormat mpeg2svcd_mux;static AVOutputFormat mpeg2dvd_mux;static int put_pack_header(AVFormatContext *ctx, uint8_t *buf, int64_t timestamp){ MpegMuxContext *s = ctx->priv_data; PutBitContext pb; init_put_bits(&pb, buf, 128); put_bits(&pb, 32, PACK_START_CODE); if (s->is_mpeg2) { put_bits(&pb, 2, 0x1); } else { put_bits(&pb, 4, 0x2); } put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); put_bits(&pb, 1, 1); put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); put_bits(&pb, 1, 1); put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff)); put_bits(&pb, 1, 1); if (s->is_mpeg2) { /* clock extension */ put_bits(&pb, 9, 0); } put_bits(&pb, 1, 1); put_bits(&pb, 22, s->mux_rate); put_bits(&pb, 1, 1); if (s->is_mpeg2) { put_bits(&pb, 1, 1); put_bits(&pb, 5, 0x1f); /* reserved */ put_bits(&pb, 3, 0); /* stuffing length */ } flush_put_bits(&pb); return pbBufPtr(&pb) - pb.buf;}static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_stream_id){ MpegMuxContext *s = ctx->priv_data; int size, i, private_stream_coded, id; PutBitContext pb; init_put_bits(&pb, buf, 128); put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); put_bits(&pb, 16, 0); put_bits(&pb, 1, 1); put_bits(&pb, 22, s->mux_rate); /* maximum bit rate of the multiplexed stream */ put_bits(&pb, 1, 1); /* marker */ if (s->is_vcd && only_for_stream_id==VIDEO_ID) { /* This header applies only to the video stream (see VCD standard p. IV-7)*/ put_bits(&pb, 6, 0); } else put_bits(&pb, 6, s->audio_bound); if (s->is_vcd) { /* see VCD standard, p. IV-7*/ put_bits(&pb, 1, 0); put_bits(&pb, 1, 1); } else { put_bits(&pb, 1, 0); /* variable bitrate*/ put_bits(&pb, 1, 0); /* non constrainted bit stream */ } if (s->is_vcd || s->is_dvd) { /* see VCD standard p IV-7 */ put_bits(&pb, 1, 1); /* audio locked */ put_bits(&pb, 1, 1); /* video locked */ } else { put_bits(&pb, 1, 0); /* audio locked */ put_bits(&pb, 1, 0); /* video locked */ } put_bits(&pb, 1, 1); /* marker */ if (s->is_vcd && only_for_stream_id==AUDIO_ID) { /* This header applies only to the audio stream (see VCD standard p. IV-7)*/ put_bits(&pb, 5, 0); } else put_bits(&pb, 5, s->video_bound); if (s->is_dvd) { put_bits(&pb, 1, 0); /* packet_rate_restriction_flag */ put_bits(&pb, 7, 0x7f); /* reserved byte */ } else put_bits(&pb, 8, 0xff); /* reserved byte */ /* DVD-Video Stream_bound entries id (0xB9) video, maximum P-STD for stream 0xE0. (P-STD_buffer_bound_scale = 1) id (0xB8) audio, maximum P-STD for any MPEG audio (0xC0 to 0xC7) streams. If there are none set to 4096 (32x128). (P-STD_buffer_bound_scale = 0) id (0xBD) private stream 1 (audio other than MPEG and subpictures). (P-STD_buffer_bound_scale = 1) id (0xBF) private stream 2, NAV packs, set to 2x1024. */ if (s->is_dvd) { int P_STD_max_video = 0; int P_STD_max_mpeg_audio = 0; int P_STD_max_mpeg_PS1 = 0; for(i=0;i<ctx->nb_streams;i++) { StreamInfo *stream = ctx->streams[i]->priv_data; id = stream->id; if (id == 0xbd && stream->max_buffer_size > P_STD_max_mpeg_PS1) { P_STD_max_mpeg_PS1 = stream->max_buffer_size; } else if (id >= 0xc0 && id <= 0xc7 && stream->max_buffer_size > P_STD_max_mpeg_audio) { P_STD_max_mpeg_audio = stream->max_buffer_size; } else if (id == 0xe0 && stream->max_buffer_size > P_STD_max_video) { P_STD_max_video = stream->max_buffer_size; } } /* video */ put_bits(&pb, 8, 0xb9); /* stream ID */ put_bits(&pb, 2, 3); put_bits(&pb, 1, 1); put_bits(&pb, 13, P_STD_max_video / 1024); /* audio */ if (P_STD_max_mpeg_audio == 0) P_STD_max_mpeg_audio = 4096; put_bits(&pb, 8, 0xb8); /* stream ID */ put_bits(&pb, 2, 3); put_bits(&pb, 1, 0); put_bits(&pb, 13, P_STD_max_mpeg_audio / 128); /* private stream 1 */ put_bits(&pb, 8, 0xbd); /* stream ID */ put_bits(&pb, 2, 3); put_bits(&pb, 1, 0); put_bits(&pb, 13, P_STD_max_mpeg_PS1 / 128); /* private stream 2 */ put_bits(&pb, 8, 0xbf); /* stream ID */ put_bits(&pb, 2, 3); put_bits(&pb, 1, 1); put_bits(&pb, 13, 2); } else { /* audio stream info */ private_stream_coded = 0; for(i=0;i<ctx->nb_streams;i++) { StreamInfo *stream = ctx->streams[i]->priv_data; /* For VCDs, only include the stream info for the stream that the pack which contains this system belongs to. (see VCD standard p. IV-7) */ if ( !s->is_vcd || stream->id==only_for_stream_id || only_for_stream_id==0) { id = stream->id; if (id < 0xc0) { /* special case for private streams (AC3 use that) */ if (private_stream_coded) continue; private_stream_coded = 1; id = 0xbd; } put_bits(&pb, 8, id); /* stream ID */ put_bits(&pb, 2, 3); if (id < 0xe0) { /* audio */ put_bits(&pb, 1, 0); put_bits(&pb, 13, stream->max_buffer_size / 128); } else { /* video */ put_bits(&pb, 1, 1); put_bits(&pb, 13, stream->max_buffer_size / 1024); } } } } flush_put_bits(&pb); size = pbBufPtr(&pb) - pb.buf; /* patch packet size */ buf[4] = (size - 6) >> 8; buf[5] = (size - 6) & 0xff; return size;}static int get_system_header_size(AVFormatContext *ctx){ int buf_index, i, private_stream_coded; StreamInfo *stream; MpegMuxContext *s = ctx->priv_data; if (s->is_dvd) return 18; // DVD-Video system headers are 18 bytes fixed length. buf_index = 12; private_stream_coded = 0; for(i=0;i<ctx->nb_streams;i++) { stream = ctx->streams[i]->priv_data; if (stream->id < 0xc0) { if (private_stream_coded) continue; private_stream_coded = 1; } buf_index += 3; } return buf_index;}static int mpeg_mux_init(AVFormatContext *ctx){ MpegMuxContext *s = ctx->priv_data; int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j; AVStream *st; StreamInfo *stream; int audio_bitrate; int video_bitrate; s->packet_number = 0; s->is_vcd = (ctx->oformat == &mpeg1vcd_mux); s->is_svcd = (ctx->oformat == &mpeg2svcd_mux); s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux || ctx->oformat == &mpeg2svcd_mux || ctx->oformat == &mpeg2dvd_mux); s->is_dvd = (ctx->oformat == &mpeg2dvd_mux); if(ctx->packet_size) s->packet_size = ctx->packet_size; else s->packet_size = 2048; s->vcd_padding_bytes_written = 0; s->vcd_padding_bitrate=0; s->audio_bound = 0; s->video_bound = 0; mpa_id = AUDIO_ID; ac3_id = AC3_ID; dts_id = DTS_ID; mpv_id = VIDEO_ID; mps_id = SUB_ID; lpcm_id = LPCM_ID; for(i=0;i<ctx->nb_streams;i++) { st = ctx->streams[i]; stream = av_mallocz(sizeof(StreamInfo)); if (!stream) goto fail; st->priv_data = stream; av_set_pts_info(st, 64, 1, 90000); switch(st->codec->codec_type) { case CODEC_TYPE_AUDIO: if (st->codec->codec_id == CODEC_ID_AC3) { stream->id = ac3_id++; } else if (st->codec->codec_id == CODEC_ID_DTS) { stream->id = dts_id++; } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) { stream->id = lpcm_id++; for(j = 0; j < 4; j++) { if (lpcm_freq_tab[j] == st->codec->sample_rate) break; } if (j == 4) goto fail; if (st->codec->channels > 8) return -1; stream->lpcm_header[0] = 0x0c; stream->lpcm_header[1] = (st->codec->channels - 1) | (j << 4); stream->lpcm_header[2] = 0x80; stream->lpcm_align = st->codec->channels * 2; } else { stream->id = mpa_id++; } /* This value HAS to be used for VCD (see VCD standard, p. IV-7). Right now it is also used for everything else.*/ stream->max_buffer_size = 4 * 1024; s->audio_bound++; break; case CODEC_TYPE_VIDEO: stream->id = mpv_id++; if (st->codec->rc_buffer_size) stream->max_buffer_size = 6*1024 + st->codec->rc_buffer_size/8; else stream->max_buffer_size = 230*1024; //FIXME this is probably too small as default#if 0 /* see VCD standard, p. IV-7*/ stream->max_buffer_size = 46 * 1024; else /* This value HAS to be used for SVCD (see SVCD standard, p. 26 V.2.3.2). Right now it is also used for everything else.*/ stream->max_buffer_size = 230 * 1024;#endif s->video_bound++; break; case CODEC_TYPE_SUBTITLE: stream->id = mps_id++; stream->max_buffer_size = 16 * 1024; break; default: return -1; } fifo_init(&stream->fifo, 16); } bitrate = 0; audio_bitrate = 0; video_bitrate = 0; for(i=0;i<ctx->nb_streams;i++) { int codec_rate; st = ctx->streams[i]; stream = (StreamInfo*) st->priv_data; if(st->codec->rc_max_rate || stream->id==VIDEO_ID) codec_rate= st->codec->rc_max_rate; else codec_rate= st->codec->bit_rate; if(!codec_rate) codec_rate= (1<<21)*8*50/ctx->nb_streams; bitrate += codec_rate; if (stream->id==AUDIO_ID) audio_bitrate += codec_rate; else if (stream->id==VIDEO_ID) video_bitrate += codec_rate; } if(ctx->mux_rate){ s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50); } else { /* we increase slightly the bitrate to take into account the headers. XXX: compute it exactly */ bitrate += bitrate*5/100; bitrate += 10000; s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -