FFMPEG抓取摄像头数据保存为一张图片

本文介绍了如何在树莓派环境下使用FFMPEG库从视频设备(例如/dev/video0)抓取一帧并保存为JPEG图片。通过调用FFMPEG的API,程序打开输入文件,找到视频流,解码帧,然后将其编码为JPEG并保存到磁盘。

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

实验环境:树莓派3.

库FFMPEG。

写在前边的声明,该文章所发代码全部为网上收集,本人经过整合,精心去除一些冗余,然后而成。

下边什么都不说了,直接上代码

#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <string.h>  
#include "libavformat/avformat.h"  
#include "libavcodec/avcodec.h"  
#include "libavdevice/avdevice.h"  
#include <libavutil/imgutils.h>    
#include <libswscale/swscale.h>
  
char* input_name= "video4linux2";  
char* file_name = "/dev/video0";  
char* out_file  = "11yuv420.yuv";  

static AVFormatContext *ifmt_ctx;
static AVFormatContext *ofmt_ctx;

typedef struct StreamContext {
    AVCodecContext *dec_ctx;
    AVCodecContext *enc_ctx;
} StreamContext;

static StreamContext *stream_ctx;
const char* jpeg_file = "cuc_view_encode.jpg";
unsigned int g_stream_index = -1;

void release_frame(AVFrame *frame)
{
    if(frame)
    {
        av_frame_unref(frame);
        av_frame_free(&frame);
    }
}

void release_packet(AVPacket *packet)
{
    if(packet)
    {
        av_packet_unref(packet);
        av_packet_free(&packet);
    }
}

int open_input_file()
{
    int i = 0;
    int ret = -1;
    int videoindex = -1;
    ifmt_ctx = NULL;    
  
    if ((ret = avformat_open_input (&ifmt_ctx, file_name, NULL, NULL)) < 0){  
        av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
        return ret;      
    }  
    av_dump_format(ifmt_ctx, 0, file_name, 0);  

    if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
        return;
    }

    stream_ctx = av_mallocz_array(ifmt_ctx->nb_streams, sizeof(*stream_ctx));
    if (!stream_ctx)
    {
        return AVERROR(ENOMEM);
    }

    for (i = 0; i < ifmt_ctx->nb_streams; i++) {
        AVStream *stream = ifmt_ctx->streams[i];
        AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
        AVCodecContext *codec_ctx;
        if (!dec) {
            av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
            return AVERROR_DECODER_NOT_FOUND;
        }
        codec_ctx = avcodec_alloc_context3(dec);
        if (!codec_ctx) {
            av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i);
            return AVERROR(ENOMEM);
        }
        ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context "
            "for stream #%u\n", i);
            return ret;
        }
        /* Reencode video & audio and remux subtitles etc. */
        if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
        || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
            if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
                codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx,

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值