请教FFmpeg大神:我用最新版解码h264文件,解码成YUV420文件后,颜色有错位,这是为什么

墨雨依旧付疏狂Q 2018-08-10 03:37:32
请教FFmpeg大神:我用最新版解码h264文件,解码成YUV420文件后,颜色有错位,这是为什么???
#pragma once
#include <iostream>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/frame.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
};

#define INBUF_SIZE 4096

using namespace std;

void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, char *filename)
{
FILE *f;
int i;

f = fopen(filename, "ab+");
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
for (i = 0; i < ysize; i++)
fwrite(buf + i * wrap, 1, xsize, f);
fclose(f);
}

void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt, const char *filename)
{
char buf[1024];
int ret;

ret = avcodec_send_packet(dec_ctx, pkt);
if (ret < 0)
{
fprintf(stderr, "Error sending a packet for decoding\n");
exit(1);
}

while (ret >= 0)
{

ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0)
{
fprintf(stderr, "Error during decoding\n");
exit(1);
}

//sws_scale(imgCtx, frame->data, frame->linesize, 0, dec_ctx->height, yuv->data, yuv->linesize);

printf("saving frame %3d\n", dec_ctx->frame_number);
fflush(stdout);

/* the picture is allocated by the decoder. no need to free it */
snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
pgm_save(frame->data[0], frame->linesize[0], dec_ctx->width, dec_ctx->height, buf);//Y
pgm_save(frame->data[1], frame->linesize[1], dec_ctx->width / 2, dec_ctx->height / 2, buf);//U
pgm_save(frame->data[2], frame->linesize[2], dec_ctx->width / 2, dec_ctx->height / 2, buf);//V
}
}

int main(int argc, char **argv)
{
const char *filename = "test3.h264", *outfilename = "frames\\frame";
const AVCodec *codec;
AVCodecParserContext *parser;
AVCodecContext *c = NULL;
FILE *f;
AVFrame *frame;
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
uint8_t *data;
size_t data_size;
int ret;
AVPacket *pkt;

pkt = av_packet_alloc();
if (!pkt)
exit(1);

/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);

/* find the MPEG-1 video decoder */
//codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}

parser = av_parser_init(codec->id);
if (!parser) {
fprintf(stderr, "parser not found\n");
exit(1);
}

c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}

/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}

f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}

frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}

while (!feof(f)) {
/* read raw data from the input file */
data_size = fread(inbuf, 1, INBUF_SIZE, f);
if (!data_size)
break;

/* use the parser to split the data into frames */
data = inbuf;
while (data_size > 0) {
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size, data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
fprintf(stderr, "Error while parsing\n");
exit(1);
}
data += ret;
data_size -= ret;

if (pkt->size)
decode(c, frame, pkt, outfilename);
}
}

/* flush the decoder */
decode(c, frame, NULL, outfilename);

fclose(f);

av_parser_close(parser);
avcodec_free_context(&c);
av_frame_free(&frame);
av_packet_free(&pkt);
system("pause");
return 0;
}
FFmpeg4.0.2解码后的YUV文件:
低版本解码正常的YUV文件:


...全文
6863 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 10 楼 郝江波 的回复:
问题解决了吗? 我遇到了同样的问题
把YUV420换成NV12 或者 NV21再试试。
郝江波 2020-11-25
  • 打赏
  • 举报
回复
问题解决了吗? 我遇到了同样的问题
  • 打赏
  • 举报
回复
YUV数据分离问题吧
Y数据没错,黑白部分正常
上色出错时UV数据问题,是不是你的UV错位存放,你分离的时候直接先1/4的U,再1/4V这样分离的?
CyberLogix 2019-03-18
  • 打赏
  • 举报
回复
看看YUV数据格式是否匹配,再按照转化算法进行对齐一行行处理就行了
Wong Chinhang 2019-03-01
  • 打赏
  • 举报
回复
有可能原先的图像格式是YUVJ420P,直接转成YUV420P会出现颜色的问题。
老雍 2019-01-31
  • 打赏
  • 举报
回复
仅仅颜色问题的话,灰度图没问题,说明Y分量正确,错误处在UV分量上。
1. 如楼上说的那样检查是否有数据错位;
2. 检查编码前与解码后的图像格式是否一致
CyberLogix 2018-11-28
  • 打赏
  • 举报
回复
U, V数据有问题,字节对齐有问题,图像边界出现错位现象
英雄@末路 2018-09-29
  • 打赏
  • 举报
回复
pgm_save 这个函数里面上来把文件名写到Y/U/V文件里面了,确定没问题?UV读取时候加偏移了么?
liu3zy 2018-09-21
  • 打赏
  • 举报
回复
解码生成的的YUV应没问题,Y数据读出正确,是UV不正确,
您发显示YUV代码上来才能确定问题出在哪。
直觉判断是:
一可能是每行后面的Panding补空部分数值不一样,
二是可能你不小心把Y数据的行宽line[0]用在了UV,所以错位。
rightorwrong 2018-08-23
  • 打赏
  • 举报
回复
肯定是格式转错了,保存成文件,用工具看看

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧