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

#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\n");
        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\n", 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\n", videostream);
    
    if (-1 == videostream)
    {
        printf("error no video stream\n");
        return;
    }

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

    
    pCodec = avcodec_find_decoder( pCodecCtx->codec_id );
    
    if(NULL == pCodec)
    {
        printf("couldn't find the decode\n");
        return -1;
    }
    
    if( avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
    {
        printf("open decode error\n");
        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\n", 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\n", 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\n",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\n");
                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\n");

    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\n", f1);
    printf("f2=%d\n", f2);

    return 0;
}

 

posted on 2016-11-09 17:17  邶风  阅读(313)  评论(0编辑  收藏  举报