Created
December 19, 2013 03:12
-
-
Save sodapanda/8033799 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <libavcodec/avcodec.h> | |
| #include <libavformat/avformat.h> | |
| #include <libswscale/swscale.h> | |
| #include <SDL2/SDL.h> | |
| #include <SDL2/SDL_thread.h> | |
| #include <stdio.h> | |
| int main(int argc, char *argv[]) { | |
| AVFormatContext *pFormatCtx = NULL; | |
| int i, videoStream; | |
| AVCodecContext *pCodecCtx = NULL; | |
| AVCodec *pCodec = NULL; | |
| AVFrame *pFrame = NULL; | |
| AVPacket packet; | |
| int frameFinished; | |
| AVDictionary *optionsDict = NULL; | |
| struct SwsContext *sws_ctx = NULL; | |
| //SDL2 | |
| SDL_Window *sdl_window = NULL; | |
| static SDL_Renderer *renderer = NULL; | |
| static SDL_Texture *texture = NULL; | |
| if(argc < 2) { | |
| fprintf(stderr, "Usage: test <file>\n"); | |
| exit(1); | |
| } | |
| // Register all formats and codecs | |
| av_register_all(); | |
| avformat_network_init(); | |
| if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { | |
| fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); | |
| exit(1); | |
| } | |
| // Open video file | |
| if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0) | |
| return -1; // Couldn't open file | |
| // Retrieve stream information | |
| if(avformat_find_stream_info(pFormatCtx, NULL)<0) | |
| return -1; // Couldn't find stream information | |
| // Dump information about file onto standard error | |
| av_dump_format(pFormatCtx, 0, argv[1], 0); | |
| // Find the first video stream | |
| videoStream=-1; | |
| for(i=0; i<pFormatCtx->nb_streams; i++) | |
| if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { | |
| videoStream=i; | |
| break; | |
| } | |
| if(videoStream==-1) | |
| return -1; // Didn't find a video stream | |
| // Get a pointer to the codec context for the video stream | |
| pCodecCtx=pFormatCtx->streams[videoStream]->codec; | |
| // Find the decoder for the video stream | |
| pCodec=avcodec_find_decoder(pCodecCtx->codec_id); | |
| if(pCodec==NULL) { | |
| fprintf(stderr, "Unsupported codec!\n"); | |
| return -1; // Codec not found | |
| } | |
| // Open codec | |
| if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0) | |
| return -1; // Could not open codec | |
| // Allocate video frame | |
| pFrame=avcodec_alloc_frame(); | |
| // Make a screen to put our video | |
| sdl_window = SDL_CreateWindow("sdl",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,pCodecCtx->width,pCodecCtx->height,SDL_WINDOW_OPENGL); | |
| if(!sdl_window) { | |
| fprintf(stderr, "SDL: could not create window - exiting\n"); | |
| exit(1); | |
| } | |
| renderer = SDL_CreateRenderer(sdl_window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE); | |
| texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_IYUV,SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width,pCodecCtx->height); | |
| sws_ctx = | |
| sws_getContext | |
| ( | |
| pCodecCtx->width, | |
| pCodecCtx->height, | |
| pCodecCtx->pix_fmt, | |
| pCodecCtx->width, | |
| pCodecCtx->height, | |
| PIX_FMT_YUV420P, | |
| SWS_BILINEAR, | |
| NULL, | |
| NULL, | |
| NULL | |
| ); | |
| // Read frames and save first five frames to disk | |
| while(av_read_frame(pFormatCtx, &packet)>=0) { | |
| // Is this a packet from the video stream? | |
| if(packet.stream_index==videoStream) { | |
| // Decode video frame | |
| avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); | |
| // Did we get a video frame? | |
| if(frameFinished) { | |
| AVPicture pict; | |
| avpicture_alloc(&pict,PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height); | |
| sws_scale | |
| ( | |
| sws_ctx, | |
| (uint8_t const * const *)pFrame->data, | |
| pFrame->linesize, | |
| 0, | |
| pCodecCtx->height, | |
| pict.data, | |
| pict.linesize | |
| ); | |
| SDL_UpdateYUVTexture(texture,NULL,pict.data[0],pict.linesize[0],pict.data[1],pict.linesize[1],pict.data[2],pict.linesize[2]); | |
| SDL_RenderClear(renderer); | |
| SDL_RenderCopy(renderer,texture,NULL,NULL); | |
| SDL_RenderPresent(renderer); | |
| } | |
| } | |
| av_free_packet(&packet); | |
| //find sleep duration from pCodecCtx and sleep | |
| } | |
| // Free the YUV frame | |
| av_free(pFrame); | |
| // Close the codec | |
| avcodec_close(pCodecCtx); | |
| // Close the video file | |
| avformat_close_input(&pFormatCtx); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment