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

📄 muxer_mpeg.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
		if(spriv->picture.mpeg1 == 0 && priv->patch_sde)		{			while((s->buffer[tmp] != 0 || s->buffer[tmp+1] != 0 || s->buffer[tmp+2] != 1 || s->buffer[tmp+3] != 0xb5 ||				((s->buffer[tmp+4] & 0xf0) != 0x20)) &&				(tmp < len-5))				tmp++;						if(tmp < len-5)		//found				patch_panscan(priv, &(s->buffer[tmp+4]));		}						if(s->buffer[3])		{	// Sequence or GOP -- scan for Picture			s->gop_start = s->h.dwLength;			while (ptr < len-5 && 				(s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0)) 				ptr++;		}		if (ptr >= len-5) 		{			pt = 0; // Picture not found?!			temp_ref = 0;			mp_msg(MSGT_MUXER, MSGL_ERR,"Warning: picture not found in GOP!\n");		} 		else 		{			pt = (s->buffer[ptr+5] & 0x1c) >> 3;			temp_ref = (s->buffer[ptr+4]<<2)+(s->buffer[ptr+5]>>6);			if(!spriv->vframes)				spriv->last_tr = spriv->max_tr = temp_ref;			d1 = temp_ref - spriv->last_tr;			if(d1 < -6)	//there's a wraparound				frames_diff = spriv->max_tr + 1 + temp_ref - spriv->last_tr;			else if(d1 > 6)	//there's a wraparound				frames_diff = spriv->max_tr + 1 + spriv->last_tr - temp_ref;			else				frames_diff = d1;			mp_msg(MSGT_MUXER, MSGL_V, "\nLAST: %d, TR: %d, DIFF: %d, MAX: %d, d1: %d\n", 			spriv->last_tr, temp_ref, frames_diff, spriv->max_tr, d1);			if(!temp_ref)				spriv->max_tr = 0;			else if(temp_ref > spriv->max_tr)				spriv->max_tr = temp_ref;						spriv->last_tr = temp_ref;			mp_msg(MSGT_MUXER, MSGL_V, "Video frame type: %c, TR: %d\n", FTYPE(pt), temp_ref);			if(spriv->picture.mpeg1 == 0) 			{				size_t tmp = ptr;							while (ptr < len-5 && 					(s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0xb5)) 						ptr++;				if(ptr < len-5) 				{					pce_ptr = &(s->buffer[ptr+4]);					if(spriv->telecine)						soft_telecine(spriv, fps_ptr, se_ptr, pce_ptr, frames_diff);					mp_header_process_extension(&(spriv->picture), &(s->buffer[ptr+4]));					if(spriv->picture.display_time >= 50 && spriv->picture.display_time <= 300) 						spriv->delta_pts = (spriv->nom_delta_pts * spriv->picture.display_time) / 100;				}				else 					spriv->delta_pts = spriv->nom_delta_pts;							ptr = tmp;			}		}				switch (pt) {			case 2: // predictive			  if (s->ipb[0]) {			    sz = len + s->ipb[0];			    s->ipb[0] = max(s->ipb[0], s->ipb[2]);			    s->ipb[2] = 0;			  } else if (s->ipb[2]) {			    sz = len + s->ipb[2];			    s->ipb[0] = s->ipb[2];			    s->ipb[2] = 0;			  } else			    sz = 4 * len; // no bidirectional frames yet?					  s->ipb[1] = len;			  break;			case 3: // bidirectional			  s->ipb[2] += len;			  sz = s->ipb[1] + s->ipb[2];			  break;			default: // intra-coded			  sz = len; // no extra buffer for it...		}		spriv->vframes++;		reorder_frame(spriv, s->buffer, len, pt, temp_ref, spriv->delta_pts);	}		mp_msg(MSGT_MUXER, MSGL_V,"parse_mpeg12_video, return %u\n", (uint32_t) len);	return sz;}static uint64_t fix_mp4_frame_duration(muxer_headers_t *vpriv){	uint64_t mn, md, mx, diff;	uint32_t i;	mn = mx = vpriv->framebuf[0].pts;	for(i = 0; i < 3; i++) 	{		mp_msg(MSGT_DECVIDEO,MSGL_V, "PTS: %llu\n", vpriv->framebuf[i].pts);		if(vpriv->framebuf[i].pts < mn)			mn = vpriv->framebuf[i].pts;		if(vpriv->framebuf[i].pts > mx)			mx = vpriv->framebuf[i].pts;	}	md = mn;	for(i=0; i<3; i++) 	{		if((vpriv->framebuf[i].pts > mn) && (vpriv->framebuf[i].pts < mx))		md = vpriv->framebuf[i].pts;	}	mp_msg(MSGT_DECVIDEO,MSGL_V, "MIN: %llu, mid: %llu, max: %llu\n", mn, md, mx);		if(mx - md > md - mn)		diff = md - mn;	else		diff = mx - md;	if(diff > 0)	{		for(i=0; i<3; i++) 		{			vpriv->framebuf[i].pts += diff;			vpriv->framebuf[i].dts += i * diff;			mp_msg(MSGT_MUXER, MSGL_V, "FIXED_PTS: %.3lf, FIXED_DTS: %.3lf\n", 				(double) (vpriv->framebuf[i].pts/92160000.0), (double) (vpriv->framebuf[i].dts/92160000.0));		}		return diff;	}	else		return 0;}static size_t parse_mpeg4_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_headers_t *vpriv, float fps, size_t len){	size_t ptr = 0;	int64_t delta_pts;	uint8_t pt;		mp_msg(MSGT_MUXER, MSGL_V,"parse_mpeg4_video, len=%u\n", (uint32_t) len);	if(len<6) 	{		mp_msg(MSGT_MUXER, MSGL_ERR,"Frame too short: %d, exit!\n", len);		return 0;	}		while(ptr < len - 5)	{		if(s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1)		{			ptr++;			continue;		}				if(s->buffer[ptr+3] >= 0x20 && s->buffer[ptr+3] <= 0x2f) //VOL		{			mp4_header_process_vol(&(vpriv->picture), &(s->buffer[ptr+4]));		}		else if(s->buffer[ptr+3] == 0xb3)	//gov		{			//fprintf(stderr, "\nGOV\n");		}		else if(s->buffer[ptr+3] == 0xb6)	//vop		{			int32_t delta;			mp4_header_process_vop(&(vpriv->picture), &(s->buffer[ptr+4]));						delta = vpriv->picture.timeinc_unit - vpriv->last_tr;			if((delta > 0) && (delta > (vpriv->picture.timeinc_resolution/2)))				delta -= vpriv->picture.timeinc_resolution;			else if((delta < 0) && (delta < (-vpriv->picture.timeinc_resolution/2)))				delta += vpriv->picture.timeinc_resolution;						delta_pts = (92160000 * (int64_t) delta) / vpriv->picture.timeinc_resolution;						pt = vpriv->picture.picture_type + 1;			mp_msg(MSGT_MUXER, MSGL_V, "\nTYPE: %c, RESOLUTION: %d, TEMP: %d, delta: %d, delta_pts: %lld = %.3lf, delta2: %.3lf\n", 				FTYPE(pt), vpriv->picture.timeinc_resolution, vpriv->picture.timeinc_unit, delta, delta_pts, (double) (delta_pts/92160000.0),				(double) delta / (double) vpriv->picture.timeinc_resolution);						vpriv->last_tr = vpriv->picture.timeinc_unit;							break;		}				ptr++;	}		vpriv->last_dts += vpriv->frame_duration;	vpriv->last_pts += delta_pts;		reorder_frame(vpriv, s->buffer, len, pt, 0, delta_pts);	vpriv->framebuf[vpriv->framebuf_used-1].pts = vpriv->last_pts;	vpriv->framebuf[vpriv->framebuf_used-1].dts = vpriv->last_dts;	vpriv->framebuf[vpriv->framebuf_used-1].idur = vpriv->frame_duration;		/*mp_msg(MSGT_MUXER, MSGL_V, "\nMPEG4V, PT: %c, LEN=%u, DELTA_PTS: %.3lf, PTS: %.3lf, DTS: %.3lf\n", 		FTYPE(pt), len, (delta_pts/92160000.0),		(double) (vpriv->framebuf[vpriv->framebuf_used-1].pts/92160000.0), 		(double) (vpriv->framebuf[vpriv->framebuf_used-1].dts/92160000.0), len);*/		if(!vpriv->frame_duration && vpriv->framebuf_used == 3)	{		vpriv->frame_duration = fix_mp4_frame_duration(vpriv);		if(vpriv->frame_duration)		{			vpriv->last_pts += vpriv->frame_duration;			vpriv->last_dts = vpriv->framebuf[vpriv->framebuf_used-1].dts;			vpriv->delta_clock = ((double) vpriv->frame_duration)/92160000.0;			mp_msg(MSGT_MUXER, MSGL_INFO, "FRAME DURATION: %llu   %.3lf\n", 				vpriv->frame_duration, (double) (vpriv->frame_duration/92160000.0));		}	}		mp_msg(MSGT_MUXER, MSGL_V, "LAST_PTS: %.3lf, LAST_DTS: %.3lf\n", 		(double) (vpriv->last_pts/92160000.0), (double) (vpriv->last_dts/92160000.0));		return len;}static void mpegfile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags){  size_t ptr=0, sz = 0;  uint64_t pts, tmp;  muxer_t *muxer = s->muxer;  muxer_priv_t *priv = (muxer_priv_t *)muxer->priv;  muxer_headers_t *spriv = (muxer_headers_t*) s->priv;  FILE *f;  float fps;  uint32_t stream_format;    f = muxer->file;   if(s->buffer == NULL)  	return;    pts = 0;  if (s->type == MUXER_TYPE_VIDEO) { // try to recognize frame type...	fps = (float) s->h.dwRate/ (float) s->h.dwScale;  	spriv->type = 1;	spriv->has_pes_priv_headers = 0;	stream_format = s->bih->biCompression;    if(is_mpeg1(stream_format) || is_mpeg2(stream_format))    {      spriv->is_mpeg12 = 1;      if(len)        sz = parse_mpeg12_video(s, priv, spriv, fps, len);      else {        tmp = (uint64_t) (92160000 / fps);        spriv->last_pts += tmp;        spriv->last_dts += tmp;      }    }    else if(is_mpeg4(stream_format))     {      spriv->is_mpeg12 = 0;      spriv->reorder = 0;      spriv->telecine = 0;      if(spriv->size == 0)        priv->use_psm = 1;      if(len)        sz = parse_mpeg4_video(s, priv, spriv, fps, len);      else {        tmp = (uint64_t) (92160000 / fps);        spriv->last_pts += tmp;        spriv->last_dts += tmp;      }    }    mp_msg(MSGT_MUXER, MSGL_V,"mpegfile_write_chunk, Video codec=%x, len=%u, mpeg12 returned %u\n", stream_format, (uint32_t) len, (uint32_t) sz);    ptr = 0;    priv->vbytes += len;        sz <<= 1;  } else { // MUXER_TYPE_AUDIO  	spriv->type = 0;	stream_format = s->wf->wFormatTag;			mp_msg(MSGT_MUXER, MSGL_V,"\nmpegfile_write_chunk, Audio codec=%x, len=%u, frame size=%u\n", 			stream_format, (uint32_t) len, (uint32_t) spriv->frame_size);	if(spriv->bitrate == 0)		spriv->bitrate = s->wf->nAvgBytesPerSec;	// I need to know the audio frame size	if(spriv->frame_size == 0)	{		spriv->frame_size = get_audio_frame_size(spriv, s->buffer, stream_format, s->wf->nSamplesPerSec);		spriv->aframe_delta_pts = ((double) spriv->frame_size / (double) spriv->bitrate);		//spriv->delta_pts = (uint64_t) (spriv->aframe_delta_pts * 92160000);		spriv->delta_pts = (uint64_t) (92160000 * spriv->frame_size) / spriv->bitrate;		mp_msg(MSGT_MUXER, MSGL_INFO, "AUDIO FRAME SIZE: %u, DELTA_PTS: %llu (%.3lf)\n", (uint32_t) spriv->frame_size, spriv->delta_pts, spriv->aframe_delta_pts);	}				if(s->b_buffer_size - s->b_buffer_len < len)	{		s->b_buffer = realloc(s->b_buffer, len  + s->b_buffer_len);		if(s->b_buffer == NULL)		{			mp_msg(MSGT_MUXER, MSGL_FATAL, "\nFATAL! couldn't realloc %d bytes\n", len  + s->b_buffer_len);			return;		}				s->b_buffer_size = len  + s->b_buffer_len;		mp_msg(MSGT_MUXER, MSGL_DBG2, "REALLOC(%d) bytes to AUDIO backbuffer\n", s->b_buffer_size);	}	memcpy(&(s->b_buffer[s->b_buffer_ptr + s->b_buffer_len]), s->buffer, len);	s->b_buffer_len += len;		if(stream_format == AUDIO_A52)	{		s->type = 1;		s->ckid = be2me_32 (0x1bd);		if(s->size == 0) 		{			spriv->max_pl_size -= 4;			if(priv->is_genmpeg1 || priv->is_genmpeg2)				fix_audio_sys_header(priv, spriv->id, 0xbd, 58*1024);	//only one audio at the moment			spriv->id = 0xbd;		}	}		if(priv->init_adelay < 0)	{		uint64_t delay_len;		priv->abytes += len;		delay_len = (uint64_t) abs((priv->init_adelay * (double) spriv->bitrate));		if(priv->abytes >= delay_len)		{			if(priv->drop)			{				mp_msg(MSGT_MUXER, MSGL_V, "\nDROPPING %llu AUDIO BYTES, DELAY: %.3lf, BR: %u\n", delay_len, priv->init_adelay, spriv->bitrate);				drop_delayed_audio(muxer, s, (int64_t) delay_len);			}			else			{				mp_msg(MSGT_MUXER, MSGL_V, "\nWRITING %llu EARLY AUDIO BYTES, DELAY: %.3lf, BR: %u\n", delay_len, priv->init_adelay, spriv->bitrate);				save_delayed_audio(muxer, s, (uint64_t) (92160000 * (-priv->init_adelay)));			}			priv->init_adelay = 0.0;			conf_init_adelay = 0;			priv->drop = 0;		}	}		sz = max(len, 2 * priv->packet_size);  }    if (s->h.dwSampleSize) {	// CBR	s->h.dwLength += len/s->h.dwSampleSize;	if (len%s->h.dwSampleSize) mp_msg(MSGT_MUXER, MSGL_ERR, "Warning! len isn't divisable by samplesize!\n");  } else {	// VBR	s->h.dwLength++;  }    s->size += len;  s->timer = (double)s->h.dwLength*s->h.dwScale/s->h.dwRate;  //if genmpeg1/2 and sz > last buffer size in the system header we must write the new sysheader  if(sz > s->h.dwSuggestedBufferSize) { // increase and set STD 	s->h.dwSuggestedBufferSize = sz;	if(priv->is_genmpeg1 || priv->is_genmpeg2) {		fix_buffer_params(priv, spriv->id, s->h.dwSuggestedBufferSize);		priv->update_system_header = 1;	}  }    if(spriv->psm_fixed == 0) {  	add_to_psm(priv, spriv->id, stream_format);	spriv->psm_fixed = 1;	priv->psm_streams_cnt++;	if((priv->psm_streams_cnt == muxer->num_videos + muxer->num_audios) && priv->use_psm)		write_psm_block(muxer, muxer->file);  }    if(priv->init_adelay != 0)    return;    flush_buffers(muxer, 0);}static void mpegfile_write_index(muxer_t *muxer){	muxer_priv_t *priv = (muxer_priv_t *) muxer->priv;	while(flush_buffers(muxer, 0) > 0);	flush_buffers(muxer, 1);	if(priv->is_genmpeg1 || priv->is_genmpeg2)		write_mpeg_pack(muxer, NULL, muxer->file, NULL, 0, 1);	//insert fake Nav Packet			mp_msg(MSGT_MUXER, MSGL_INFO, "\nOverhead: %.3lf%% (%llu / %llu)\n", 100.0 * (double)priv->headers_size / (double)priv->data_size, priv->headers_size, priv->data_size);}static void mpegfile_write_header(muxer_t *muxer){	muxer_priv_t *priv = (muxer_priv_t*) muxer->priv;		priv->headers_cnt++;		if((priv->is_genmpeg1 || priv->is_genmpeg2) && (priv->headers_cnt == muxer->avih.dwStreams))	{		int i;		for(i = 0; i < muxer->avih.dwStreams; i++)		{			priv->sys_info.streams[i].bufsize = muxer->streams[i]->h.dwSuggestedBufferSize;			mp_msg(MSGT_MUXER, MSGL_V, "IDX: %d, BUFSIZE: %u\n", i, priv->sys_info.streams[i].bufsize);		}	}		//write the first system header only for generic mpeg1/2 muxes, and only when we have collected all necessary infos	if(priv->is_genmpeg1 || priv->is_genmpeg2 || ((priv->is_xvcd || priv->is_xsvcd) && (priv->headers_cnt == 1)))	{		write_mpeg_pack(muxer, NULL, muxer->file, NULL, 0, 0);		priv->update_system_header = 0;	}		return;}static void setup_sys_params(muxer_priv_t *priv){	if(priv->is_dvd)	{		priv->sys_info.cnt = 4;				priv->sys_info.streams[0].id = 0xb9;		priv->sys_info.streams[0].type = 1;		priv->sys_info.streams[0].bufsize = 232*1024;					priv->sys_info.streams[1].id = 0xb8;		priv->sys_info.streams[1].type = 0;		priv->sys_info.streams[1].bufsize = 4*1024;				priv->sys_info.streams[2].id = 0xbd;		priv->sys_info.streams[2].type = 1;		priv->sys_info.streams[2].bufsize = 58*1024;				priv->sys_info.streams[3].id = 0xbf;		priv->sys_info.streams[3].type = 1;		priv->sys_info.streams[3].bufsize = 2*1024;	}	else if(priv->is_xvcd || priv->is_xsvcd)	{		priv->sys_info.cnt = 2;				priv->sys_info.streams[0].id = 0xe0;		priv->sys_info.streams[0].type = 1;		priv->sys_info.streams[0].bufsize = (priv->is_xvcd ? 46: 230)*1024;					priv->sys_info.streams[1].id = 0xc0;		priv->sys_info.streams[1].type = 0;		priv->sys_info.streams[1].bufsize = 4*1024;	}	else		priv->sys_info.cnt = 0;}int muxer_init_muxer_mpeg(muxer_t *muxer){  muxer_priv_t *priv;  priv = (muxer_priv_t *) calloc(1, sizeof(muxer_pri

⌨️ 快捷键说明

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