• 简单播放器


    简单播放器,存在一个问题,在播放一段时间之后,画面会突然变暗

    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libswscale/swscale.h>
    #include <stdio.h>
    #include <SDL2/SDL.h>
    
    int main(int argc, char* argv[])
    {
        AVFormatContext    *pFormatCtx;
        int                i, videoindex;
        AVCodecContext    *pCodecCtx;
        AVCodec            *pCodec;
        
        int screen_w=0,screen_h=0;  
        SDL_Window *screen;   
        SDL_Renderer* sdlRenderer;  
        SDL_Texture* sdlTexture;  
        SDL_Rect sdlRect;
        
        av_register_all();
        avformat_network_init();
        pFormatCtx = avformat_alloc_context();
        if(avformat_open_input(&pFormatCtx,argv[1],NULL,NULL)!=0)
        {
            printf("open file error
    ");
            return -1;
        }
    
        av_dump_format(pFormatCtx, 0, "s", 0);
    
        if ( avformat_find_stream_info(pFormatCtx,NULL) < 0 )
        {
            return -1;
        }
    
        i = 0;
        int videostream = -1;
        printf("pFormatCtx->nb_streams=%d
    ", pFormatCtx->nb_streams);
        for(i=0;i<pFormatCtx->nb_streams;i++)
        {
            if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
            {
                videostream = i;
                break;
            }
        }
        printf("videostream=%d
    ", videostream);
        
        if (-1 == videostream)
        {
            printf("error no video stream
    ");
            return;
        }
    
        pCodecCtx = pFormatCtx->streams[videostream]->codec;
    
        
        pCodec = avcodec_find_decoder( pCodecCtx->codec_id );
        
        if(NULL == pCodec)
        {
            printf("couldn't find the decode
    ");
            return -1;
        }
        
        if( avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
        {
            printf("open decode error
    ");
            return -1;
        }
    
        AVFrame    *pFrame,*pFrameYUV;
        pFrame = av_frame_alloc();
        pFrameYUV = av_frame_alloc();
        uint8_t *out_buffer;
    
        int num = avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
        printf("num=%d
    ", num);
    
    
        out_buffer = (uint8_t *)av_malloc(num*sizeof(uint8_t));
        avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
    
    
        AVPacket packet;
        int ret = -1;
        i = 0;
        struct SwsContext *img_convert_ctx = NULL;
        img_convert_ctx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt , pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
        
        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) 
        {    
            printf( "Could not initialize SDL - %s
    ", SDL_GetError());   
            return -1;  
        }
        
        screen_w = pCodecCtx->width;  
        screen_h = pCodecCtx->height;  
        //SDL 2.0 Support for multiple windows  
        screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,  
            screen_w, screen_h,  
            SDL_WINDOW_OPENGL);
    
      
        if(!screen) 
        {    
            printf("SDL: could not create window - exiting:%s
    ",SDL_GetError());    
            return -1;  
        }
        
        sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
        sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height);    
        sdlRect.x=0;  
        sdlRect.y=0;  
        sdlRect.w=screen_w;  
        sdlRect.h=screen_h;
        
        
        int f1 = 0;
        int f2 = 0;
        int got_picture = -1;
        while(av_read_frame(pFormatCtx, &packet)>=0)
        {
            f1++;
            if(packet.stream_index == videostream)
            {
    
                
                ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
            
                if(ret < 0)
                {
                    printf("decode error
    ");
                    return -1;
                }
                
                if(got_picture)
                {
                        //转换
                        sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
                        
                        SDL_UpdateYUVTexture(sdlTexture, &sdlRect,  
                        pFrameYUV->data[0], pFrameYUV->linesize[0],  
                        pFrameYUV->data[1], pFrameYUV->linesize[1],  
                        pFrameYUV->data[2], pFrameYUV->linesize[2]);  
                        
                        SDL_RenderClear( sdlRenderer );    
                        SDL_RenderCopy( sdlRenderer, sdlTexture,  NULL, &sdlRect);   
                        SDL_RenderPresent( sdlRenderer );
                        
                        SDL_Delay(40);
    
                        f2++;
    
                }
            }             
    
            av_free_packet(&packet);
        }
        printf("0000000000
    ");
    
        while (1) {  
            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);  
            if (ret < 0)  
                break;  
            if (!got_picture)  
                break;  
            sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,   
                pFrameYUV->data, pFrameYUV->linesize);  
            f2++;
    
            //SDL---------------------------  
            SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );   
            SDL_RenderClear( sdlRenderer );    
            SDL_RenderCopy( sdlRenderer, sdlTexture,  NULL, &sdlRect);
            SDL_RenderPresent( sdlRenderer );    
            //SDL End-----------------------  
            //Delay 40ms  
            SDL_Delay(40);  
        }
    
        SDL_Quit();
    
        sws_freeContext(img_convert_ctx);
    
         free(out_buffer);
        av_free(pFrameYUV);
    
        // Free the YUV frame
        av_free(pFrame);
    
        // Close the codec
        avcodec_close(pCodecCtx);
    
        // Close the video file
        avformat_close_input(&pFormatCtx);
    
        printf("f1=%d
    ", f1);
        printf("f2=%d
    ", f2);
    
        return 0;
    }
  • 相关阅读:
    线程池、进程池(concurrent.futures模块)和协程
    python中socket、进程、线程、协程、池的创建方式和应用场景
    IO多路复用和local概念
    pymysql模块
    HTML初识
    CSS之选择器
    CSS之样式属性(背景固定、圆形头像、模态框)
    字符串格式的方法%s、format和python3.6新特性f-string和类型注解
    common-pool2 使用
    apache-common pool的使用
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/6047756.html
Copyright © 2020-2023  润新知