FFmpeg转换yuv为h264视频流

[备份代码使用,未优化]


#include "MyEncodeYUV.h"

#include


#define __STDC_CONSTANT_MACROS


#include

#include

#include




int flush_encoder(AVFormatContext *fmt_ctx,unsigned int stream_index){

    int ret;

    int got_frame;

    AVPacket enc_pkt;

    if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &

          CODEC_CAP_DELAY))

        return 0;

    while (1) {

        enc_pkt.data = NULL;

        enc_pkt.size = 0;

        av_init_packet(&enc_pkt);

        ret = avcodec_encode_video2 (fmt_ctx->streams[stream_index]->codec, &enc_pkt,

                                     NULL, &got_frame);

        av_frame_free(NULL);

        if (ret < 0)

            break;

        if (!got_frame){

            ret=0;

            break;

        }

        printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n",enc_pkt.size);

        /* mux encoded frame */

        ret = av_write_frame(fmt_ctx, &enc_pkt);

        if (ret < 0)

            break;

    }

    return ret;

}


int ecode_main(char * yuvFilePath,char *outFilePath,int videoWidth,int videoHeight,long num,int videoInfo[])

{

    AVFormatContext* pFormatCtx;

    AVOutputFormat* fmt;

    AVStream* video_st;

    AVCodecContext* pCodecCtx;

    AVCodec* pCodec;

    AVPacket pkt;

    uint8_t* picture_buf;

    AVFrame* pFrame;

    int picture_size;

    int y_size;

    int framecnt=0;

    FILE *in_file = fopen(yuvFilePath, "rb");   //Input raw YUV data

    int in_w=videoWidth,in_h=videoHeight;                              //Input data's width and height

    int framenum=num;                                   //Frames to encode

    //const char* out_file = "src01.h264";              //Output Filepath

    //const char* out_file = "src01.ts";

    //const char* out_file = "src01.hevc";

    const char* out_file =outFilePath;

    

    

    

    avcodec_register_all();

    av_register_all();


    //Method1.

    pFormatCtx = avformat_alloc_context();

    //Guess Format

    fmt = av_guess_format(NULL, out_file, NULL);

    

    

    if (NULL==fmt) {

//        av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);

        printf("========fmt===is null==\n");

        return -1;

    }else

    {

        printf("=======yes ==ok!");

    }

    

    pFormatCtx->oformat = fmt;

    

    //Method 2.

    //avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);

    //fmt = pFormatCtx->oformat;

    printf("==========open output====");

    

    //Open output URL

    if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){

        printf("Failed to open output file! \n");

        return -1;

    }

    printf("==========open output=1===\n");

    

    

//    int videoCodec[8];

//    videoCodec[0]=pCodecCtx->pix_fmt;

//    videoCodec[1]=pCodecCtx->time_base.num;

//    videoCodec[2]=pCodecCtx->time_base.den;

//    videoCodec[3]=pCodecCtx->bit_rate;

//    videoCodec[4]=pCodecCtx->gop_size;

//    videoCodec[5]=pCodecCtx->qmin;

//    videoCodec[6]=pCodecCtx->qmax;

//    videoCodec[7]=pCodecCtx->qcompress;


    video_st = avformat_new_stream(pFormatCtx, 0);

    video_st->time_base.num = 1;

    video_st->time_base.den = 25;

//    video_st->metadata;

  

    

    if (video_st==NULL){

        return -1;

    }

    //Param that must set

    pCodecCtx = video_st->codec;

    pCodecCtx->codec_id =AV_CODEC_ID_H264;

//    pCodecCtx->codec_id = fmt->video_codec;

    pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;

    pCodecCtx->pix_fmt = PIX_FMT_YUV420P;

    pCodecCtx->width = in_w;

    pCodecCtx->height = in_h;

    pCodecCtx->time_base.num = 1;

    pCodecCtx->time_base.den = 25;

    pCodecCtx->bit_rate =videoInfo[3];

    pCodecCtx->gop_size=videoInfo[4];

    


    //H264

//    ctx->me_range = 16;

//    ctx->max_qdiff = 4;


//    pCodecCtx->me_range = 16;

//    pCodecCtx->max_qdiff = 4;

    

    pCodecCtx->qmin =3;

    pCodecCtx->qmax =30;

    pCodecCtx->qcompress =1;

    

    

    //Optional Param

//    pCodecCtx->max_b_frames=codecCtx->max_b_frames;

    

    

    

    printf("=222video info==video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d=====bit_rate:%d==gop_size:%d\n==compress:%f",

           pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,

           pCodecCtx->time_base.num, pCodecCtx->time_base.den,

           pCodecCtx->sample_aspect_ratio.num, pCodecCtx->sample_aspect_ratio.den,pCodecCtx->bit_rate,pCodecCtx->gop_size,  pCodecCtx->qcompress );

    

    // Set Option

    AVDictionary *param = 0;

    //H.264

    if(pCodecCtx->codec_id == AV_CODEC_ID_H264) {

        av_dict_set(¶m, "preset", "slow", 0);

        av_dict_set(¶m, "tune", "zerolatency", 0);

        //av_dict_set(¶m, "profile", "main", 0);

    }

    //H.265

    if(pCodecCtx->codec_id == AV_CODEC_ID_H265){

        av_dict_set(¶m, "preset", "ultrafast", 0);

        av_dict_set(¶m, "tune", "zero-latency", 0);

    }

    

    //Show some Information

    av_dump_format(pFormatCtx, 0, out_file, 1);

    

    printf("==========open output==2==\n");

    


    pCodec = avcodec_find_encoder(pCodecCtx->codec_id);

    printf("==========open output==3==\n");

    


    if (!pCodec){

        printf("Can not find encoder! \n");

        return -1;

    }

    if (avcodec_open2(pCodecCtx, pCodec,¶m) < 0){

        printf("Failed to open encoder! \n");

        return -1;

    }

    //Failed to read raw data

    printf("==========open output==4==\n");

    


    pFrame = av_frame_alloc();

    picture_size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);

    picture_buf = (uint8_t *)av_malloc(picture_size);

    avpicture_fill((AVPicture *)pFrame, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);

    printf("==========open output==5==\n");

    


    //Write File Header

//    avformat_write_header(pFormatCtx,NULL);

       printf("=======avformat_write_header===%d\n",avformat_write_header(pFormatCtx,NULL));

    av_new_packet(&pkt,picture_size);

    

    y_size = pCodecCtx->width * pCodecCtx->height;

      printf("=======av_new_packet======width:%d,height:%d \n",pCodecCtx->width,pCodecCtx->height);

    for (int i=0; i

        //Read raw YUV data

        printf("=======Read raw YUV data===%d\n",i);

        

       if(feof(in_file)){

            break;

       } else if (fread(picture_buf, 1, y_size*3/2, in_file) <= 0){

           printf("Failed to read raw data! \n");

           return -1;

       }

        pFrame->data[0] = picture_buf;              // Y

        pFrame->data[1] = picture_buf+ y_size;      // U

        pFrame->data[2] = picture_buf+ y_size*5/4// V

        //PTS

        pFrame->pts=i;

        int got_picture=0;

        //Encode

        int ret = avcodec_encode_video2(pCodecCtx, &pkt,pFrame, &got_picture);

        if(ret < 0){

            printf("Failed to encode! \n");

            return -1;

        }

        if (got_picture==1){

            printf("Succeed to encode frame: %5d\tsize:%5d\n",framecnt,pkt.size);

            framecnt++;

            pkt.stream_index = video_st->index;

            ret = av_write_frame(pFormatCtx, &pkt);

            av_free_packet(&pkt);

        }

    }

    //Flush Encoder

    

     printf("=======flush_encoder===\n");

    int ret = flush_encoder(pFormatCtx,0);

    if (ret < 0) {

        printf("Flushing encoder failed\n");

        return -1;

    }

    

    //Write file trailer

    printf("=======av_write_trailer===\n");


    av_write_trailer(pFormatCtx);

    printf("=======av_write_trailer==after=\n");

    


    //Clean

    if (video_st){

        avcodec_close(video_st->codec);

        av_free(pFrame);

        av_free(picture_buf);

    }

    avio_close(pFormatCtx->pb);

    avformat_free_context(pFormatCtx);

    

    fclose(in_file);

    

    printf("========encode yuv success!===\n");

    

    return 0;

}


你可能感兴趣的:(FFmpeg)