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 (&DDSD, 0, sizeof (DDSURFACEDESC2));
ddsd.dwsize = sizeof (DDSD);
Decoder_handle *phandle = (Decoder_handle *) Dwhandle;
HRESULT Ddrval;
Av_init_packet (& (PHANDLE->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->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->C->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->C->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 (&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;
}
}
}