首页 > 其他分享 >Macos arm64 ffmpeg h264 还原成yuv

Macos arm64 ffmpeg h264 还原成yuv

时间:2024-02-28 16:33:04浏览次数:19  
标签:Macos ffmpeg parameters h264 frame av codec AV NULL

首先编译 ffmpeg

  • 由于编译很多依赖尝试了三天果断放弃~
  • 使用brew
brew install  ffmpeg
brew info  ffmpeg

cmakelist.txt

cmake_minimum_required(VERSION 3.20)
project(ffmpeg_base C)
set(CMAKE_C_STANDARD 11)
set(FFMPEG_DIR /usr/local/Cellar/ffmpeg/6.1.1_3)
include_directories(${FFMPEG_DIR}/include/)
link_directories(${FFMPEG_DIR}/lib/)
add_executable(ffmpeg_base main.c)
target_link_libraries(ffmpeg_base
        swscale
        swresample
        avcodec
        avutil
        avdevice
        avfilter
        avformat
)

源码

#include <stdio.h>
#include <time.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>


#define IMAGE_WIDTH   1920
#define IMAGE_HEIGHT  1080
char* in_file = "/Users/jimogangdan/CLionProjects/x264_encoder/video1.h264";
char* out_file = "/Users/jimogangdan/CLionProjects/x264_encoder/video1.yuv";
void print_pict_type(int frame_cnt, AVFrame* pFrame);

// ffplay -video_size 1920x1080 -i video1.yuv
int main(int argc, char** argv)
{
    AVFormatContext* avFormatContext = avformat_alloc_context();
    if (avformat_open_input(&avFormatContext, in_file, NULL, NULL) != 0)
    {
        av_log(NULL, AV_LOG_ERROR, "can not open  input file \n");
        return -1;
    }

    if (avformat_find_stream_info(avFormatContext, NULL) < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "find stream error");
        return -1;
    }

    int videoIndex = -1;
    for (int i = 0; i < avFormatContext->nb_streams; i++)
    {
        if (AVMEDIA_TYPE_VIDEO == avFormatContext->streams[i]->codecpar->codec_type)
        {
            videoIndex = i;
            break;
        }
    }

    if (videoIndex == -1)
    {
        av_log(NULL, AV_LOG_ERROR, "not find a video stream");
        return -1;
    }

    const AVCodecParameters* codec_parameters = avFormatContext->streams[videoIndex]->codecpar;
    const AVCodec* pCodec = avcodec_find_decoder(codec_parameters->codec_id);
    if (!pCodec)
    {
        av_log(NULL, AV_LOG_ERROR, "Codec not found\n");
        return -1;
    }

    AVCodecContext* pCodecContext = avcodec_alloc_context3(pCodec);
    if (!pCodecContext)
    {
        av_log(NULL, AV_LOG_ERROR, "Could not allocate video codec context\n");
        return -1;
    }

    int openResult = avcodec_open2(pCodecContext, pCodec, NULL);
    if (openResult < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "avcodec open2 result %d", openResult);
        return -1;
    }

    FILE* pYUVFile = fopen(out_file, "wb+");
    if (pYUVFile == NULL)
    {
        av_log(NULL, AV_LOG_ERROR, " fopen outPut file error");
        return -1;
    }

    AVPacket* packet = av_malloc(sizeof(AVPacket));
    AVFrame* pFrame = av_frame_alloc();
    AVFrame* pFrameYUV = av_frame_alloc();

    const uint8_t* out_buffer = (unsigned char*)av_malloc(
        av_image_get_buffer_size(
            AV_PIX_FMT_YUV420P,
            codec_parameters->width,
            codec_parameters->height,
            1
        )
    );

    av_image_fill_arrays(
        pFrameYUV->data,
        pFrameYUV->linesize,
        out_buffer,
        AV_PIX_FMT_YUV420P,
        codec_parameters->width,
        codec_parameters->height,
        1
    );

    struct SwsContext* img_convert_ctx = sws_getContext(
        codec_parameters->width,
        codec_parameters->height,
        codec_parameters->codec_type,
        codec_parameters->width,
        codec_parameters->height,
        AV_PIX_FMT_YUV420P,
        SWS_BICUBIC,
        NULL,
        NULL,
        NULL
    );

    int readPackCount = -1;
    int frame_cnt = 0;
    const clock_t start_time = clock();
    while ((readPackCount = av_read_frame(avFormatContext, packet) >= 0))
    {
        av_log(NULL, AV_LOG_INFO, " read fame count is %d\n", readPackCount);

        if (packet->stream_index == videoIndex)
        {
            const int sendPacket = avcodec_send_packet(pCodecContext, packet);
            if (sendPacket != 0)
            {
                av_log(NULL, AV_LOG_ERROR, "avodec send packet error %d\n", sendPacket);
                continue;
            }
            const int receiveFrame = avcodec_receive_frame(pCodecContext, pFrame);

            if (receiveFrame != 0)
            {
                av_log(NULL, AV_LOG_INFO, "avcodec_receive_frame is being  green ,dropped %d\n", receiveFrame);
                continue;
            }
            sws_scale(
                img_convert_ctx, (const uint8_t*const *)
                pFrame->data,
                pFrame->linesize,
                0,
                pCodecContext->height,
                pFrameYUV->data,
                pFrameYUV->linesize
            );

            const int y_size = codec_parameters->width * codec_parameters->height;
            fwrite(pFrameYUV->data[0], 1, y_size, pYUVFile); //Y
            fwrite(pFrameYUV->data[1], 1, y_size / 4, pYUVFile); //U
            fwrite(pFrameYUV->data[2], 1, y_size / 4, pYUVFile); //V

            print_pict_type(frame_cnt, pFrame);
            frame_cnt++;
        }
    }

    av_log(NULL, AV_LOG_INFO, "frame count is %d", frame_cnt);
    const clock_t end_time = clock();
    av_log(NULL, AV_LOG_INFO, "decode video use Time %ld", (end_time - start_time));

    av_packet_unref(packet);
    sws_freeContext(img_convert_ctx);
    fclose(pYUVFile);
    av_frame_free(&pFrameYUV);
    av_frame_free(&pFrame);
    avcodec_close(pCodecContext);
    avformat_close_input(&avFormatContext);

    return 0;
}

void print_pict_type(int frame_cnt, AVFrame* pFrame)
{
    char pictypeStr[10] = {0};
    switch (pFrame->pict_type)
    {
    case AV_PICTURE_TYPE_I:
        {
            sprintf(pictypeStr, "I");
            break;
        }
    case AV_PICTURE_TYPE_P:
        {
            sprintf(pictypeStr, "P");
            break;
        }
    case AV_PICTURE_TYPE_B:
        {
            sprintf(pictypeStr, "B");
            break;
        }
    default:
        break;
    }
    av_log(NULL, AV_LOG_INFO, "Frame index %5d. Tpye %s\n", frame_cnt, pictypeStr);
}

标签:Macos,ffmpeg,parameters,h264,frame,av,codec,AV,NULL
From: https://www.cnblogs.com/guanchaoguo/p/18040931

相关文章

  • 编码层判断帧类型H264
    由于靠起始码判断帧类型无法严谨区分I,P,B;所以需要到slice层去判断;以下是代码(转载)/*仅用于精准判断帧类型*//*----https://blog.csdn.net/zhuweigangzwg/article/details/44152239-----------*/#include<stdio.h>#include<stdlib.h>#include<string.h>//H264一帧数......
  • windows之FFmpeg 软、硬解码
    设备支持qsv硬件加速,则虚线判断是否可以支持硬解码namespaceCoder.FFmpeg{///<summary>///视频解码器///</summary>publicunsafeclassFFmpegVideoDecoder:IDisposable{#region私有变量//格式转换器privaterea......
  • macos arm64 编译静态库
    下载ffmpeghttps://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2编译sudo./configure--enable-static--enable-gpl--enable-libx264--prefix=/opt/local--extra-cflags=-I/opt/local/include--extra-ldflags=-L/opt/local/lib--pkg-config-flags="--static&qu......
  • ffmpeg 工具及命令介绍
    ffprobe工具介绍查看帮助信息:ffprobe--help使用方式:ffprobe[OPTIONS][INPUT_FILE]查看多媒体数据包:ffprobe-show_packetsoutput.mp4ffprobe-show_packets-show_dataoutput.mp4查看封装格式:ffprobe-show_formatoutput.mp4查看视频文件的帧信息:ffprobe-sh......
  • CrossOver 24 for Mac:在 macOS 上运行 Windows 应用
    CrossOver24forMac:在macOS上运行Windows应用请访问原文链接:https://sysin.org/blog/crossover/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgCrossOver:在macOS、Linux和ChromeOS上运行您的Windows®应用对比所有跨平台方案对比内容CrossOver™......
  • M1 MacOS 配置C++环境时遇到的插件问题
    配置环境参照博客:https://www.cnblogs.com/BYGAO/p/15135609.html遇到问题:在Terminal--ConfigureDefaultBuildTasks--C/C++clang++这一步没有C/C++clang++选项。解决方法:shift+command+p打开搜索框,搜索SettingsSync:ShowSettings在IgnoredExtensions中打......
  • 苹果AppleMacOs最新Sonoma系统本地训练和推理GPT-SoVITS模型实践
    GPT-SoVITS是少有的可以在MacOs系统下训练和推理的TTS项目,虽然在效率上没有办法和N卡设备相提并论,但终归是开发者在MacOs系统构建基于M系列芯片AI生态的第一步。环境搭建首先要确保本地环境已经安装好版本大于6.1的FFMPEG软件:(base)➜~ffmpeg-versionffmpegversion6......
  • Windows环境使用ffmpeg转换文件格式
    先安装ffmpeg,官网下载地址https://ffmpeg.org/download.html直接保存即可 将命令保存为.bat 格式,放到ffmpeg.exe所在文件夹, 将所需转换的文件也放到该文件夹,双击bat文件运行即可1.flv 转mp4@echoofffor%%iin("*.flv")doffmpeg-i"%%i"-ccopy"%%i".mp4 ......
  • x264 yuv to h264 c99
    如何编译引入x264参考这里正式编码#include<stdint.h>#include<x264.h>#include<stdio.h>#include<unistd.h>#include<fcntl.h>#include<stdlib.h>#include<string.h>#defineCLEAR(x)(memset((&x),0,sizeof(x)))#def......
  • ffmpeg之avformat_alloc_output_context2
    函数原型:intavformat_alloc_output_context2(AVFormatContext**ctx,constAVOutputFormat*oformat,constchar*format_name,constchar*filename);功能:查找根据format_name或者filename或者oformat输出类型,并且初始化ctx结......