- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 ffmpeg 和 OpenGL + SDL 播放视频文件。播放速度非常慢且闪烁。该代码是来自不同博客/网站的积累,我不太确定发生了什么。很抱歉发布这么长的代码,但这是最小化版本。我的实际代码在窗口模式下也不能很好地运行。以下版本在窗口模式下以某种方式流畅播放。
#ifndef INT64_C
#define INT64_C(c) (int64_t)(c)
#define UINT64_C(c) (uint64_t)(c)
#endif
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
#include <SDL.h>
#include <GL/gl.h>
int fullscreen = 1, videoStream = -1, frameFinished=0;
const PixelFormat CONV_FORMAT = PIX_FMT_RGB24;
const char *fname = "moviesample.mp4";
AVFormatContext *pFormatCtx = NULL;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVFrame *pFrame = 0, *pFrameRGB = 0;
AVPacket packet;
AVDictionary *optionsDict = NULL;
struct SwsContext *sws_ctx = NULL;
GLuint texture_video;
void av_init();
void draw_frame();
int main(int argc, const char **argv) {
SDL_Event event;
av_init();
uint16_t width = fullscreen ? 1600 : pCodecCtx->width;
uint16_t height = fullscreen ? 900 : pCodecCtx->height;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_SetVideoMode(width, height, 32,
SDL_OPENGL | SDL_HWPALETTE | SDL_HWSURFACE | SDL_HWACCEL |
(fullscreen ? SDL_FULLSCREEN : 0)
);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.4f, 0.4f, 0.0f);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
glShadeModel( GL_SMOOTH );
glGenTextures(1, &texture_video);
glBindTexture(GL_TEXTURE_2D, texture_video);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pCodecCtx->width, pCodecCtx->height,
0, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
sws_ctx = sws_getCachedContext(sws_ctx, pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, CONV_FORMAT,
SWS_BICUBIC, NULL, NULL, NULL);
while (1) {
draw_frame();
SDL_GL_SwapBuffers();
SDL_PollEvent(&event);
switch(event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {
SDL_Quit();
exit(0);
}
break;
default:
break;
}
}
return 0;
}
void draw_frame() {
if (av_read_frame(pFormatCtx, &packet)>=0) {
if(packet.stream_index==videoStream) {
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
if(frameFinished) {
sws_scale (sws_ctx, (uint8_t const * const *)pFrame->data,
pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,
pFrameRGB->linesize);
glBindTexture( GL_TEXTURE_2D, texture_video );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pCodecCtx->width,
pCodecCtx->height, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
}
glClear(GL_COLOR_BUFFER_BIT);
glScalef(1.0f, -1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
glScalef(1.0f, -1.0f, 1.0f);
}
av_free_packet(&packet);
} else {
av_seek_frame(pFormatCtx, videoStream, 0, AVSEEK_FLAG_FRAME);
}
}
void av_init() {
av_register_all();
avformat_open_input(&pFormatCtx, fname, NULL, NULL);
avformat_find_stream_info(pFormatCtx, NULL);
for(uint8_t i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
avcodec_open2(pCodecCtx, pCodec, &optionsDict);
pFrame = avcodec_alloc_frame();
pFrameRGB = avcodec_alloc_frame();
int bytes = avpicture_get_size(CONV_FORMAT, pCodecCtx->width,
pCodecCtx->height);
uint8_t *video_buffer = (uint8_t*)av_malloc( bytes * sizeof(uint8_t) );
avpicture_fill((AVPicture *)pFrameRGB, video_buffer, CONV_FORMAT,
pCodecCtx->width, pCodecCtx->height);
}
最佳答案
在全屏模式下,您可能会获得 vsync,这意味着 SDL_GL_SwapBuffers()
将每帧阻塞 16 毫秒左右。
要在窗口模式下模拟效果,请在主 while(1)
循环的末尾添加一个 SDL_Delay(16)
。
重写 draw_frame()
以便它抽取 libav
直到 它获得下一帧,而不是仅在每个主循环中抽取一次并且希望你得到一个框架:
// g++ main.cpp `pkg-config sdl gl libswscale libavcodec libavformat --libs --cflags` && SDL_VIDEO_FULLSCREEN_HEAD=0 ./a.out
#ifndef INT64_C
#define INT64_C(c) (int64_t)(c)
#define UINT64_C(c) (uint64_t)(c)
#endif
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
#include <SDL.h>
#include <GL/gl.h>
int fullscreen = 1, videoStream = -1, frameFinished=0;
const PixelFormat CONV_FORMAT = PIX_FMT_RGB24;
const char *fname = "/home/genpfault/vid.mpg";
AVFormatContext *pFormatCtx = NULL;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVFrame *pFrame = 0, *pFrameRGB = 0;
AVPacket packet;
AVDictionary *optionsDict = NULL;
struct SwsContext *sws_ctx = NULL;
GLuint texture_video;
void av_init();
void next_frame();
int main(int argc, const char **argv) {
SDL_Event event;
av_init();
uint16_t width = fullscreen ? 1920 : pCodecCtx->width;
uint16_t height = fullscreen ? 1200 : pCodecCtx->height;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_SetVideoMode(width, height, 32,
SDL_OPENGL |
(fullscreen ? SDL_FULLSCREEN : 0)
);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.4f, 0.4f, 0.0f);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
glShadeModel( GL_SMOOTH );
glGenTextures(1, &texture_video);
glBindTexture(GL_TEXTURE_2D, texture_video);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pCodecCtx->width, pCodecCtx->height,
0, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
sws_ctx = sws_getCachedContext(sws_ctx, pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, CONV_FORMAT,
SWS_BICUBIC, NULL, NULL, NULL);
while (1) {
while( SDL_PollEvent(&event) )
{
switch(event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {
SDL_Quit();
exit(0);
}
break;
default:
break;
}
}
next_frame();
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture( GL_TEXTURE_2D, texture_video );
glScalef(1.0f, -1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
glScalef(1.0f, -1.0f, 1.0f);
SDL_GL_SwapBuffers();
}
return 0;
}
void next_frame()
{
while( true )
{
if( av_read_frame(pFormatCtx, &packet) >= 0 )
{
if( packet.stream_index == videoStream )
{
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
if(frameFinished)
{
sws_scale (sws_ctx, (uint8_t const * const *)pFrame->data,
pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,
pFrameRGB->linesize);
glBindTexture( GL_TEXTURE_2D, texture_video );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pCodecCtx->width,
pCodecCtx->height, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
break;
}
}
av_free_packet(&packet);
}
else
{
av_seek_frame(pFormatCtx, videoStream, 0, AVSEEK_FLAG_FRAME);
}
}
}
void av_init() {
av_register_all();
avformat_open_input(&pFormatCtx, fname, NULL, NULL);
avformat_find_stream_info(pFormatCtx, NULL);
for(uint8_t i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
avcodec_open2(pCodecCtx, pCodec, &optionsDict);
pFrame = avcodec_alloc_frame();
pFrameRGB = avcodec_alloc_frame();
int bytes = avpicture_get_size(CONV_FORMAT, pCodecCtx->width,
pCodecCtx->height);
uint8_t *video_buffer = (uint8_t*)av_malloc( bytes * sizeof(uint8_t) );
avpicture_fill((AVPicture *)pFrameRGB, video_buffer, CONV_FORMAT,
pCodecCtx->width, pCodecCtx->height);
}
关于c++ - OpenGL + ffmpeg 在全屏模式下运行缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14782266/
我正在尝试使用 Qt 制作游戏,因为它太棒了 ;) 而且您可以免费获得所需的所有东西。唯一的问题是更改系统分辨率和设置 QWidget(或 QGLWidget)“真正的”全屏。 你们中有人成功地做到了
有没有办法以全屏模式(没有工具栏、导航)启动 gwt-app? 我只找到了打开新窗口的提示: Window.open("SOMEURL","SOMETITLE", "fullscreen=yes
if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscr
我想解释一下我现在在做什么。我开发了一个 aar(sdk) 并且运行良好。但是,我希望我的 sdk 在被调用时占据全屏,即使调用者有一个工具栏。我尝试了此链接中的示例 [ How to set act
我是 Blazor 的新手,我正在尝试了解如何以全屏模式打开浏览器。我知道我可以执行 Javascript 中断并运行 Javascript,但这违背了 Blazor 的目的。 如何在 Blazor
我正在创建一个全屏应用程序,并且想知道是否有某种方法可以使 NSAlert 位于我创建的 CGDisplayCapture 之上。现在,NSAlert 显示在显示捕获后面。我的主窗口显示得很好(在使用
有人可以解释一下下面的代码是如何工作的吗? 元素指的是视频,全屏指的是页面上的链接。 我无法理解 if 语句 var element = document.getElementById('elemen
我想要实现的是类似于 Instagram 应用内网络浏览器,在您点击广告时使用: 我所做的是,我使用了 WebView bottomSheetDialogFragment,并覆盖了 onCreateD
第二个 ViewController 的顶部有这个空间,它几乎在手机上显示为可关闭的弹出窗口。如何使全屏显示(删除橙色箭头指向的空间)? 最佳答案 这是 iOS 13 的一项更改。用户将开始期望能够滑
我正在尝试在全屏模式下使用 emacs 并使用合适的字体。我有一台运行 Ubuntu 的基于 nvidia 的笔记本电脑。首次加载时,字体很大,认为是 16pt 字体。我使用菜单选项设置了合适的字体(
我有一个 GridView,我使用 BaseAdapter 来调整我的 GridView 中的图像和文本。我有一个问题,当我运行我的应用程序时,我的“GridView”有左、右、上和下边距。我不需要这
是否可以在全屏模式下使用 Android Studio 例如只有我们编码的那个字段应该显示在整个屏幕上。 像这样: 最佳答案 您可以使用“无干扰模式”: 关于全屏 Android Studio,我们在
我正在制作一个应用程序,当手机处于纵向时,我需要 fragment 显示菜单栏(带有设置快捷方式等),但当它处于横向时,我需要全屏。 因此,我有一个管理 2 个 fragment 的 Activity
我想知道是否可以在没有标签栏和导航栏的情况下全屏推送 NavigationController 的 ViewController。我的问题如下: 我的应用在 TabBarController 中嵌入了
我制作了一个1920 * 1048的flash(16:9的屏幕),并将其嵌入到html中喜欢: 问题是: 在 4:3 屏幕中,flash 的宽度为 100%,但顶部和底部有白色填充。看来闪光灯
我想制作一个同时包含多个文本的HTML5视频。 文本应该以不同的css布局(文本颜色、字体、阴影)显示在视频的不同位置(同时) 我试过这个教程http://www.artandlogic.com/bl
需要一些帮助。 我需要水平滑动一次长图像,然后再水平滑动回来...我在这里学习了一个教程 https://css-tricks.com/creating-a-css-sliding-backgroun
我正在制作一个简单的登录页面,并试图将以下图像作为背景全屏:image 我的 CSS 目前看起来像这样: body { background-image: url('/images/bg.jp
我想用透明色覆盖我的背景图片,但颜色没有覆盖背景图片。 这是我的演示: http://jsfiddle.net/farna/73kx2/ CSS 代码: .overlay{ backgroun
有什么方法可以隐藏状态栏并保持操作栏可见吗? 最佳答案 是的,有。您应该在 Activity 的 onCreate 方法中设置 FLAG_FULLSCREEN。 @Override public vo
我是一名优秀的程序员,十分优秀!