将各种格式flv,avi,mp4等的文件,转码成MP4(无音频)

来源:互联网 发布:linq 修改数据 编辑:程序博客网 时间:2024/05/18 03:39

需要的配置请参考:http://blog.csdn.net/geolo/article/details/48439747

/* * test14.cpp * * 将各种格式flv,mp4的文件,转码成MP4 */#include <string.h>#include <math.h>#include "test06.h"#define __STDC_CONSTANT_MACROSint flush_encoder_14(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;        }        LOGE("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 Test14(){    LOGE("Test06 start \n");    AVFormatContext *mInFormatCtx;    AVCodecContext  *mInCodecCtx;    AVCodec         *mInCodec;    AVStream        *mInStream;    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;    char *mVideoFileName = "/sdcard/22.flv";    //FILE *in_file = fopen("src01_480x272.yuv", "rb"); //Input raw YUV data    FILE *in_file = fopen(mVideoFileName, "rb");   //Input raw YUV data    int in_w=480,in_h=272;                              //Input data's width and height    int framenum = 1000;                                   //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 = "/sdcard/test14.mp4";    LOGE("Test06 run 01 \n");    av_register_all();    avcodec_register_all();    avformat_network_init();    //Method1.    pFormatCtx = avformat_alloc_context();    //Guess Format    fmt = av_guess_format(NULL, out_file, NULL);    pFormatCtx->oformat = fmt;    LOGE("Test06 run 02 \n");    //Method 2.    //avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);    //fmt = pFormatCtx->oformat;    AVCodec *_avcodecV = avcodec_find_encoder(AV_CODEC_ID_H264);    video_st = avformat_new_stream(pFormatCtx, _avcodecV);    //video_st->time_base.num = 1;    //video_st->time_base.den = 25;    LOGE("Test06 run 03 \n");    if (video_st==NULL){        LOGE("video_st==NULL \n");        return -1;    }    //Param that must set    pCodecCtx = video_st->codec;    pCodecCtx->flags   |= CODEC_FLAG_QSCALE;    pCodecCtx->qmin          = 0  ; //0是无损压缩。    pCodecCtx->qmax          = 22 ; //20-30是比较合适的范围。    pCodecCtx->bit_rate      = 0;    pCodecCtx->gop_size      = 12;    pCodecCtx->width         = in_w;    pCodecCtx->height        = in_h;    pCodecCtx->time_base.num = 1;//分子    pCodecCtx->time_base.den = 25;//分母    pCodecCtx->pix_fmt       = AV_PIX_FMT_YUV420P;    pCodecCtx->profile       = FF_PROFILE_H264_BASELINE ;    pCodecCtx->max_b_frames  = 0;    pCodecCtx->codec_id      = fmt->video_codec;    pCodecCtx->codec_type    = AVMEDIA_TYPE_VIDEO;    //H264    //  pCodecCtx->me_range = 16;    //  pCodecCtx->max_qdiff = 4;    //  pCodecCtx->qcompress = 0.6;    //Optional Param    if (fmt->flags & AVFMT_GLOBALHEADER){        pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;    }    // Set Option    AVDictionary *param = 0;    //H.264    if(pCodecCtx->codec_id == AV_CODEC_ID_H264) {        av_dict_set(&param, "preset", "slow", 0);        av_dict_set(&param, "tune", "zerolatency", 0);        //av_dict_set(&param, "profile", "main", 0);    }    //H.265    if(pCodecCtx->codec_id == AV_CODEC_ID_H265){        av_dict_set(&param, "preset", "ultrafast", 0);        av_dict_set(&param, "tune", "zero-latency", 0);    }    //Show some Information    av_dump_format(pFormatCtx, 0, out_file, 1);    LOGE("Test06 run 04 \n");    pCodec = avcodec_find_encoder(pCodecCtx->codec_id);    if (!pCodec){        LOGE("Can not find encoder! \n");        return -1;    }    if (avcodec_open2(pCodecCtx, pCodec,&param) < 0){        LOGE("Failed to open encoder! \n");        return -1;    }    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);    //Open output URL    if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){        LOGE("Failed to open output file! \n");        return -1;    }    //Write File Header    avformat_write_header(pFormatCtx,NULL);    av_new_packet(&pkt,picture_size);    y_size = pCodecCtx->width * pCodecCtx->height;    LOGE("Test06 run 05 \n");    //////   解码部分  //////////////    mInFormatCtx = avformat_alloc_context();    if(avformat_open_input(&mInFormatCtx, mVideoFileName, NULL, NULL)!=0){        return -1;    }    if(avformat_find_stream_info(mInFormatCtx, NULL)<0){        return -1;    }    av_dump_format(mInFormatCtx, 0, mVideoFileName, 0);    LOGE("Test06 run 06 \n");    int                  videoStream;    videoStream = -1;    videoStream = av_find_best_stream(mInFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &mInCodec, 0);    if(mInCodec == NULL) {        LOGE( "Unsupported pCodec!\n");        return -1; // Codec not found    }    mInCodecCtx = mInFormatCtx->streams[videoStream]->codec;    AVDictionary    *optionsDict = NULL;    if(avcodec_open2(mInCodecCtx, mInCodec, &optionsDict)<0){        LOGE("---- 不能打开 视频 解码库 ---");        return -1;    }    LOGE("videoStream == %d \n", videoStream);    struct SwsContext    *sws_ctx = NULL;    sws_ctx = sws_getContext(            mInCodecCtx->width,            mInCodecCtx->height,            mInCodecCtx->pix_fmt,            in_w,            in_h,            AV_PIX_FMT_YUV420P,            SWS_FAST_BILINEAR,            NULL, NULL, NULL);    AVFrame              *mInFrame;    mInFrame = av_frame_alloc();    if(mInFrame == NULL){        LOGE("Failed to pFrameYUV==NULL ! \n");        return -1;    }    AVFrame              *pFrameYUV;    pFrameYUV = av_frame_alloc();    int numBytes = avpicture_get_size(PIX_FMT_YUV420P, in_w, in_h);    uint8_t* buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));    avpicture_fill((AVPicture *) pFrameYUV, buffer, PIX_FMT_YUV420P,in_w, in_h);    LOGE("start encoder! \n");    //初始化SwsContext    SwsContext *rgbToyuvcxt = sws_getContext(            in_w,            in_h,            AV_PIX_FMT_RGB24,            in_w,            in_h,            AV_PIX_FMT_YUV420P,            SWS_POINT,            NULL,NULL,NULL);    AVFrame *m_pRGBFrame =  av_frame_alloc(); //RGB帧数据    int rgbnumBytes = avpicture_get_size(AV_PIX_FMT_RGB24, in_w, in_h);    ///////////////////////////////    for (int i=0; i < framenum; i++){        AVPacket                packet;        if(av_read_frame(mInFormatCtx, &packet) >= 0 ){            if (packet.stream_index == videoStream) {                int completed;                avcodec_decode_video2(mInCodecCtx, mInFrame, &completed,&packet);// Decode video frame                sws_scale(                        sws_ctx,                        (uint8_t const * const *)mInFrame->data,                        mInFrame->linesize,                        0,                        mInCodecCtx->height,                        pFrameYUV->data,                        pFrameYUV->linesize);                pFrame->data[0] = pFrameYUV ->data[0]; // Y                pFrame->data[1] = pFrameYUV ->data[1]; // U                pFrame->data[2] = pFrameYUV ->data[2]; // V                /**/                //PTS                //pFrame->pts = pFrameYUV-> pts;                //在编码前设置好,结果的pkt的配置                av_free_packet(&pkt);                av_init_packet(&pkt);                pkt.pts = framecnt;                pkt.dts = pkt.pts ;                //pkt.duration = 1;                int got_picture=0;                //Encode                int ret = avcodec_encode_video2(pCodecCtx, &pkt,pFrame, &got_picture);                if(ret < 0){                    LOGE("Failed to encode! \n");                    return -1;                }                if (got_picture == 1){                    LOGE("Succeed to encode frame: %5d\t , size:%5d\n",framecnt,pkt.size);                    //pkt.flags |= AV_PKT_FLAG_KEY;                    pkt.stream_index = video_st->index;                    framecnt++;                    ret = av_interleaved_write_frame(pFormatCtx, &pkt);                    av_free_packet(&pkt);                }            }        }    }    //Flush Encoder    int ret = flush_encoder_14(pFormatCtx,0);    if (ret < 0) {        LOGE("Flushing encoder failed\n");        return -1;    }    //Write file trailer    av_write_trailer(pFormatCtx);    //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);    return 0;}
0 0
原创粉丝点击