如何使用ffmpeg的库将YUV420P图像转换为JPEG?

2023-12-03

我正在尝试转换 YUV420P 图像(AV_PIX_FMT_YUV420P) 使用 ffmpeg 转换为 JPEGlibavformat and libavcodec。到目前为止,这是我的代码:

AVFormatContext* pFormatCtx;
AVOutputFormat* fmt;
AVStream* video_st;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;

uint8_t* picture_buf;
AVFrame* picture;
AVPacket pkt;
int y_size;
int got_picture=0;
int size;

int ret=0;

FILE *in_file = NULL;                            //YUV source
int in_w = 720, in_h = 576;                      //YUV's width and height
const char* out_file = "encoded_pic.jpg";    //Output file

in_file = fopen(argv[1], "rb");
av_register_all();

pFormatCtx = avformat_alloc_context();

fmt = NULL;
fmt = av_guess_format("mjpeg", NULL, NULL);
pFormatCtx->oformat = fmt;

//Output URL
if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0)
{
    printf("Couldn't open output file.");
    return -1;
}

video_st = avformat_new_stream(pFormatCtx, 0);

if (video_st==NULL)
    return -1;

pCodecCtx = video_st->codec;
pCodecCtx->codec_id = fmt->video_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;

pCodecCtx->width = in_w;
pCodecCtx->height = in_h;

pCodecCtx->time_base.num = 1;
pCodecCtx->time_base.den = 25;

//Output some information
av_dump_format(pFormatCtx, 0, out_file, 1);

pCodec = avcodec_find_encoder(pCodecCtx->codec_id);

if (!pCodec)
{
    printf("Codec not found.");
    return -1;
}

if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){
    printf("Could not open codec.\n");
    return -1;
}

picture = avcodec_alloc_frame();
size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);

picture_buf = (uint8_t *)av_malloc(size);

if (!picture_buf)
    return -1;

avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);

//Write Header
avformat_write_header(pFormatCtx,NULL);

y_size = pCodecCtx->width * pCodecCtx->height;
av_new_packet(&pkt,y_size*3);

//Read YUV
if (fread(picture_buf, 1, y_size*3/2, in_file) <=0)
{
    printf("Could not read input file.");
    return -1;
}

picture->data[0] = picture_buf;  // Y
picture->data[1] = picture_buf+ y_size;  // U
picture->data[2] = picture_buf+ y_size*5/4; // V

//Encode
ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);
if(ret < 0)
{
    printf("Encode Error.\n");
    return -1;
}

if (got_picture==1)
{
    pkt.stream_index = video_st->index;
    ret = av_write_frame(pFormatCtx, &pkt);
}

av_free_packet(&pkt);
//Write Trailer
av_write_trailer(pFormatCtx);

printf("Encode Successful.\n");

if (video_st)
{
    avcodec_close(video_st->codec);
    av_free(picture);
    av_free(picture_buf);
}

avio_close(pFormatCtx->pb);
avformat_free_context(pFormatCtx);

fclose(in_file);

我收到此错误:

Output #0, mjpeg, to 'encoded_pic.jpg':
Stream #0.0: Video: mjpeg, yuv420p, 720x576, q=2-31, 200 kb/s, 90k tbn, 25 tbc
[mjpeg @ 0x78c3a0] Specified pix_fmt is not supported
Could not open codec.

ffmpeg 的文档中是否提到不允许这种转换?如果有的话,我们该如何规避呢?当我们使用命令行版本的ffmpeg时,ffmpeg内部是如何转换的呢?


下列code是你的问题:

.pix_fmts       = (const enum AVPixelFormat[]){
    AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE
},

如您所见,它需要 AV_PIX_FMT_YUVJ420P,而不是 YUV420P。这是一个旧的遗留物,很大程度上被认为已弃用,但它尚未被删除或标记为删除,并且仍在某些地方使用。 YUVJ420P的字面意思是“带有JPEG颜色范围的YUV420P”(即像素使用0-255范围而不是16-235范围,其中0而不是16是黑色,255而不是235是白色)。您也可以使用 AV_PIX_FMT_YUV420P 来执行此操作,然后设置例如avctx->color_range 至AVCOL_RANGE_JPEG.

你可能不关心这个,你想知道,如何将 AV_PIX_FMT_YUV420P 转换为 AV_PIX_FMT_YUVJ420P?好吧,在这种情况下,您的输入是 JPEG,因此它可能使用 JPEG 范围数据(通过检查 avctx->color_range 或 avframe->color_range 进行检查)。然后你可以简单地将avframe->pix_fmt从AV_PIX_FMT_YUV420P更改为AV_PIX_FMT_YUVJ420P。如果出于某种原因 color_range 是 AVCOL_RANGE_MPEG,您可能可以使用libswscale要在具有 MPEG 范围的 AV_PIX_FMT_YUV420P 和 AV_PIX_FMT_YUVJ420P 之间进行转换,请参见例如这个例子.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用ffmpeg的库将YUV420P图像转换为JPEG? 的相关文章

  • 使用 libavcodec 将 .m4a 转换为 PCM

    我正在尝试将 m4a 文件转换为原始 PCM 文件 以便可以在 Audacity 中播放它 根据 AVCodecContext 它是一个使用示例格式 AV SAMPLE FMT FLTP 的 44100 Hz 轨道 据我了解 当使用 avc
  • Ghostscript是否可以为PDF的每个页面添加水印

    我转换PDF gt 许多 JPEG and 许多 JPEG gt 许多 PDF using ghostscript 我需要在每个转换后的 JPEG PDF 页面上添加水印文本 是否可以仅使用 Ghostscript 和 PostScript
  • 延迟加载带有图片、源和 img 标签的图像(webp、jpg)(React)

    我目前正在尝试使用 React 实现延迟加载图像组件 我最初的解决方案是一个非常简单和基本的方法 I used Image API https developer mozilla org en US docs Web API HTMLIma
  • 什么是 YUV 格式? (从一个不会玩的初学者的角度来看)[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 视频质量指标称为VMAF https github com Netflix vmaf由 Netflix 评估 YUV 格式的视频 但什么是
  • 带有 base64 字符串的 HTML 图像标签(数据 URI)

    我大约每 50 200 毫秒从一系列 httprequests 获取 jpeg 图像的二进制数据 我将此数据转换为 base64 字符串 并使用 javascript 将字符串插入到 img 标记中 var img document get
  • 无需解码图像即可获取 JPEG 分辨率

    我试图在不解码文件的情况下获取 JPEG 图像的分辨率 我从互联网上获得了几个样本 但没有一个可以正常工作 似乎是这样因为manyJPEG 文件不是标准文件 但任何图形应用程序 Irfan PSP Firefox 等 都可以打开它们 JPE
  • 是否有任何免费或商业 jpeg 解码速度非常快 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在使用 c libjpeg 来解
  • libavformat/ffmpeg 与 x264 和 RTP 同步时出现问题

    我一直在开发一些实时直播的流媒体软件 来自各种摄像机和网络流使用 H 264 为了实现这一点 我直接使用 x264 编码器 使用 零延迟 预设 并提供 NAL 因为它们可用于 libavformat 打包到 RTP 最终是 RTSP 中 理
  • 在 Windows 上将 PPT 转换为 JPG/PNG

    我想在 Windows 环境中以编程方式转换一组图像中的 ppt 演示文稿 每张幻灯片一个 我尝试修改以下将 ppt 转换为 pdf 的代码 完美工作 但没有成功 谁能帮我 多谢 Option Explicit Sub WriteLine
  • 快速解码 JPEG 图像的方法

    我需要解码 解压为位图 非常小的 大约 1200 1200 JPEG 问题是我需要尽快完成 我尝试过 libjpeg 但速度很慢 我也尝试过 BitmapFactory decodeByteArray 它有点快 但仍然不够快 还有什么其他选
  • 已知尺寸的 JPEG 图像的最大文件大小

    我将让用户上传使用 JPEG 压缩的 300x300 图像 有没有办法确定此类图像的最大文件大小是多少 我可以想象这可以通过以 100 质量压缩随机噪声来尝试 但是有理论上的最大值吗 假设图像是完全不可压缩的随机噪声 它可以是每个像素 3
  • 使用 ColdFusion 从 HTML 生成图像

    我有一个 ColdFusion 页面 其中有一个样式化的 HTML 表格 我希望能够做的是设置一个功能 允许我们的客户将表格保存为图像文件 以便在幻灯片放映中使用 我已经阅读了 cfcontent 的一些文档 但是 我开始感觉我需要一个第三
  • 将一堆扩展名为“.jpg”的 PNG 图像重命名为“.png”

    所以我有一个包含数千个图像文件的文件夹 所有这些文件都保存为 jpg 问题是其中一些文件实际上是 PNG 图像文件 因此它们无法在很多程序中打开 除非我手动将其扩展名更改为 png 例如 Ubuntu 图像查看器会抛出此错误 解释 JPEG
  • 测量 jpeg 中的空白

    我想测量白色 黄色的 jpeg 数量 在可以调整的容差范围内 我正在尝试开发一种质量控制工具来测量杏仁的缺陷 缺陷是棕色杏仁皮上的划痕 见下图 由于这些缺陷是白色 黄色的 我想要一种简单地将图像加载到 R 中并让它测量白色图像的量的方法 然
  • Unity 的 YUV 着色器?

    我在 Unity 中有一些 适当的 平面的 YUV 纹理 我只想看看它们供开发使用 Unity 他们的着色器语言变体 实际上有一个可用的 YUV 着色器吗 从概念上讲 从 YUV 转换为 RGB 很简单 但有点繁琐 YUV 到 RGB 转换
  • 如何在 R 中将 JPEG 转换为图像矩阵

    我需要将 JPEG 图像转换为矩阵 我想在矩阵上运行 SVD 我曾经用过 library jpeg library biOps myjpg lt readJpeg Snapshot 1 jpg gt dim myjpg 1 398 506
  • 使用鼠标光标捕获屏幕截图

    我使用以下代码在 Windows 上获取屏幕截图 hdcMem CreateCompatibleDC hdc int cx GetDeviceCaps hdc HORZRES int cy GetDeviceCaps hdc VERTRES
  • “标准”RGB 到灰度转换

    我正在尝试编写一个转换器算法 该算法采用 JPEG 图像并返回其 PGM 便携式灰度图 版本 问题是我无法理解 官方 JPG gt PGM 转换器如何从经典 RGB 格式开始为最终像素分配什么值 我猜是 0 gt 255 一开始 我使用了这
  • 使用 .NET 创建采用 JPEG 压缩的多页 TIFF

    有没有办法使用 NET 创建多页 TIFF 和 JPEG 压缩 我可以使用 LZW 压缩创建 TIFF 但文件非常大 好像EncoderValue枚举 我用来设置压缩 甚至没有合适的成员 你可以看看 gt gt 这篇文章 https sta
  • YUV420p 上的大量绿色 --> iOS 上 OpenGL 2.0 着色器中的 RGB

    我想使用 ffmpeg 和 OpenGL ES 2 0 为 iOS 制作一个电影播放器 但我有一些问题 输出 RGB 图像有很多绿色 这是代码和图像 480x320 宽度和高度 512x512 纹理宽度和高度 我从 ffmpeg AVFra

随机推荐