一 费了几天功夫, 一度怀疑实现不了, 结果发现非常简单, 安装msys64, 然后在msys64中安装ffmpeg, 然后就可以编译, 但运行也要在msys64环境下
二 下面的方法经测试可以用
一 下载ffmpeg
1.1
Releases · BtbN/FFmpeg-Builds · GitHub
1.2 解压到某一目录
二 修改cmakefiles.txt
cmake_minimum_required(VERSION 3.4.0)
project(video VERSION 0.1.0)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
cmake_policy(SET CMP0074 NEW)
#set(FFMPEG_ROOT "D:\\lib_for_vnc\\ffmpeg-4.4")
set(FFMPEG_ROOT "D:\\lib_for_vnc\\ffmpeg-n4.4.2-2-g7ffb7d4b04-win64-lgpl-shared-4.4")
#set(FFMPEG_ROOT "D:\\lib_for_vnc\\ffmpeg-n5.0-latest-win64-lgpl-shared-5.0")
find_package(FFMPEG COMPONENTS avcodec avutil avformat swscale)
include_directories(${FFMPEG_INCLUDE_DIRS})
message(STATUS ${FFMPEG_LIBRARIES})
include(CTest)
enable_testing()
add_executable(video main.cpp)
target_link_libraries(video ${FFMPEG_LIBRARIES} ${SDL2_LIBRARIES})
#target_link_libraries(hello ${jpeg_lib} ${GTK2_LIBRARIES})
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
#[==[
Provides the following variables:
* `FFMPEG_INCLUDE_DIRS`: Include directories necessary to use FFMPEG.
* `FFMPEG_LIBRARIES`: Libraries necessary to use FFMPEG. Note that this only
includes libraries for the components requested.
* `FFMPEG_VERSION`: The version of FFMPEG found.
The following components are supported:
* `avcodec`
* `avdevice`
* `avfilter`
* `avformat`
* `avresample`
* `avutil`
* `swresample`
* `swscale`
For each component, the following are provided:
* `FFMPEG_<component>_FOUND`: Libraries for the component.
* `FFMPEG_<component>_INCLUDE_DIRS`: Include directories for
the component.
* `FFMPEG_<component>_LIBRARIES`: Libraries for the component.
* `FFMPEG::<component>`: A target to use with `target_link_libraries`.
Note that only components requested with `COMPONENTS` or `OPTIONAL_COMPONENTS`
are guaranteed to set these variables or provide targets.
#]==]
function (_ffmpeg_find component headername)
find_path("FFMPEG_${component}_INCLUDE_DIR"
NAMES
"lib${component}/${headername}"
PATHS
"${FFMPEG_ROOT}/include"
~/Library/Frameworks
/Library/Frameworks
/usr/local/include
/usr/include
/sw/include # Fink
/opt/local/include # DarwinPorts
/opt/csw/include # Blastwave
/opt/include
/usr/freeware/include
PATH_SUFFIXES
ffmpeg
DOC "FFMPEG's ${component} include directory")
mark_as_advanced("FFMPEG_${component}_INCLUDE_DIR")
# On Windows, static FFMPEG is sometimes built as `lib<name>.a`.
if (WIN32)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".lib")
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "" "lib")
endif ()
find_library("FFMPEG_${component}_LIBRARY"
NAMES
"${component}"
PATHS
"${FFMPEG_ROOT}/lib"
~/Library/Frameworks
/Library/Frameworks
/usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
/sw/lib
/opt/local/lib
/opt/csw/lib
/opt/lib
/usr/freeware/lib64
"${FFMPEG_ROOT}/bin"
DOC "FFMPEG's ${component} library")
mark_as_advanced("FFMPEG_${component}_LIBRARY")
if (FFMPEG_${component}_LIBRARY AND FFMPEG_${component}_INCLUDE_DIR)
set(_deps_found TRUE)
set(_deps_link)
foreach (_ffmpeg_dep IN LISTS ARGN)
if (TARGET "FFMPEG::${_ffmpeg_dep}")
list(APPEND _deps_link "FFMPEG::${_ffmpeg_dep}")
else ()
set(_deps_found FALSE)
endif ()
endforeach ()
if (_deps_found)
if (NOT TARGET "FFMPEG::${component}")
add_library("FFMPEG::${component}" UNKNOWN IMPORTED)
set_target_properties("FFMPEG::${component}" PROPERTIES
IMPORTED_LOCATION "${FFMPEG_${component}_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${FFMPEG_${component}_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LIBRARIES "${_deps_link}")
endif ()
set("FFMPEG_${component}_FOUND" 1
PARENT_SCOPE)
set(version_header_path "${FFMPEG_${component}_INCLUDE_DIR}/lib${component}/version.h")
if (EXISTS "${version_header_path}")
string(TOUPPER "${component}" component_upper)
file(STRINGS "${version_header_path}" version
REGEX "#define *LIB${component_upper}_VERSION_(MAJOR|MINOR|MICRO) ")
string(REGEX REPLACE ".*_MAJOR *\([0-9]*\).*" "\\1" major "${version}")
string(REGEX REPLACE ".*_MINOR *\([0-9]*\).*" "\\1" minor "${version}")
string(REGEX REPLACE ".*_MICRO *\([0-9]*\).*" "\\1" micro "${version}")
if (NOT major STREQUAL "" AND
NOT minor STREQUAL "" AND
NOT micro STREQUAL "")
set("FFMPEG_${component}_VERSION" "${major}.${minor}.${micro}"
PARENT_SCOPE)
endif ()
endif ()
else ()
set("FFMPEG_${component}_FOUND" 0
PARENT_SCOPE)
set(what)
if (NOT FFMPEG_${component}_LIBRARY)
set(what "library")
endif ()
if (NOT FFMPEG_${component}_INCLUDE_DIR)
if (what)
string(APPEND what " or headers")
else ()
set(what "headers")
endif ()
endif ()
set("FFMPEG_${component}_NOT_FOUND_MESSAGE"
"Could not find the ${what} for ${component}."
PARENT_SCOPE)
endif ()
endif ()
endfunction ()
_ffmpeg_find(avutil avutil.h)
_ffmpeg_find(avresample avresample.h
avutil)
_ffmpeg_find(swresample swresample.h
avutil)
_ffmpeg_find(swscale swscale.h
avutil)
_ffmpeg_find(avcodec avcodec.h
avutil)
_ffmpeg_find(avformat avformat.h
avcodec avutil)
_ffmpeg_find(avfilter avfilter.h
avutil)
_ffmpeg_find(avdevice avdevice.h
avformat avutil)
if (TARGET FFMPEG::avutil)
set(_ffmpeg_version_header_path "${FFMPEG_avutil_INCLUDE_DIR}/libavutil/ffversion.h")
if (EXISTS "${_ffmpeg_version_header_path}")
file(STRINGS "${_ffmpeg_version_header_path}" _ffmpeg_version
REGEX "FFMPEG_VERSION")
string(REGEX REPLACE ".*\"n?\(.*\)\"" "\\1" FFMPEG_VERSION "${_ffmpeg_version}")
unset(_ffmpeg_version)
else ()
set(FFMPEG_VERSION FFMPEG_VERSION-NOTFOUND)
endif ()
unset(_ffmpeg_version_header_path)
endif ()
set(FFMPEG_INCLUDE_DIRS)
set(FFMPEG_LIBRARIES)
set(_ffmpeg_required_vars)
foreach (_ffmpeg_component IN LISTS FFMPEG_FIND_COMPONENTS)
if (TARGET "FFMPEG::${_ffmpeg_component}")
set(FFMPEG_${_ffmpeg_component}_INCLUDE_DIRS
"${FFMPEG_${_ffmpeg_component}_INCLUDE_DIR}")
set(FFMPEG_${_ffmpeg_component}_LIBRARIES
"${FFMPEG_${_ffmpeg_component}_LIBRARY}")
list(APPEND FFMPEG_INCLUDE_DIRS
"${FFMPEG_${_ffmpeg_component}_INCLUDE_DIRS}")
list(APPEND FFMPEG_LIBRARIES
"${FFMPEG_${_ffmpeg_component}_LIBRARIES}")
if (FFMEG_FIND_REQUIRED_${_ffmpeg_component})
list(APPEND _ffmpeg_required_vars
"FFMPEG_${_ffmpeg_required_vars}_INCLUDE_DIRS"
"FFMPEG_${_ffmpeg_required_vars}_LIBRARIES")
endif ()
endif ()
endforeach ()
unset(_ffmpeg_component)
if (FFMPEG_INCLUDE_DIRS)
list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
endif ()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FFMPEG
REQUIRED_VARS FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES ${_ffmpeg_required_vars}
VERSION_VAR FFMPEG_VERSION
HANDLE_COMPONENTS)
unset(_ffmpeg_required_vars)
三 测试文件
3.1 测试文件1
#include <stdio.h>
extern "C"{
#include <libavutil/avutil.h>
}
int main()
{
printf("ffmpeg version:%s\n", av_version_info());
return 0;
}
3.2 测试文件2
/*
* Copyright (c) 2014 Stefano Sabatini
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file
* libavformat AVIOContext API example.
*
* Make libavformat demuxer access media content through a custom
* AVIOContext read callback.
* @example avio_reading.c
*/
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavutil/file.h>
}
struct buffer_data {
uint8_t *ptr;
size_t size; ///< size left in the buffer
};
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
{
struct buffer_data *bd = (struct buffer_data *)opaque;
buf_size = FFMIN(buf_size, bd->size);
if (!buf_size)
return AVERROR_EOF;
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
/* copy internal buffer data to buf */
memcpy(buf, bd->ptr, buf_size);
bd->ptr += buf_size;
bd->size -= buf_size;
return buf_size;
}
int main(int argc, char *argv[])
{
AVFormatContext *fmt_ctx = NULL;
AVIOContext *avio_ctx = NULL;
uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;
size_t buffer_size, avio_ctx_buffer_size = 4096;
char *input_filename = NULL;
int ret = 0;
struct buffer_data bd = { 0 };
if (argc != 2) {
fprintf(stderr, "usage: %s input_file\n"
"API example program to show how to read from a custom buffer "
"accessed through AVIOContext.\n", argv[0]);
return 1;
}
input_filename = argv[1];
/* slurp file content into buffer */
ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
if (ret < 0)
goto end;
/* fill opaque structure used by the AVIOContext read callback */
bd.ptr = buffer;
bd.size = buffer_size;
if (!(fmt_ctx = avformat_alloc_context())) {
ret = AVERROR(ENOMEM);
goto end;
}
avio_ctx_buffer = (unsigned char *)av_malloc(avio_ctx_buffer_size);
if (!avio_ctx_buffer) {
ret = AVERROR(ENOMEM);
goto end;
}
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
0, &bd, &read_packet, NULL, NULL);
if (!avio_ctx) {
ret = AVERROR(ENOMEM);
goto end;
}
fmt_ctx->pb = avio_ctx;
ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Could not open input\n");
goto end;
}
ret = avformat_find_stream_info(fmt_ctx, NULL);
if (ret < 0) {
fprintf(stderr, "Could not find stream information\n");
goto end;
}
av_dump_format(fmt_ctx, 0, input_filename, 0);
end:
avformat_close_input(&fmt_ctx);
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
if (avio_ctx)
av_freep(&avio_ctx->buffer);
avio_context_free(&avio_ctx);
av_file_unmap(buffer, buffer_size);
if (ret < 0) {
fprintf(stderr, "Error occurred\n" );
return 1;
}
return 0;
}
四 错误排除
4.1 error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS
#ifdef __cplusplus
#define __STDC_CONSTANT_MACROS
#ifdef _STDINT_H
#undef _STDINT_H
#endif
# include "stdint.h"
#endif
4.2 gcc 版本
经测试
ffmpeg-n4.4.2-2-g7ffb7d4b04-win64-lgpl-shared-4.4
ffmpeg-n5.0-latest-win64-lgpl-shared-5.0
gcc 12.1.0 是通过 msys64 安装的