FFmpeg decoding H264

Source: Internet
Author: User

Initialize FFmpeg

typedef struct
{
struct avcodec *codec;//codecl;
struct Avcodeccontext *c;//Codec context
int frame_count;
struct Avframe *picture;//Frame
avpacket avpkt;


int iwidth;
int iheight;
int comsumedsize;
int got_picture;
} Decoder_handle;
Decoder_handle *phandle = (Decoder_handle *) malloc (sizeof (decoder_handle));
		if (Phandle = = NULL) {OutputDebugString (_t (" -1\n"));
	return-1;

	} avcodec_register_all ();

	Av_init_packet (& (PHANDLE->AVPKT));
	Phandle->codec = Avcodec_find_decoder (AV_CODEC_ID_MPEG4);
	Phandle->codec = Avcodec_find_decoder (av_codec_id_h264);
		if (!phandle->codec) {OutputDebugString (_t (" -2\n"));
	Return-2;
	} phandle->c = Avcodec_alloc_context3 (PHANDLE->CODEC);
		if (!phandle->c) {OutputDebugString (_t (" -3\n"));
	return-3;

	} if (phandle->codec->capabilities&codec_cap_truncated) phandle->c->flags |= CODEC_FLAG_TRUNCATED;
	Phandle->c->extradata=new uint8_t[30];
	memset (phandle->c->extradata,0,30);
	Phandle->c->codec_type = Avmedia_type_video;
	PHANDLE->C->PIX_FMT = pix_fmt_yuv420p;  
	Phandle->c->time_base.num = 1; Phandle->c->frame_number = 1;
	One video frame per packet;  
	phandle->c->bit_rate = 0; phandle->c->time_base.den = 30;//frame rate;
	Phandle->c->width = 320;//video width;
	
	Phandle->c->height = 240;//video high;
	if (Avcodec_open2 (Phandle->c, Phandle->codec, NULL) < 0)//{//OutputDebugString (_t (" -4\n"));
	return-4;
	} phandle->picture = Av_frame_alloc ();
		if (!phandle->picture) {OutputDebugString (_t (" -5\n"));
	return-5; }




Receive SPS and PPS, and then assign values to Avcodeccontext's Extradata,sps and PPS for the following operations

                        unsigned char startcode[] = {0,0,0,1};
			memcpy (m_dechandle->c->extradata+m_dechandle->c->extradata_size,startcode,sizeof (Startcode));
			M_dechandle->c->extradata_size+=sizeof (Startcode);
			memcpy (M_dechandle->c->extradata+m_dechandle->c->extradata_size,pwsabuf->buf+headoffset, Nret-headoffset);
			m_dechandle->c->extradata_size+=nret-headoffset;




And then open the encoder.

if (Avcodec_open2 (M_dechandle->c, M_dechandle->codec, NULL) < 0)
				{
					OutputDebugString (_t (" -4\n"));
					return;
				}
				OutputDebugString (_t ("Open decoder succeeded"));

Packaged

BOOL streamdecode::unpackrtph264 (void * Bufin, int len, void * * pbufout, int * poutlen) {* Poutlen = 0
	;
	if (Len < Rtp_headlen) {return false;
	} unsigned char * src = (unsigned char *) Bufin + Rtp_headlen; unsigned char head1 = * SRC;
	Gets the first byte; unsigned char head2 = * (src + 1);
	Gets the second byte; unsigned char nal = head1 & 0x1f; Gets the type domain of FU indicator, unsigned char flag = head2 & 0xe0;  Gets the first three bits of the FU header, determining if the current is the beginning, middle, or end of the packet unsigned char Nal_fua = (Head1 & 0xe0) | (Head2 & 0x1f);
	fu_a nal bool Bfinishframe = false;
			if (nal = = 0x1c)//Judge nal type is 0x1c=28, description is fu-a fragment {//fu-a if (flag = = 0x80)//Start {* Pbufout = src-3; * (int *) (* pbufout) = 0x01000000;
			ZYF: Big mode will have a problem * ((char *) (* pbufout) + 4) = Nal_fua;
			
			
		* Poutlen = Len-rtp_headlen + 3;
			else if (flag = = 0x40)//END {* Pbufout = src + 2;* Poutlen = len-rtp_headlen-2;
			else//Middle {* Pbufout = src + 2;
			
		* Poutlen = len-rtp_headlen-2;
		} else//single packet data {* Pbufout = src-4; * (int *) (* pbufout) = 0x01000000;
	ZYF: Big mode will have a problem * Poutlen = Len-rtp_headlen + 4;
return bfinishframe;    }

To splice into a frame of data after packing; Decode display

Decoder_decode (Decoder_h dwhandle, uint8_t *pdatain, int ninsize) {if (dwhandle <= 0) {return-1;
	} DDSURFACEDESC2 DDSD;
	memset (&AMP;DDSD, 0, sizeof (DDSURFACEDESC2)); 
	ddsd.dwsize = sizeof (DDSD);
	Decoder_handle *phandle = (Decoder_handle *) Dwhandle;

	HRESULT Ddrval;
	Av_init_packet (& (PHANDLE-&GT;AVPKT));
	Phandle->avpkt.size = ninsize;
	
	Phandle->avpkt.data = Pdatain;
	phandle->avpkt.dts=0;
	phandle->avpkt.flags=1;
	phandle->avpkt.duration=1;
	phandle->avpkt.priv=0;


	unsigned char * LPSURF; Phandle->comsumedsize = Avcodec_decode_video2 (Phandle->c, Phandle->picture, &pHandle->got_picture,
	& (PHANDLE-&GT;AVPKT));
		if (Phandle->comsumedsize < 0) {OutputDebugString (_t ("Decoding failed \ n"));
	Return-2;
		} if (phandle->got_picture) {//outputdebugstring (_t ("decoded)");
		cwnd* pwnd = M_dlg->getdlgitem (Idc_playwindow);
		CRect RC;
			if (pwnd) {pwnd->getwindowrect (RC); int nwidth=phandle->c->width; Rc. WiDTH (); int NHEIGHT=PHANDLE-&GT;C-&GT;HEIGHT;//RC.			
			Height ();  
			avframe* Pframeyuv=avcodec_alloc_frame ();  
			uint8_t *out_buffer= (uint8_t *) Av_malloc (avpicture_get_size (Pix_fmt_yuv420p,nwidth, nHeight));
			Avpicture_fill ((Avpicture *) PFRAMEYUV, Out_buffer, pix_fmt_yuv420p, nwidth, nheight); Img_convert_ctx = Sws_getcontext (Phandle->c->width, Phandle->c->height, PHANDLE-&GT;C-&GT;PIX_FMT,   
			Nwidth, nheight, pix_fmt_yuv420p, sws_bicubic, NULL, NULL, NULL); Sws_scale (Img_convert_ctx, (const uint8_t* const*) Phandle->picture->data, phandle->picture->linesize, 0  
			, Phandle->c->height, Pframeyuv->data, pframeyuv->linesize);  

			Sws_freecontext (IMG_CONVERT_CTX); Ddsd.dwflags = Ddsd_caps | Ddsd_height | Ddsd_width |
			Ddsd_pixelformat; Ddsd.ddsCaps.dwCaps = Ddscaps_offscreenplain | ddscaps_videomemory;//| 
			Ddscaps_systemmemory;
			Ddsd.dwheight = nheight;
			Ddsd.dwwidth = nwidth; ddsd.ddpfPixelFormat.dwSize = sizeof (ddpixelformat); Ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC |
			DDPF_YUV;
			Ddsd.ddpfPixelFormat.dwFourCC =MAKEFOURCC (' Y ', ' V ', ' 1 ', ' 2 ');///MAKEFOURCC (' I ', ' 4 ', ' 2 ', ' 0 ');

			Ddsd.ddpfPixelFormat.dwYUVBitCount = 8; if (Dd_ok!= (ddrval = Lpdd->createsurface (&AMP;DDSD, &lpddsoffscreen, NULL)) {OutputDebugString (_T ("Create off-screen table
				Face failed \ n ")); AfxMessageBox (_t) failed to create the off screen surface.
				\ n "));
			return 0; } do {ddrval = Lpddsoffscreen->lock (null,&ddsd,ddlock_wait |
			Ddlock_writeonly,null);
			while (Ddrval = = dderr_wasstilldrawing);
				if (ddrval!= dd_ok) {outputdebugstring ("Write off screen surface failed \ n")); AfxMessageBox (_t ("Write off screen surface failed.)

			\ n "));
			} Lpsurf = (unsigned char *) (ddsd.lpsurface);
			Lpbyte ptry = pframeyuv->data[0];
			Lpbyte Ptru = pframeyuv->data[1];
			Lpbyte PTRV = pframeyuv->data[2];
				if (lpsurf) {int i = 0;
					for (i = 0; i < ddsd.dwheight i++) {memcpy (Lpsurf, Ptry, ddsd.dwwidth);
					Ptry + = Ddsd.dwwidth; Lpsurf+ + Ddsd.lpitch;   
					for (i = 0; i < DDSD.DWHEIGHT/2 i++) {//memcpy (Lpsurf, LpV, DDSD.DWWIDTH/2);   
					LpV + + pframe->width/2;   
					Lpsurf + = DDSD.LPITCH/2;
					memcpy (Lpsurf, PTRV, DDSD.DWWIDTH/2); 
					PTRV + = DDSD.DWWIDTH/2;
				Lpsurf + = DDSD.LPITCH/2;
					for (i = 0; i < DDSD.DWHEIGHT/2 i++) {memcpy (Lpsurf, Ptru, DDSD.DWWIDTH/2);
					Ptru + = DDSD.DWWIDTH/2;  
				Lpsurf + = DDSD.LPITCH/2;
			} lpddsoffscreen->unlock (NULL);			

			CRect Localrect;
			GetWindowRect (Pwnd->m_hwnd, &localrect);

			Localrect.bottom + + (localrect.bottom-localrect.top) * 72/278;

			HRESULT Ddres=lpddsprimary->blt (&localrect, Lpddsoffscreen, NULL, ddblt_wait, NULL);  
			Av_free (Out_buffer);
			Av_free (PFRAMEYUV);
				if (lpddsoffscreen) {lpddsoffscreen->release ();
			Lpddsoffscreen = NULL;
 }
		}	
	}








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.