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

需要的配置请参考: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_MACROS

int 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;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值