- 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/
我喜欢 smartcase,也喜欢 * 和 # 搜索命令。但我更希望 * 和 # 搜索命令区分大小写,而/和 ?搜索命令遵循 smartcase 启发式。 是否有隐藏在某个地方我还没有找到的设置?我宁
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 10年前关闭。 Improve this qu
从以下网站,我找到了执行java AD身份验证的代码。 http://java2db.com/jndi-ldap-programming/solution-to-sslhandshakeexcepti
似乎 melt 会使用 id 列和堆叠的测量变量 reshape 您的数据框,然后通过转换让您执行聚合。 ddply,从 plyr 包看起来非常相似..你给它一个数据框,几个用于分组的列变量和一个聚合
我的问题是关于 memcached。 Facebook 使用 memcached 作为其结构化数据的缓存,以减少用户的延迟。他们在 Linux 上使用 UDP 优化了 memcached 的性能。 h
在 Camel route ,我正在使用 exec 组件通过 grep 进行 curl ,但使用 ${HOSTNAME} 的 grep 无法正常工作,下面是我的 Camel 路线。请在这方面寻求帮助。
我正在尝试执行相当复杂的查询,在其中我可以排除与特定条件集匹配的项目。这是一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我正在尝试执行相当复杂的查询,我可以在其中排除符合特定条件集的项目。这里有一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我发现了很多嵌入/内容项目的旧方法,并且我遵循了在这里找到的最新方法(我假设):https://blog.angular-university.io/angular-ng-content/ 我正在尝试
我正在寻找如何使用 fastify-nextjs 启动 fastify-cli 的建议 我曾尝试将代码简单地添加到建议的位置,但它不起作用。 'use strict' const path = req
我正在尝试将振幅 js 与 React 和 Gatsby 集成。做 gatsby developer 时一切看起来都不错,因为它发生在浏览器中,但是当我尝试 gatsby build 时,我收到以下错
我试图避免过度执行空值检查,但同时我想在需要使代码健壮的时候进行空值检查。但有时我觉得它开始变得如此防御,因为我没有实现 API。然后我避免了一些空检查,但是当我开始单元测试时,它开始总是等待运行时异
尝试进行包含一些 NOT 的 Kibana 搜索,但获得包含 NOT 的结果,因此猜测我的语法不正确: "chocolate" AND "milk" AND NOT "cow" AND NOT "tr
我正在使用开源代码共享包在 iOS 中进行 facebook 集成,但收到错误“FT_Load_Glyph failed: glyph 65535: error 6”。我在另一台 mac 机器上尝试了
我正在尝试估计一个标准的 tobit 模型,该模型被审查为零。 变量是 因变量 : 幸福 自变量 : 城市(芝加哥,纽约), 性别(男,女), 就业(0=失业,1=就业), 工作类型(失业,蓝色,白色
我有一个像这样的项目布局 样本/ 一种/ 源/ 主要的/ java / java 资源/ .jpg 乙/ 源/ 主要的/ java / B.java 资源/ B.jpg 构建.gradle 设置.gr
如何循环遍历数组中的多个属性以及如何使用map函数将数组中的多个属性显示到网页 import React, { Component } from 'react'; import './App.css'
我有一个 JavaScript 函数,它进行 AJAX 调用以返回一些数据,该调用是在选择列表更改事件上触发的。 我尝试了多种方法来在等待时显示加载程序,因为它当前暂停了选择列表,从客户的 Angul
可能以前问过,但找不到。 我正在用以下形式写很多语句: if (bar.getFoo() != null) { this.foo = bar.getFoo(); } 我想到了三元运算符,但我认
我有一个表单,在将其发送到 PHP 之前我正在执行一些验证 JavaScript,验证后的 JavaScript 函数会发布用户在 中输入的文本。页面底部的标签;然而,此消息显示短暂,然后消失...
我是一名优秀的程序员,十分优秀!