[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