H264 Code Stream Package MP4

Source: Internet
Author: User
Tags printf

Code stream encapsulation using open Source Library FFmpeg

The H264 stream is written to H264 buffer via the function h264buff_write (), and mux_thread the received stream into the MP4 file.

Here I use a separate thread encapsulation stream is to solve the recording process of the cycle of the problem, or can not be separate pull thread.


Type declaration

/*---------------for muxing--------------*/
#ifndef int64_c
#define INT64_C (c) (C # # LL)
#define Uint64_c (c) (C # # ULL)
#endif

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

#define Stream_frame_rate
#define STREAM_PIX_FMT    pix_fmt_yuv420p/    * av_pix_fmt_yuv420p */* Default PIX_FMT */


static int
h264buff_write (char *buf, int n, int instns);

global variable Declaration

static int h264buff_flag = 0;
sem_t Sem_f;
static Char h264bufa[5242880];/*5mb*///[54857600];   /*50mb*/
static char h264bufb[5242880];//[54857600];

static int a_size;
static int b_size;

function declaration

/*------------------------muxing---------------------------------*/*-----------------< 0 = Error 0 = i-frame 1  = P-frame 2 = b-frame 3 = s-frame--------------------*/static int getvoptype (const void *p, int len) {if ( !p | |

	6 >= len) return-1;
	unsigned char *b = (unsigned char*) p; /* Verify NAL marker */if (B[0] | | B[1] | |
		0x01! = b[2]) {b++;
	if (B[0] | | b[1] | | 0x01! = b[2]) return-1;
	} B + = 3;
		/* Verify VOP ID */if (0xb6 = = *b) {b++;
	Return (*b & 0xc0) >> 6;
		} switch (*b) {case 0x65:return 0;
		Case 0x61:return 1;
	Case 0x01:return 2;
} return-1;

	} static int get_nal_type (void *p, int len) {if (!p | | 5 >= len) return-1;

	unsigned char *b = (unsigned char*) p;
		/* Verify NAL Marker * * if (b[0] | | b[1] | | 0x01 = b[2]) {b++;
	if (B[0] | | b[1] | | 0x01! = b[2]) return-1;
	} B + = 3;
Return (*b & 0x1f); }/* Add an OUTPUT stream */static Avstream *add_stream (AVFormatcontext *oc, Avcodec **codec, struct mux_priv *mux_p, void *p, int len) {Avcodeccontext *PCC;
	Avstream *pst;
	Avbitstreamfiltercontext * Avfilter;

	Enum Codecid codec_id = codec_id_h264;
	PST = Av_new_stream (OC, 0);
		if (!pst) {printf ("could not allocate stream \ n");
	return NULL;
	} Pst->id = oc->nb_streams-1;
	PCC = pst->codec;
	Mux_p->vi = pst->index;

	Avcodec_get_context_defaults2 (PCC, NULL);
	pcc->codec_id = codec_id;
	Pcc->codec_type = Codec_type_video;
	Pcc->bit_rate = 3000000;
	Pcc->width = 720;
	Pcc->height = 480;
	Pcc->time_base.den = 30;
	Pcc->time_base.num = 1;
	Pcc->frame_number = 1;
	Pcc->gop_size = 12;

	PCC-&GT;PIX_FMT = stream_pix_fmt;
	Avfilter = Av_bitstream_filter_init ("H264_mp4toannexb");
	Pcc->extradata_size = Len;      Pcc->extradata = (uint8_t*) p;


	/*set the PPS SPS of H264 */printf ("\n\nzorro, pcc->codec_id =%d. \ n", (int) pcc->codec_id); if (Oc->oformat->flags & Avfmt_globAlheader) {pcc->flags |= codec_flag_global_header;
} return PST; } static int CreateMp4 (Avformatcontext **pm_poc, char *pszfilename, struct mux_priv *mux_p, void *p, int len) {int R Et
	Successfully returned 0, failed to return 1//const char* pszfilename = "Output002.mp4";
	Avoutputformat *fmt;
	Avcodec *video_codec;
	Avstream *m_pvideost;

	Avformatcontext *m_poc;
		/*0x67 or 0x27*/if (0x07! = Get_nal_type (P, Len)) {printf ("Can not detect nal type");
	return-1;


	} av_register_all (); /* Auto detect the output format from the name. Default is MPEG.
	*/FMT = Guess_format (null, pszfilename, NULL);
		if (!fmt) {printf ("Could not deduce output format from file extension:using mpeg.\n");
	FMT = Guess_format ("MPEG", pszFileName, NULL);
		} if (!fmt) {fprintf (stderr, "Could not find suitable output format\n");
	return-1;//}/* Allocate the output media context */M_poc = Av_alloc_format_context ();
	*pm_poc = M_poc;
		if (!M_POC) {fprintf (stderr, "Memory error\n");
	return-1;
}	M_poc->oformat = FMT;
	snprintf (m_poc->filename, sizeof (M_poc->filename), "%s", pszFileName); 
			if (fmt->video_codec! = Codec_id_none) {if (M_pvideost = Add_stream (M_poc, &video_codec, Mux_p, p, len) = = NULL) {
		return-1; }}/* Set the output parameters (must is done even if no parameters).
		*/if (Av_set_parameters (M_poc, NULL) < 0) {printf ("Invalid output format parameters\n");
	return-1;

	} dump_format (M_poc, 0, pszFileName, 1); /* Open the output file, if needed */if (!) Fmt->flags & Avfmt_nofile) {if (Url_fopen (&AMP;M_POC-&GT;PB, pszFileName, url_wronly) < 0) {printf ("Coul
			D not open '%s ' \ n ', pszfilename);
		return-1;
	}}/* Write The stream header, if any */ret = Av_write_header (M_POC);
		if (Ret < 0) {printf ("Error occurred when opening output file");
	return-1;
} return 0; }/* Write H264 data to MP4 file */static int writevideo (Avformatcontext *m_poc, struct mux_priv *mux_p, void* data, int Nlen) {int ret;
		if (0 > Mux_p->vi) {printf ("Vi less than 0");
	return-1;

	} Avstream *pst = m_poc->streams[mux_p->vi];

	Init packet Avpacket PKT;

	My add, in order to calculate pts avcodeccontext *c = pst->codec;
	Av_init_packet (&AMP;PKT); Pkt.flags |= (0 >= getvoptype (data, Nlen))?   

	pkt_flag_key:0;
	Pkt.stream_index = pst->index;
	Pkt.data = (uint8_t*) data;

	Pkt.size = Nlen;
	Wait for key frame if (Mux_p->waitkey) if (0 = = (Pkt.flags & pkt_flag_key)) return 0;


	else Mux_p->waitkey = 0;
	Pkt.dts = Av_nopts_value;
	pkt.pts = Av_nopts_value;
	Pkt.pts = (ptsinc++) * (180000/stream_frame_rate);

	Pkt.dts = (ptsinc++) * (90000/stream_frame_rate);
	ret = Av_interleaved_write_frame (M_poc, &AMP;PKT);
	if (Ret < 0) {printf ("Cannot write frame");
	} av_free_packet (&AMP;PKT);
return 0;
	} static void CloseMp4 (Avformatcontext *m_poc) {/* no need Zorro Waitkey =-1; VI =-1;

	*/if (M_POC) Av_write_trailer (M_POC); If (M_poc &&!)
		(M_poc->oformat->flags & Avfmt_nofile)) Url_fclose (M_POC-&GT;PB);/* for New:avio_close (M_POC-&GT;PB);
		*/if (M_POC) {av_free (M_POC);
   	 M_poc = NULL; }}/*==============get_h264nal================ *function:get a NAL from H264buff,when we find the next NAL, ret Urn 0, or return-1, *author:zorro *date:6/3/2015 *======================================*/static int get_h264nal (void
	*pbuff, int plen, int *nal_len, int *nal_type) {unsigned char *h264data = (unsigned char*) pbuff;
           int h264len = Plen;

	int next_type;
		if (Plen <4) {*nal_len = Plen;
	return-1; }//Check this NAL type if (h264data[1] | | H264DATA[2] | |
	0x01! = H264data[3]) {*nal_type = 0;
		}else{*nal_type = h264data[4] & 0x1f;
		h264data+=4;
	h264len-=4; } while (H264len) {if (h264data[0] = = 0x00 && h264data[1] = = 0x00 && h264data[2] = = 0x01) {Next_typ
		
		    	E = h264data[3] & 0x1f; if (Next_type = = 0x01 | | Next_type = = 0x05) {if (h264data[-1] = = 0x00) h264data--;
				*nal_len = H264data-(unsigned char *) pbuff;
			return 0;
		}} h264data+=1;
		
	H264len-=1;
	} *nal_len = H264data-(unsigned char *) pbuff;
return-1; }/*==============mux_thread==================== *function:read h264data from H264 file, and packet it to MP4 file *aut Hor:zorro *date:6/3/2015 *======================================*/void mux_thread (void *arg) {struct Encode *enc = (
	struct encode *) arg;
	int instns = enc->cmdl->instns;
	struct Mux_priv mux_p = {0,-1, 1};
	Char *h264head;

	int H264len;
	unsigned char nalbuf[512 * 1024];
	int Nal_len;
	int Read_len;

	int nal_type;
	
	int RS;
	

Avformatcontext * Pformatctx = NULL;
	Waitenc:sem_wait (& Sem_f);
		if (H264buff_flag = = 1) {h264head = H264bufa;
		H264len = a_size;
	a_size = 0;
		}else{h264head = H264BUFB;
		H264len = b_size;
	b_size = 0; } do{/* reach the next NAL or h264buf end*/rs = get_h264nal (H264head, H264leN, &read_len, &nal_type);
		if ((H264len-read_len) < 0) {printf ("\n\n\nzorro, get_h264nal err.\n\n");
		}/* No data to read, break out*/if (read_len <= 0) break;
			/* New nal*/if (Nal_type > 0) {memcpy (Nalbuf, H264head, Read_len); 
			Nal_len = Read_len;	   if (Nal_type = = 0x05) Mux_p.waitkey = 1;
			/*check key frame*/}else{/* Last nal*/memcpy (&nalbuf[nal_len], h264head, Read_len);
		Nal_len + = Read_len; 
		} H264head + = Read_len;

		H264len-= Read_len;
			/* Reach the h264buf end */if (Rs < 0) {if (! enc_end) goto Waitenc;
		printf ("reach the H264 buff end, H264len =%d, Nal_len =%d, Nal_type =%d\n", H264len, Nal_len, Nal_type);

		
		} if (0 < Nal_len) {memset (&nalbuf[nal_len], 0, ff_input_buffer_padding_size); if (!pformatctx) {if (CREATEMP4 (&pformatctx, Enc->cmdl->output, &mux_p, Nalbuf, Nal_len) < 0) {bre
			Ak }} if (Pformatctx) if (Writevideo (Pformatctx, &Amp;mux_p, Nalbuf, Nal_len) < 0) break;

	}/* End if (0 < Nal_len) */if (quitflag) break;
	}while (0 < Nal_len);
	CLOSEMP4 (PFORMATCTX); Ins_priv[instns].
	a_size = 0; Ins_priv[instns].
	b_size = 0;
printf ("\nmuxing end\n"); }/*==============h264buff_write================ *function:copy The encoded data Frome Vpu to H264buff, *author:zorro * date:6/3/2015 *======================================*/static int h264buff_write (char *buf, int n, int instns) {//if (
	
	Fwrite_thread_err < 0)//return-1; if (! H264buff_flag) {if (a_size >= 5000000) {printf ("Zorro,memory err, out of H264bufa range:
			\ n ");
		return-1;
		} memcpy (void *) (& h264bufa[A_size]), (void *) BUF, n);
		A_size+=n;
			 if (a_size >= 5000000) {h264buff_flag = 1;
		Sem_post (& Sem_f); }}else{if (b_size >= 5000000) {printf ("Zorro,memory err, out of H264BUFB range:
			\ n ");
		return-1;
		} memcpy (void *) (& h264bufb[B_size]), (void *) BUF, n); B_siZe+=n;
			if (b_size >= 5000000) {h264buff_flag = 0;
		Sem_post (& Sem_f);
}} return 0; }/*------------------------muxing---------------------------------*/



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.