📄 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "avformat.h"#define MAX_PAYLOAD_SIZE 4096//#define DEBUG_SEEK#undef NDEBUG#include <assert.h>typedef struct { uint8_t buffer[MAX_PAYLOAD_SIZE]; int buffer_ptr; int nb_frames; /* number of starting frame encountered (AC3) */ int frame_start_offset; /* starting offset of the frame + 1 (0 if none) */ uint8_t id; int max_buffer_size; /* in bytes */ int packet_number; int64_t start_pts; int64_t start_dts; uint8_t lpcm_header[3]; int lpcm_align;} 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 scr_stream_index; /* stream from which the system clock is computed (VBR case) */ int64_t last_scr; /* current system clock */ double vcd_padding_bitrate; 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 LPCM_ID 0xa0static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };#ifdef CONFIG_ENCODERSstatic AVOutputFormat mpeg1system_mux;static AVOutputFormat mpeg1vcd_mux;static AVOutputFormat mpeg2vob_mux;static AVOutputFormat mpeg2svcd_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, rate_bound, 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); rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */ put_bits(&pb, 22, rate_bound); 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) { /* 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); put_bits(&pb, 8, 0xff); /* reserved byte */ /* 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; 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, ac3_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); if (s->is_vcd || s->is_svcd) s->packet_size = 2324; /* VCD/SVCD 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; mpv_id = VIDEO_ID; lpcm_id = LPCM_ID; s->scr_stream_index = -1; 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; 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_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: /* by default, video is used for the SCR computation */ if (s->scr_stream_index == -1) s->scr_stream_index = i; stream->id = mpv_id++; if (s->is_vcd) /* 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; s->video_bound++; break; default: av_abort(); } } /* if no SCR, use first stream (audio) */ if (s->scr_stream_index == -1) s->scr_stream_index = 0; bitrate = 0; audio_bitrate = 0; video_bitrate = 0; for(i=0;i<ctx->nb_streams;i++) { st = ctx->streams[i]; stream = (StreamInfo*) st->priv_data; bitrate += st->codec.bit_rate; if (stream->id==AUDIO_ID) audio_bitrate += st->codec.bit_rate; else if (stream->id==VIDEO_ID) video_bitrate += st->codec.bit_rate; } if (s->is_vcd) { double overhead_rate; /* The VCD standard mandates that the mux_rate field is 3528 (see standard p. IV-6). The value is actually "wrong", i.e. if you calculate it using the normal formula and the 75 sectors per second transfer rate you get a different value because the real pack size is 2324, not 2352. But the standard explicitly specifies that the mux_rate field in the header must have this value.*/ s->mux_rate=2352 * 75 / 50; /* = 3528*/ /* The VCD standard states that the muxed stream must be exactly 75 packs / second (the data rate of a single speed cdrom). Since the video bitrate (probably 1150000 bits/sec) will be below the theoretical maximum we have to add some padding packets to make up for the lower data rate. (cf. VCD standard p. IV-6 )*/ /* Add the header overhead to the data rate. 2279 data bytes per audio pack, 2294 data bytes per video pack*/ overhead_rate = ((audio_bitrate / 8.0) / 2279) * (2324 - 2279); overhead_rate += ((video_bitrate / 8.0) / 2294) * (2324 - 2294); overhead_rate *= 8; /* Add padding so that the full bitrate is 2324*75 bytes/sec */ s->vcd_padding_bitrate = 2324 * 75 * 8 - (bitrate + overhead_rate); } else { /* we increase slightly the bitrate to take into account the headers. XXX: compute it exactly */ bitrate += 2000; s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -