美文网首页
2020-08-18

2020-08-18

作者: shaozq | 来源:发表于2020-08-18 23:44 被阅读0次
    #include <stdio.h>
    
    #include "pch.h"
    
    #define _CRT_SECURE_NO_WARNINGS
    
    #define __STDC_CONSTANT_MACROS
    
    extern "C"
    
    {
    
    #include "libavcodec/avcodec.h"
    
    #include "libavformat/avformat.h"
    
    #include "libswscale/swscale.h"
    
    #include "libswscale/swscale.h"
    
    };
    
    int main(int argc, char* argv[])
    
    {
    
    AVFormatContext* pAVFormatContext;
    
    AVCodecContext* pAVCodecContext;
    
    AVCodec* pAVCodec;
    
    AVPacket* pAVPacket;
    
    AVFrame* pAvFrame;
    
    AVFrame*    pFrameYUV;
    
    int videoindex = -1;
    
    uint8_t *out_buffer;
    
    int frame_cnt = 0;
    
    int got_pic, ret;
    
    struct SwsContext *img_convert_ctx;
    
    char filepath[] = "cuc_ieschool.flv";
    
    FILE* file_yuv = fopen("shao_test.yuv", "wb+");
    
    av_register_all();
    
    avformat_network_init();
    
    pAVFormatContext = avformat_alloc_context();
    
    if (avformat_open_input(&pAVFormatContext, filepath, NULL, NULL) != 0) {
    
    printf("Couldn't open input stream.\n");
    
    return -1;
    
    }
    
    if (avformat_find_stream_info(pAVFormatContext, NULL) < 0) {
    
    printf("Couldn't find stream information.\n");
    
    return -1;
    
    }
    
    printf("video duration: %d", pAVFormatContext->duration);
    
    printf("video formatName: %s", pAVFormatContext->iformat->name);
    
    for (int i = 0; i < pAVFormatContext->nb_streams;i ++) {
    
    if (pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
    
    videoindex = i;
    
    break;
    
    }
    
    }
    
    if (videoindex == -1) {
    
    printf("Didn't find a video stream.\n");
    
    return -1;
    
    }
    
    pAVCodecContext = pAVFormatContext->streams[videoindex]->codec;
    
    pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id);
    
    printf("video width=%d , height = %d\n", pAVCodecContext->width,pAVCodecContext->height);
    
    if (pAVCodec == NULL) {
    
    printf("cannot find codec");
    
    return -1;
    
    }
    
    if (avcodec_open2(pAVCodecContext,pAVCodec,NULL) < 0) {
    
    printf("can not open file \n");
    
    return -1;
    
    }
    
    av_dump_format(pAVFormatContext, 0, filepath, 0);
    
    pAvFrame = av_frame_alloc();
    
    pFrameYUV = av_frame_alloc();
    
    pAVPacket = reinterpret_cast<AVPacket*> (av_malloc(sizeof(AVPacket)));
    
    out_buffer = (uint8_t*)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pAVCodecContext->width, pAVCodecContext->height));
    
    avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pAVCodecContext->width, pAVCodecContext->height);
    
    img_convert_ctx = sws_getContext(pAVCodecContext->width, pAVCodecContext->height, pAVCodecContext->pix_fmt,
    
    pAVCodecContext->width, pAVCodecContext->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
    
    int yuv_size = pAVCodecContext->width * pAVCodecContext->height;
    
    while (av_read_frame(pAVFormatContext, pAVPacket) >= 0) {
    
    if (pAVPacket->stream_index == videoindex) {
    
    /*
    
    * 在此处添加输出H264码流的代码
    
    * 取自于packet,使用fwrite()
    
    */
    
    ret = avcodec_decode_video2(pAVCodecContext, pAvFrame, &got_pic, pAVPacket);
    
    if (ret < 0) {
    
    printf("Decode Error.\n");
    
    return -1;
    
    }
    
    if (got_pic) {
    
    sws_scale(img_convert_ctx, (const uint8_t* const*)pAvFrame->data, pAvFrame->linesize, 0, pAVCodecContext->height,
    
    pFrameYUV->data, pFrameYUV->linesize);
    
    printf("Decoded frame index: %d\n", frame_cnt);
    
    fwrite(pFrameYUV->data[0], 1, yuv_size, file_yuv);
    
    fwrite(pFrameYUV->data[1], 1, yuv_size / 4, file_yuv);
    
    fwrite(pFrameYUV->data[2], 1, yuv_size / 4, file_yuv);
    
    /*
    
    * 在此处添加输出YUV的代码
    
    * 取自于pFrameYUV,使用fwrite()
    
    */
    
    frame_cnt++;
    
    }
    
    }
    
    av_free_packet(pAVPacket);
    
    }
    
    //FIX: Flush Frames remained in Codec
    
    while (1) {
    
    ret = avcodec_decode_video2(pAVCodecContext, pAvFrame, &got_pic, pAVPacket);
    
    if (ret < 0)
    
    break;
    
    if (got_pic) {
    
    fwrite(pAvFrame->data[0], 1, yuv_size, file_yuv);
    
    fwrite(pAvFrame->data[1], 1, yuv_size / 4, file_yuv);
    
    fwrite(pAvFrame->data[2], 1, yuv_size / 4, file_yuv);
    
    printf("decode frame cuss %d\n", pAVPacket->dts);
    
    }
    
    av_free_packet(pAVPacket);
    
    }
    
    av_frame_free(&pAvFrame);
    
    avcodec_close(pAVCodecContext);
    
    avformat_close_input(&pAVFormatContext);
    
    return 0;
    
    }
    

    相关文章

      网友评论

          本文标题:2020-08-18

          本文链接:https://www.haomeiwen.com/subject/usvljktx.html