简单播放器,存在一个问题,在播放一段时间之后,画面会突然变暗
#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; }