FFmpeg解析视频保存为yuv

[作为自己备份代码使用,尚未优化]


#include "MyFilterVideo.h"


#define __STDC_CONSTANT_MACROS


#include "MyEncodeYUV.h"


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


#include "MyMuxerToMP4.h"

#include "MyDecodAudioToAac.h"

#define ENABLE_YUVFILE 1


//add by nil 旋转角度

#define MT_VIDEO_ROTATE_0 0

#define MT_VIDEO_ROTATE_90 90

#define MT_VIDEO_ROTATE_180 180

#define MT_VIDEO_ROTATE_270 270


const char *filter_descr = "movie=my_logo.png[wm];[in][wm]overlay=5:5[out]";


AVFormatContext *pFormatCtx;

AVCodecContext *pCodecCtx;

AVFilterContext *buffersink_ctx;

AVFilterContext *buffersrc_ctx;

AVFilterGraph *filter_graph;


//add by nil

AVDictionary *format_opts = NULL;

//=======


static int video_stream_index = -1;

static int64_t last_pts = AV_NOPTS_VALUE;

int frameCount=0;//一个多少帧




int getRotateAngle(AVStream* avStream)

{

    AVDictionaryEntry *tag = NULL;

    int   m_Rotate=-1;

    tag = av_dict_get(avStream->metadata, "rotate", tag, 0);

    if (tag==NULL)

    {

        m_Rotate = 0;

    }

    else

    {

        int angle = atoi(tag->value);

        angle %= 360;

        if (angle == 90)

        {

            m_Rotate = MT_VIDEO_ROTATE_90;

        }

        else if (angle == 180)

        {

            m_Rotate = MT_VIDEO_ROTATE_180;

        }

        else if (angle == 270)

        {

            m_Rotate = MT_VIDEO_ROTATE_270;

        }

        else

        {

            m_Rotate = MT_VIDEO_ROTATE_0;

        }

    }

    return m_Rotate;

}


static int open_input_file(const char *filename)

{

    int ret;

    AVCodec *dec;

    

    if ((ret = avformat_open_input(&pFormatCtx, filename, NULL, &format_opts)) < 0) {

        printf( "Cannot open input file\n");

        return ret;

    }

    

   

    if ((ret = avformat_find_stream_info(pFormatCtx, NULL)) < 0) {

        printf( "Cannot find stream information\n");

        return ret;

    }

    

    

    /* select the video stream */

    ret = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);

    if (ret < 0) {

        printf( "Cannot find a video stream in the input file\n");

        return ret;

    }

    video_stream_index = ret;

    pCodecCtx = pFormatCtx->streams[video_stream_index]->codec;

   

    

    

    /* init the video decoder */

    if ((ret = avcodec_open2(pCodecCtx, dec, NULL)) < 0) {

        printf( "Cannot open video decoder\n");

        return ret;

    }

    

    return 0;

}


static int init_filters(const char *filters_descr)

{

    char args[512];

    int ret;

    AVFilter *buffersrc  = avfilter_get_by_name("buffer");

    AVFilter *buffersink = avfilter_get_by_name("ffbuffersink");

    AVFilterInOut *outputs = avfilter_inout_alloc();

    AVFilterInOut *inputs  = avfilter_inout_alloc();

    enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };

    AVBufferSinkParams *buffersink_params;

    

    filter_graph = avfilter_graph_alloc();

    

    /* buffer video source: the decoded frames from the decoder will be inserted here. */

    snprintf(args, sizeof(args),

             "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",

             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);

    

    ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",

                                       args, NULL, filter_graph);

    if (ret < 0) {

        printf("Cannot create buffer source\n");

        return ret;

    }

    

    /* buffer video sink: to terminate the filter chain. */

    buffersink_params = av_buffersink_params_alloc();

    buffersink_params->pixel_fmts = pix_fmts;

    ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",

                                       NULL, buffersink_params, filter_graph);

    av_free(buffersink_params);

    if (ret < 0) {

        printf("Cannot create buffer sink\n");

        return ret;

    }

    

    /* Endpoints for the filter graph. */

    outputs->name       = av_strdup("in");

    outputs->filter_ctx = buffersrc_ctx;

    outputs->pad_idx    = 0;

    outputs->next       = NULL;

    

    inputs->name       = av_strdup("out");

    inputs->filter_ctx = buffersink_ctx;

    inputs->pad_idx    = 0;

    inputs->next       = NULL;

    

    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,

                                        &inputs, &outputs, NULL)) < 0)

        return ret;

    

    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)

        return ret;

    return 0;

}



//获取视频旋转角度,add by nil

int leishaohua_main(char *video_file,char * overlay_filters,char *outFileNameYUV,char *outFileNameH264,char *outAacFileName,char *outMP4FileName)

{

    int ret;

    AVPacket packet;

    AVFrame frame;

    int got_frame;

    

    //nil add video width and height

    int video_width=480;

    int video_heigh=320;

    

    avcodec_register_all();

    av_register_all();

    avfilter_register_all();

    

    

    

    if ((ret = open_input_file(video_file)) < 0)

        goto end;

    if ((ret = init_filters(overlay_filters)) < 0)

        goto end;

    

    

#if ENABLE_YUVFILE

    FILE *fp_yuv=fopen(outFileNameYUV,"wb+");

#endif

    

    

    /* read all packets */

    while (1) {

        AVFilterBufferRef *picref;

        if ((ret = av_read_frame(pFormatCtx, &packet)) < 0)

            break;

        

        if (packet.stream_index == video_stream_index) {

            avcodec_get_frame_defaults(&frame);

            

            AVStream *stream=pFormatCtx->streams[packet.stream_index];

            

            int angle=getRotateAngle(stream);

            printf("======yes====angle:%d",angle);

            

//            double angle=get_rotation(stream);

//            printf("==============hello=======good====:%d\n",(int)angle);

            

            got_frame = 0;

            ret = avcodec_decode_video2(pCodecCtx, &frame, &got_frame, &packet);

            if (ret < 0) {

                printf( "Error decoding video\n");

                break;

            }

            

            video_width=frame.width;

            video_heigh=frame.height;

            printf("============VIDEO WIDTH:%d=HEIGHT:%d\n",video_width,video_heigh);

            

            

            if (got_frame) {

                frame.pts = av_frame_get_best_effort_timestamp(&frame);

                

                /* push the decoded frame into the filtergraph */

                if (av_buffersrc_add_frame(buffersrc_ctx, &frame) < 0) {

                    printf( "Error while feeding the filtergraph\n");

                    break;

                }

                

                /* pull filtered pictures from the filtergraph */

                

                while (1) {

                    ret = av_buffersink_get_buffer_ref(buffersink_ctx, &picref, 0);

                    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)

                        break;

                    if (ret < 0)

                        goto end;

                    

                    if (picref) {

#if ENABLE_YUVFILE

                        int y_size=picref->video->w*picref->video->h;

                        printf("=========video===width:%d===height:%d\n",picref->video->w,picref->video->h);

                        printf("=======num:%d\n",++frameCount);

                        fwrite(picref->data[0],1,y_size,fp_yuv);     //Y

                        fwrite(picref->data[1],1,y_size/4,fp_yuv);   //U

                        fwrite(picref->data[2],1,y_size/4,fp_yuv);   //V

#endif

                        

                        avfilter_unref_bufferp(&picref);

                    }

                }

            }

        }

        av_free_packet(&packet);

    }

#if ENABLE_YUVFILE

    fclose(fp_yuv);

#endif

end:


    //

    //

    printf("=====Success===save yuv=====\n");

    //    pCodecCtx->codec_id =AV_CODEC_ID_H264;

    //    pCodecCtx->codec_id = codecCtx->codec_id;

    //    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 = 400000;

    //    pCodecCtx->gop_size=250;

    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;

    

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

                 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);

    

    if (pCodecCtx)

        avcodec_close(pCodecCtx);

    avfilter_graph_free(&filter_graph);

    avformat_close_input(&pFormatCtx);

    

    if (ret < 0 && ret != AVERROR_EOF) {

        char buf[1024];

        av_strerror(ret, buf, sizeof(buf));

        printf("Error occurred: %s\n", buf);

        return -1;

    }

    


    

    printf("=====begin=====ecode_main====\n");


    ecode_main(outFileNameYUV,outFileNameH264,video_width,video_heigh,frameCount,videoCodec);

    decodeToAacMain(video_file,outAacFileName);

    muxer_main(outFileNameH264,outAacFileName,outMP4FileName);


    

    printf("=====success===all===ret%d\n",ret);

    

    

    return 0;

}



你可能感兴趣的:(FFmpeg)