1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include "sdl_ffmpeg.h"
int thread_ctrl = 0; int sfp_refresh_thread(void *opaque) { thread_ctrl = 0; while (!thread_ctrl) { SDL_Event event; event.type = SFM_REFRESH_EVENT; SDL_PushEvent(&event); SDL_Delay(20); } thread_ctrl = 0; SDL_Event event; event.type = SFM_BREAK_EVENT; SDL_PushEvent(&event);
return 0; }
int sdl_ffmpeg() { const char filepath[] = "D:/ffmpeg/learn/test.mov"; AVFormatContext *pFormatCtx = avformat_alloc_context(); avformat_open_input(&pFormatCtx, filepath, nullptr, nullptr); avformat_find_stream_info(pFormatCtx, nullptr);
int videoindex = -1; for (unsigned char i = 0; i < pFormatCtx->nb_streams; ++i) { if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { videoindex = i; break; } } const AVCodec *pCodec = avcodec_find_decoder(pFormatCtx->streams[videoindex]->codecpar->codec_id); AVCodecContext *pCodecCtx = avcodec_alloc_context3(pCodec); avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoindex]->codecpar); avcodec_open2(pCodecCtx, pCodec, nullptr);
AVFrame *pFrameYUV = av_frame_alloc(); uint8_t *buffer = (uint8_t *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1));
av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
SwsContext *img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, nullptr, nullptr, nullptr);
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); int screen_w = pCodecCtx->width; int screen_h = pCodecCtx->height; SDL_Window* screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
SDL_Renderer* sdlRenderer = SDL_CreateRenderer(screen, -1, 0); SDL_Texture *sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height); SDL_Rect sdlRect; AVPacket *packet = av_packet_alloc(); SDL_Thread *video_tid = SDL_CreateThread(sfp_refresh_thread, NULL, NULL); SDL_Event event; AVFrame *pFrame = av_frame_alloc(); int ret; while(true) { SDL_WaitEvent(&event); if (event.type == SFM_REFRESH_EVENT) { if (av_read_frame(pFormatCtx, packet) >= 0) { if (packet->stream_index == videoindex) { ret = avcodec_send_packet(pCodecCtx, packet); while (ret >= 0) { ret = avcodec_receive_frame(pCodecCtx, pFrame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } sws_scale(img_convert_ctx, (const uint8_t *const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
SDL_UpdateTexture(sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0]); sdlRect.x = 0; sdlRect.y = 0; sdlRect.w = screen_w; sdlRect.h = screen_h; SDL_RenderClear(sdlRenderer); SDL_RenderCopy(sdlRenderer, sdlTexture, &sdlRect, &sdlRect); SDL_RenderPresent(sdlRenderer); } } av_packet_unref(packet); } else { thread_ctrl = 1; } } else if (event.type == SDL_WINDOWEVENT) { SDL_GetWindowSize(screen, &screen_w, &screen_h); } else if (event.type == SDL_QUIT) { thread_ctrl = 1; } else if (event.type == SFM_BREAK_EVENT) { break; }
}
sws_freeContext(img_convert_ctx); SDL_Quit(); av_frame_free(&pFrameYUV); av_frame_free(&pFrame); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx); return 0; }
|