- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
Windows 10 x64,ffmpeg: 3.1, 预建 dll
这里绝对是新手。
我正在尝试一个非常基本的案例来解码视频文件中的帧,但每次尝试都失败了。最终的代码片段如下所示:
#define __STDC_CONSTANT_MACROS
extern "C" {
#include<libavutil/avutil.h>
#include<libavutil/imgutils.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}
#include <iostream>
int main(int argc, char **argv) {
AVFormatContext* ctx_format = nullptr;
AVCodecContext* ctx_codec = nullptr;
AVCodec* codec = nullptr;
AVFrame* frame = av_frame_alloc();
int stream_idx;
SwsContext* ctx_sws = nullptr;
const char* fin = argv[1];
AVStream *vid_stream = nullptr;
AVPacket* pkt = av_packet_alloc();
av_register_all();
if (int ret = avformat_open_input(&ctx_format, fin, nullptr, nullptr) != 0) {
std::cout << 1 << std::endl;
return ret;
}
if (avformat_find_stream_info(ctx_format, nullptr) < 0) {
std::cout << 2 << std::endl;
return -1; // Couldn't find stream information
}
av_dump_format(ctx_format, 0, fin, false);
for (int i = 0; i < ctx_format->nb_streams; i++)
if (ctx_format->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
stream_idx = i;
vid_stream = ctx_format->streams[i];
break;
}
if (vid_stream == nullptr) {
std::cout << 4 << std::endl;
return -1;
}
codec = avcodec_find_decoder(vid_stream->codecpar->codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
ctx_codec = avcodec_alloc_context3(codec);
if(avcodec_parameters_to_context(ctx_codec, vid_stream->codecpar)<0)
std::cout << 512;
if (avcodec_open2(ctx_codec, codec, nullptr)<0) {
std::cout << 5;
return -1;
}
//av_new_packet(pkt, pic_size);
while(av_read_frame(ctx_format, pkt) >= 0){
int ret = avcodec_send_packet(ctx_codec, pkt);
if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
std::cout << "avcodec_send_packet: " << ret << std::endl;
break;
}
if (pkt->stream_index == stream_idx) {
while (ret >= 0) {
ret = avcodec_receive_frame(ctx_codec, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
//std::cout << "avcodec_receive_frame: " << ret << std::endl;
break;
}
std::cout << "frame: " << ctx_codec->frame_number << std::endl;
}
}
av_packet_unref(pkt);
}
avformat_close_input(&ctx_format);
av_packet_unref(pkt);
avcodec_free_context(&ctx_codec);
avformat_free_context(ctx_format);
return 0;
}
它基本上保留所有默认值,并尝试从中读取数据包和解码帧。 avcodec_send_packet
在 while 循环的第一轮或第二轮调用中总是返回负值。
flv 的输出:
> .\streamer_test.exe .\SampleVideo_360x240_5mb.flv
Input #0, flv, from '.\SampleVideo_360x240_5mb.flv':
Metadata:
encoder : Lavf53.24.2
Duration: 00:00:53.32, start: 0.000000, bitrate: 787 kb/s
Stream #0:0: Audio: aac (LC), 48000 Hz, 5.1, fltp, 384 kb/s
Stream #0:1: Video: flv1, yuv420p, 320x240, 500 kb/s, 1k fps, 25 tbr, 1k tbn
frame: 1
[flv @ 000001545edb66c0] Bad picture start code
[flv @ 000001545edb66c0] header damaged
avcodec_send_packet: -1094995529
mp4 输出:
> .\streamer_test.exe .\SampleVideo_360x240_10mb.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\SampleVideo_360x240_10mb.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
creation_time : 1970-01-01T00:00:00.000000Z
encoder : Lavf53.24.2
Duration: 00:02:05.95, start: 0.000000, bitrate: 669 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 282 kb/s, 15 fps, 15 t
br, 15360 tbn, 30 tbc (default)
Metadata:
creation_time : 1970-01-01T00:00:00.000000Z
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 5.1, fltp, 383 kb/s (default)
Metadata:
creation_time : 1970-01-01T00:00:00.000000Z
handler_name : SoundHandler
[h264 @ 000002e2446a6cc0] Invalid NAL unit size (17191968 > 1007).
[h264 @ 000002e2446a6cc0] Error splitting the input into NAL units.
avcodec_send_packet: -1094995529
mkv 的输出:
> .\streamer_test.exe .\SampleVideo_1280x720_2mb.mkv
Input #0, matroska,webm, from '.\SampleVideo_1280x720_2mb.mkv':
Metadata:
ENCODER : Lavf53.24.2
Duration: 00:00:10.65, bitrate: 1575 kb/s
Stream #0:0: Video: mpeg4 (Simple Profile), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1k tbn, 25 tbc (de
fault)
Stream #0:1: Audio: aac (LC), 48000 Hz, 5.1, fltp (default)
frame: 1
[mpeg4 @ 000001166798ede0] header damaged
avcodec_send_packet: -1
所以我猜 avcodec_send_packet
调用一定有问题,但无法弄清楚缺少什么。关于原因的任何想法?非常感谢您的帮助!
最佳答案
调用av_read_frame
会返回音频/视频流,你需要用不同的AVCodecContext
来处理它们。
因为你用avcodec_send_packet
发送音频流,但是你的 AVCodecContext
用于视频流,你得到了错误。
看来你只对视频流感兴趣。
更改您的代码
while(av_read_frame(ctx_format, pkt) >= 0){
int ret = avcodec_send_packet(ctx_codec, pkt);
if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
std::cout << "avcodec_send_packet: " << ret << std::endl;
break;
}
if (pkt->stream_index == stream_idx) {
while (ret >= 0) {
ret = avcodec_receive_frame(ctx_codec, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
//std::cout << "avcodec_receive_frame: " << ret << std::endl;
break;
}
std::cout << "frame: " << ctx_codec->frame_number << std::endl;
}
}
av_packet_unref(pkt);
}
以下内容将起作用。
while(av_read_frame(ctx_format, pkt) >= 0){
if (pkt->stream_index == stream_idx) {
int ret = avcodec_send_packet(ctx_codec, pkt);
if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
std::cout << "avcodec_send_packet: " << ret << std::endl;
break;
}
while (ret >= 0) {
ret = avcodec_receive_frame(ctx_codec, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
//std::cout << "avcodec_receive_frame: " << ret << std::endl;
break;
}
std::cout << "frame: " << ctx_codec->frame_number << std::endl;
}
}
av_packet_unref(pkt);
}
使用ffmpeg解码时,记得针对不同的流成对调用avcodec_send_packet/avcodec_receive_frame
关于c++ - ffmpeg 调用 avcodec_send_packet 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44711921/
为了让我的代码几乎完全用 Jquery 编写,我想用 Jquery 重写 AJAX 调用。 这是从网页到 Tomcat servlet 的调用。 我目前情况的类似代码: var http = new
我想使用 JNI 从 Java 调用 C 函数。在 C 函数中,我想创建一个 JVM 并调用一些 Java 对象。当我尝试创建 JVM 时,JNI_CreateJavaVM 返回 -1。 所以,我想知
环顾四周,我发现从 HTML 调用 Javascript 函数的最佳方法是将函数本身放在 HTML 中,而不是外部 Javascript 文件。所以我一直在网上四处寻找,找到了一些简短的教程,我可以根
我有这个组件: import {Component} from 'angular2/core'; import {UserServices} from '../services/UserService
我正在尝试用 C 实现一个简单的 OpenSSL 客户端/服务器模型,并且对 BIO_* 调用的使用感到好奇,与原始 SSL_* 调用相比,它允许一些不错的功能。 我对此比较陌生,所以我可能会完全错误
我正在处理有关异步调用的难题: 一个 JQuery 函数在用户点击时执行,然后调用一个 php 文件来检查用户输入是否与数据库中已有的信息重叠。如果是这样,则应提示用户确认是否要继续或取消,如果他单击
我有以下类(class)。 public Task { public static Task getInstance(String taskName) { return new
嘿,我正在构建一个小游戏,我正在通过制作一个数字 vector 来创建关卡,该数字 vector 通过枚举与 1-4 种颜色相关联。问题是循环(在 Simon::loadChallenge 中)我将颜
我有一个java spring boot api(数据接收器),客户端调用它来保存一些数据。一旦我完成了数据的持久化,我想进行另一个 api 调用(应该处理持久化的数据 - 数据聚合器),它应该自行异
首先,这涉及桌面应用程序而不是 ASP .Net 应用程序。 我已经为我的项目添加了一个 Web 引用,并构建了各种数据对象,例如 PayerInfo、Address 和 CreditCard。但问题
我如何告诉 FAKE 编译 .fs文件使用 fsc ? 解释如何传递参数的奖励积分,如 -a和 -target:dll . 编辑:我应该澄清一下,我正在尝试在没有 MSBuild/xbuild/.sl
我使用下划线模板配置了一个简单的主干模型和 View 。两个单独的 API 使用完全相同的配置。 API 1 按预期工作。 要重现该问题,请注释掉 API 1 的 URL,并取消注释 API 2 的
我不确定什么是更好的做法或更现实的做法。我希望从头开始创建目录系统,但不确定最佳方法是什么。 我想我在需要显示信息时使用对象,例如 info.php?id=100。有这样的代码用于显示 Game.cl
from datetime import timedelta class A: def __abs__(self): return -self class B1(A):
我在操作此生命游戏示例代码中的数组时遇到问题。 情况: “生命游戏”是约翰·康威发明的一种细胞自动化技术。它由一个细胞网格组成,这些细胞可以根据数学规则生存/死亡/繁殖。该网格中的活细胞和死细胞通过
如果我像这样调用 read() 来读取文件: unsigned char buf[512]; memset(buf, 0, sizeof(unsigned char) * 512); int fd;
我用 C 编写了一个简单的服务器,并希望调用它的功能与调用其他 C 守护程序的功能相同(例如使用 ./ftpd start 调用它并使用 ./ftpd stop 关闭该实例)。显然我遇到的问题是我不知
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
我希望能够从 cmd 在我的 Windows 10 计算机上调用 python3。 我已重新安装 Python3.7 以确保选择“添加到路径”选项,但仍无法调用 python3 并使 CMD 启动 P
我是一名优秀的程序员,十分优秀!