我正在尝试使用 FFmpeg 库编写视频。到目前为止,我可以成功地使用 .avi 扩展名对视频进行编码,但是当我使用 .mp4 扩展名时,应用程序完全忽略我指定的比特率选项。
这是我用来指定编码设置的代码片段:
//define video stream
AVOutputFormat* outFmt = nullptr;
outFmt = av_guess_format(NULL, m_pcFilename.c_str(), NULL);
avformat_alloc_output_context2(&m_pcOC, outFmt, NULL, NULL);
AVFormatContext* m_pcOC;
AVStream* m_pcVideoSt = avformat_new_stream(m_pcOC, NULL);
AVCodec* codec = nullptr;
codec = avcodec_find_encoder(codecID);
avcodec_get_context_defaults3(m_pcVideoSt->codec, codec);
//set some parameters
double dBitrate = std::stod(bitrate);
m_pcVideoSt->codec->codec_id = codecID;
m_pcVideoSt->codec->codec_type = AVMEDIA_TYPE_VIDEO;
m_pcVideoSt->codec->bit_rate = dBitrate;
m_pcVideoSt->codec->bit_rate_tolerance = 20000;
m_pcVideoSt->codec->width = m_iOutCols;
m_pcVideoSt->codec->height = m_iOutRows;
m_pcVideoSt->codec->time_base.den = static_cast<int>(dFps);
m_pcVideoSt->codec->time_base.num = 1;
if (m_pcOC->oformat->flags & AVFMT_GLOBALHEADER)
{
m_pcVideoSt->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
} …Run Code Online (Sandbox Code Playgroud) 我有一个原始图像缓冲区(在内存中)从我想要转换为JPEG(用于减小大小)的相机捕获.问题是将这些图像保存为.pgm格式会导致我无法承受的巨大文件大小,因为保存这个大小的大文件所涉及的内存限制和延迟(我正在处理的应用程序中的约束) .
我想知道如何使用LIBAVCODEC将图像缓冲区压缩/编码为.jpg格式?我的图像捕获代码在C中.
我想提取视频文件的信息以获得其I/P/B帧的计数.如何在ffmpeg中做到这一点?或者我应该使用libavformat和libavcodec进行编程吗?非常感谢!
libavcodec文档对于何时释放已分配的数据以及如何释放它并不十分具体.阅读完文档和示例后,我将下面的示例程序放在一起.在源代码中有一些特定的问题,但我的一般问题是,我是否在下面的代码中正确释放所有内存?我意识到下面的程序在发生错误后没有进行任何清理 - 重点是最终清理.
testfile()函数是有问题的.
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
}
#include <cstdio>
using namespace std;
void AVFAIL (int code, const char *what) {
char msg[500];
av_strerror(code, msg, sizeof(msg));
fprintf(stderr, "failed: %s\nerror: %s\n", what, msg);
exit(2);
}
#define AVCHECK(f) do { int e = (f); if (e < 0) AVFAIL(e, #f); } while (0)
#define AVCHECKPTR(p,f) do { p = (f); if (!p) AVFAIL(AVERROR_UNKNOWN, #f); } while (0)
void testfile (const char *filename) {
AVFormatContext *format;
unsigned …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个方法,在查询时提供下一帧和显示时间戳.代码目前看起来像这样:
while( getNextFrame(image, pts) )
{
// show current image
drawImage(currentImage);
sleep(pts);
currentImage = image;
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我一直在关注Dranger教程,但是为了可靠地获取帧的PTS值而停滞不前(http://www.dranger.com/ffmpeg/tutorial05.html).返回的PTS值始终为0.
此外,get_buffer()已被弃用,所以我现在使用该get_buffer2()方法设置全局pts值.但是,该release_buffer方法也已被弃用,我似乎无法找到它的替代品.这让我相信教程中列出的方法可能不再是完成此任务的最佳方法.
简而言之,使用最新的ffmpeg,可靠地获取帧pts值的最佳方法是什么?
我可以从相机获得原始h.264帧.(它不包含任何网络标头,例如rtsp,http).它们是h.264原始数据.我将这些数据逐帧推送到队列中.我用Google搜索了许多ffmpeg示例,该示例将avformat_open_input()与本地文件路径或网络路径一起使用.当我将帧保存到文件并使用avformat_open_input()时,我可以看到视频.
我的问题是我想要实时解码帧,而不是将其保存为文件.有没有人对此有任何想法?
谢谢!
我正在考虑重新混合一些保存音频和视频的容器,以便提取最好的第一个音频流,并将其存储在一个新容器中,例如仅存在音频流。
\n\nFFmpeg 的输出上下文是这样创建的:
\n\nAVFormatContext* output_context = NULL;\navformat_alloc_output_context2( &output_context, NULL, "mp4", NULL );\nRun Code Online (Sandbox Code Playgroud)\n\n我有一个可接受的输出的候选列表,例如 MP4、M4A 等 \xe2\x80\xa6 基本上是 Apple 的音频文件服务可读的输出:
\n\nkAudioFileAIFFType = \'AIFF\',\nkAudioFileAIFCType = \'AIFC\',\nkAudioFileWAVEType = \'WAVE\',\nkAudioFileSoundDesigner2Type = \'Sd2f\',\nkAudioFileNextType = \'NeXT\',\nkAudioFileMP3Type = \'MPG3\', // mpeg layer 3\nkAudioFileMP2Type = \'MPG2\', // mpeg layer 2\nkAudioFileMP1Type = \'MPG1\', // mpeg layer 1\nkAudioFileAC3Type = \'ac-3\',\nkAudioFileAAC_ADTSType = \'adts\',\nkAudioFileMPEG4Type = \'mp4f\',\nkAudioFileM4AType = \'m4af\',\nkAudioFileM4BType = \'m4bf\',\nkAudioFileCAFType = \'caff\',\nkAudioFile3GPType = \'3gpp\',\nkAudioFile3GP2Type = \'3gp2\',\nkAudioFileAMRType = \'amrf\'\nRun Code Online (Sandbox Code Playgroud)\n\n我的问题是:FFmpeg 中是否有一个简单的 API,可以根据音频流所在的编解码器来选择兼容的输出容器?
\n我有一个使用 libavcodec (ffmpeg) 的项目。我正在使用它以 4:2:2 Profile, Main Level 对 MPEG-2 视频进行编码。我在 AVCodecContext 中选择了像素格式 PIX_FMT_YUV422P,但是我得到的视频输出的所有颜色都是错误的,在我看来,编码器错误地读取缓冲区,好像它认为它是 4:2:0 色度而不是比 4:2:2。这是我的编解码器设置:
//
// AVFormatContext* _avFormatContext previously defined as mpeg2video
//
//
// Set up the video stream for output
//
AVVideoStream* _avVideoStream = av_new_stream(_avFormatContext, 0);
if (!_avVideoStream)
{
err = ccErrWFFFmpegUnableToAllocateStream;
goto bail;
}
_avCodecContext = _avVideoStream->codec;
_avCodecContext->codec_id = CODEC_ID_MPEG2VIDEO;
_avCodecContext->codec_type = CODEC_TYPE_VIDEO;
//
// Set up required parameters
//
_avCodecContext->rc_max_rate = _avCodecContext->rc_min_rate = _avCodecContext->bit_rate = src->_avCodecContext->bit_rate;
_avCodecContext->flags = CODEC_FLAG_INTERLACED_DCT;
_avCodecContext->flags2 = CODEC_FLAG2_INTRA_VLC | …Run Code Online (Sandbox Code Playgroud) 我正在尝试将多个文件中的所有流复制到一个文件中,而无需对流进行转码。你通常用ffmpeg效用做的事情ffmpeg -i “file_with_audio.mp4” -i “file_with_video.mp4” -c copy -shortest file_with_audio_and_video.mp4
这是代码:
int ffmpegOpenInputFile(const char* filename, AVFormatContext **ic) {
int ret;
unsigned int i;
*ic = avformat_alloc_context();
if (!(*ic))
return -1; // Couldn't allocate input context
if((ret = avformat_open_input(ic, filename, NULL, NULL)) < 0)
return ret; // Couldn't open file
// Get format info (retrieve stream information)
if ((ret = avformat_find_stream_info(*ic, NULL)) < 0)
return ret; // Couldn't find stream information
for (int i = 0; i < (*ic)->nb_streams; …Run Code Online (Sandbox Code Playgroud) 我试图将一个可以采用任意帧并使用ffmpeg 3.3.3 API构建视频的类放在一起.我一直在努力为此找到一个很好的例子,因为示例似乎仍然使用已弃用的函数,所以我试图使用头文件中的文档并通过引用一些似乎正在使用的github repos来修补它新版本.
如果我使用av_interleaved_write_frame将编码数据包写入输出,则ffprobe输出以下内容:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0000000002760120] moov atom not found0
X:\Diagnostics.mp4: Invalid data found when processing input
Run Code Online (Sandbox Code Playgroud)
ffplay无法播放使用此方法生成的文件.
如果我改为将其交换为对avio_write的调用,则ffprobe输出:
Input #0, h264, from 'X:\Diagnostics.mp4':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 672x380 [SAR 1:1 DAR 168:95], 25 fps, 25 tbr, 1200k tbn, 50 tbc
Run Code Online (Sandbox Code Playgroud)
ffplay可以主要播放这个文件,直到它结束,当它输出:
Input #0, h264, from 'X:\Diagnostics.mp4': 0KB sq= 0B f=0/0
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 672x380 [SAR 1:1 DAR 168:95], 25 fps, 25 tbr, …Run Code Online (Sandbox Code Playgroud) ffmpeg ×10
libavcodec ×10
libavformat ×5
libav ×3
video ×3
c ×2
encoding ×2
audio ×1
c++ ×1
compression ×1
h.264 ×1
memory-leaks ×1
mpeg-2 ×1
opencv ×1
pts ×1
x264 ×1