Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ H264编码-无法使用VLC播放器播放视频_C++_Ffmpeg_Libavcodec - Fatal编程技术网

C++ H264编码-无法使用VLC播放器播放视频

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

我无法使用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: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,