[FFmpeg-user] Regarding encoding H.264 by using FFMPEG
梦幻工作室
fantasyvideo at 126.com
Wed Aug 29 15:21:41 CEST 2012
I tried to encode one mpeg2 video to h.264, but the encoded video can’t be
played by vlc. My ffmpeg is 0.11.1.
My code is as below:
int CStreamReader::Read(std::string name, std::string destIP, int port)
{
AVFormatContext *pFormatCtx = avformat_alloc_context();
name = "/home/test/Videos/test.mpg";
av_register_all();
avcodec_register_all();
avformat_network_init();
int nResult = avformat_open_input(&pFormatCtx,name.c_str(),NULL,NULL);
if(pFormatCtx==NULL || avformat_find_stream_info(pFormatCtx,NULL)<0)
{
return -1;
}
av_dump_format(pFormatCtx,0,name.c_str(),0);
int videoStreamIndex = -1;
for(int i=0;i<pFormatCtx->nb_streams;++i)
{
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoStreamIndex = i;
break;
}
}
if(videoStreamIndex == -1)
{
return -1;
}
AVCodecContext *pCodecCtx = NULL;
pCodecCtx = pFormatCtx->streams[videoStreamIndex]->codec;
AVCodec *pCodec;
enum CodecID id = pCodecCtx->codec_id;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec == NULL)
{
return -1;
}
if(avcodec_open2(pCodecCtx,pCodec,NULL)<0)
{
return -1;
}
AVFrame* pFrame = avcodec_alloc_frame();
if(pFrame==NULL)
{
return -1;
}
char portStr[5];
sprintf(portStr,"%d",port);
std::string outfileName = "rtp://" + destIP+":"+portStr;
outfileName ="test.h264";
AVOutputFormat *fmt = av_guess_format("mp4", outfileName.c_str(),NULL);
if(!fmt)
{
printf("could not deduce output format from outfile\n");
exit(0);
}
AVFormatContext* oc = avformat_alloc_context();
if(!oc)
{
printf("memory error\n");
exit(0);
}
oc->oformat = fmt;
av_strlcpy(oc->filename,outfileName.c_str(),sizeof(oc->filename));
AVStream* videoStream = av_new_stream(oc,0);
if(!videoStream)
{
printf("couldn't alloc video stream\n");
exit(0);
}
AVCodecContext* pVideoCodec = videoStream->codec;
pVideoCodec->codec_id = CODEC_ID_H264;
pVideoCodec->codec_type = AVMEDIA_TYPE_VIDEO;
pVideoCodec->bit_rate = 500000;
pVideoCodec->width = 352;
pVideoCodec->height = 288;
pVideoCodec->time_base.den = 25;
pVideoCodec->time_base.num = 1;
pVideoCodec->dct_algo = 0;
pVideoCodec->gop_size = 1;
// pVideoCodec->refs = 3;
// pVideoCodec->max_b_frames = 3;
// pVideoCodec->trellis = 2;
pVideoCodec->me_pre_cmp = 2;
pVideoCodec->me_method=7;
pVideoCodec->me_range = 16;
pVideoCodec->max_qdiff = 4;
pVideoCodec->qmin = 10;
pVideoCodec->qmax = 51;
pVideoCodec->qcompress = 0.6;
//pVideoCodec->qblur = 0.5;
pVideoCodec->nsse_weight = 8;
pVideoCodec->i_quant_factor = (float)0.8;
pVideoCodec->b_quant_factor = 1.25;
pVideoCodec->b_quant_offset = 1.25;
pVideoCodec->pix_fmt = PIX_FMT_YUV420P;
//
pVideoCodec->flags |= CODEC_FLAG_GLOBAL_HEADER;
if(!strcmp(oc->oformat->name,"mp4")||
!strcmp(oc->oformat->name,"mov")||
!strcmp(oc->oformat->name,"3gp"))
{
pVideoCodec->flags &= ~CODEC_FLAG_QSCALE;
}
AVCodec* pVideoEncoder = avcodec_find_encoder(CODEC_ID_H264);
if(pVideoEncoder==NULL)
{
printf("find video encoder failed\n");
exit(0);
}
int error = avcodec_open(pVideoCodec,pVideoEncoder);
if(error<0)
{
printf("open video encoder failed\n");
// exit(0);
}
if(!oc->nb_streams)
{
printf("output file doesn't have any stream\n");
exit(0);
}
if(avio_open2(&oc->pb,outfileName.c_str(),AVIO_FLAG_WRITE,NULL,NULL)<0)
{
printf("creating output failed\n");
exit(0);
}
if(avformat_write_header(oc,NULL)<0)
{
printf("couldn't write header for output file\n");
exit(0);
}
AVPacket packet;
uint8_t *ptr, *out_buf;
int out_size;
static short *samples = NULL;
static unsigned int samples_size = 0;
uint8_t* video_outbuf;
int video_outbuf_size =4000000;
video_outbuf = (unsigned char*)malloc(video_outbuf_size);
int flag;
int frameFinished;
int len;
int frame_index =0;
int ret;
while(av_read_frame(pFormatCtx,&packet)>=0)
{
if(packet.stream_index==videoStreamIndex)
{
len =
avcodec_decode_video2(pCodecCtx,pFrame,&packet.size,&packet);
if(len<0)
{
printf("error while decoding\n");
exit(0);
}
else{
pFrame->pts =
av_rescale(frame_index,AV_TIME_BASE*(int64_t)pVideoCodec->time_base.num,pVid
eoCodec->time_base.den);
pFrame->pict_type = AV_PICTURE_TYPE_NONE;
out_size =
avcodec_encode_video(pVideoCodec,video_outbuf,video_outbuf_size,pFrame);
if(out_size>0)
{
//printf("encoding success\n");
AVPacket encodedPacket;
av_init_packet(&encodedPacket);
if(pVideoCodec->coded_frame&&pVideoCodec->coded_frame->key_frame)
{
encodedPacket.flags = packet.flags;
encodedPacket.stream_index = videoStream->index;
encodedPacket.data = video_outbuf;
encodedPacket.size = out_size;
ret = av_write_frame(oc,&encodedPacket);
}
frame_index++;
}
else
{
ret = av_write_frame(oc,&packet);
if(ret!=0)
{
printf("while write video frame error\n");
exit(0);
}
}
}
}
av_free_packet(&packet);
}
av_write_trailer(oc);
for(int i=0;i<oc->nb_streams;++i)
{
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
av_free(oc);
av_free(pFrame);
// av_free(out_buf);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);
free(video_outbuf);
printf("finished\n");
return 0;
}
More information about the ffmpeg-user
mailing list