X-Git-Url: http://47.100.26.94:8080/?a=blobdiff_plain;ds=sidebyside;f=yuvPlayer.cpp;fp=yuvPlayer.cpp;h=322975e798a3dd109074c33748d56a5aede6440f;hb=7de7c3da29277838e63b63ffd2512b4014b90fa7;hp=0000000000000000000000000000000000000000;hpb=6f9d61a8fc090e669369ec1279818e0c3543313d;p=yuv-player.git diff --git a/yuvPlayer.cpp b/yuvPlayer.cpp new file mode 100644 index 0000000..322975e --- /dev/null +++ b/yuvPlayer.cpp @@ -0,0 +1,108 @@ +#include +#include +#include "SDL2/SDL.h" + +using namespace std; + +/* + * Convert MP4 to YUV + * ffmpeg -i big_buck_bunny_720p_10mb.mp4 -c:v rawvideo -pix_fmt yuv420p out.yuv + * + * Play YUV with ffplay + * ffplay -f rawvideo -pixel_format yuv420p -video_size 1280x720 -i ./out.yuv + * + */ + +class YuvPlayer +{ +public: + YuvPlayer(int width, int height); + void play(string fname); + ~YuvPlayer(); + +private: + bool readFrame(ifstream& in, uint8_t *raw, size_t size); + void updateRenderer(uint8_t *raw); + string file; + int width = 1280; + int height = 720; + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Texture *texture; +}; + +YuvPlayer::YuvPlayer(int w, int h) +: width(w) +, height(h) +{ + SDL_Init(SDL_INIT_VIDEO); + window = SDL_CreateWindow("YUV Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN); + if (window == nullptr){ + cout << "create error: " << SDL_GetError() << endl; + } + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, width, height); +} + +YuvPlayer::~YuvPlayer() +{ + SDL_DestroyWindow(window); + SDL_Quit(); +} + +void YuvPlayer::play(string file) +{ + size_t frame_size = width * height * 3 / 2; + uint8_t *raw = (uint8_t *) malloc(sizeof(uint8_t) * frame_size); + ifstream in (file, ios::binary); + if (!in.is_open()) { + cout << "failed to open " << file << endl; + } + + SDL_Event event; + bool quit = false; + while(!quit) { + SDL_WaitEvent(&event); + switch(event.type){ + case SDL_QUIT: + quit = true; + break; + case SDL_KEYDOWN: + switch(event.key.keysym.sym){ + case SDLK_q: + quit = true; + break; + case SDLK_RIGHT: + readFrame(in, raw, frame_size); + updateRenderer(raw); + break; + default: + break; + } + default: + break; + } + } + free(raw); +} + +bool YuvPlayer::readFrame(ifstream& in, uint8_t *raw, size_t size) +{ + in.read(reinterpret_cast(raw), size); + return true; +} + +void YuvPlayer::updateRenderer(uint8_t *raw) +{ + SDL_UpdateTexture(texture, nullptr, raw, width * SDL_BYTESPERPIXEL(SDL_PIXELFORMAT_IYUV)); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, nullptr, nullptr); + SDL_RenderPresent(renderer); +} + +int main() +{ + string fname = "out.yuv"; + YuvPlayer player(1280, 720); + player.play(fname); +}