Step by step learning, a little progress every day
FFmpeg + x264 + QT Decoding code H264
Decoding: H264 encoded format of the MP4 file decoded after saving RGB to PPM format
Encoding: Encode the decoded RGB format to H264
Code:
Decoding section:
. Pro
TEMPLATE = App
CONFIG + = Console
CONFIG-= qt
SOURCES + = Main.cpp
Includepath + =-i/usr/local/include/
LIBS + =-l/usr/local/lib-lavformat-lavcodec-lavutil-lswscale \
-lpostproc-lavfilter-lswresample-lavdevice-lx264-lm-lz-lpthread
Main.cpp
#include <iostream>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
using namespace Std;
void Saveframe (Avframe *pframe, int width, int height, int iFrame)
{
FILE *pfile;
Char szfilename[32];
int y;
sprintf (szFileName, "... /video/frame%d.ppm ", iFrame);
Pfile=fopen (szFileName, "WB");
if (pfile==null)
Return
fprintf (PFile, "p6\n%d%d\n255\n", width, height);
for (y=0; yFwrite (Pframe->data[0]+y*pframe->linesize[0], 1, width*3, pFile);
Fclose (PFile);
}
int main (int argc, char *argv[])
{
Avformatcontext *pformatctx = NULL;
int I, videostream;
Avcodeccontext *pcodecctx = NULL;
Avcodec *pcodec = NULL;
Avframe *pframe = NULL;
Avframe *pframergb = NULL;
Avpacket packet;
int framefinished;
int numbytes;
uint8_t *buffer = NULL;
Avdictionary *optionsdict = NULL;
struct Swscontext *sws_ctx = NULL;
Av_register_all ();
if (Avformat_open_input (&pformatctx, "... /video/0.mp4 ", NULL, NULL)!=0)
return-1;
if (Avformat_find_stream_info (Pformatctx, NULL) <0)
return-1;
Av_dump_format (pformatctx, 0, argv[1], 0);
Videostream=-1;
for (i=0; i<pformatctx->nb_streams; i++)
if (Pformatctx->streams[i]->codec->codec_type==avmedia_type_video) {
Videostream=i;
Break
}
if (videostream==-1)
return-1;
pcodecctx=pformatctx->streams[videostream]->codec;
Pcodec=avcodec_find_decoder (pcodecctx->codec_id);
if (pcodec==null) {
fprintf (stderr, "Unsupported codec!\n");
return-1;
}
if (Avcodec_open2 (Pcodecctx, Pcodec, &optionsdict) <0)
return-1;
Pframe=avcodec_alloc_frame ();
Pframergb=avcodec_alloc_frame ();
if (pframergb==null)
return-1;
Numbytes=avpicture_get_size (Pix_fmt_rgb24, Pcodecctx->width,
Pcodecctx->height);
Buffer= (uint8_t *) Av_malloc (numbytes*sizeof (uint8_t));
Sws_ctx =
Sws_getcontext
(
Pcodecctx->width,
Pcodecctx->height,
PCODECCTX->PIX_FMT,
Pcodecctx->width,
Pcodecctx->height,
Pix_fmt_rgb24,
Sws_bilinear,
Null
Null
Null
);
Avpicture_fill (Avpicture *) Pframergb, buffer, pix_fmt_rgb24,
Pcodecctx->width, Pcodecctx->height);
i=0;
while (Av_read_frame (Pformatctx, &packet) >=0)
{
if (Packet.stream_index==videostream)
{
Avcodec_decode_video2 (Pcodecctx, Pframe, &framefinished,
&packet);
if (framefinished)
{
Sws_scale
(
Sws_ctx,
(uint8_t const * const *) Pframe->data,
Pframe->linesize,
0,
Pcodecctx->height,
Pframergb->data,
Pframergb->linesize
);
++i;
Saveframe (Pframergb, Pcodecctx->width, Pcodecctx->height,
i);
}
}
Av_free_packet (&packet);
}
Av_free (buffer);
Av_free (PFRAMERGB);
Av_free (pframe);
Avcodec_close (PCODECCTX);
Avformat_close_input (&PFORMATCTX);
return 0;
}
Coding:
TEMPLATE = App
CONFIG + = Console
CONFIG-= qt
SOURCES + = Main.cpp
Includepath + =-i/usr/local/include/
LIBS + =-l/usr/local/lib-lavformat-lavcodec-lavutil-lswscale \
-lpostproc-lavfilter-lswresample-lavdevice-lx264-lm-lz-lpthread
Main.cpp
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
using namespace Std;
int main ()
{
Char *p = "p6\n720 576\n255\n";
int headlen = strlen (p);
struct stat statbuff;
memset (&statbuff, 0, sizeof (statbuff));
if (Stat (".. /video/frame10.ppm ", &statbuff) < 0)
{
Perror ("stat error");
return-1;
}
int filelen = statbuff.st_size;
int datalen = Filelen-headlen;
cout << "FileSize:" << filelen << Endl;
cout << "Headlen:" << headlen << Endl;
cout << "Datalen:" << datalen << Endl;
Avframe *prgbframe = new Avframe;
Avframe *pyuvframe = new Avframe;
Avcodeccontext *pcodecctx = NULL;
Avcodeccontext *PINCODECCTC = NULL;
Avcodec *pcodech264;
uint8_t *yuv_buff;
uint8_t *rgb_buff;
Av_register_all ();
Avcodec_register_all ();
pCodecH264 = Avcodec_find_encoder (codec_id_h264);
if (pCodecH264 = = NULL)
{
return-1;
}
Pcodecctx = Avcodec_alloc_context3 (pCodecH264);
if (Pcodecctx = = NULL)
{
return-1;
}
Pcodecctx->bit_rate = 4000000;
Pcodecctx->width = 720;
Pcodecctx->height = 576;
Avrational rate;
Rate.num = 1;
Rate.den = 25;
Pcodecctx->time_base = rate;
Pcodecctx->gop_size = 8;
Pcodecctx->max_b_frames = 1;
PCODECCTX->PIX_FMT = Pix_fmt_yuv420p;//pix_fmt_rgb24
if (Avcodec_open2 (Pcodecctx, Pcodech264,null) < 0)
{
return-1;
}
int yuvsize = Pcodecctx->width * pcodecctx->height;
Yuv_buff = (uint8_t *) malloc ((yuvsize*3)/2);
Rgb_buff = (uint8_t *) malloc (datalen);
int outbuf_size = 1024*1024;
uint8_t * outbuf= (uint8_t*) malloc (outbuf_size);
int u_size = 0;
FILE *f = NULL;
Char *filename = ".. /video/test.h264 ";
f = fopen (filename, "WB");
{
if (f = = NULL)
{
Perror ("fopen h264 error");
return-1;
}
}
Swscontext *scxt = Sws_getcontext (Pcodecctx->width, Pcodecctx->height, Pix_fmt_bgr24,
Pcodecctx->width,pcodecctx->height, pix_fmt_yuv420p,
Sws_point,null,null,null);
Avpacket avpkt;
int iFrame = 1;
FILE *frgb = NULL;
while (true)
{
Char szfilename[32];
sprintf (szFileName, "... /video/frame%d.ppm ", iFrame);
Frgb = fopen (szFileName, "R");
if (Frgb = = NULL)
{
Break
}
Fseek (Frgb,headlen,seek_set);
Fread (Rgb_buff,sizeof (uint8_t), DATALEN,FRGB);
Fclose (FRGB);
Frgb = NULL;
iframe++;
Avpicture_fill ((avpicture*) prgbframe,rgb_buff,pix_fmt_rgb24,pcodecctx->width,pcodecctx->height);
Avpicture_fill ((avpicture*) pyuvframe,yuv_buff,pix_fmt_yuv420p,pcodecctx->width,pcodecctx->height);
Sws_scale (SCXT, Prgbframe->data, prgbframe->linesize,0,pcodecctx->height,pyuvframe->data,pyuvframe- >linesize);
int got_packet_ptr = 0;
Av_init_packet (&AVPKT);
Avpkt.data = Outbuf;
Avpkt.size = outbuf_size;
U_size = Avcodec_encode_video2 (Pcodecctx, &avpkt, Pyuvframe, &got_packet_ptr);
if (u_size = = 0)
{
Fwrite (Avpkt.data, 1, avpkt.size, f);
}
pyuvframe->pts++;
}
Fclose (f);
Free (prgbframe);
Free (pyuvframe);
Free (Rgb_buff);
Free (OUTBUF);
Avcodec_close (PCODECCTX);
Av_free (PCODECCTX);
return 0;
}