- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用以下代码,我得到了电影文件的口吃渲染。有趣的是,当用 ffmpeg 转储信息时,它说它有 25 fps 和 00:01:32.90 的持续时间;然而,当计算帧数和它自己运行的时间时,它给出了大约 252 秒的时间,我猜接收帧和发送包的代码 (int cap(vid v)) 多次绘制相同的帧。但我看不出有什么问题?
//PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/:/usr/lib64/pkgconfig/ --> add path to PKF_Config search path
//export PKG_CONFIG_PATH --> export PKG_Config search path to become visible for gcc
//gcc ffmpeg_capture_fl.c -Wall -pedantic -fPIC `pkg-config --cflags --libs libavdevice libavformat libavcodec libavutil libavdevice libavfilter libswscale libswresample sdl2`
#include <libavdevice/avdevice.h>
#include <libavutil/opt.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include <stdio.h>
#include <stdlib.h>
#include <libavutil/rational.h>
#include <sys/time.h>
#include <unistd.h>
typedef struct vid{
AVFormatContext *inc;
AVInputFormat *iformat;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
int videoStream;} vid;
typedef struct sws{
struct SwsContext *ctx;
uint8_t **buffer;
int *linesize;
} sws;
vid cap_init_fl(char *fl);
int cap(vid v);
void cap_close(vid v);
sws init_swsctx(int width, int height, enum AVPixelFormat pix_fmt, int new_width, int new_height, enum AVPixelFormat new_pxf);
void conv_pxlformat(sws scale, uint8_t **src_data, int *src_linesize, int height);
void free_sws(sws inp);
#include <SDL2/SDL.h>
typedef struct sdl_window{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_Event *event;
int width;
int height;
int pitch;
uint32_t sdl_pxl_frmt;
}sdl_window;
sdl_window init_windowBGR24_ffmpg(int width, int height);
int render_on_texture_update(sdl_window wow, uint8_t *data);
void close_window(sdl_window wow);
vid cap_init_fl(char *fl){
vid v = {NULL, NULL, NULL, NULL, NULL, -1};
int i;
av_register_all();
avdevice_register_all();
if( 0 > avformat_open_input( &(v.inc), fl , v.iformat, NULL)) {
printf("Input device could not been opened\n");
cap_close(v);
exit(1);
}
if(avformat_find_stream_info(v.inc, NULL)<0){
printf("Stream information could not been found.\n");
cap_close(v);
exit(2);
}
// Dump information about file onto standard error
av_dump_format(v.inc, 0, fl, 0);
// Find the first video stream
v.videoStream=-1;
for(i=0; i<v.inc->nb_streams; i++){
if(v.inc->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
v.videoStream=i;
break;
}}
if(v.videoStream==-1){
printf("Could not find video stream.\n");
cap_close(v);
exit(3);
}
// Find the decoder for the video stream
v.pCodec=avcodec_find_decoder(v.inc->streams[v.videoStream]->codecpar->codec_id);
if(v.pCodec==NULL) {
printf("Unsupported codec!\n");
cap_close(v);
exit(4);
// Codec not found
}
// Get a pointer to the codec context for the video stream
if((v.pCodecCtx=avcodec_alloc_context3(NULL)) == NULL){
printf("Could not allocate codec context\n");
cap_close(v);
exit(10);}
avcodec_parameters_to_context (v.pCodecCtx, v.inc->streams[v.videoStream]->codecpar);
// Open codec
if(avcodec_open2(v.pCodecCtx, v.pCodec, NULL)<0){
printf("Could not open codec");
cap_close(v);
exit(5);
}
// Allocate video frame
v.pFrame=av_frame_alloc();
if(v.pFrame==NULL){
printf("Could not allocate AVframe");
cap_close(v);
exit(6);}
return v;
}
int cap(vid v){
int errorCodeRF, errorCodeSP, errorCodeRecFR;
AVPacket pkt;
if((errorCodeRF = av_read_frame(v.inc, &pkt)) >= 0){
if (pkt.stream_index == v.videoStream) {
errorCodeSP = avcodec_send_packet(v.pCodecCtx, &pkt);
if (errorCodeSP >= 0 || errorCodeSP == AVERROR(EAGAIN)){
errorCodeRecFR = avcodec_receive_frame(v.pCodecCtx, v.pFrame);
if (errorCodeRecFR < 0){
av_packet_unref(&pkt);
return errorCodeRecFR;
}
else{
av_packet_unref(&pkt);
return 0;
}
}
else{
av_packet_unref(&pkt);
return errorCodeSP;}
}}
else{
return errorCodeRF;}
return 1;
}
void cap_close(vid v){
if(v.pFrame != NULL) av_free(v.pFrame);
avcodec_close(v.pCodecCtx);
avformat_close_input(&(v.inc));
if(v.inc != NULL) avformat_free_context(v.inc);
v.inc = NULL;
v.iformat = NULL;
v.pCodecCtx = NULL;
v.pCodec = NULL;
v.pFrame = NULL;
v.videoStream=-1;}
sws init_swsctx(int width, int height, enum AVPixelFormat pix_fmt, int new_width, int new_height, enum AVPixelFormat new_pxf){
int nwidth, nheight;
sws scale;
scale.buffer = (uint8_t **) malloc(4 * sizeof(uint8_t *));
scale.linesize = (int *) malloc(4 * sizeof(int));
nwidth = (new_width <= 0) ? width : new_width;
nheight = (new_height <= 0) ? height : new_height;
av_image_alloc(scale.buffer, scale.linesize, nwidth, nheight, new_pxf, 1);
scale.ctx = sws_getContext(width, height, pix_fmt, nwidth, nheight, new_pxf, SWS_BILINEAR, NULL, NULL, NULL);
if(scale.ctx==NULL){
printf("Could not allocate SWS-Context\n");
av_freep(&(scale.buffer)[0]);
free(scale.buffer);
free(scale.linesize);
exit(12);
}
return scale;}
void conv_pxlformat(sws scale, uint8_t **src_data, int *src_linesize, int height){
sws_scale(scale.ctx, (const uint8_t **) src_data, src_linesize, 0, height, scale.buffer, scale.linesize);
}
void free_sws(sws inp){
av_freep(&(inp.buffer)[0]);
free(inp.buffer);
free(inp.linesize);
}
sdl_window init_windowBGR24_ffmpg(int width, int height){
sdl_window wow;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Couldn't initialize SDL in function: create_sdl_window(...)\n");
exit(7);}
wow.window = SDL_CreateWindow("SDL_CreateTexture",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
width, height,
SDL_WINDOW_RESIZABLE);
wow.renderer = SDL_CreateRenderer(wow.window, -1, SDL_RENDERER_ACCELERATED);
wow.texture = SDL_CreateTexture(wow.renderer, SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STREAMING, width, height);
wow.width = width;
wow.height = height;
wow.pitch = width * 3; //only true for 3 byte / 24bit packed formats like bgr24
wow.sdl_pxl_frmt = SDL_PIXELFORMAT_BGR24;
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
SDL_SetHint(SDL_HINT_RENDER_VSYNC, "enable");
SDL_RenderSetLogicalSize(wow.renderer, wow.width, wow.height);
return wow;
}
int render_on_texture_update(sdl_window wow, uint8_t *data){
if (SDL_UpdateTexture(wow.texture, NULL, data, wow.pitch)< 0){
printf("SDL_render_on_texture_update_failed: %s\n", SDL_GetError());
return -1;
}
SDL_RenderClear(wow.renderer);
SDL_RenderCopy(wow.renderer, wow.texture, NULL, NULL);
SDL_RenderPresent(wow.renderer);
return 0;
}
void close_window(sdl_window wow){
SDL_DestroyRenderer(wow.renderer);
SDL_Quit();
}
int main(){
int n, vid_error;
long int time_per_frame_usec, duration_usec;
vid v;
sdl_window wow;
struct timeval tval_start, tval_start1, tval_end, tval_duration;
sws scale;
SDL_Event event;
vid_error = AVERROR(EAGAIN);
v = cap_init_fl("mw_maze_test.mp4");
while(vid_error == AVERROR(EAGAIN)){
vid_error =cap(v);}
if(vid_error < 0){
printf("Could not read from Capture\n");
cap_close(v);
return 0;
}
wow = init_windowBGR24_ffmpg((v.pCodecCtx)->width, (v.pCodecCtx)->height);
scale = init_swsctx((v.pCodecCtx)->width, (v.pCodecCtx)->height, (v.pCodecCtx)->pix_fmt, 0, 0, AV_PIX_FMT_BGR24);
time_per_frame_usec = ((long int)((v.inc)->streams[v.videoStream]->avg_frame_rate.den) * 1000000 / (long int) ((v.inc)->streams[v.videoStream]->avg_frame_rate.num));
printf("Time per frame: %ld\n", time_per_frame_usec);
n = 0;
gettimeofday(&tval_start, NULL);
gettimeofday(&tval_start1, NULL);
while ((vid_error =cap(v)) >= 0) {
if (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT)
break;}
conv_pxlformat(scale, (v.pFrame)->data, (v.pFrame)->linesize, (v.pCodecCtx)->height);
gettimeofday(&tval_end, NULL);
timersub(&tval_end, &tval_start, &tval_duration);
duration_usec = (long int)tval_duration.tv_sec * 1000000 + (long int)tval_duration.tv_usec;
while(duration_usec < time_per_frame_usec) {
gettimeofday(&tval_end, NULL);
timersub(&tval_end, &tval_start, &tval_duration);
duration_usec = (long int)tval_duration.tv_sec * 1000000 + (long int)tval_duration.tv_usec;
}
gettimeofday(&tval_start, NULL);
render_on_texture_update(wow, *(scale.buffer));
n++;
}
gettimeofday(&tval_end, NULL);
timersub(&tval_end, &tval_start1, &tval_duration);
duration_usec = (long int)tval_duration.tv_sec * 1000000 + (long int)tval_duration.tv_usec;
printf("Total time and frames; %ld %i\n", duration_usec, n);
if(vid_error == AVERROR(EAGAIN)){
printf("AVERROR(EAGAIN) occured\n)");
}
sws_freeContext(scale.ctx);
free_sws(scale);
close_window(wow);
cap_close(v);
return 0;
}
the output is:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'mw_maze_test.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2014-02-14T21:09:52.000000Z
Duration: 00:01:32.90, start: 0.000000, bitrate: 347 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 384x288 [SAR 1:1 DAR 4:3], 249 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 96 kb/s (default)
Metadata:
creation_time : 2014-02-14T21:09:53.000000Z
handler_name : IsoMedia File Produced by Google, 5-11-2011
Time per frame: 40000
Total time and frames; 252881576 6322
最佳答案
发布后一分钟就想通了。问题是 (int cap(vid v))
当帧不是视频帧(因此是音频帧)时返回 1。每次从 cap >= 0
返回时,main 中的 while 循环都会运行。因此对于音频帧也是如此,因此需要将主循环更改为仅在从视频帧返回时运行:
while ((vid_error =cap(v)) >= 0) {
if(vid_error == 0){
// code as before
}}...
关于c - 使用 ffmpeg 和 sdl2 进行口吃渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65406881/
问题解决了 转到底部查看解决方案。 大家好,我用谷歌搜索了很长时间,但没有找到任何东西,所以,我们开始吧: 我有这样的设置: Compiler: MinGW IDE: Netbeans Library
如何在 SDL 中创建一个插入主窗口的新窗口?所以它可以是有重点的,有单独的绘图上下文和单独的处理事件。 最佳答案 窗中窗 您可以使用下面的示例在窗口中创建一个窗口。该示例将生成两个窗口,其中 sub
我是 SDL 的新手,我只是好奇为什么 sdl 使用静态和动态库?我的意思是,sdl.dll 中有哪些函数,为什么它是动态链接而不是静态链接?谢谢。 最佳答案 SDL.dll包含您在 SDL 中使用的
我通过 brew 在我的 mac 上安装了 SDL,但我无法包含它!这是我太简单的代码: #include int main(){ return 0; } 用cc编译时,CC找不到SDL.h
我正在尝试制作一个以恒定帧速率运行的 SDL 程序。但是我发现即使我的程序滞后很多并且跳过了很多帧(即使它以低帧运行并且没有渲染太多)。 你们有什么建议可以让我的程序运行更流畅吗? #include
我目前正在编写一款非常复杂和狡猾的游戏,它会让您充满敬畏和胜利 - 哦,好吧,这是 15 个谜题,我只是在熟悉 SDL。 我在窗口模式下运行,并使用 SDL_Flip 作为一般情况的页面更新,因为它会
我知道 SDL_TEXTUREACCESS_STATIC 和 SDL_TEXTUREACCESS_TARGET 之间的区别。我正在为一款游戏编写 SDL 后端,该游戏的平台无关核心不会告诉平台相关纹理
我们最近移植了 Bitfighter从 GLUT 到 SDL。这样做有很多好处,但也有一些缺点,特别是在窗口管理领域。 Bitfighter 在固定纵横比窗口(800x600 像素)中运行。用户可以将
我正在尝试使用 SDL 2.0 了解整个 2D 加速渲染过程。 所以我的问题是在屏幕上绘制圆圈最有效的方法是什么,为什么? 一些方法是: 首先创建一个软件表面,然后在该表面上绘制必要的像素,然后从该表
我正在尝试将纹理保存到 png 中,而我唯一得到的是 是屏幕的一部分的屏幕截图。 我的代码示例: src_texture = SDL_CreateTextureFromSurface( render
我正在使用 SDL1.2 在我的 openGL 框架中处理窗口管理。 程序运行时是否可以在不调用 SDL_Quit() 的情况下破坏窗口(表面)? ? 背景:我的框架实际上只是多媒体环境中的一个 gf
如何在 SDL 中缩放 Sprite ? 最佳答案 SDL 不直接提供缩放功能,但有 an additional library called SDL_gfx它提供旋转和缩放功能。还有another
我刚刚开始使用SDL2_ttf。我已经弄清楚如何使用 TTF_RenderText_Blished 在屏幕上获取一些文本,但是如何让它进行换行和自动换行? 似乎不支持\n;它只是创造一个空间而不是沿着
我安装了 FEDORA 和 SDL,并希望在编译时用 C 编程图形,我得到了很多对 SDL_MapRGB、SDL_Init 等的 undefined reference 我搜索了文件系统 SDL.dl
我在我的项目中使用 SDL 库,并且在 Windows 平台上工作。 当我决定将项目迁移到 SDL 2 时,我遇到了一个问题: SDL 1.2 中有一个选项可以将 stdout/stderr 的输出打
我正在尝试使用 Derelict 和 D 编写一个简单的图形测试程序。 当我尝试用 SDL 做几乎任何事情时,它都会出现段错误。这是有问题的代码: import std.stdio; import
我在考虑是否尝试使用 SDL 作为 DirectX 的替代品,似乎我只创建 2D 游戏,但是我找不到任何地方是否需要在最终用户计算机上安装 SDL 才能玩用 C# 开发的游戏,图形使用 SDL。 有人
我想使用 SDL_net 作为一个供少数程序使用的帮助程序库。然而,其中一些程序本身可能已经在使用 SDL。如果我理解正确的话,这意味着我在初始化/释放我的库时不能盲目使用 SDL_Init 和 SD
我希望我的游戏引擎停止将鼠标移动到中心(用于偏航和俯仰相机计算)。我写了一些应该处理它的代码,但鼠标在最小化时仍然移动。 void mainLoop() { // This is the ma
结构SDL_Keysym 有SDL_Scancode 和SDL_Keycode 成员。它们之间有什么区别?该文档并没有真正为我清除它。我都试过了,它们似乎做同样的事情。 最佳答案 参见 the SDL
我是一名优秀的程序员,十分优秀!