- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
作为一个更大项目的一部分,我正在尝试同时解码多个高清 (1920x1080) 视频流。每个视频流都以原始 yuv420p 格式存储在 AVI 容器中。我有一个 Decoder 类,我从中创建了不同线程中的许多对象(每个线程一个对象)。 Decoder中的两个主要方法是decode()
和 getNextFrame()
,我在下面提供了实现。
当我分离解码逻辑并使用它解码单个流时,一切正常。但是,当我使用多线程代码时,出现段错误并且程序在解码循环的处理代码中崩溃。经过一番调查,我意识到 AVFrame
的数据数组填写getNextFrame()
包含超出范围的地址(根据 gdb)。
我真的迷路了!我没有做任何会改变 AVFrame
内容的事情在我的代码中。我尝试访问 AVFrame 的唯一地方是当我调用 sws_scale()
时转换颜色格式,这就是在第二种情况下由于损坏 AVFrame
而发生段错误的地方。 .非常感谢任何关于为什么会发生这种情况的建议。提前致谢。
decode()
方法:
void decode() {
QString filename("video.avi");
AVFormatContext* container = 0;
if (avformat_open_input(&container, filename.toStdString().c_str(), NULL, NULL) < 0) {
fprintf(stderr, "Could not open %s\n", filename.toStdString().c_str());
exit(1);
}
if (avformat_find_stream_info(container, NULL) < 0) {
fprintf(stderr, "Could not find file info..\n");
}
// find a video stream
int stream_id = -1;
for (unsigned int i = 0; i < container->nb_streams; i++) {
if (container->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
stream_id = i;
break;
}
}
if (stream_id == -1) {
fprintf(stderr, "Could not find a video stream..\n");
}
av_dump_format(container, stream_id, filename.toStdString().c_str(), false);
// find the appropriate codec and open it
AVCodecContext* codec_context = container->streams[stream_id]->codec; // Get a pointer to the codec context for the video stream
AVCodec* codec = avcodec_find_decoder(codec_context->codec_id); // Find the decoder for the video stream
if (codec == NULL) {
fprintf(stderr, "Could not find a suitable codec..\n");
return -1; // Codec not found
}
// Inform the codec that we can handle truncated bitstreams -- i.e.,
// bitstreams where frame boundaries can fall in the middle of packets
if (codec->capabilities & CODEC_CAP_TRUNCATED)
codec_context->flags |= CODEC_FLAG_TRUNCATED;
fprintf(stderr, "Codec: %s\n", codec->name);
// open the codec
int ret = avcodec_open2(codec_context, codec, NULL);
if (ret < 0) {
fprintf(stderr, "Could not open the needed codec.. Error: %d\n", ret);
return -1;
}
// allocate video frame
AVFrame *frame = avcodec_alloc_frame(); // deprecated, should use av_frame_alloc() instead
if (!frame) {
fprintf(stderr, "Could not allocate video frame..\n");
return -1;
}
int frameNumber = 0;
// as long as there are remaining frames in the stream
while (getNextFrame(container, codec_context, stream_id, frame)) {
// Processing logic here...
// AVFrame data array contains three addresses which are out of range
}
// freeing resources
av_free(frame);
avcodec_close(codec_context);
avformat_close_input(&container);
}
getNextFrame()
方法:
bool getNextFrame(AVFormatContext *pFormatCtx,
AVCodecContext *pCodecCtx,
int videoStream,
AVFrame *pFrame) {
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
char buf[1024];
int len;
int got_picture;
AVPacket avpkt;
av_init_packet(&avpkt);
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
// read data from bit stream and store it in the AVPacket object
while(av_read_frame(pFormatCtx, &avpkt) >= 0) {
// check the stream index of the read packet to make sure it is a video stream
if(avpkt.stream_index == videoStream) {
// decode the packet and store the decoded content in the AVFrame object and set the flag if we have a complete decoded picture
avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &avpkt);
// if we have completed decoding an entire picture (frame), return true
if(got_picture) {
av_free_packet(&avpkt);
return true;
}
}
// free the AVPacket object that was allocated by av_read_frame
av_free_packet(&avpkt);
}
return false;
}
锁管理回调函数:
static int lock_call_back(void ** mutex, enum AVLockOp op) {
switch (op) {
case AV_LOCK_CREATE:
*mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
pthread_mutex_init((pthread_mutex_t *)(*mutex), NULL);
break;
case AV_LOCK_OBTAIN:
pthread_mutex_lock((pthread_mutex_t *)(*mutex));
break;
case AV_LOCK_RELEASE:
pthread_mutex_unlock((pthread_mutex_t *)(*mutex));
break;
case AV_LOCK_DESTROY:
pthread_mutex_destroy((pthread_mutex_t *)(*mutex));
free(*mutex);
break;
}
return 0;
}
最佳答案
我找出了问题的原因。就是获取解码帧返回前调用av_free_packet()
。我注释掉了那个电话,程序成功了!我仍然不太确定为什么这会影响填充的 AVFrame
。
我也不确定删除该调用是否会导致我的代码发生内存泄漏。
希望 libavcodec 专家可以阐明这一点并解释我做错了什么。
关于c++ - libavcodec 返回的损坏的 AVFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27702200/
我需要在H.264容器中快速搜索MP4编码的视频流。我使用libav解码帧,因此偶然发现avformat_seek_file()方法。 我的问题是,假设H.264流以关键帧开头,而当我寻求时间戳0(无
我正在尝试解码用 H264 编码的视频。我将 AVPacket 的数据及其大小发送到解码器代码。我正在尝试解码帧并将其显示在 GUI 上。问题是当我解码帧时,它返回的帧字节数与数据包的大小相同,这意味
我想使用 libavcodec对于一个项目,问题是我不明白我应该从哪里获得官方版本,这个库非常受欢迎,我不知道官方网站是什么。 例如有 2 个主要项目,如 libav和 ffmpeg正在使用它,但我找
这是我使用 ffmpeg 的 libav* 解码音频流的过程 [videofile]--> (read audio packets) --> [pkts queue] --> (decoder) --
我有一个用 .3gp h.264 编码的视频,我希望在 C 中获得它的帧率和持续时间。这是我在打开后使用的代码文件并找到合适的编解码器: AVRational rational = gVideoCod
我正在通过 v4l 从相机中抓取视频帧,我需要将它们转码为 mpeg4 格式,以便通过 RTP 连续流式传输它们。 一切实际上都“有效”,但在重新编码时有些东西我没有:输入流产生 15fps,而输出为
我正在学习使用 libavcodec 进行编程。但我卡住了。我使用的所有教程都是视频文件,我需要一个音频文件。我正在使用 Ubuntu。 我应该如何从音频流中读取 AVCodecContext? 顺便
我正在使用 9.7 版的 libavcodec 编写一个简单的演示,几乎与 official example 中的示例完全相同。 . 但是,我无法打开编码器。另外,av_opt_set(context
我按照 Dranger 的教程使用 libav 和 FFMPEG 显示视频。 http://dranger.com/ffmpeg/ avcodec_decode_video2 似乎是视频解码过程中最慢
我正在尝试使用 ffmpeg 库制作一个最简单的应用程序。 这是我的代码: 主.c: #include #include #include int main() { avformat_n
什么AvPixelFormat我应该使用 *.png(PNG-24 和 PNG-8)图像吗? 我正在尝试使用 sws_scale 从 png 转换为 PIX_FMT_YUV420P 编辑,代码: av
我正在尝试使用 FFMpeg 中的 libavcodec 库来解码然后重新编码 h264 视频。 我有解码部分工作(很好地渲染到一个 SDL 窗口)但是当我尝试重新编码帧时,我在重新编码的视频样本中得
我有一个与 ffmpeg 库链接的 C++ 计算机视觉应用程序,该库提供从视频流到分析例程的帧。这个想法可以提供一个中等通用的视频流标识符,并且视频源将被解压缩并逐帧传递给分析例程(运行用户的分析功能
我想改变 gop 动态以适应玩家。较小的 gop 有助于降低首屏成本; Big gop 有助于降低比特率以节省带宽。 我发现nvenc有一个可以解决上述问题的功能。 https://docs.nvid
我想制作一个从 h.264 到 h.265 的转码视频应用程序。 我对 有疑问libavcodec 图书馆。我的项目中有这个库,所有功能都在工作,但是当我尝试设置编解码器时:avcodec_find_
当尝试获取 AVFrame 的时间戳时,有一个名为 best_effort_timestamp 的字段它描述为: frame timestamp estimated using various heu
除了调用 av_register_all(),是否有选择使用单个解码器的示例? 我想我将不得不调用 avcodec_register()、av_register_codec_parser() 等...
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 7年前关闭。 Improve th
我下载了一个软件( info-beamer ),我想使用 GPU 加速来解码 H.264 视频。我知道我的平台能够使用 GPU 解码 H.264 视频。我使用以下命令对 gstreamer 进行了一些
我正在 try catch 相机输出并使用 libavcodec 制作视频。作为如何完成此操作的示例,我使用了 ffmpeg muxing example . 问题是 4 秒视频的大小约为 15mb,
我是一名优秀的程序员,十分优秀!