Linux FFmpeg glwf Glad 解码显示视频

2019-08-16  本文已影响0人  贼噶人
2019-08-16 13-08-35 的屏幕截图.png
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <math.h>
#include "stb_image.h"
#include "stb_image_write.h"
#include <linux/soundcard.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<stdio.h>
#include<linux/soundcard.h>
#include <sys/ioctl.h>

extern "C"{
    #include <libavcodec/avcodec.h>
    #include <libswscale/swscale.h>
    #include <libavformat/avformat.h>
    #include <libavutil/imgutils.h>
    #include <libavutil/opt.h>
}
static void progressInput(GLFWwindow *window){
    if(NULL != window){
        if(GLFW_PRESS == glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT)){
            glfwTerminate();
        }
    }
}

static void Callback(GLFWwindow*,int x,int y){
    glViewport(0, 0, x, y);
}

static void muxer(){
    AVFormatContext *videoFormatContext = NULL;
    avformat_open_input(&videoFormatContext,"/home/gangzhou/zaojiaoji.mp4",NULL,NULL);
    if(NULL == videoFormatContext){
        printf("avformat_open_input video error\n");
        exit(0);
    }
    if(avformat_find_stream_info(videoFormatContext,NULL) < 0){
        printf("avformat_find_stream_info video error\n");
        exit(0);
    }
    AVFormatContext *audioFormatContext = NULL;
    avformat_open_input(&audioFormatContext,"/home/gangzhou/mv.mp4",NULL,NULL);
    if(NULL == audioFormatContext){
        printf("avformat_open_input audio error\n");
        exit(0);
    }
    if(avformat_find_stream_info(audioFormatContext,NULL) < 0){
        printf("avformat_find_stream_info video error\n");
        exit(0);
    }
    AVFormatContext *outAVFormatContext = NULL;
    avformat_alloc_output_context2(&outAVFormatContext,NULL,NULL,"home/gangzhou/out.mp4");
    if(NULL == outAVFormatContext){
        printf("avformat_alloc_output_context2 video error\n");
        exit(0);
    }
    int videoStreamIndex;
    int outVideoStreamIndex;
    int audioStreamIndex1;
    int outAudioStreamIndex1;
    for (int i = 0;i < videoFormatContext->nb_streams;++i){
        AVStream *avStream = videoFormatContext->streams[i];
        if(AVMEDIA_TYPE_VIDEO == avStream->codecpar->codec_type){
            AVStream *outStream = avformat_new_stream(outAVFormatContext
                    ,avStream->codec->codec);
            videoStreamIndex = i;
            if(NULL == outStream){
                printf("avformat_new_stream video error\n");
                exit(0);
            }
            outVideoStreamIndex = outStream->index;
            if(avcodec_parameters_copy(outStream->codecpar,avStream->codecpar) < 0){
                printf("avcodec_parameters_copy video error\n");
                exit(0);
            }
            outStream->time_base.num = avStream->time_base.num;
            outStream->time_base.den = avStream->time_base.den;
            outStream->duration = avStream->duration;
            outStream->avg_frame_rate.num = avStream->avg_frame_rate.num;
            outStream->avg_frame_rate.den = avStream->avg_frame_rate.den;
        }else if(AVMEDIA_TYPE_AUDIO == avStream->codecpar->codec_type){
            AVStream *outStream = avformat_new_stream(outAVFormatContext
                    ,avcodec_find_encoder(avStream->codecpar->codec_id));
            audioStreamIndex1 = i;
            if(NULL == outStream){
                printf("avformat_new_stream audio error\n");
                exit(0);
            }
            outAudioStreamIndex1 = outStream->index;
            if(avcodec_parameters_copy(outStream->codecpar,avStream->codecpar) < 0){
                printf("avcodec_parameters_copy audio error\n");
                exit(0);
            }
            break;
        }
    }
    int audioStreamIndex;
    int outAudioStreamIndex;
    for (int i = 0;i < audioFormatContext->nb_streams;++i){
        AVStream *avStream = audioFormatContext->streams[i];
        if(AVMEDIA_TYPE_AUDIO == avStream->codecpar->codec_type){
            AVStream *outStream = avformat_new_stream(outAVFormatContext
                    ,avcodec_find_encoder(avStream->codecpar->codec_id));
            audioStreamIndex = i;
            if(NULL == outStream){
                printf("avformat_new_stream audio error\n");
                exit(0);
            }
            outAudioStreamIndex = outStream->index;
            if(avcodec_parameters_copy(outStream->codecpar,avStream->codecpar) < 0){
                printf("avcodec_parameters_copy audio error\n");
                exit(0);
            }
            break;
        }
    }
    if(!(outAVFormatContext->flags & AVFMT_NOFILE)){
        if(avio_open(&outAVFormatContext->pb,"/home/gangzhou/out.mp4",AVIO_FLAG_WRITE) < 0){
            printf("avio_open  error\n");
            exit(0);
        }
    }
    if(avformat_write_header(outAVFormatContext,NULL) < 0){
        printf("avformat_write_header  error\n");
        exit(0);
    }
    AVPacket *avPacket = av_packet_alloc();
    while (1){
        if(!av_read_frame(videoFormatContext,avPacket)){
            if(avPacket->stream_index == videoStreamIndex){
                avPacket->stream_index = outVideoStreamIndex;
                avPacket->pos = -1;
                av_interleaved_write_frame(outAVFormatContext,avPacket);
                av_packet_unref(avPacket);
            }

            if(avPacket->stream_index == audioStreamIndex1) {
                avPacket->stream_index = outAudioStreamIndex1;
                av_interleaved_write_frame(outAVFormatContext, avPacket);
                av_packet_unref(avPacket);
            }
        } else{
            break;
        }
        if(!av_read_frame(audioFormatContext,avPacket)){
            if(avPacket->stream_index == audioStreamIndex) {
                avPacket->stream_index = outAudioStreamIndex;
                av_interleaved_write_frame(outAVFormatContext, avPacket);
                av_packet_unref(avPacket);
            }
        } else{
            break;
        }
    }
    av_write_trailer(outAVFormatContext);
    av_packet_free(&avPacket);
    avformat_free_context(videoFormatContext);
    avformat_free_context(audioFormatContext);
    avformat_free_context(outAVFormatContext);
}


int main() {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }
    glfwSetFramebufferSizeCallback(window,Callback);
    glViewport(0, 0, 800, 600);
    glClearColor(1.0f, 0.3f, 0.3f, 1.0f);
    float vertices[] = {-1.0f,-1.0f,0.0f,0.0f,1.0f,
                        1.0f,-1.0f,0.0f,1.0f,1.0f,
                        1.0f,1.0f,0.2f,1.0f,0.0f,
                        -1.0f,1.0f,0.2f,0.0f,0.0f};
    unsigned int vertexShader =  glCreateShader(GL_VERTEX_SHADER);
    char *vertexShaderSource = "#version 330 core \n layout(location = 0) in vec3 aPos; layout(location = 1) in vec2 tPos;out vec2 TexCoord;out vec4 color;void main(){gl_Position = vec4(aPos,1.0); color = vec4(1.0,aPos.y,aPos.z,1.0);TexCoord = tPos;} ";
    glShaderSource(vertexShader,1,&vertexShaderSource,NULL);
    glCompileShader(vertexShader);
    int status;
    char info[512] = {0};
    glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&status);
    if(!status){
        glGetShaderInfoLog(vertexShader,512,NULL,info);
        printf("%s\n",info);
        glfwTerminate();
    }
    unsigned int fragmentShader =  glCreateShader(GL_FRAGMENT_SHADER);
    char *fragmentShaderSource = "#version 330 core  \n out vec4 FragColor;uniform vec4 uniColor;uniform sampler2D texture1;uniform sampler2D texture2;in vec4 color; in vec2 TexCoord; void main() {FragColor = mix(texture(texture1,TexCoord),texture(texture2,TexCoord),0.2) * uniColor;}";
    glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
    glCompileShader(fragmentShader);
    glGetShaderiv(fragmentShader,GL_COMPILE_STATUS,&status);
    if(!status){
        glGetShaderInfoLog(fragmentShader,512,NULL,info);
        printf("%s\n",info);
        glfwTerminate();
    }

    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram,vertexShader);
    glAttachShader(shaderProgram,fragmentShader);
    glLinkProgram(shaderProgram);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glGetProgramiv(fragmentShader,GL_COMPILE_STATUS,&status);

    if(!status){
        glGetProgramInfoLog(fragmentShader,512,NULL,info);
        printf("%s\n",info);
        glfwTerminate();
    }

    int uniColorLocation = glGetUniformLocation(shaderProgram,"uniColor");
    unsigned int indices[] = {0,1,2,2,3,0};
    unsigned int VAO;
    glGenVertexArrays(1,&VAO);
    glBindVertexArray(VAO);
    unsigned int VBO;
    glGenBuffers(1,&VBO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices,GL_STATIC_DRAW);

    unsigned int EBO;
    glGenBuffers(1,&EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices),indices,GL_STATIC_DRAW);

    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE, 5 * sizeof(float),(void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE, 5 * sizeof(float),(void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    int imageW;
    int imageH;
    int nrChannels;
   // stbi_set_flip_vertically_on_load(true);
    stbi_uc *uc = stbi_load("/home/gangzhou/CLionProjects/untitled1/1.jpg"
            ,&imageW,&imageH,&nrChannels,0);

    unsigned int texture;
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1,&texture);
    glBindTexture(GL_TEXTURE_2D,texture);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,imageW,imageH,0,GL_RGB,GL_UNSIGNED_BYTE,uc);
    glGenerateMipmap(GL_TEXTURE_2D);
    stbi_image_free(uc);

    uc = stbi_load("/home/gangzhou/CLionProjects/untitled1/2.jpg"
            ,&imageW,&imageH,&nrChannels,0);
    unsigned int texture1;
    glActiveTexture(GL_TEXTURE1);
    glGenTextures(1,&texture1);
    glBindTexture(GL_TEXTURE_2D,texture1);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,imageW,imageH,0,GL_RGB,GL_UNSIGNED_BYTE,uc);
    glGenerateMipmap(GL_TEXTURE_2D);
    stbi_image_free(uc);


    avcodec_register_all();
    avformat_network_init();
    muxer();
    int videoStreamIndex = 0;
    {
        AVFormatContext *avFormatContext = avformat_alloc_context();
        if(avformat_open_input(&avFormatContext,
                "/home/gangzhou/桌面/zaojiaoji.mp4",NULL,NULL)){
            printf("avformat_open_input error \n");
            glfwTerminate();
        }
        if(avformat_find_stream_info(avFormatContext,NULL) < 0){
            printf("avformat_find_stream_info error \n");
            glfwTerminate();
        }
        for (int i = 0; i < avFormatContext->nb_streams; ++i) {
            if(AVMEDIA_TYPE_VIDEO == avFormatContext->streams[i]->codecpar->codec_type){
                videoStreamIndex = i;
                printf("find video stream %d\n"
                        ,videoStreamIndex);
                break;
            }
        }
        AVCodec *videoCodec = avcodec_find_decoder(avFormatContext->
                streams[videoStreamIndex]->codecpar->codec_id);
        if(NULL == videoCodec){
            printf("avcodec_find_decoder error\n");
            glfwTerminate();
        }
        AVCodecContext *videoDecodeContext = avcodec_alloc_context3(videoCodec);
        if(NULL == videoDecodeContext){
            printf("avcodec_alloc_context3 error\n");
            glfwTerminate();
        }
        if(avcodec_parameters_to_context(videoDecodeContext
                ,avFormatContext->streams[videoStreamIndex]->codecpar) < 0){
            printf("avcodec_parameters_to_context error\n");
            glfwTerminate();
        }
        if(avcodec_open2(videoDecodeContext,videoCodec,NULL)){
            printf("avcodec_open2 error\n");
            glfwTerminate();
        }
        AVPacket* avPacket = av_packet_alloc();
        if(NULL == avPacket){
            printf("av_packet_alloc error\n");
            glfwTerminate();
        }
        AVFrame* avFrame = av_frame_alloc();
        if(NULL == avFrame){
            printf("av_frame_alloc error\n");
            glfwTerminate();
        }
        struct SwsContext *swsContext = sws_getContext(videoDecodeContext->width
                ,videoDecodeContext->height,videoDecodeContext->pix_fmt,videoDecodeContext->width
                ,videoDecodeContext->height,AV_PIX_FMT_RGB24,SWS_BICUBIC,NULL,NULL,NULL);
        uint8_t *dst[4];
        int dstStride[4];
        if(av_image_alloc(dst,dstStride,videoDecodeContext->width,videoDecodeContext->height
                ,AV_PIX_FMT_RGB24,1) < 0){
            printf("av_image_alloc error\n");
            glfwTerminate();
        }
        glViewport(0, 0, videoDecodeContext->width,videoDecodeContext->height);
        glfwSetWindowSize(window,videoDecodeContext->width,videoDecodeContext->height);
        FILE *wFile = fopen("/home/gangzhou/CLionProjects/untitled1/video","wb");
        if(-1 == status){
            printf("SOUND_PCM_WRITE_BITS error\n");
            exit(0);
        }
        while (!av_read_frame(avFormatContext,avPacket)){
            if(avPacket->stream_index == videoStreamIndex){
                int ret = avcodec_send_packet(videoDecodeContext,avPacket);
                if(ret){
                    printf("avcodec_send_packet error\n");
                    glfwTerminate();
                }
                while (ret >= 0){
                    ret = avcodec_receive_frame(videoDecodeContext,avFrame);
                    if(!ret){
                        sws_scale(swsContext,(const uint8_t * const *)avFrame->data,avFrame->linesize,0
                                ,avFrame->height,dst,dstStride);
                        usleep(30000);
                        glDeleteTextures(1,&texture1);
                        glActiveTexture(GL_TEXTURE1);
                        glGenTextures(1,&texture1);
                        glBindTexture(GL_TEXTURE_2D,texture1);
                        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
                        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
                        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
                        glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,avFrame->width
                                ,avFrame->height,0,GL_RGB,GL_UNSIGNED_BYTE,dst[0]);
                        glGenerateMipmap(GL_TEXTURE_2D);

                        glClearColor(1.0f, 0.3f, 0.3f, 1.0f);
                        glClear(GL_COLOR_BUFFER_BIT);
                        glUseProgram(shaderProgram);
                        float value = sin(glfwGetTime()) /2 +0.5f;
                        glUniform1i(glGetUniformLocation(shaderProgram,"texture1"),1);
                        glUniform4f(uniColorLocation,1.0f,value,1.0f,0.5f);
                        glBindVertexArray(VAO);
                        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
                        glBindVertexArray(0);
                        glfwSwapBuffers(window);
                        glfwPollEvents();
                        av_frame_unref(avFrame);
                    }
                }
            }
            av_packet_unref(avPacket);
        }
    }
    while(!glfwWindowShouldClose(window))
    {
        progressInput(window);
        glClearColor(1.0f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(shaderProgram);
        float value = sin(glfwGetTime()) /2 +0.5f;
        glUniform1i(glGetUniformLocation(shaderProgram,"texture1"),1);
        glUniform4f(uniColorLocation,1.0f,value,1.0f,0.5f);
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
        glBindVertexArray(0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读