FFmpeg_将yuv格式图片存储为jpg格式

本文详细介绍了使用FFmpeg进行视频编码的过程,包括设置输入输出格式、初始化编解码器、读取YUV源文件并将其编码为JPEG格式的输出文件。通过具体的代码示例,展示了如何利用AVFormatContext、AVCodecContext等关键结构体完成视频编码任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ffmpeg中对文件的输入和输出用一个结构体AVFormatContext来指定,其中AVInputFormat指定的是输入,AVOutputFormat指定的是输出,输出格式用函数av_guess_format来查找指定格式。

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include "libavdevice/avdevice.h"
#include "libavutil/pixfmt.h"
#include "libswscale/swscale.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/time.h"
#include "libswresample/swresample.h" 

int main(int argc, char* argv[])
{
    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=640,in_h=480;                 //YUV's width and height
    const char* out_file = "out.jpg";      //Output file 
    in_file = fopen("out.yuv", "rb");
    
    av_register_all();
    pFormatCtx = avformat_alloc_context();
    //Guess format
    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_YUVJ422P;
 
    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.");
        return -1;
    }
    picture = av_frame_alloc();
    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*2);
    
    //Read YUV
    if (fread(picture_buf, 1, y_size*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*3/2;  // 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);
 
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值