【FFMPEG应用篇】MP4转YUV存储

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}

int main() {
    av_register_all();

    AVFormatContext* formatContext = avformat_alloc_context();
    if (avformat_open_input(&formatContext, "4k.mp4", NULL, NULL) != 0) {
        fprintf(stderr, "Error opening input file.\n");
        return -1;
    }

    if (avformat_find_stream_info(formatContext, NULL) < 0) {
        fprintf(stderr, "Error finding stream information.\n");
        return -1;
    }

    av_dump_format(formatContext, 0, "4k.mp4", 0);

    AVCodec* codec = NULL;
    AVCodecContext* codecContext = NULL;
    int videoStreamIndex = -1;
    for (int i = 0; i < formatContext->nb_streams; i++) {
        if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            codec = avcodec_find_decoder(formatContext->streams[i]->codecpar->codec_id);
            codecContext = avcodec_alloc_context3(codec);
            avcodec_parameters_to_context(codecContext, formatContext->streams[i]->codecpar);
            avcodec_open2(codecContext, codec, NULL);
            break;
        }
    }

    AVPacket packet;
    av_init_packet(&packet);

    AVFrame* frame = av_frame_alloc();
    AVFrame* frameRGB = av_frame_alloc();

    struct SwsContext* swsContext = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt, codecContext->width, codecContext->height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);

    while (av_read_frame(formatContext, &packet) >= 0) {
        if (packet.stream_index == videoStreamIndex) {
            int response = avcodec_send_packet(codecContext, &packet);
            if (response < 0) {
                fprintf(stderr, "Error decoding frame.\n");
                return -1;
            }
            response = avcodec_receive_frame(codecContext, frame);
            if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
                continue;
            }
            else if (response < 0) {
                fprintf(stderr, "Error decoding frame.\n");
                return -1;
            }

            av_image_alloc(frameRGB->data, frameRGB->linesize, codecContext->width, codecContext->height, AV_PIX_FMT_YUV420P, 1);

            sws_scale(swsContext, (uint8_t const* const*)frame->data, frame->linesize, 0, codecContext->height, frameRGB->data, frameRGB->linesize);

            // Save frame as YUV file
            FILE* yuvFile = fopen("4k.yuv", "wb");
            if (yuvFile) {
                fwrite(frameRGB->data[0], 1, codecContext->width * codecContext->height, yuvFile); // Y
                fwrite(frameRGB->data[1], 1, codecContext->width * codecContext->height / 4, yuvFile); // U
                fwrite(frameRGB->data[2], 1, codecContext->width * codecContext->height / 4, yuvFile); // V
                fclose(yuvFile);
            }

            av_frame_unref(frame);
            av_frame_unref(frameRGB);
        }
        av_packet_unref(&packet);
    }

    av_frame_free(&frame);
    av_frame_free(&frameRGB);
    avcodec_free_context(&codecContext);
    avformat_close_input(&formatContext);
    avformat_free_context(formatContext);
    sws_freeContext(swsContext);

    return 0;
}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: ffmpeg是一个广泛使用的开源多媒体处理库,支持多种音视频解码格式。在使用ffmpeg进行JPG解码时,它会将JPG图像换为YUV格式。YUV是一种用于存储和传输彩色图像的格式,它将亮度(Y)和色度(U和V)分离开来。 首先,ffmpeg会读取JPG图像文件,并将其解析为像素数据。然后,它会根据JPG中的颜色信息,将像素数据换为YUV格式。Y分量表示图像的亮度信息,U和V分量表示图像的色度信息。 在进行YUV换时,ffmpeg会根据JPG图像的色彩空间信息进行自适应处理。常见的色彩空间包括RGB和YCbCr,其中YCbCr就是一种YUV的变体。通过将RGB图像换为YCbCr,可以更有效地压缩图像数据,并减少存储或传输所需的空间和带宽。 因此,当使用ffmpeg解码JPG图像时,它会将输入的JPG换为YUV格式,并提供Y,U和V三个分量的像素数据。这些像素数据可以根据需要进行进一步的处理或者用于其他操作,如视频编码、图像处理等。 总之,使用ffmpeg解码JPG图像时,它会将图像换为YUV格式,将亮度和色度信息分离开来,以便于后续的处理和应用。 ### 回答2: FFmpeg是一个开源的多媒体处理工具集,可以实现音视频的编解码码、处理等功能。在FFmpeg中,可以通过使用libjpeg库来实现JPG格式的解码。 JPG是一种常见的图片压缩格式,其编码方式使用了基于离散余弦变换(DCT)的算法。要解码JPG图片到YUV格式,需要以下几个步骤: 1. 打开JPG文件:通过FFmpeg提供的接口,可以打开并读取JPG文件。 2. 解码JPG图像:使用libjpeg库提供的函数,可以将JPG图像解码为RGB(红绿蓝)格式。 3. 换为YUV格式:在FFmpeg中,可以使用swscale库提供的函数将RGB图像换为YUV格式。YUV是一种常用的视频颜色空间,其中包括亮度(Y)和色度(U、V)分量。 4. 保存YUV图像:将换后的YUV图像保存到文件中,或者用于后续的视频处理。 需要注意的是,解码JPG到YUV格式是一个比较复杂的过程,需要对图像编码和颜色空间换等进行处理。在使用FFmpeg进行解码时,可以针对具体的需求选择不同的设置和参数,以获得所需的解码效果。 总之,使用FFmpeg可以方便地实现JPG图像解码YUV格式的功能,通过调用FFmpeg提供的接口和库函数,可以完成文件的打开、图像的解码和颜色空间的换等操作。这为后续的视频处理提供了基础。 ### 回答3: ffmpeg是一个开源的多媒体处理工具,可以在命令行中使用。jpg是一种常见的图片格式,而yuv则是一种常见的视频像素格式。 使用ffmpeg解码jpg图片到yuv像素格式的过程可以分为以下几步: 1. 安装ffmpeg:在电脑上安装ffmpeg软件,可以从官方网站或其他途径下载并安装。 2. 打开命令行界面:在电脑上打开命令行界面,可以通过搜索或者运行cmd命令打开。 3. 编写解码命令:在命令行中输入ffmpeg解码命令。命令的基本格式如下所示: `ffmpeg -i input.jpg -pix_fmt yuv420p output.yuv` 这条命令中,`-i input.jpg`表示输入的jpg图片文件,`-pix_fmt yuv420p`表示输出的像素格式为yuv420p,`output.yuv`表示输出的yuv文件名。 4. 执行命令:在命令行中按下回车键执行解码命令。此时,ffmpeg会加载输入的jpg文件,将其解码yuv420p格式,并输出到指定的文件中。 通过以上步骤,我们可以使用ffmpeg将jpg图片解码yuv像素格式。这样的操作对于一些视频处理任务或者需要将图片换为视频的应用场景非常有用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

༄yi笑奈何

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值