为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

FFMPEG+SDL2.0解码视频播放器

2017-09-19 6页 doc 28KB 15阅读

用户头像

is_353097

暂无简介

举报
FFMPEG+SDL2.0解码视频播放器#include "stdafx.h" extern "C"{     #include "libavcodec\avcodec.h"     #include "libavformat\avformat.h"     #include "libswscale\swscale.h"     #include "sdl\SDL.h"     #include "sdl\SDL_test_images.h"     #include "sdl\SDL_thread.h" } #include #include /* void...
FFMPEG+SDL2.0解码视频播放器
#include "stdafx.h" extern "C"{     #include "libavcodec\avcodec.h"     #include "libavformat\avformat.h"     #include "libswscale\swscale.h"     #include "sdl\SDL.h"     #include "sdl\SDL_test_images.h"     #include "sdl\SDL_thread.h" } #include #include /* void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame){ FILE *pFile; char szFilename[32]; int y; sprintf(szFilename, "frame%d.ppm", iFrame); pFile = fopen(szFilename, "wb"); if (pFile == NULL){ cout << "open file:" << szFilename << " error." << endl; return; } //Write header }*/ //SDL2.lib;swscale.lib;postproc.lib;swresample.lib;avcodec.lib;avdevice.lib;avfilter.lib;avformat.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) int _tmain(int argc, char *agrv[]){     av_register_all();    //注册了所有的文件格式和编解码的库,它们将被自动的使用在被打开的合适格式的文件上     AVFormatContext *pFormatCtx;     pFormatCtx = avformat_alloc_context();     char filepath[] = "D:\\迅雷下载\\12.rmvb";     //Open an input stream and read the header     if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0){         printf("Can't open the file\n");         SDL_Delay(500);         return -1;     }     //Retrieve stream information     if (avformat_find_stream_info(pFormatCtx, NULL) < 0){         printf("Couldn't find stream information.\n");         return -1;     }     int i, videoIndex;     AVCodecContext *pCodecCtx;     AVCodec *pCodec;     //Find the first video stream     videoIndex = -1;     for (i = 0; i < pFormatCtx->nb_streams; i++){//视音频流的个数         if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){             videoIndex = i;             break;         }     }     if (videoIndex == -1)         return -1;     //Get a pointer to the codec context for the video stream     //流中关于编解码器的信息就是被我们叫做"codec context"(编解码器上下文)     //的东西。这里面包含了流中所使用的关于编解码器的所有信     pCodecCtx = pFormatCtx->streams[videoIndex]->codec;     //Find the decoder for the video stream     pCodec = avcodec_find_decoder(pCodecCtx->codec_id);     if (pCodec == NULL){         printf("Unsupported codec!\n");         return -1;     }     //Open codec     if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){         printf("Could not open codec.\n");         return -1;     }     //allocate video frame and set its fileds to default value     AVFrame *pFrame, *pFrameYUV;     pFrame = av_frame_alloc();     pFrameYUV = av_frame_alloc();     //即使我们申请了一帧的内存,当转换的时候,我们仍然需要一个地方来放置原始     //的数据。我们使用avpicture_get_size 来获得我们需要的大小, 然后手工申请     //内存空间:     uint8_t *out_buffer;     int numBytes;     numBytes = avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);     //av_malloc 是ffmpeg 的malloc,用来实现一个简单的malloc 的包装,这样来保     //证内存地址是对齐的(4 字节对齐或者2 字节对齐)。它并不能保 护你不被内     //存泄漏,重复释放或者其它malloc 的问所困扰。     out_buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));     //Assign appropriate parts of buffer to image planes in pFrameYUV     //Note that pFrameYUV is an AVFrame, but AVFrame is a superset of AVPicture     avpicture_fill((AVPicture*)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);     //----------------SDL--------------------------------------//     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)){         printf("Could not initialize SDL -%s\n", SDL_GetError());         exit(1);     }     SDL_Window *window = nullptr;     window = SDL_CreateWindow("MyPlayer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,         pCodecCtx->width, pCodecCtx->height, SDL_WINDOW_SHOWN);     if (!window){         printf("Could not initialize SDL -%s\n", SDL_GetError());         return 1;     }     SDL_Renderer *ren = nullptr;     ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);     if (ren == nullptr){         printf("%s\n", SDL_GetError() );         return -1;     }     SDL_Texture *texture = nullptr;     texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_YV12,         SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);     SDL_Rect rect;     rect.x = 0, rect.y = 0;     rect.w = pCodecCtx->width;     rect.h = pCodecCtx->height;     //*************************************************************//     //通过读取包来读取整个视频流,然后把它解码成帧,最后转换格式并且保存     int frameFinished;     //int psize = pCodecCtx->width * pCodecCtx->height;     AVPacket packet;     av_new_packet(&packet, numBytes);     //output file information     printf(" ---------------------------------\n");     av_dump_format(pFormatCtx, 0, filepath, 0);     printf("-----------------------------------------\n");     i = 0;     int ret;     static struct SwsContext *img_convert_ctx;     img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,         pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P,         SWS_BICUBIC, NULL, NULL, NULL);     //Read the next frame of a stream     while (av_read_frame(pFormatCtx, &packet) >= 0){         //Is this a packet from the video stream?         if (packet.stream_index == videoIndex){             //decode video frame of size packet.size from packet.data into picture             ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);             //Did we get a video frame?             if (ret >= 0){                 //Convert the image from its native format to YUV                 if (frameFinished){                     sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data,                         pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);                     SDL_UpdateYUVTexture(texture, &rect, pFrameYUV->data[0], pFrameYUV->linesize[0],                         pFrameYUV->data[1], pFrameYUV->linesize[1], pFrameYUV->data[2], pFrameYUV->linesize[2]);                     SDL_RenderClear(ren);                     SDL_RenderCopy(ren, texture, &rect, &rect);                     SDL_RenderPresent(ren);                 }                 SDL_Delay(50);             }             else{                 printf("%s\n", "decode error");                 return -1;             }         }     }     av_free_packet(&packet);     SDL_Event event;     SDL_PollEvent(&event);     switch (event.type){     case SDL_QUIT:         SDL_Quit();         exit(0);         break;     default:         break;     }     SDL_DestroyTexture(texture);     av_frame_free(&pFrame);     av_frame_free(&pFrameYUV);     avcodec_close(pCodecCtx);     avformat_close_input(&pFormatCtx);     return 0; }
/
本文档为【FFMPEG+SDL2.0解码视频播放器】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索