C++에서 SDL 및 libav를 사용하여 Linux의 화면에 비디오를 그립니다. 대부분의 비디오 코드 열기 코드는 this tutorial을 기반으로하지만, 일부 기능이 변경되었습니다. 나는이 같은 SDL을 초기화 :SDL 비디오 오버레이가 SDL_Flip으로 깜박임
SDL_Init(SDL_INIT_EVERYTHING);
const SDL_VideoInfo * info = SDL_GetVideoInfo();
screen = SDL_SetVideoMode(info->current_w, info->current_h, 0, SDL_SWSURFACE | SDL_FULLSCREEN);
나는 꽤 큰이기 때문에 전체 코드를 게시하지 않을거야,하지만 다음 쇼는 어떻게 비디오 오버레이를 표시하려고합니다. 일부 변수는 formatCtx
및 packet
과 같은 내 Video 클래스의 클래스 멤버입니다.
void Video::GetOverlay(SDL_Overlay * overlay) {
int frameFinished;
while (av_read_frame(formatCtx, &packet) >= 0) {
if (packet.stream_index == videoStream) {
avcodec_decode_video2(codecCtx, frame, &frameFinished, &packet);
if (frameFinished) {
SDL_LockYUVOverlay(overlay);
AVPicture pict;
pict.data[0] = overlay->pixels[0];
pict.data[1] = overlay->pixels[2];
pict.data[2] = overlay->pixels[1];
pict.linesize[0] = overlay->pitches[0];
pict.linesize[1] = overlay->pitches[2];
pict.linesize[2] = overlay->pitches[1];
SwsContext * ctx = sws_getContext (codecCtx->width, codecCtx->height, codecCtx->pix_fmt,
codecCtx->width, codecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(ctx, frame->data, frame->linesize, 0, codecCtx->height, pict.data, pict.linesize);
sws_freeContext(ctx);
SDL_UnlockYUVOverlay(overlay);
++frameIndex;
return;
}
}
av_free_packet(&packet);
}
}
그리고 내 돌이의
:SDL_Overlay * overlay = SDL_CreateYUVOverlay(video->GetWidth(), video->GetHeight(), SDL_YV12_OVERLAY, screen);
while (true) {
video->GetOverlay(overlay);
SDL_Rect rect = { 400, 200, video->GetWidth(), video->GetHeight() };
SDL_DisplayYUVOverlay(overlay, &rect);
SDL_Flip(screen);
}
이 작동, 비디오 재생은하지만 많이 깜박입니다. 마치 각 프레임의 동일한 위치에 이미지를 그려 봅니다. SDL_Flip(screen)
으로 전화를 끊으면 비디오가 정상적으로 재생됩니다. 너무 빨리, 아직 비디오 촬영을하지 않았지만, 임시 SDL_Delay(10)
을 추가하면 꽤 좋아 보입니다. 그러나 내 동영상을 표시하기 위해 SDL_Flip
을 삭제하면 화면에 다른 것을 그릴 수 없습니다. SDL_BlitSurface
및 SDL_FillRect
모두 화면에 아무 것도 그리지 못합니다. 이미 플래그에 SDL_DOUBLEBUF
을 추가하려고 시도했지만 상황을 변경하지 않았습니다.
필요한 경우 더 많은 코드를 제공 할 수 있지만 다른 모든 문제 (그림 그리기 또는 SDL_Flip
없이 비디오 표시) 때문에 게시 된 코드 어딘가에 문제가 있다고 생각합니다.
내가 뭘 잘못하고 있니?
분명히 vsync가 SDL_Flip에 의해 꺼지거나 사용되지 않을 수있는 여러 가지 플랫폼이나 상황 (예 : ATI/nVidia 드라이버 설정)이 있습니다. "sdl_flip vsync"에 대한 검색을 제안하십시오. 당신은 이런 것들 중 하나를 치는 것일 수 있습니다. – leander