从avi转换为mp4(x264)时,我遇到了fps问题.最终问题出现在PTS和DTS值中,因此第12-15行在av_interleaved_write_frame函数之前添加:
1. AVFormatContext* outContainer = NULL;
2. avformat_alloc_output_context2(&outContainer, NULL, "mp4", "c:\\test.mp4";
3. AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
4. AVStream *outStream = avformat_new_stream(outContainer, encoder);
5. // outStream->codec initiation
6. // ...
7. avformat_write_header(outContainer, NULL);
8. // reading and decoding packet
9. // ...
10. avcodec_encode_video2(outStream->codec, &encodedPacket, decodedFrame, &got_frame)
11.
12. if (encodedPacket.pts != AV_NOPTS_VALUE)
13. encodedPacket.pts = av_rescale_q(encodedPacket.pts, outStream->codec->time_base, outStream->time_base);
14. if (encodedPacket.dts != AV_NOPTS_VALUE)
15. encodedPacket.dts = av_rescale_q(encodedPacket.dts, outStream->codec->time_base, outStream->time_base);
16.
17. av_interleaved_write_frame(outContainer, &encodedPacket)
Run Code Online (Sandbox Code Playgroud)
看完很多帖后我还是不明白:
outStream->codec->time_base
= 1/25和outStream->time_base
= 1/12800.第一个由我设定,但我无法弄清楚为什么和谁设置12800?我注意到在行(7) …我正在编写一个视频解码器(使用FFMPEG/AVCodec)来自定义实现mpeg4视频流.这个视频流的特点是它可以分成许多"子"流,根据同一个父节点创建许多P帧.我正在尝试解码的视频流实际上是一种"视频树".像这样的东西:
I <--P <--P <---------------------P <-------------- P <------------ P
\ <--P <--P <--P \ <--P <--P \ <--P <--P
Run Code Online (Sandbox Code Playgroud)
我已经写了一个基本的解码器,当我决定遵循一条路径时工作正常,问题是当我尝试在视频树中跟随多个路径时.此时我需要"解析"我的解码器以跟随两个不同的视频流.拆分不仅可能发生在关键帧之后,甚至在P帧之后,所以我需要复制AVCodecContext(我使用avcodec_copy_context
)但它似乎从干净的状态创建新的解码器..它似乎忽略了以前的视频状态因此,解码的P帧被"应用"到空视频帧.可能复制上下文使用avcodec_copy_context
是不够的...任何建议?如何复制上下文和解码器的完整状态?或者,有没有其他方法使用引用解码我的流?谢谢!
我正在尝试使用libavcodec将视频编码为H264
ffmpeg::avcodec_encode_video(codec,output,size,avframe);
返回错误,我没有正确设置avframe-> pts值.
我已经尝试将其设置为0,1,AV_NOPTS_VALUE和90khz*framenumber但仍然得到错误non-strictly-monotonic PTS
ffmpeg.c示例使用ffmpeg :: av_rescale_q()设置packet.pts,但只有在对帧进行编码后才会调用它!
当与MP4V编解码器一起使用时,avcodec_encode_video()会自行正确设置pts值.
我正在使用 ffmpeg 库对 MPEG 传输流中的视频进行解码、缩放和重新编码。我刚刚从源代码重新编译到 v3.3.2,并从旧的 avcodec_decode_video2() API 更改为新的发送/接收 API。
旧的和新的 API 都非常缓慢地解码视频。
25 fps 视频 = 每 40 毫秒 1 帧。但是,我看到每帧要解码 70 到 120 毫秒。这是一个文件翻译器,因此需要它比实时运行得更快。
代码大纲如下。有人对如何提高解码速度有任何想法吗?还有其他关于弃用avcodec_decode_video2()
缓慢的帖子;这些都没有得到解决。新的 API 没有运行得更快...
gettimeofday(&tv1, NULL);
int rc = av_read_frame(pFormatContext, pESPacket);
gettimeofday(&tv2, NULL);
int ret = avcodec_send_packet(pDecoderContext, pESPacket);
if (ret < 0)
continue;
ret = avcodec_receive_frame(pDecoderContext, pFrameDec);
if (ret != 0)
{
printf("avcodec_receive_frame error: %d\n", ret);
continue;
}
gettimeofday(&tv3, 0);
u_long twoMinusOne = (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - …
Run Code Online (Sandbox Code Playgroud) 我正在尝试优化一个用于播放视频的软件,该软件内部使用 FFmpeg 库进行解码。我们发现,在某些大型(4K、60fps)视频中,有时解码帧所需的时间比该帧应显示的时间要长;遗憾的是,由于问题域的原因,简单地缓冲/跳过帧不是一种选择。
然而,FFmpeg 可执行文件似乎能够以大约 2 倍的速度很好地解码有问题的视频,因此我一直在努力找出我们做错了什么。
我已经编写了一个非常精简的解码器程序用于测试;源码在这里(大约200行)。从分析来看,解码过程中的一个主要瓶颈似乎是函数avcodec_send_packet()
,每次调用最多可能需要 50 毫秒。然而,在 FFmpeg 中测量相同的调用会显示出奇怪的行为:
(这些是解码 4K 25fps VP9 编码视频时每次调用 avcodec_send_packet() 所需的时间(以毫秒为单位)。)
基本上,当 FFmpeg 使用此函数时,似乎只需要任意时间即可完成每 N 个调用,其中 N 是用于解码的线程数。然而,我的测试解码器和实际产品都使用4个线程进行解码,并且不会发生这种情况;当使用基于帧的线程时,测试解码器的行为类似于仅使用 1 个线程的 FFmpeg。这似乎表明我们根本没有使用多线程,但通过使用更多线程我们仍然看到了性能的改进。
FFmpeg 的结果平均起来大约是我们解码器的两倍,所以显然我们做错了一些事情。我一直在阅读 FFmpeg 的源代码,试图找到任何线索,但到目前为止我还没有找到任何线索。
我的问题是:FFmpeg 在这里做什么而我们没有做什么?或者,我们如何提高解码器的性能?
任何帮助是极大的赞赏。
我正在构建一个Android应用程序,它将编码从相机预览中捕获的图像,然后对其进行解码.我正在使用ffmpeg库进行编码和解码.要使用x264构建静态库,我已经使用了本教程.http://dl.dropbox.com/u/22605641/ffmpeg_android/main.html.作为ffmpeg的源代码,如果我使用从教程中给出的链接下载的那个,我可以构建它但是如果我使用从这里下载的源代码git clone git://source.ffmpeg.org/ffmpeg则无法构建库. git ffmpeg.我在ubuntu中构建了库,并在Eclipse的Windows 7中使用它.由于我只需要h264编码器和解码器,我使用了以下ffmpeg代码,稍微修改了一下教程.
#!/bin/bash
NDK=~/Documents/android-ndk-r8e
PLATFORM=$NDK/platforms/android-8/arch-arm
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
PREFIX=/home/android-ffmpeg
function build_one
{
./configure --target-os=linux --prefix=$PREFIX \
--enable-cross-compile \
--enable-runtime-cpudetect \
--disable-asm \
--arch=arm \
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
--disable-stripping \
--nm=$PREBUILT/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--enable-nonfree \
--enable-version3 \
--disable-everything \
--enable-gpl \
--disable-doc \
--enable-avresample \
--disable-ffplay \
--disable-ffserver \
--enable-ffmpeg \
--disable-ffprobe \
--enable-avcodec \
--enable-libx264 \
--enable-encoder=libx264 \
--enable-encoder=libx264rgb \
--enable-decoder=h263 \
--enable-decoder=h264 \
--enable-decoder=svq3 \
--enable-zlib \
--enable-gpl \
--enable-pic \
--disable-devices \ …
Run Code Online (Sandbox Code Playgroud) 我正在编写用于将实时音频和视频从webcamera流式传输到rtmp-server的程序.我在MacOS X 10.8中工作,因此我使用AVFoundation框架从输入设备获取音频和视频帧.这个框架进入代表:
-(void) captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer: (CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
,
其中sampleBuffer
包含音频或视频数据.
当我收到音频数据时sampleBuffer
,我试图将这些数据转换为libavcodec AVFrame
并用其编码AVFrame
:
aframe = avcodec_alloc_frame(); //AVFrame *aframe;
int got_packet, ret;
CMItemCount numSamples = CMSampleBufferGetNumSamples(sampleBuffer); //CMSampleBufferRef
NSUInteger channelIndex = 0;
CMBlockBufferRef audioBlockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
size_t audioBlockBufferOffset = (channelIndex * numSamples * sizeof(SInt16));
size_t lengthAtOffset = 0;
size_t totalLength = 0;
SInt16 *samples = NULL;
CMBlockBufferGetDataPointer(audioBlockBuffer, audioBlockBufferOffset, &lengthAtOffset, &totalLength, (char **)(&samples));
const AudioStreamBasicDescription *audioDescription = CMAudioFormatDescriptionGetStreamBasicDescription(CMSampleBufferGetFormatDescription(sampleBuffer));
aframe->nb_samples =(int) numSamples;
aframe->channels=audioDescription->mChannelsPerFrame;
aframe->sample_rate=(int)audioDescription->mSampleRate;
//my webCamera configured to …
Run Code Online (Sandbox Code Playgroud) 当我使用mpeg4或h264编码器时,我能够使用ffmpeg 3.1.0的API成功编码图像以生成有效的AVI文件.但是,当我使用快速同步编码器(h264_qsv)时,avcodec_encode_video2会在某些时候挂起.我发现当使用1920x1080的图像时,avcodec_encode_video2很少会挂起.使用256x256图像时,该功能很可能会挂起.
我在下面创建了测试代码,演示了avcodec_encode_video2的挂起.代码将创建一个1000帧,256x256 AVI,比特率为400000.帧被简单分配,因此输出视频应该只是绿色帧.
使用Windows 7和Windows 10,使用32位或64位测试应用程序观察到该问题.
如果有人知道如何避免avcodec_encode_video2挂起,我将非常感激!在此先感谢您的任何帮助.
extern "C"
{
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "avcodec.h"
#include "avformat.h"
#include "swscale.h"
#include "avutil.h"
#include "imgutils.h"
#include "opt.h"
#include <rational.h>
}
#include <iostream>
// Globals
AVCodec* m_pCodec = NULL;
AVStream *m_pStream = NULL;
AVOutputFormat* m_pFormat = NULL;
AVFormatContext* m_pFormatContext = NULL;
AVCodecContext* m_pCodecContext = NULL;
AVFrame* m_pFrame = NULL;
int m_frameIndex;
// Output format
AVPixelFormat m_pixType = AV_PIX_FMT_NV12;
// Use for mpeg4
//AVPixelFormat m_pixType = AV_PIX_FMT_YUV420P;
// Output frame rate …
Run Code Online (Sandbox Code Playgroud) 我想从图像创建一个视频,我的代码是
avconv -f image2 -i test2.jpg -s 320X240 -r 30 -pix_fmt yuv420p -qmin 10 foo.mpg
Run Code Online (Sandbox Code Playgroud)
但是我收到了一个错误
VBV buffer size not set, muxing may fail
Run Code Online (Sandbox Code Playgroud)
我怎么解决这个问题?