ffmpeg 编码

编码可以简单理解为将连续的图片帧转变成视频流的过程。以H264为例给出编码的代码:

        int  InitEncoderCodec(int width, int height)
        {
            auto enc = avcodec_find_encoder(AV_CODEC_ID_H264);        
            encodeContext = avcodec_alloc_context3(enc);
            auto codec = encodeContext;
            codec->codec_id = enc->id;
            codec->time_base.num = 1;
            codec->time_base.den = 25;
            codec->gop_size = 10;
            codec->bit_rate = 400000;
            codec->pix_fmt            = AV_PIX_FMT_YUV420P;
            codec->width              =  width;
            codec->height             = height;
            codec->has_b_frames = 0;
            codec->max_b_frames = 0;
            AVDictionary* options = nullptr; 
            if (!av_dict_get(options, "threads", nullptr, 0))
            {
                av_dict_set(&options, "threads", "auto", 0);
            }
            auto hr = avcodec_open2(codec,enc,nullptr);
            return hr;
        }

稍微解释下:AV_CODEC_ID_H264是264 codec ID,如果是其他的编码器替换相应的ID.  avcodec_open2返回0表示打开编码器成功,打开失败返回负值。
encode输入是一个AVFrame。注意:Frame的宽高要与codec的宽高一致。编码后的packet组成PES流。

    shared_ptr<AVPacket> encode(AVFrame* frame)
        {    
            int gotpacket = 0;
            shared_ptr<AVPacket> packet = nullptr;
            shared_ptr<AVPacket> pkt((AVPacket*)av_malloc(sizeof(AVPacket)), [&](AVPacket *p){av_free_packet(p);av_freep(&p);});
            av_init_packet(pkt.get());
            pkt->data = nullptr;
            pkt->size = 0;
 
            int hr = avcodec_encode_video2(encodeContext, pkt.get(), frame, &gotpacket);
            if(hr >= 0 && gotpacket)
            {  
                packet = pkt;            
            }
            return packet;
        }        

 

视频下载地址:http://www.chungen90.com/?list_53

 Demo下载地址: http://www.chungen90.com/?list_52

posted @ 2016-06-16 16:32  王纲  阅读(1622)  评论(0编辑  收藏  举报