ffmpeg C语言实现视频从MP4转成AVI

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qqqq245425070/article/details/86671281

这是一个通过c代码实现视频格式的转换。

#include <libavutil/log.h>
#include <libavformat/avformat.h>
#include <stdio.h>
#include "libavcodec/avcodec.h"
int main(int argc,char* arg[]){
    av_log_set_level(AV_LOG_INFO);
    AVOutputFormat *ofmt = NULL;
    AVBitStreamFilterContext *vbsf = NULL;
    AVFormatContext *ifmt_ctx = NULL,*ofmt_ctx = NULL;
    AVPacket pkt;
    char *in_filename,*out_filename;
    int ret,i;
    int frame_index = 0;
    in_filename = "./jichi.mp4";
    out_filename = "./jichi.avi";
    av_register_all();
    if((ret = avformat_open_input(&ifmt_ctx,in_filename,0,0))<0){
            av_log(NULL,AV_LOG_ERROR,"Could not find open input file.");
            goto end;
    }
    if((ret = avformat_find_stream_info(ifmt_ctx,0))<0){
        av_log(NULL,AV_LOG_ERROR,"Failed to retrieve input stream information");
        goto end;
    }
    vbsf = av_bitstream_filter_init("h264_mp4toannexb");
    av_dump_format(ifmt_ctx,0,in_filename,0);
    avformat_alloc_output_context2(&ofmt_ctx,NULL,NULL,out_filename);
    if(!ofmt_ctx){
        av_log(NULL,AV_LOG_ERROR,"could not create output context");
        ret = AVERROR_UNKNOWN;
        goto end;
    }
    ofmt = ofmt_ctx->oformat;
    printf("ifmt_ctx->nb_streams = %d \n",ifmt_ctx->nb_streams);
    for(i = 0 ; i < ifmt_ctx->nb_streams;i++){
        printf("i = %d \n",i);
        AVStream *in_stream = ifmt_ctx->streams[i];
        AVStream *out_stream = avformat_new_stream(ofmt_ctx,in_stream->codec->codec);
        if(!out_stream){
            av_log(NULL,AV_LOG_ERROR,"Failed allocationg output Stream");
            ret = AVERROR_UNKNOWN;
            goto end;
        }
        if(avcodec_copy_context(out_stream->codec,in_stream->codec)<0){
            av_log(NULL,AV_LOG_ERROR,"Failed to copy context from input to output stream codec context");
            goto end;
        }
        out_stream->codec->codec_tag = 0;
        if(ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER){
            out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
        }
    }
    av_dump_format(ofmt_ctx,0,out_filename,1);
    if(!(ofmt->flags & AVFMT_NOFILE)){
        ret = avio_open(&ofmt_ctx->pb,out_filename,AVIO_FLAG_WRITE);
        if(ret < 0){
            av_log(NULL,AV_LOG_ERROR,"could not open output file %s",out_filename);
            goto end;
        }
    }
    if(avformat_write_header(ofmt_ctx,NULL)<0){
        av_log(NULL,AV_LOG_ERROR,"Error occurred when opening output file");
        goto end;
    }
    while(1){
        AVStream *in_stream, *out_stream;
        ret = av_read_frame(ifmt_ctx,&pkt);
        if(ret < 0){
            break;
        }
        in_stream = ifmt_ctx->streams[pkt.stream_index];
        out_stream = ofmt_ctx->streams[pkt.stream_index];
        pkt.pts = av_rescale_q_rnd(pkt.pts,in_stream->time_base,out_stream->time_base,(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
        pkt.dts = av_rescale_q_rnd(pkt.dts,in_stream->time_base,out_stream->time_base,(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
        pkt.duration = av_rescale_q(pkt.duration,in_stream->time_base,out_stream->time_base);
        pkt.pos = -1;
        if(pkt.stream_index == 0){
            AVPacket fpkt = pkt;
            int a = av_bitstream_filter_filter(vbsf,out_stream->codec,NULL,&fpkt.data,&fpkt.size,pkt.data,pkt.size ,pkt.flags & AV_PKT_FLAG_KEY);
            pkt.data = fpkt.data;
            pkt.size = fpkt.size;
        }
        if(av_write_frame(ofmt_ctx,&pkt) < 0){
            av_log(NULL,AV_LOG_ERROR,"Error muxing packed");
            break;
        }
        av_packet_unref(&pkt);
        frame_index ++;
    }
    av_write_trailer(ofmt_ctx);
    avformat_close_input(&ifmt_ctx);
    end:
    if(ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE)){
        avio_close(ofmt_ctx->pb);
    }
    avformat_free_context(ofmt_ctx);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qqqq245425070/article/details/86671281