其他分享
首页 > 其他分享> > ffmpeg解码随笔

ffmpeg解码随笔

作者:互联网

运行资源下载:

链接:https://pan.baidu.com/s/1XEZHO5SnvvFfCfVbfqjdwQ
提取码:odie

 

// 写文件方式提取 11.yuv 里的 y u v 
void extract_yuv(const char* path,int width,int height){

    FILE* fp = fopen(path,"rb+");
    FILE* f1 = fopen("yuv420_y.y","wb+");
    FILE* f2 = fopen("yuv420_u.y","wb+");
    FILE* f3 = fopen("yuv420_v.y","wb+");

    unsigned char* p = (unsigned char*)malloc(width*height*3/2);

    int i = 0;
    while (i<1)
    {
        fread(p, 1, width*height * 3 / 2, fp);
        fwrite(p, 1, width*height, f1);
        fwrite(p + width*height, 1, width*height / 4, f2);
        fwrite(p + width*height*(1 + 1 / 4), 1, width*height / 4, f3);
        i++;
    }

    free(p); p = NULL;
    fclose(fp);
    fclose(f1);
    fclose(f2);
    fclose(f3);
}
写文件方式提取 11.yuv 里的 y u v
// 使用ffmpeg获取视频的信息
void getInfo(){

    av_register_all();

    AVFormatContext * pFormat = NULL;
    const char* path = "11.mp4";

    avformat_open_input(&pFormat, path, NULL, NULL);

    av_dump_format(pFormat, NULL, path, 0);

    int time = pFormat->duration;
    int mbittime = (time / 1000000) / 60;
    int mmintime = (time / 1000000) % 60;
    printf("该视频时长=%d分:%d秒\n", mbittime, mmintime);

    // 获取网络流的信息
    /*av_register_all();

    AVFormatContext * pFormat = NULL;
    const char* path = "http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8";
    avformat_network_init();
    AVDictionary *opt = NULL;
    av_dict_set(&opt, "rtsp_transport", "tcp", 0);
    av_dict_set(&opt, "max_delay", "550", 0);

    avformat_open_input(&pFormat, path, NULL, &opt);

    av_dump_format(pFormat, NULL, path, 0);*/
}
使用ffmpeg获取视频的信息
void extract_mp4_3(const char* path){

    FILE* f1 = fopen("y.y","wb+");
    FILE* f2 = fopen("u.y", "wb+");
    FILE* f3 = fopen("v.y", "wb+");

    av_register_all();

    AVFormatContext* format = NULL;
    avformat_open_input(&format,path,NULL,NULL);

    avformat_find_stream_info(format,NULL);
    int bestStream = av_find_best_stream(format,AVMEDIA_TYPE_VIDEO,NULL,NULL,NULL,NULL);

    AVCodec* codec = avcodec_find_decoder(format->streams[bestStream]->codec->codec_id);
    
    avcodec_open2(format->streams[bestStream]->codec, codec, NULL);

    // ---------- 解码
    AVPacket* packet = (AVPacket*)av_malloc(sizeof(AVPacket));
    AVFrame* frame = av_frame_alloc();
    int go, frameCount = 0;
    int width = format->streams[bestStream]->codec->width;
    int height = format->streams[bestStream]->codec->height;

    // ---- 用来存储转用sws_scale转换过来的数据,后续用这个数据就不会播放的时候出问题
    AVFrame* frameDst = av_frame_alloc();
    int fmt = format->streams[bestStream]->codec->pix_fmt;
    uint8_t* buff = (uint8_t*)av_malloc(avpicture_get_size((AVPixelFormat)fmt, width,height));
    avpicture_fill((AVPicture*)frameDst, buff,(AVPixelFormat)fmt,width,height);

    SwsContext* swsCtx = sws_getContext(width,height,(AVPixelFormat)fmt,width,height,AV_PIX_FMT_YUV420P,SWS_BICUBIC,NULL,NULL,NULL);

    while (av_read_frame(format, packet) >= 0) // 解码1 将数据读到包里
    {
        if (packet->stream_index == AVMEDIA_TYPE_VIDEO){
            avcodec_decode_video2(format->streams[bestStream]->codec, frame, &go, packet); // 解码2 将包里的数据解码到frame
            if (go){

                sws_scale(swsCtx,frame->data,frame->linesize,0,height,frameDst->data,frameDst->linesize);

                fwrite(frameDst->data[0], 1, width*height, f1);
                fwrite(frameDst->data[1], 1, width*height, f2);
                fwrite(frameDst->data[2], 1, width*height, f3);

                frameCount++;
                printf("写了%d帧了\n", frameCount);
            }    
        }

        av_free_packet(packet);
    }

    fclose(f1);
    fclose(f2);
    fclose(f3);

    av_frame_free(&frame);
    av_frame_free(&frameDst);
    av_free(buff);
    sws_freeContext(swsCtx);
    avformat_close_input(&format);
}
经典解码,提取MP4里的Y U V

 

标签:NULL,ffmpeg,format,解码,height,width,av,随笔,frame
来源: https://www.cnblogs.com/fxw1/p/16536277.html