首页 > 其他分享 >ffmpeg修改颜色空间

ffmpeg修改颜色空间

时间:2024-05-28 21:21:48浏览次数:18  
标签:颜色 ffmpeg avcodec ret 修改 codecCtx av return NULL

方法1:命令修改颜色空间

# 修改颜色空间
ffmpeg -i input.mp4 -s 1280*1024 -pix_fmt rgb24 output.rgb
# 播放
ffplay -s 1280*1024 -pix_fmt rgb24 output.rgb

方法2:代码转换

 main.c

#include "libavutil/log.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libavcodec/avcodec.h"
#include "libavutil/parseutils.h"
#include "libswscale/swscale.h"
#include "libavutil/imgutils.h"

int decodeVideo(AVCodecContext *codecCtx, AVPacket *packet, struct SwsContext *c, int dstWeight, int dstHeight,
                AVFrame *dstFrame, FILE *dst) {
    int ret = avcodec_send_packet(codecCtx, packet);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "avcodec_send_packet failed: %s\n", av_err2str(ret));
        av_packet_unref(packet);
        return ret;
    }
    AVFrame *frame = av_frame_alloc();
    while ((ret = avcodec_receive_frame(codecCtx, frame)) == 0) {
        sws_scale(c, (const uint8_t *const *) frame->data, frame->linesize, 0, codecCtx->height, dstFrame->data,
                  dstFrame->linesize);
        fwrite(dstFrame->data[0], 1, dstWeight * dstHeight * 3, dst);
    }
    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
        av_frame_free(&frame);
        return 0;
    } else if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "avcodec_receive_frame failed: %s\n", av_err2str(ret));
        av_frame_free(&frame);
        return ret;
    }
    av_frame_free(&frame);
    return 0;
}

int main(int argc, char **argv) {
    av_log_set_level(AV_LOG_DEBUG);
    if (argc < 4) {
        av_log(NULL, AV_LOG_ERROR, "Usage: %s inputFile outputFile\n", argv[0]);
        return -1;
    }
    const char *inputFile = argv[1];
    const char *outputFile = argv[2];
    const char *dstVideoSizeString = argv[3];
    int ret;
    int dstHeight = 0;
    int dstWeight = 0;
    ret = av_parse_video_size(&dstWeight, &dstHeight, dstVideoSizeString);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "av_parse_video_size failed: %s\n", inputFile, av_err2str(ret));
        return -1;
    }
    AVFormatContext *fCtx = NULL;


    if ((ret = avformat_open_input(&fCtx, inputFile, NULL, NULL)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Open input file %s failed: %s\n", inputFile, av_err2str(ret));
        return -1;
    }
    if ((ret = avformat_find_stream_info(fCtx, NULL)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Find input file stream info failed: %s\n", av_err2str(ret));
        avformat_close_input(&fCtx);
        return -1;
    }

    ret = av_find_best_stream(fCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "av_find_best_stream failed: %s\n", av_err2str(ret));
        avformat_close_input(&fCtx);
        return -1;
    }
    int videoIndex = ret;

    AVCodecContext *codecCtx = avcodec_alloc_context3(NULL);
    if (codecCtx == NULL) {
        av_log(NULL, AV_LOG_ERROR, "avcodec_alloc_context3 failed\n");
        avformat_close_input(&fCtx);
        return -1;
    }
    if ((ret = avcodec_parameters_to_context(codecCtx, fCtx->streams[videoIndex]->codecpar)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "avcodec_parameters_to_context failed: %s\n", av_err2str(ret));
        avformat_close_input(&fCtx);
        avcodec_free_context(&codecCtx);
        return -1;
    }

    AVCodec *decoder = avcodec_find_decoder(codecCtx->codec_id);
    if (decoder == NULL) {
        av_log(NULL, AV_LOG_ERROR, "avcodec_find_decoder failed\n");
        avformat_close_input(&fCtx);
        avcodec_free_context(&codecCtx);
        return -1;
    }
    if ((ret = avcodec_open2(codecCtx, decoder, NULL)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "avcodec_open2 failed: %s\n", av_err2str(ret));
        avformat_close_input(&fCtx);
        avcodec_free_context(&codecCtx);
        return -1;
    }
    enum AVPixelFormat dstFormat = AV_PIX_FMT_RGB24;
    struct SwsContext *swsCtx = sws_getContext(codecCtx->width, codecCtx->height, codecCtx->pix_fmt,
                                               dstWeight, dstHeight, dstFormat,
                                               SWS_FAST_BILINEAR, NULL, NULL, NULL);
    if (swsCtx == NULL) {
        av_log(NULL, AV_LOG_ERROR, "sws_getContext failed\n");
        avformat_close_input(&fCtx);
        avcodec_free_context(&codecCtx);
        return -1;
    }
    AVFrame *dstFrame = av_frame_alloc();
    ret = av_image_get_buffer_size(dstFormat, dstWeight, dstHeight, 1);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "av_image_get_buffer_size failed:%s\n", av_err2str(ret));
        avformat_close_input(&fCtx);
        avcodec_free_context(&codecCtx);
        return -1;
    }
    uint8_t *outBuffer = av_malloc(ret);
    av_image_fill_arrays(dstFrame->data, dstFrame->linesize, outBuffer, dstFormat, dstWeight, dstHeight, 1);
    FILE *dst = fopen(outputFile, "wb");
    if (dst == NULL) {
        av_log(NULL, AV_LOG_ERROR, "open outputFile failed\n");
        avformat_close_input(&fCtx);
        avcodec_free_context(&codecCtx);
        return -1;
    }

    AVPacket *packet = av_packet_alloc();
    if (!packet) {
        av_log(NULL, AV_LOG_ERROR, "Could not allocate AVPacket\n");
        avformat_close_input(&fCtx);
        avcodec_free_context(&codecCtx);
        fclose(dst);
        return -1;
    }

    while (av_read_frame(fCtx, packet) == 0) {
        if (packet->stream_index == videoIndex) {
            if (decodeVideo(codecCtx, packet, swsCtx, dstWeight, dstHeight, dstFrame, dst) < 0) {
                av_packet_unref(packet);
                break;
            }
        }
        av_packet_unref(packet);
    }
    decodeVideo(codecCtx, NULL, swsCtx, dstWeight, dstHeight, dstFrame, dst);

    // Cleanup
    av_packet_free(&packet);
    avformat_close_input(&fCtx);
    avcodec_free_context(&codecCtx);
    fclose(dst);
    av_frame_free(&dstFrame);
    return 0;
}

Makefile

TARGET=main
SRC=main.c
CC=gcc
CFLAGS=-I /usr/local/ffmpeg/include
LDFLAGS=-L /usr/local/ffmpeg/lib
LDFLAGS+= -lavutil -lavformat -lavcodec -lswscale
all:$(TARGET)
$(TARGET):$(SRC)
	$(CC) $(SRC) $(CFLAGS) $(LDFLAGS) -o $(TARGET)
clean:
	rm -rf $(TARGET)

  

 

标签:颜色,ffmpeg,avcodec,ret,修改,codecCtx,av,return,NULL
From: https://www.cnblogs.com/navysummer/p/18218944

相关文章

  • PostgreSQL数据库实战:轻松修改字段名称
    哈喽,大家好,我是木头左!在本文中,将深入探讨PostgreSQL数据库中的一个强大功能,即如何轻松修改字段名称。无论你是一个新手开发者,还是一个经验丰富的DBA,这篇文章都将为你提供实用的技巧和建议。一、为什么需要修改字段名称?在开发过程中,经常会遇到需要修改表结构的情况,比如添加新......
  • npm清理缓存及修改配置源
    1、npm清理缓存 npmcacheclean--force如果要查看npm缓存的位置可以用下面的命令 npmcachedir有人的npm可能没有这个命令,可以改用这个命令去查看 npmconfiglist--json 如果是yarn就可以用下面的命令查看缓存位置 yarncachedir2、查看配置源 npm config get ......
  • SpringBoot修改内置的Tomcat版本
    springboot内置tomcat各版本漏洞及修复情况参考链接:https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core打开项目,找到pom.xml文件找到对应节点,按以下步骤修改:1、pom添加tomcat版本信息   <properties>       <java.version>1.8</java.ver......
  • 如何在本地修改Hosts文件设置域名访问?
    网站在未上线的时候,我们一般会在本地搭建Web环境并安装WordPress来设计页面、测试插件、数据备份、网站搬家。为了能够在本地通过域名访问网站,就需要在修改hosts文件来绑定域名,方法如下:windows系统修改hosts文件步骤1:打开hosts文件,路径如下所示;找到hosts文件,选择使用记事本打开......
  • Windows10(家庭版)中DockerDesktop(docker)的配置、安装、修改镜像源、使用
    场景Windows10中Docker的安装与遇到的那些坑:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/119209218上面讲DockerDesktop在windows10非家庭版上的安装,如果是家庭版,则需要执行如下步骤。注:博客:https://blog.csdn.net/badao_liumang_qizhi实现1、虚拟化检......
  • kvm 修改虚拟机名称
    目录kvm修改虚拟机名称关闭虚拟机修改配置文件名称删除原有的虚拟机然后启动虚拟机即可xml配置文件详情2kvm修改虚拟机名称关闭虚拟机注意:如果虚拟机有快照需要先删除快照!virshlist--allvirshshutdowntest_66.124正常关闭后,虚拟机状态state为:shutoff修改配置文件名......
  • 通过上传修改文件名
      functionuploadFile(option){constfile=option.file; //拿到文件流对象constnewName=`custom_${Date.now()}_${file.name}`;//定义文件名constnewBlob=newBlob([file],{type:newName}); //创建新的File对象,使用修改后的文件名 constnewFile......
  • git修改文件提交
    1,检查当前状态,查看是否有未提交的更改gitstatus2,如果有未提交的更改,使用gitadd命令将修改的文件添加到暂存区gitadd<file>如果添加所有修改的文件,可以使用gitadd.3,提交这些更改到你的本地仓库gitcommit-m“此处是提交的备注”4,如果已经做了一些更改并且想要查......
  • Vue+OpenLayers7入门到实战:OpenLayers实现在地图上拖拽编辑修改绘制图形
    返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战前言本章介绍如何使用OpenLayers7在地图上拖拽编辑修改绘制图形。在前面一章中,我们已经学会了如何绘制基础的三种图形线段、圆形和多边形:《Vue+OpenLayers7入门到实战:OpenLayers图形绘制功能,OpenLayers实现在地......
  • ffmpeg修改分辨率
    方法1:命令修改分辨率#修改分辨率ffmpeg-iinput.mp4-vfscale=1280:1024-frawvideooutput.yuv#播放ffplay-s1280*1024-pix_fmtyuv420poutput.yuv方法2:代码转换 main.c#include"libavutil/log.h"#include"libavformat/avformat.h"#include"l......