⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 muxer_mpeg.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include "config.h"#include "../version.h"#include "../mp_msg.h"#include "bswap.h"#include "aviheader.h"#include "ms_hdr.h"#include "muxer.h"#include "stream.h"#include "demuxer.h"#include "stheader.h"#include "../m_option.h"#include "mpeg_hdr.h"#define PACK_HEADER_START_CODE 0x01ba#define SYSTEM_HEADER_START_CODE 0x01bb#define PSM_START_CODE 0x01bc#define PES_PRIVATE1 0x01bd#define PES_PRIVATE2 0x01bf#define MUX_MPEG1 1#define MUX_MPEG2 2#define VIDEO_MPEG1 0x10000001#define VIDEO_MPEG2 0x10000002#define AUDIO_MP2 0x50#define AUDIO_MP3 0x55#define AUDIO_A52 0x2000#define AUDIO_LPCM 0x10001	/* only a placeholder at the moment */#define ASPECT_1_1 1#define ASPECT_4_3 2#define ASPECT_16_9 3#define ASPECT_2_21_1 4#define FRAMERATE_23976 1#define FRAMERATE_24 2#define FRAMERATE_25 3#define FRAMERATE_2997 4#define FRAMERATE_30 5#define FRAMERATE_50 6#define FRAMERATE_5994 7#define FRAMERATE_60 8static char ftypes[] = {'?', 'I', 'P', 'B'}; #define FTYPE(x) (ftypes[(x)])static const char *framerates[] = {	"unchanged", "23.976", "24", "25", "29.97", "30", "50", "59.94", "60"};static const char *aspect_ratios[] = {	"unchanged", "1/1", "4/3", "16/9", "2.21/1"};static char *conf_mux = "mpeg2";static uint16_t conf_packet_size = 0;		//dvdstatic uint32_t conf_muxrate = 0;		//kb/sstatic float conf_vaspect = 0; static float conf_vframerate = 0;static uint32_t conf_vwidth = 0, conf_vheight = 0, conf_panscan_width = 0, conf_panscan_height = 0;static uint32_t conf_vbitrate = 0;static int conf_init_vpts = 200, conf_init_apts = 200;static int conf_ts_allframes = 0;static int conf_init_adelay = 0;static int conf_drop = 0;static int conf_skip_padding = 0;static int conf_reorder = 0;static int conf_telecine = 0;enum FRAME_TYPE {	I_FRAME = 1,	P_FRAME = 2,	B_FRAME = 3};typedef struct {	uint8_t *buffer;	size_t size;	size_t alloc_size;	uint8_t type;	uint32_t temp_ref;	uint64_t pts, dts, idur;} mpeg_frame_t;typedef struct {	uint8_t cnt;		// how many entries we use	struct {		uint8_t id, type;		uint32_t bufsize;		uint32_t format;	} streams[50];		//16 video + 16 audio mpa + 16 audio private + bd/bf for dvd} sys_info_t;typedef struct {	uint8_t cnt;		// how many entries we use	struct {		uint8_t id;		uint8_t type;		uint32_t format;	} streams[50];		//16 video + 16 audio mpa + 16 audio private + bd/bf for dvd} psm_info_t;typedef struct {	int mux;	sys_info_t sys_info;	psm_info_t psm_info;	uint16_t packet_size;	int is_dvd, is_xvcd, is_xsvcd, is_genmpeg1, is_genmpeg2, ts_allframes, has_video, has_audio;	int skip_padding;	int update_system_header, use_psm;	off_t headers_size, data_size;	uint64_t scr, vbytes, abytes, init_delay_pts;	uint32_t muxrate;	uint8_t *buff, *tmp, *residual;	uint32_t residual_cnt, headers_cnt;	double init_adelay;	int drop;		//video patching parameters	uint8_t vaspect, vframerate;	uint16_t vwidth, vheight, panscan_width, panscan_height;	uint32_t vbitrate;	int patch_seq, patch_sde;	int psm_streams_cnt;} muxer_priv_t;typedef struct {	int has_pts, has_dts, pes_is_aligned, type, is_late, min_pes_hlen, psm_fixed;	uint64_t pts, last_pts, last_dts, dts, init_pts, init_dts, size, frame_duration, delta_pts, nom_delta_pts, frame_size, last_saved_pts;	uint32_t buffer_size;	uint8_t pes_priv_headers[4], has_pes_priv_headers;	//for A52 and LPCM	uint32_t bitrate, rest;	int32_t compensate;	double delta_clock, timer, aframe_delta_pts, last_dpts;	mpeg_frame_t *framebuf;	uint16_t framebuf_cnt;	uint16_t framebuf_used;	uint16_t max_pl_size;	int32_t last_tr;	int max_tr;	uint8_t id, reorder, is_mpeg12, telecine;	uint64_t vframes;	uint8_t trf;	mp_mpeg_header_t picture;} muxer_headers_t;m_option_t mpegopts_conf[] = {	{"format", &(conf_mux), CONF_TYPE_STRING, 0, 0 ,0, NULL},	{"size", &(conf_packet_size), CONF_TYPE_INT, CONF_RANGE, 0, 65535, NULL},	{"muxrate", &(conf_muxrate), CONF_TYPE_INT, CONF_RANGE, 0, 12000000, NULL},	//12 Mb/s	{"vaspect", &(conf_vaspect), CONF_TYPE_FLOAT, 0, 0, 0, NULL},	{"vframerate", &(conf_vframerate), CONF_TYPE_FLOAT, 0, 0, 0, NULL},	{"vwidth", &(conf_vwidth), CONF_TYPE_INT, CONF_RANGE, 1, 4095, NULL},	{"vheight", &(conf_vheight), CONF_TYPE_INT, CONF_RANGE, 1, 4095, NULL},	{"vpswidth", &(conf_panscan_width), CONF_TYPE_INT, CONF_RANGE, 1, 16383, NULL},	{"vpsheight", &(conf_panscan_height), CONF_TYPE_INT, CONF_RANGE, 1, 16383, NULL},	{"vbitrate", &(conf_vbitrate), CONF_TYPE_INT, CONF_RANGE, 1, 104857599, NULL},	{"init_vpts", &(conf_init_vpts), CONF_TYPE_INT, CONF_RANGE, 100, 700, NULL},		//2*frametime at 60fps	{"init_apts", &(conf_init_apts), CONF_TYPE_INT, CONF_RANGE, 100, 700, NULL},	{"vdelay", &conf_init_adelay, CONF_TYPE_INT, CONF_RANGE, 1, 32760, NULL},	{"drop", &conf_drop, CONF_TYPE_FLAG, 0, 0, 1, NULL},	{"tsaf", &conf_ts_allframes, CONF_TYPE_FLAG, 0, 0, 1, NULL},	{"skip_padding", &conf_skip_padding, CONF_TYPE_FLAG, 0, 0, 1, NULL},	{"reorder", &conf_reorder, CONF_TYPE_FLAG, 0, 0, 1, NULL},	{"noreorder", &conf_reorder, CONF_TYPE_FLAG, 0, 0, 0, NULL},	{"telecine", &conf_telecine, CONF_TYPE_FLAG, 0, 0, 1, NULL},	{NULL, NULL, 0, 0, 0, 0, NULL}};static void fix_audio_sys_header(muxer_priv_t *priv, uint8_t id, uint8_t newid, uint32_t size){	uint8_t i;		for(i = 0; i < priv->sys_info.cnt; i++)	{		if(priv->sys_info.streams[i].id == id)		{			priv->sys_info.streams[i].id = newid;			priv->sys_info.streams[i].type = 1;			priv->sys_info.streams[i].bufsize = size;		}	}}static void fix_buffer_params(muxer_priv_t *priv, uint8_t id, uint32_t size){	uint8_t i;		for(i = 0; i < priv->sys_info.cnt; i++)		if(priv->sys_info.streams[i].id == id)			priv->sys_info.streams[i].bufsize = size;}static inline int is_mpeg1(uint32_t x){	return (		(x == 0x10000001) ||		(x == mmioFOURCC('m','p','g','1')) ||		(x == mmioFOURCC('M','P','G','1'))	);}static inline int is_mpeg2(uint32_t x){	return (		(x == 0x10000002) ||		(x == mmioFOURCC('m','p','g','2')) ||		(x == mmioFOURCC('M','P','G','2')) ||		(x == mmioFOURCC('m','p','e','g')) ||		(x == mmioFOURCC('M','P','E','G'))	);}static inline int is_mpeg4(uint32_t x){	return (		(x == 0x10000004) ||		(x == mmioFOURCC('d','i','v','x')) ||		(x == mmioFOURCC('D','I','V','X')) ||		(x == mmioFOURCC('x','v','i','d')) ||		(x == mmioFOURCC('X','V','I','D')) ||		(x == mmioFOURCC('X','v','i','D')) ||		(x == mmioFOURCC('x','v','i','x')) ||		(x == mmioFOURCC('X','V','I','X')) ||		(x == mmioFOURCC('m','p','4','v')) ||		(x == mmioFOURCC('M','P','4','V')) ||		(x == mmioFOURCC('F', 'M','P','4')) ||		(x == mmioFOURCC('f', 'm','p','4'))	);}//from unrarlib.cstatic uint32_t CalcCRC32(uint8_t *buff, uint32_t size){	uint32_t i, j, CRCTab[256], crc;		for(i = 0;i < 256; i++)	{		for(crc = i, j = 0; j < 8; j++)			crc= (crc & 1) ? (crc >> 1)^0xEDB88320L : (crc >> 1);		CRCTab[i] = crc;	}		crc = 0xffffffff;	for(i = 0; i < size; i++)		crc = (crc << 8) ^ CRCTab[((crc >> 24) ^ buff[i]) & 0xff];		return crc;}static void add_to_psm(muxer_priv_t *priv, uint8_t id, uint32_t format){	uint8_t i;		i = priv->psm_info.cnt;	priv->psm_info.streams[i].id = id;	priv->psm_info.streams[i].format = format;		if(is_mpeg1(format))		priv->psm_info.streams[i].type = 0x01;	else if(is_mpeg2(format))		priv->psm_info.streams[i].type = 0x02;	else if(is_mpeg4(format))		priv->psm_info.streams[i].type = 0x10;	else if(format == AUDIO_MP2 || format == AUDIO_MP3)		priv->psm_info.streams[i].type = 0x03;	else		priv->psm_info.streams[i].type = 0x81;		if(format == AUDIO_A52)		memcpy((char*) &(priv->psm_info.streams[i].format), "AC-3", 4);		priv->psm_info.cnt++;}static mpeg_frame_t *init_frames(uint16_t num, size_t size){	mpeg_frame_t *tmp;	uint16_t i;		tmp = (mpeg_frame_t *) calloc(num, sizeof(mpeg_frame_t));	if(tmp == NULL)		return NULL;			for(i=0; i < num; i++)	{		tmp[i].buffer = (uint8_t *) calloc(1, size);		if(tmp[i].buffer == NULL)			return NULL;		tmp[i].size = 0;		tmp[i].alloc_size = size;		tmp[i].pts = 0;	}		return tmp;}static uint32_t calc_pack_hlen(muxer_priv_t *priv, muxer_headers_t *h);static muxer_stream_t* mpegfile_new_stream(muxer_t *muxer,int type){  muxer_priv_t *priv = (muxer_priv_t*) muxer->priv;  muxer_stream_t *s;  muxer_headers_t *spriv;  if (!muxer) return NULL;  if(muxer->avih.dwStreams>=MUXER_MAX_STREAMS){    mp_msg(MSGT_MUXER, MSGL_ERR, "Too many streams! increase MUXER_MAX_STREAMS !\n");    return NULL;  }  switch (type) {    case MUXER_TYPE_VIDEO:      if (muxer->num_videos >= 16) {	mp_msg(MSGT_MUXER, MSGL_ERR, "MPEG files can't contain more than 16 video streams!\n");	return NULL;      }      break;    case MUXER_TYPE_AUDIO:      if (muxer->num_audios >= 16) {	mp_msg(MSGT_MUXER, MSGL_ERR, "MPEG files can't contain more than 16 audio streams!\n");	return NULL;      }      break;    default:      mp_msg(MSGT_MUXER, MSGL_ERR, "Unknown stream type!\n");      return NULL;  }  s = (muxer_stream_t*) calloc(1, sizeof(muxer_stream_t));  if(!s) return NULL; // no mem!?  if (!(s->b_buffer = malloc(priv->packet_size))) {    free (s);    return NULL; // no mem?!  }  s->b_buffer_size = priv->packet_size;  s->b_buffer_ptr = 0;  s->b_buffer_len = 0;  s->priv = (muxer_headers_t*) calloc(1, sizeof(muxer_headers_t));  if(s->priv == NULL) {    free(s);    return NULL;  }  spriv = (muxer_headers_t *) s->priv;  muxer->streams[muxer->avih.dwStreams]=s;  s->type=type;  s->id=muxer->avih.dwStreams;  s->muxer=muxer;    if (type == MUXER_TYPE_VIDEO) {    spriv->type = 1;    spriv->init_dts = 0;    spriv->init_pts = conf_init_vpts * 90 * 1024;    spriv->last_pts = spriv->init_pts;    spriv->last_saved_pts = 0;    spriv->init_dts = spriv->last_dts = spriv->init_pts;    spriv->pts = spriv->dts = 0;    spriv->last_dpts = spriv->timer;    spriv->delta_pts = spriv->nom_delta_pts = 0;    spriv->id = 0xe0 + muxer->num_videos;    s->ckid = be2me_32 (0x100 + spriv->id);    if(priv->is_genmpeg1 || priv->is_genmpeg2) {      int n = priv->sys_info.cnt;            priv->sys_info.streams[n].id = spriv->id;      priv->sys_info.streams[n].type = 1;      priv->sys_info.streams[n].bufsize = (s->h.dwSuggestedBufferSize > 0 ? s->h.dwSuggestedBufferSize : 46*1024);      priv->sys_info.cnt++;    }    muxer->num_videos++;    priv->has_video++;    s->h.fccType=streamtypeVIDEO;    if(!muxer->def_v) muxer->def_v=s;    spriv->framebuf_cnt = 30;    spriv->framebuf_used = 0;    spriv->framebuf = init_frames(spriv->framebuf_cnt, (size_t) 5000);    memset(&(spriv->picture), 0, sizeof(spriv->picture));    if(spriv->framebuf == NULL) {      mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't allocate initial frames structure, abort!\n");      return NULL;    }    if(priv->is_xvcd)      spriv->min_pes_hlen = 18;    else if(priv->is_xsvcd)      spriv->min_pes_hlen = 22;    spriv->reorder = conf_reorder;    spriv->telecine = conf_telecine;    mp_msg (MSGT_MUXER, MSGL_DBG2, "Added video stream %d, ckid=%X\n", muxer->num_videos, s->ckid);  } else { // MUXER_TYPE_AUDIO    spriv->type = 0;    spriv->pts = 1;    spriv->dts = 0;    spriv->max_pl_size = priv->packet_size - calc_pack_hlen(priv, spriv);    spriv->init_pts = conf_init_apts * 90 * 1024;    spriv->pts = spriv->init_pts;    spriv->dts = 0;    spriv->id = 0xc0 + muxer->num_audios;    s->ckid = be2me_32 (0x100 + spriv->id);    if(priv->is_genmpeg1 || priv->is_genmpeg2) {      int n = priv->sys_info.cnt;            priv->sys_info.streams[n].id = spriv->id;      priv->sys_info.streams[n].type = 0;      priv->sys_info.streams[n].bufsize = (s->h.dwSuggestedBufferSize > 0 ? s->h.dwSuggestedBufferSize : 4*1024);      priv->sys_info.cnt++;    }    if(priv->is_xvcd)      spriv->min_pes_hlen = 13;    else if(priv->is_xsvcd)      spriv->min_pes_hlen = 17;        muxer->num_audios++;    priv->has_audio++;    s->h.fccType=streamtypeAUDIO;    mp_msg (MSGT_MUXER, MSGL_DBG2, "Added audio stream %d, ckid=%X\n", s->id - muxer->num_videos + 1, s->ckid);  }  muxer->avih.dwStreams++;  return s;}static void write_mpeg_ts(unsigned char *b, uint64_t ts, uint8_t mod) {  ts >>= 10;  b[0] = mod | ((ts >> 29) & 0xf) | 1;  b[1] = (ts >> 22) & 0xff;  b[2] = ((ts >> 14) & 0xff) | 1;  b[3] = (ts >> 7) & 0xff;  b[4] = ((ts << 1) & 0xff) | 1;}static void write_mpeg_rate(int type, unsigned char *b, unsigned int rate) {	rate = (rate+49) / 50;		if(type == MUX_MPEG1)	{		b[0] = ((rate >> 15) & 0x7f) | 0x80;		b[1] = (rate >> 7) & 0xff;		b[2] = ((rate << 1) & 0xff) | 1;	}	else	{		b[0] = (rate >> 14);		b[1] = (rate >> 6) & 0xff;		b[2] = ((rate & 0x3f) << 2) | 0x03;		}}static void write_mpeg_std(unsigned char *b, unsigned int size, unsigned int type, uint8_t mod) {	//type = 0:mpeg audio/128, 1:video and pes private streams (including ac3/dts/lpcm)/1024	if(type == 0)	//audio		size = (size + 127) / 128;	else		//video or other		size = ((size + 1023) / 1024);	if(! size)		size++;	b[0] = ((size >> 8) & 0x3f) | (type==1 ? 0x60 : 0x40) | mod;	b[1] = size & 0xff;}static void write_mpeg2_scr(unsigned char *b, uint64_t ts) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -