我们几乎做完了;我们仅仅剩了最后一件事:显示视频!下面就是 video_display函数:
void video_display(VideoState *is) {
SDL_Rect rect; VideoPicture *vp; AVPicture pict; float aspect_ratio; int w, h, x, y; int i;
vp = &is->pictq[is->pictq_rindex]; if(vp->bmp) { if(is->video_st->codec->sample_aspect_ratio.num == 0) { aspect_ratio = 0; } else { aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio) * is->video_st->codec->width / is->video_st->codec->height; } if(aspect_ratio <= 0.0) { aspect_ratio = (float)is->video_st->codec->width / (float)is->video_st->codec->height; } h = screen->h; w = ((int)rint(h * aspect_ratio)) & -3; if(w > screen->w) { w = screen->w; h = ((int)rint(w / aspect_ratio)) & -3; } x = (screen->w - w) / 2; y = (screen->h - h) / 2;
rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_DisplayYUVOverlay(vp->bmp, &rect); } } |
因为我们的屏幕可以是任意尺寸(我们设置为640x480并且用户可以自己来改变尺寸),我们需要动态计算出我们显示的图像的矩形大小。所以一开始 我们需 要计算出电影的纵横比aspect ratio,表示方式为宽度除以高度。某些编解码器会有奇数采样纵横比,只是简单表示了一个像素或者一个采样的宽度除以高度的比例。因为宽度和高度在我们 的编解码器中是用像素为单位的,所以实际的纵横比与纵横比乘以样本纵横比相同。某些编解码器会显示纵横比为0,这表示每个像素的纵横比为1x1。然后我们 把电影缩放到适合屏幕的尽可能大的尺寸。这里的& -3表示与-3做与运算,实际上是让它们4字节对齐。然后我们把电影移到中心位置,接着调用SDL_DisplayYUVOverlay()函数。
结果是什么?我们做完了吗?嗯,我们仍然要重新改写声音部分的代码来使用新的VideoStruct结构体,但是那些只是尝试着改变,你可以看一下 那些参考示例代码。最后我们要做的是改变ffmpeg提供的默认退出回调函数为我们的退出回调函数。
VideoState *global_video_state;
int decode_interrupt_cb(void) { return (global_video_state && global_video_state->quit); } |
我们在主函数中为大结构体设置了global_video_state。
这就是了!让我们编译它:
gcc -o tutorial04 tutorial04.c -lavutil -lavformat -lavcodec -lz -lm / `sdl-config --cflags --libs` |
请享受一下没有经过同步的电影!下次我们将编译一个可以最终工作的电影播放器。