C++ H264编码-无法使用VLC播放器播放视频
我无法使用FFmpeg libav正确编码H264视频。我无法在VLC媒体播放器中播放编码视频,尽管我可以在MPC-HC上播放视频,但时间显示为C++ H264编码-无法使用VLC播放器播放视频,c++,ffmpeg,libavcodec,C++,Ffmpeg,Libavcodec,我无法使用FFmpeg libav正确编码H264视频。我无法在VLC媒体播放器中播放编码视频,尽管我可以在MPC-HC上播放视频,但时间显示为00:00/00:00。很明显我遗漏了什么 来自MPC-HC的媒体信息显示: 一般性 格式:AVC 格式/信息:高级视频编解码器 文件大小:110千磅 持续时间:2秒400毫秒 总比特率:375 Kbps 写入库:x264核心148 r2665 a01e339 编码设置:cabac=0/ref=3/deblock=1:0:0/analysis=0x1:0
00:00/00:00
。很明显我遗漏了什么
来自MPC-HC的媒体信息显示:
一般性格式:AVC
格式/信息:高级视频编解码器
文件大小:110千磅
持续时间:2秒400毫秒
总比特率:375 Kbps
写入库:x264核心148 r2665 a01e339
编码设置:cabac=0/ref=3/deblock=1:0:0/analysis=0x1:0x111/me=hex/submi=7/psy=1/psy\u-rd=1.00:0.00/mixed\u-ref=1/me-range=16/chroma\u-me=1/grillist=1/8x8dct=0/cqcm=0/死区=21,11/fast\u-pskip=1/chroma\u-qp\u-offset=-2/线程=7/lookahead\u-threads=1/分片线程=0/nr=0/decimate=0/0bluray\u compat=0/Constraint\u intra=0/bframes=0/weightp=0/keyint=12/keyint\u min=1/scenecut=40/intra\u refresh=0/rc\u lookahead=12/rc=abr/mbtree=1/bitrate=2000/ratetol=1.0/qcomp=0/qpmax=69/qpstep=4/ip\u ratio=1.40/aq=1:1.00 视频
格式:AVC
格式/信息:高级视频编解码器
格式配置文件:Baseline@L2.1
格式设置,CABAC:否
格式设置,重新格式化:3帧
格式设置,GOP:M=1,N=12
持续时间:2秒400毫秒
比特率:2000 Kbps
宽度:320像素
高度:240像素
显示纵横比:4:3
帧速率模式:可变
帧速率:20.833fps
颜色空间:YUV
色度二次采样:4:2:0
位深度:8位
扫描类型:渐进式
位/(像素*帧):1.250
流大小:586千磅
写入库:x264核心148 r2665 a01e339
编码设置:cabac=0/ref=3/deblock=1:0:0/analysis=0x1:0x111/me=hex/submi=7/psy=1/psy\u-rd=1.00:0.00/mixed\u-ref=1/me-range=16/chroma\u-me=1/grillist=1/8x8dct=0/cqcm=0/死区=21,11/fast\u-pskip=1/chroma\u-qp\u-offset=-2/线程=7/lookahead\u-threads=1/分片线程=0/nr=0/decimate=0/0bluray\u compat=0/Constraint\u intra=0/bframes=0/weightp=0/keyint=12/keyint\u min=1/scenecut=40/intra\u refresh=0/rc\u lookahead=12/rc=abr/mbtree=1/bitrate=2000/ratetol=1.0/qcomp=0/qpmax=69/qpstep=4/ip\u ratio=1.40/aq=1:1.00 我注意到上面的信息有些奇怪: -帧速率为
20.833
fps,而不是指定的10 fps。
-2s400ms的持续时间似乎也不正确,因为视频播放了超过4s
另外,(AVFrame*picture)->pict\u type
始终设置为AV\u picture\u type\u NONE
。我认为这不正常
我使用的库是ffmpeg-20160219-git-98a0053-win32-dev。如果你能帮我摆脱这种困惑,我将不胜感激
/*
* Video encoding example
*/
char filename[] = "test.mp4";
int main(int argc, char** argv)
{
AVCodec *codec = NULL;
AVCodecContext *codecCtx= NULL;
AVFormatContext *pFormatCtx = NULL;
AVStream * pVideoStream = NULL;
AVFrame *picture = NULL;
int i, x, y, //
ret, // Return value
got_packet_ptr; // Data encoded into packet
printf("Video encoding\n");
// Register all formats and codecs
av_register_all();
// allocate context
pFormatCtx = avformat_alloc_context();
memcpy(pFormatCtx->filename,filename,
min(strlen(filename), sizeof(pFormatCtx->filename)));
// guess format
pFormatCtx->oformat = av_guess_format("h264", NULL, NULL);
if (NULL==pFormatCtx->oformat)
{
cerr << "Could not guess output format" << endl;
return -1;
}
// Find the codec.
codec = avcodec_find_encoder(pFormatCtx->oformat->video_codec);
if (codec == NULL) {
fprintf(stderr, "Codec not found\n");
return -1;
}
// Set context
int framerate = 10;
codecCtx = avcodec_alloc_context3(codec);
avcodec_get_context_defaults3(codecCtx, codec);
codecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
codecCtx->profile = FF_PROFILE_H264_BASELINE;
// Resolution must be a multiple of two.
codecCtx->width = 320;
codecCtx->height = 240;
codecCtx->bit_rate = 2000000;
codecCtx->time_base.den = framerate;
codecCtx->time_base.num = 1;
codecCtx->gop_size = 12; // emit one intra frame every twelve frames at most
// Open the codec.
if (avcodec_open2(codecCtx, codec, NULL) < 0)
{
printf("Cannot open video codec\n");
return -1;
}
// Add stream to pFormatCtx
pVideoStream = avformat_new_stream(pFormatCtx, codec);
if (!pVideoStream)
{
printf("Cannot add new video stream\n");
return -1;
}
pVideoStream->codec = codecCtx;
pVideoStream->time_base.den = framerate;
pVideoStream->time_base.num = 1;
if (avio_open2(&pFormatCtx->pb, filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
{
printf("Cannot open file\n");
return -1;
}
// Write file header.
avformat_write_header(pFormatCtx, NULL);
// Create frame
picture= av_frame_alloc();
picture->format = codecCtx->pix_fmt;
picture->width = codecCtx->width;
picture->height = codecCtx->height;
int bufferImgSize = av_image_get_buffer_size(codecCtx->pix_fmt, codecCtx->width,
codecCtx->height,1);
av_image_alloc(picture->data, picture->linesize, codecCtx->width, codecCtx->height, codecCtx->pix_fmt, 32);
AVPacket avpkt;
/* encode 1 second of video */
for(i=0;i<50;i++)
{
/* prepare a dummy image */
/* Y */
for(y=0;y<codecCtx->height;y++)
{
for(x=0;x<codecCtx->width;x++)
{
picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
}
}
/* Cb and Cr */
for(y=0;y<codecCtx->height/2;y++)
{
for(x=0;x<codecCtx->width/2;x++)
{
picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
}
}
// Get timestamp
picture->pts = (float) i * (1000.0/(float)(codecCtx->time_base.den)) * 90;
// Encode frame to packet
av_init_packet(&avpkt);
got_packet_ptr = 0;
int error = avcodec_encode_video2(codecCtx, &avpkt, picture, &got_packet_ptr);
if (!error && got_packet_ptr > 0)
{
// Write packet with frame.
ret = (av_interleaved_write_frame(pFormatCtx, &avpkt) == 0);
}
av_packet_unref(&avpkt);
}
// Flush remaining encoded data
while(1)
{
av_init_packet(&avpkt);
got_packet_ptr = 0;
// Encode frame to packet.
int error = avcodec_encode_video2(codecCtx, &avpkt, NULL, &got_packet_ptr);
if (!error && got_packet_ptr > 0)
{
// Write packet with frame.
ret = (av_interleaved_write_frame(pFormatCtx, &avpkt) == 0);
}
else
{
break;
}
av_packet_unref(&avpkt);
}
av_write_trailer(pFormatCtx);
av_packet_unref(&avpkt);
av_frame_free(&picture);
avcodec_close(codecCtx);
av_free(codecCtx);
cin.get();
}
/*
*视频编码示例
*/
字符文件名[]=“test.mp4”;
int main(int argc,字符**argv)
{
AVCodec*codec=NULL;
AVCodecContext*codecCtx=NULL;
AVFormatContext*pFormatCtx=NULL;
AVStream*pVideoStream=NULL;
AVFrame*picture=NULL;
int i,x,y//
ret,//返回值
获取\u数据包\u ptr;//编码到数据包中的数据
printf(“视频编码”);
//注册所有格式和编解码器
av_寄存器_all();
//分配上下文
pFormatCtx=avformat_alloc_context();
memcpy(pFormatCtx->filename,filename,
最小值(strlen(文件名),sizeof(pFormatCtx->filename));
//猜测格式
pFormatCtx->oformat=av_guess_格式(“h264”,NULL,NULL);
if(NULL==pFormatCtx->oformat)
{
cerr(视频编解码器);
如果(编解码器==NULL){
fprintf(stderr,“找不到编解码器”);
返回-1;
}
//设置上下文
整数帧率=10;
codecCtx=avcodec\u alloc\u context3(编解码器);
avcodec_get_context_defaults3(codecCtx,codec);
codecCtx->pix_fmt=AV_pix_fmt_YUV420P;
codecCtx->profile=FF\u profile\u H264\u基线;
//分辨率必须是2的倍数。
codecCtx->宽度=320;
codecCtx->高度=240;
CODECTX->比特率=2000000;
codecCtx->time\u base.den=帧速率;
codecCtx->time_base.num=1;
codecCtx->gop_size=12;//最多每12帧发射一帧
//打开编解码器。
if(avcodec_open2(codecCtx,codec,NULL)<0)
{
printf(“无法打开视频编解码器\n”);
返回-1;
}
//将流添加到pFormatCtx
pVideoStream=avformat\u new\u流(pFormatCtx,编解码器);
如果(!pVideoStream)
{
printf(“无法添加新视频流\n”);
返回-1;
}
pVideoStream->codec=codectx;
pVideoStream->time\u base.den=帧速率;
pVideoStream->time_base.num=1;
if(avio_open2(&pFormatCtx->pb,文件名,avio_标志_写入,NULL,NULL)<0)
{
printf(“无法打开文件\n”);
返回-1;
}
//写入文件头。
avformat_write_头(pFormatCtx,NULL);
//创建框架
picture=av_frame_alloc();
图片->格式=编解码器CTX->pix\U fmt;
图片->宽度=编码CTX->宽度;
图片->高度=编码CTX->高度;
int bufferImgSize=av_image_get_buffer_size(codecCtx->pix_fmt,codecCtx->width,