FFmpeg内存模式和文件模式

0

不用写出文件直接读取编码数据

    aliang::media::VideoEncoder encoder(1080, 1080);
    // 文件模式
    // AVFormatContext* outputCtx = avformat_alloc_context();
    // avformat_alloc_output_context2(&outputCtx, NULL, NULL, "D:/tmp/aliang1.mp4");
    // AVStream* video_stream = avformat_new_stream(outputCtx, NULL);
    // avcodec_parameters_from_context(video_stream->codecpar, encoder.codecCtx);
    // avio_open(&outputCtx->pb, "D:/tmp/aliang1.mp4", AVIO_FLAG_WRITE);
    // AVDictionary *options = nullptr;
    // // frag_keyframe+empty_moov
    // // frag_keyframe+empty_moov+default_base_moof
    // av_dict_set(&options, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
    // avformat_write_header(outputCtx, &options);
    // 内存模式
    std::ofstream stream_ts;
    stream_ts.open("D:/tmp/aliang3.mp4", std::ios_base::binary);
    AVFormatContext* outputCtx = avformat_alloc_context();
    size_t buf_size = 4096;
    uint8_t* buf = new uint8_t[buf_size];
    outputCtx->oformat = av_guess_format("mp4", NULL, NULL);
    outputCtx->pb = avio_alloc_context(buf, buf_size, 1, &stream_ts, NULL, write_packet, NULL);
    AVStream* video_stream = avformat_new_stream(outputCtx, NULL);
    avcodec_parameters_from_context(video_stream->codecpar, encoder.codecCtx);
    AVDictionary *options = nullptr;
    // frag_keyframe+empty_moov
    // frag_keyframe+empty_moov+default_base_moof
    av_dict_set(&options, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
    avformat_write_header(outputCtx, &options);
    auto frame{ cv::imread("D:/tmp/bike.jpg") };
    size_t length = 0;
    std::vector<char> data(4 * 1024 * 1024);
    const int width  = frame.cols;
    const int height = frame.rows;
    cv::cvtColor(frame, frame, cv::COLOR_BGR2YUV_I420);
    for(int i = 0; i < 100; ++i) {
        encoder.enc(width, height, frame.data);
        while(encoder.get(data, length)) {
            av_write_frame(outputCtx, encoder.packet);
        }
    }
    av_write_trailer(outputCtx);
    std::cout << "完成\n";