欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

用FFmpeg将YUV转换为JPEG并存储:图像处理基础(五)再探

最编程 2024-08-15 15:55:32
...
int yuv420_to_jpg(void *data,int w,int h,char *file)
{
    av_register_all();
    AVFormatContext *pFormatCtx = avformat_alloc_context();
    AVOutputFormat *fmt = av_guess_format("mjpeg", NULL, NULL);
    pFormatCtx->oformat = fmt;
    if (avio_open(&pFormatCtx->pb,file, AVIO_FLAG_READ_WRITE) < 0){
        printf("Couldn't open output file.");
        return -1;
    }
    AVStream *video_st = avformat_new_stream(pFormatCtx, 0);
    if (video_st==NULL){
        return -1;
    }
    AVCodecContext *pCodecCtx = video_st->codec;
    pCodecCtx->codec_id = fmt->video_codec;
    pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
    pCodecCtx->pix_fmt = PIX_FMT_YUVJ420P;
    pCodecCtx->width = w; 
    pCodecCtx->height = h;
    pCodecCtx->time_base.num = 1;
    pCodecCtx->time_base.den = 25;
    AVCodec *pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
    if (!pCodec){
        return -1;
    }
    if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){
        return -1;
    }
    AVFrame *picture = av_frame_alloc();
    int size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
    uint8_t *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);
    avformat_write_header(pFormatCtx,NULL);
    int y_size = pCodecCtx->width * pCodecCtx->height;
    AVPacket pkt;
    av_new_packet(&pkt,y_size*3);
    memcpy(picture_buf,data,y_size*3/2);
    picture->data[0] = picture_buf;
    picture->data[1] = picture_buf+ y_size;
    picture->data[2] = picture_buf+ y_size*5/4;
    int got_picture = 0;
    int 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);
    av_write_trailer(pFormatCtx);
    if (video_st){
        avcodec_close(video_st->codec);
        av_free(picture);
        av_free(picture_buf);
    }
    avio_close(pFormatCtx->pb);
    avformat_free_context(pFormatCtx);
    return 1;
}

推荐阅读