c++ - 使用 FFmpeg 解码 YUYV422 原始图像
问题描述
我有一组顺序的 YUYV422 原始图像,我希望将其转换为视频。问题似乎是当在avcodec_receive_frame
. 该帧仅包含一个通道而不是 YUYV 格式的四个通道。这导致Input picture width <640> is greater then stride (0)
因为只有第零个数据索引和行大小设置在帧中。我不知道这是 ffmpeg 错误还是我的错误配置。
#include "icsFfmpegImageDecoder.h"
#include <stdexcept>
ImageDecoder::ImageDecoder(std::string filename)
{
AVInputFormat* iformat;
if (!(iformat = av_find_input_format("image2")))
throw std::invalid_argument(std::string("input Codec not found\n"));
this->fctx = NULL;
if (avformat_open_input(&this->fctx, filename.c_str(), iformat, NULL) < 0)
{
std::string error = "Failed to open input file ";
error += filename;
error += "\n";
throw std::invalid_argument(error);
}
#ifdef LIB_AVFORMAT_STREAM_CODEC_DEPRECATED
if (!(this->codec = avcodec_find_decoder(this->fctx->streams[0]->codecpar->codec_id)))
throw std::invalid_argument(std::string("Failed to find codec\n"));
if (!(this->cctx = avcodec_alloc_context3(this->codec)))
throw std::invalid_argument(std::string("could not create image read context codec"));
if (avcodec_parameters_to_context(this->cctx, this->fctx->streams[0]->codecpar) < 0)
throw std::invalid_argument(std::string("could not get contest codec from stream"));
#else
this->cctx = this->fctx->streams[0]->codec;
if (!(this->codec = avcodec_find_decoder(this->cctx->codec_id)))
throw std::invalid_argument(std::string("Failed to find codec\n"));
#endif
if (this->cctx->codec_id == AV_CODEC_ID_RAWVIDEO) {
// TODO Make Dynamic
this->cctx->pix_fmt = AV_PIX_FMT_YUYV422 ;
this->cctx->height = 800;
this->cctx->width = 1280;
}
if (avcodec_open2(this->cctx, this->codec, NULL) < 0)
throw std::invalid_argument(std::string("Failed to open codec\n"));
#ifdef USING_NEW_AVPACKET_SETUP
if (!(this->pkt = av_packet_alloc()))
throw std::invalid_argument(std::string("Failed to alloc frame\n"));
#else
this->pkt = new AVPacket();
av_init_packet(this->pkt);
#endif
read_file();
}
ImageDecoder::~ImageDecoder()
{
avcodec_close(this->cctx);
avformat_close_input(&this->fctx);
#ifdef USING_NEW_AVPACKET_SETUP
av_packet_free(&this->pkt);
#else
av_free_packet(this->pkt);
delete this->pkt;
#endif
}
void ImageDecoder::read_file()
{
if (av_read_frame(this->fctx, this->pkt) < 0)
throw std::invalid_argument(std::string("Failed to read frame from file\n"));
if (this->pkt->size == 0)
this->ret = -1;
}
#ifdef LIB_AVCODEC_USE_SEND_RECEIVE_NOTATION
void ImageDecoder::send_next_packet() {
if ((this->ret = avcodec_send_packet(this->cctx, this->pkt)) < 0)
throw std::invalid_argument("Error sending a packet for decoding\n");
}
bool ImageDecoder::receive_next_frame(AVFrame* frame)
{
if (this->ret >= 0)
{
this->ret = avcodec_receive_frame(this->cctx, frame);
if (this->ret == AVERROR_EOF)
return false;
else if (this->ret == AVERROR(11))//11 == EAGAIN builder sucks
return false;
else if (this->ret < 0)
throw std::invalid_argument("Error during decoding\n");
return true;
}
return false;
}
#else
void ImageDecoder::decode_frame(AVFrame* frame)
{
int got_frame = 0;
if (avcodec_decode_video2(this->cctx, frame, &got_frame, this->pkt) < 0)
throw std::invalid_argument("Error while decoding frame %d\n");
}
#endif
解决方案
推荐阅读
- c# - MVC.Grid 可以使用动态列吗?
- python - 在 Python 中从 SQL 读取转换数据类型
- java - JNI 将 java base64 字符串传递给 C++ 并将 base64 字符串返回给 java
- angular - 角度路由选择器“app-home”与元素不匹配
- mongodb - connect-mongo autoRemoveInterval 无法正常工作
- python - 使用漂亮的汤刮网站返回“无”
- java - SpringBoot:在同一个响应中发送一个 zip 文件作为附件和一个 JSON 正文
- google-apps-script - 使用 getNotes 动态自动填充列
- javascript - 异步函数中的 JSON.parse(Fetch_Get_JSON_Data)
- node.js - 我该如何克服这个“Cannot Get /”nginx 错误?