Merge branch 'master' into dev

This commit is contained in:
xiongguangjie
2023-12-12 14:18:48 +08:00
367 changed files with 4894 additions and 4868 deletions

View File

@@ -14,6 +14,6 @@ assignees: ''
- 此处展开您咨询内容的描述
**注意事项**
- 技术咨询前请先认真阅读readme, [wiki](https://github.com/xia-chu/ZLMediaKit/wiki),如有必要您也可以同时搜索已经答复的issue如果没找到答案才在此提issue
- 技术咨询前请先认真阅读readme, [wiki](https://github.com/ZLMediaKit/ZLMediaKit/wiki),如有必要您也可以同时搜索已经答复的issue如果没找到答案才在此提issue
- 技术咨询不属于bug缺陷要求用户先star(收藏)本项目否则会直接关闭issue

View File

@@ -47,7 +47,7 @@ set(MediaServer_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/media-server")
# TODO: 补一个函数处理各种库
# 添加 mov、flv 库用于 MP4 录制
if (ENABLE_MP4 OR ENABLE_HLS_FMP4)
if (ENABLE_MP4)
# MOV
set(MediaServer_MOV_ROOT ${MediaServer_ROOT}/libmov)
aux_source_directory(${MediaServer_MOV_ROOT}/include MOV_SRC_LIST)
@@ -80,10 +80,6 @@ if (ENABLE_MP4 OR ENABLE_HLS_FMP4)
message(STATUS "ENABLE_MP4 defined")
update_cached_list(MK_COMPILE_DEFINITIONS ENABLE_MP4)
endif ()
if (ENABLE_HLS_FMP4)
message(STATUS "ENABLE_HLS_FMP4 defined")
update_cached_list(MK_COMPILE_DEFINITIONS ENABLE_HLS_FMP4)
endif ()
endif ()
# 添加 mpeg 用于支持 ts 生成
@@ -151,6 +147,17 @@ if(HAVE_RECVMMSG_API)
list(APPEND COMPILE_DEFINITIONS HAVE_RECVMMSG_API)
endif()
# check the socket buffer size set by the upper cmake project, if it is set, use the setting of the upper cmake project, otherwise set it to 256K
# if the socket buffer size is set to 0, it means that the socket buffer size is not set, and the kernel default value is used(just for linux)
if(DEFINED SOCKET_DEFAULT_BUF_SIZE)
if (SOCKET_DEFAULT_BUF_SIZE EQUAL 0)
message(STATUS "Socket default buffer size is not set, use the kernel default value")
else()
message(STATUS "Socket default buffer size is set to ${SOCKET_DEFAULT_BUF_SIZE}")
endif ()
add_definitions(-DSOCKET_DEFAULT_BUF_SIZE=${SOCKET_DEFAULT_BUF_SIZE})
endif()
set(ToolKit_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/ZLToolKit)
# 收集源代码
file(GLOB ToolKit_SRC_LIST

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

12
AUTHORS
View File

@@ -87,4 +87,14 @@ WuPeng <wp@zafu.edu.cn>
[Deepslient](https://github.com/Deepslient)
[imp_rayjay](https://github.com/rayjay214)
[ArmstrongCN](https://github.com/ArmstrongCN)
[leibnewton](https://github.com/leibnewton)
[leibnewton](https://github.com/leibnewton)
[Grin](https://github.com/xyyangkun)
[xbpeng121](https://github.com/xbpeng121)
[lvchenyun](https://github.com/lvchenyun)
[Fummowo](https://github.com/Fummowo)
[Jovial Young ](https://github.com/JHYoung1034)
[yujitai](https://github.com/yujitai)
[KisChang](https://github.com/kisChang)
[zjx94](https://github.com/zjx94)
[LeiZhi.Mai ](https://github.com/blueskiner)
[JiaHao](https://github.com/nashiracn)

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -24,11 +24,13 @@
cmake_minimum_required(VERSION 3.1.3)
# 加载自定义模块
# Load custom modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
project(ZLMediaKit LANGUAGES C CXX)
# 使能 C++11
# Enable C++11
set(CMAKE_CXX_STANDARD 11)
option(ENABLE_API "Enable C API SDK" ON)
@@ -42,7 +44,6 @@ option(ENABLE_JEMALLOC_STATIC "Enable static linking to the jemalloc library" OF
option(ENABLE_JEMALLOC_DUMP "Enable jemalloc to dump malloc statistics" OFF)
option(ENABLE_MEM_DEBUG "Enable Memory Debug" OFF)
option(ENABLE_MP4 "Enable MP4" ON)
option(ENABLE_HLS_FMP4 "Enable HLS-FMP4" ON)
option(ENABLE_MSVC_MT "Enable MSVC Mt/Mtd lib" ON)
option(ENABLE_MYSQL "Enable MySQL" OFF)
option(ENABLE_OPENSSL "Enable OpenSSL" ON)
@@ -58,8 +59,11 @@ option(ENABLE_X264 "Enable x264" OFF)
option(ENABLE_WEPOLL "Enable wepoll" ON)
option(DISABLE_REPORT "Disable report to report.zlmediakit.com" off)
option(USE_SOLUTION_FOLDERS "Enable solution dir supported" ON)
##############################################################################
# 设置socket默认缓冲区大小为256k.如果设置为0则不设置socket的默认缓冲区大小,使用系统内核默认值(设置为0仅对linux有效)
# Set the default buffer size of the socket to 256k. If set to 0, the default buffer size of the socket will not be set,
# and the system kernel default value will be used (setting to 0 is only valid for linux)
set(SOCKET_DEFAULT_BUF_SIZE 262144 CACHE STRING "Default buffer size for socket" FORCE)
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE "Debug")
@@ -68,12 +72,14 @@ endif()
message(STATUS "编译类型: ${CMAKE_BUILD_TYPE}")
# 方便排查编译问题, 需要 FORCE CACHE, 否则需要命令行设置才生效
# To facilitate the troubleshooting of compilation problems, you need to FORCE CACHE, otherwise you need to set it on the command line to take effect
set(CMAKE_VERBOSE_MAKEFILE ON CACHE INTERNAL "" FORCE)
# TODO: include 当前目录会导致 server 编译出错, 待排除
set(CMAKE_INCLUDE_CURRENT_DIR OFF)
# 安装路径
# Install path
if(NOT CMAKE_INSTALL_PREFIX)
if(UNIX)
set(INSTALL_PATH_LIB lib${LIB_SUFFIX})
@@ -81,6 +87,7 @@ if(NOT CMAKE_INSTALL_PREFIX)
set(INSTALL_PATH_RUNTIME bin)
elseif(WIN32)
# Windows 下安装到了用户主目录下?
# Install to the user's home directory under Windows?
set(INSTALL_PATH_LIB $ENV{HOME}/${CMAKE_PROJECT_NAME}/lib)
set(INSTALL_PATH_INCLUDE $ENV{HOME}/${CMAKE_PROJECT_NAME}/include)
else()
@@ -95,11 +102,14 @@ endif()
string(TOLOWER ${CMAKE_SYSTEM_NAME} SYSTEM_NAME_LOWER)
# 设置输出目录, 包括 bin, lib 以及其他文件
# Windows 也不再区分 32/64
# Set the output directory, including bin, lib and other files
# Windows no longer distinguishes 32/64
set(OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/release/${SYSTEM_NAME_LOWER}/${CMAKE_BUILD_TYPE})
set(LIBRARY_OUTPUT_PATH ${OUTPUT_DIR})
set(EXECUTABLE_OUTPUT_PATH ${OUTPUT_DIR})
# 添加 git 版本信息
# Add git version information
set(COMMIT_HASH "Git_Unkown_commit")
set(COMMIT_TIME "Git_Unkown_time")
set(BRANCH_NAME "Git_Unkown_branch")
@@ -140,6 +150,7 @@ message(STATUS "Git version is ${BRANCH_NAME} ${COMMIT_HASH}/${COMMIT_TIME} ${BU
##############################################################################
# 方便修改全局变量
# Convenient to modify global variables
function(update_cached name value)
set("${name}" "${value}" CACHE INTERNAL "*** Internal ***" FORCE)
endfunction()
@@ -202,6 +213,7 @@ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
endif()
# mediakit 以及各个 runtime 依赖
# mediakit and various runtime dependencies
update_cached(MK_LINK_LIBRARIES "")
update_cached(MK_COMPILE_DEFINITIONS ENABLE_VERSION)
@@ -226,9 +238,11 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
endif()
# 多个模块依赖 ffmpeg 相关库, 统一查找
# Multiple modules depend on ffmpeg related libraries, unified search
if(ENABLE_FFMPEG)
find_package(PkgConfig QUIET)
# 查找 ffmpeg/libutil 是否安装
# find ffmpeg/libutil installed
if(PKG_CONFIG_FOUND)
pkg_check_modules(AVUTIL QUIET IMPORTED_TARGET libavutil)
if(AVUTIL_FOUND)
@@ -238,6 +252,7 @@ if(ENABLE_FFMPEG)
endif()
# 查找 ffmpeg/libavcodec 是否安装
# find ffmpeg/libavcodec installed
if(PKG_CONFIG_FOUND)
pkg_check_modules(AVCODEC QUIET IMPORTED_TARGET libavcodec)
if(AVCODEC_FOUND)
@@ -247,6 +262,7 @@ if(ENABLE_FFMPEG)
endif()
# 查找 ffmpeg/libswscale 是否安装
# find ffmpeg/libswscale installed
if(PKG_CONFIG_FOUND)
pkg_check_modules(SWSCALE QUIET IMPORTED_TARGET libswscale)
if(SWSCALE_FOUND)
@@ -256,6 +272,7 @@ if(ENABLE_FFMPEG)
endif()
# 查找 ffmpeg/libswresample 是否安装
# find ffmpeg/libswresample installed
if(PKG_CONFIG_FOUND)
pkg_check_modules(SWRESAMPLE QUIET IMPORTED_TARGET libswresample)
if(SWRESAMPLE_FOUND)
@@ -265,6 +282,7 @@ if(ENABLE_FFMPEG)
endif()
# 查找 ffmpeg/libutil 是否安装
# find ffmpeg/libutil installed
if(NOT AVUTIL_FOUND)
find_package(AVUTIL QUIET)
if(AVUTIL_FOUND)
@@ -275,6 +293,7 @@ if(ENABLE_FFMPEG)
endif ()
# 查找 ffmpeg/libavcodec 是否安装
# find ffmpeg/libavcodec installed
if(NOT AVCODEC_FOUND)
find_package(AVCODEC QUIET)
if(AVCODEC_FOUND)
@@ -285,6 +304,7 @@ if(ENABLE_FFMPEG)
endif()
# 查找 ffmpeg/libswscale 是否安装
# find ffmpeg/libswscale installed
if(NOT SWSCALE_FOUND)
find_package(SWSCALE QUIET)
if(SWSCALE_FOUND)
@@ -295,6 +315,7 @@ if(ENABLE_FFMPEG)
endif()
# 查找 ffmpeg/libswresample 是否安装
# find ffmpeg/libswresample installed
if(NOT SWRESAMPLE_FOUND)
find_package(SWRESAMPLE QUIET)
if(SWRESAMPLE_FOUND)
@@ -309,7 +330,7 @@ if(ENABLE_FFMPEG)
update_cached_list(MK_LINK_LIBRARIES ${CMAKE_DL_LIBS})
else()
set(ENABLE_FFMPEG OFF)
message(WARNING "ffmpeg 相关功能未找到")
message(WARNING "ffmpeg related functions not found")
endif()
endif()
@@ -317,7 +338,7 @@ if(ENABLE_MEM_DEBUG)
update_cached_list(MK_LINK_LIBRARIES
"-Wl,-wrap,free;-Wl,-wrap,malloc;-Wl,-wrap,realloc;-Wl,-wrap,calloc")
update_cached_list(MK_COMPILE_DEFINITIONS ENABLE_MEM_DEBUG)
message(STATUS "已启用内存调试功能")
message(STATUS "Memory debugging enabled")
endif()
if(ENABLE_ASAN)
@@ -327,10 +348,11 @@ if(ENABLE_ASAN)
# > In order to use AddressSanitizer you will need to
# > compile and link your program using clang with the -fsanitize=address switch.
update_cached_list(MK_LINK_LIBRARIES "-fsanitize=address")
message(STATUS "已启用 Address Sanitize")
message(STATUS "Address Sanitize enabled")
endif()
# TODO: 下载静态编译 jemalloc 后静态编译链接?
# 下载jemalloc后静态编译
# Static compilation after downloading jemalloc
set(DEP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdpart/external-${CMAKE_SYSTEM_NAME})
if(ENABLE_JEMALLOC_STATIC)
if(NOT EXISTS ${DEP_ROOT_DIR})
@@ -345,10 +367,12 @@ if(ENABLE_JEMALLOC_STATIC)
include_directories(SYSTEM ${DEP_ROOT_DIR}/${JEMALLOC_NAME}/include/jemalloc)
link_directories(${DEP_ROOT_DIR}/${JEMALLOC_NAME}/lib)
# 用于影响后续查找过程
# Used to affect subsequent lookup process
set(JEMALLOC_ROOT_DIR "${DEP_ROOT_DIR}/${JEMALLOC_NAME}")
endif()
# 默认链接 jemalloc 库避免内存碎片
# Link the jemalloc library by default to avoid memory fragmentation
find_package(JEMALLOC QUIET)
if(JEMALLOC_FOUND)
message(STATUS "found library: ${JEMALLOC_LIBRARIES}")
@@ -363,6 +387,7 @@ if(JEMALLOC_FOUND)
endif()
# 查找 openssl 是否安装
# find openssl installed
find_package(OpenSSL QUIET)
if(OPENSSL_FOUND AND ENABLE_OPENSSL)
message(STATUS "found library: ${OPENSSL_LIBRARIES}, ENABLE_OPENSSL defined")
@@ -379,6 +404,7 @@ else()
endif()
# 查找 mysql 是否安装
# find mysql installed
find_package(MYSQL QUIET)
if(MYSQL_FOUND AND ENABLE_MYSQL)
message(STATUS "found library: ${MYSQL_LIBRARIES}, ENABLE_MYSQL defined")
@@ -391,6 +417,7 @@ if(MYSQL_FOUND AND ENABLE_MYSQL)
endif()
# 查找 x264 是否安装
# find x264 installed
find_package(X264 QUIET)
if(X264_FOUND AND ENABLE_X264)
message(STATUS "found library: ${X264_LIBRARIES}, ENABLE_X264 defined")
@@ -401,6 +428,7 @@ if(X264_FOUND AND ENABLE_X264)
endif()
# 查找 faac 是否安装
# find faac installed
find_package(FAAC QUIET)
if(FAAC_FOUND AND ENABLE_FAAC)
message(STATUS "found library:${FAAC_LIBRARIES}, ENABLE_FAAC defined")
@@ -449,6 +477,8 @@ add_subdirectory(3rdpart)
add_subdirectory(src)
add_subdirectory(ext-codec)
if(ENABLE_SRT)
add_subdirectory(srt)
endif()
@@ -468,26 +498,31 @@ if(ENABLE_PLAYER AND ENABLE_FFMPEG)
endif()
#MediaServer主程序
#MediaServer main program
if(ENABLE_SERVER)
add_subdirectory(server)
endif()
# Android 会 add_subdirectory 并依赖该变量
# Android will add_subdirectory and depend on this variable
if(ENABLE_SERVER_LIB AND NOT CMAKE_PARENT_LIST_FILE STREQUAL CMAKE_CURRENT_LIST_FILE)
set(MK_LINK_LIBRARIES ${MK_LINK_LIBRARIES} PARENT_SCOPE)
endif()
# IOS 不编译可执行程序
# IOS does not compile executable programs
if(IOS)
return()
endif()
#cpp测试demo程序
#cpp test demo program
if (ENABLE_TESTS)
add_subdirectory(tests)
endif ()
# 拷贝www文件夹、配置文件、默认证书
# Copy www folder, configuration file, default certificate
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/www" DESTINATION ${EXECUTABLE_OUTPUT_PATH})
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/conf/config.ini" DESTINATION ${EXECUTABLE_OUTPUT_PATH})
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/default.pem" DESTINATION ${EXECUTABLE_OUTPUT_PATH})

10
LICENSE
View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,11 @@ 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.
----------------------------------------------------------------------------------------
补充协议:
本项目采用类MIT协议用户在履行MIT协议义务的同时应当同时遵循保留ZLMediaKit软件版权信息的义务。
用户不得去除ZLMediaKit提供的各种服务中包括但不限于 "title"、"Server"、"User-Agent" 等字段中 "ZLMediaKit" 的信息。
否则本项目主要权利人(项目发起人、主要作者)保留声索起诉的权利。

View File

@@ -36,6 +36,7 @@
- 极致体验,[独家特性](https://github.com/ZLMediaKit/ZLMediaKit/wiki/ZLMediakit%E7%8B%AC%E5%AE%B6%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D)
- [谁在使用zlmediakit?](https://github.com/ZLMediaKit/ZLMediaKit/issues/511)
- 全面支持ipv6网络
- 支持多轨道模式(一个流中多个视频/音频)
## 项目定位
@@ -76,16 +77,19 @@
- 通过cookie追踪技术可以模拟HLS播放为长连接可以实现HLS按需拉流、播放统计等业务
- 支持HLS播发器支持拉流HLS转rtsp/rtmp/mp4
- 支持H264/H265/AAC/G711/OPUS编码
- 支持多轨道模式
- TS
- 支持http[s]-ts直播
- 支持ws[s]-ts直播
- 支持H264/H265/AAC/G711/OPUS编码
- 支持多轨道模式
- fMP4
- 支持http[s]-fmp4直播
- 支持ws[s]-fmp4直播
- 支持H264/H265/AAC/G711/OPUS/MJPEG编码
- 支持多轨道模式
- HTTP[S]与WebSocket
- 服务器支持`目录索引生成`,`文件下载`,`表单提交请求`
@@ -104,11 +108,13 @@
- 支持es/ps rtp转推
- 支持GB28181主动拉流模式
- 支持双向语音对讲
- 支持多轨道模式
- MP4点播与录制
- 支持录制为FLV/HLS/MP4
- RTSP/RTMP/HTTP-FLV/WS-FLV支持MP4文件点播支持seek
- 支持H264/H265/AAC/G711/OPUS编码
- 支持多轨道模式
- WebRTC
- 支持WebRTC推流支持转其他协议
@@ -188,6 +194,8 @@ bash build_docker_images.sh
- [AKStreamNVR](https://github.com/langmansh/AKStreamNVR) 前后端分离web项目,支持webrtc播放
- SDK
- [spring-boot-starter](https://github.com/lunasaw/zlm-spring-boot-starter) 本项目hook和rest接口starter
- [java sdk](https://github.com/lidaofu-hub/j_zlm_sdk) 本项目c sdk完整java包装库
- [c# sdk](https://github.com/malegend/ZLMediaKit.Autogen) 本项目c sdk完整c#包装库
- [metaRTC](https://github.com/metartc/metaRTC) 全国产纯c webrtc sdk
@@ -334,6 +342,16 @@ bash build_docker_images.sh
[ArmstrongCN](https://github.com/ArmstrongCN)
[leibnewton](https://github.com/leibnewton)
[1002victor](https://github.com/1002victor)
[Grin](https://github.com/xyyangkun)
[xbpeng121](https://github.com/xbpeng121)
[lvchenyun](https://github.com/lvchenyun)
[Fummowo](https://github.com/Fummowo)
[Jovial Young ](https://github.com/JHYoung1034)
[yujitai](https://github.com/yujitai)
[KisChang](https://github.com/kisChang)
[zjx94](https://github.com/zjx94)
[LeiZhi.Mai ](https://github.com/blueskiner)
[JiaHao](https://github.com/nashiracn)
同时感谢JetBrains对开源项目的支持本项目使用CLion开发与调试

View File

@@ -157,7 +157,7 @@ It is recommended to compile on Ubuntu or macOS. Compiling on Windows is cumbers
- **You must use Git to clone the complete code. Do not download the source code by downloading the ZIP package. Otherwise, the submodule code will not be downloaded by default. You can do it like this:**
```
git clone https://github.com/xia-chu/ZLMediaKit.git
git clone https://github.com/ZLMediaKit/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
```
@@ -357,6 +357,8 @@ bash build_docker_images.sh
- [Hikvision ehome server implemented in Go](https://github.com/tsingeye/FreeEhome)
- Client
- [Http Api and hook in zlm-spring-boot-starter](https://github.com/lunasaw/zlm-spring-boot-starter)
- [Complete java wrapper library for c sdk](https://github.com/lidaofu-hub/j_zlm_sdk)
- [Complete C# wrapper library for c sdk](https://github.com/malegend/ZLMediaKit.Autogen)
- [Push client implemented based on C SDK](https://github.com/hctym1995/ZLM_ApiDemo)
- [Http API and Hook in C#](https://github.com/chengxiaosheng/ZLMediaKit.HttpApi)
@@ -498,6 +500,16 @@ Thanks to all those who have supported this project in various ways, including b
[ArmstrongCN](https://github.com/ArmstrongCN)
[leibnewton](https://github.com/leibnewton)
[1002victor](https://github.com/1002victor)
[Grin](https://github.com/xyyangkun)
[xbpeng121](https://github.com/xbpeng121)
[lvchenyun](https://github.com/lvchenyun)
[Fummowo](https://github.com/Fummowo)
[Jovial Young ](https://github.com/JHYoung1034)
[yujitai](https://github.com/yujitai)
[KisChang](https://github.com/kisChang)
[zjx94](https://github.com/zjx94)
[LeiZhi.Mai ](https://github.com/blueskiner)
[JiaHao](https://github.com/nashiracn)
Also thank to JetBrains for their support for open source project, we developed and debugged zlmediakit with CLion:

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -280,7 +280,6 @@ API_EXPORT uint16_t API_CALL mk_rtc_server_start(uint16_t port) {
class WebRtcArgsUrl : public mediakit::WebRtcArgs {
public:
WebRtcArgsUrl(std::string url) { _url = std::move(url); }
~WebRtcArgsUrl() = default;
toolkit::variant operator[](const std::string &key) const override {
if (key == "url") {
@@ -305,7 +304,8 @@ API_EXPORT void API_CALL mk_webrtc_get_answer_sdp2(void *user_data, on_user_data
auto session = std::make_shared<HttpSession>(Socket::createSocket());
std::string offer_str = offer;
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
WebRtcPluginManager::Instance().getAnswerSdp(*session, type, WebRtcArgsUrl(url),
auto args = std::make_shared<WebRtcArgsUrl>(url);
WebRtcPluginManager::Instance().getAnswerSdp(*session, type, *args,
[offer_str, session, ptr, cb](const WebRtcInterface &exchanger) mutable {
try {
auto sdp_answer = exchangeSdp(exchanger, offer_str);

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,115 +1,70 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "mk_frame.h"
#include "mk_track.h"
#include "Extension/Frame.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/AAC.h"
#include "Record/MPEG.h"
#include "Extension/Factory.h"
using namespace mediakit;
extern "C" {
#define XX(name, type, value, str, mpeg_id) API_EXPORT const int MK##name = value;
#define XX(name, type, value, str, mpeg_id, mp4_id) API_EXPORT const int MK##name = value;
CODEC_MAP(XX)
#undef XX
}
class FrameFromPtrForC : public FrameFromPtr {
namespace {
class BufferFromPtr : public toolkit::Buffer {
public:
using Ptr = std::shared_ptr<FrameFromPtrForC>;
template<typename ...ARGS>
FrameFromPtrForC(bool cache_able, uint32_t flags, on_mk_frame_data_release cb, std::shared_ptr<void> user_data, ARGS &&...args) : FrameFromPtr(
std::forward<ARGS>(args)...) {
_flags = flags;
BufferFromPtr(char *ptr, size_t size, on_mk_frame_data_release cb, std::shared_ptr<void> user_data) {
_ptr = ptr;
_size = size;
_cb = cb;
_user_data = std::move(user_data);
_cache_able = cache_able;
}
~FrameFromPtrForC() override {
if (_cb) {
_cb(_user_data.get(), _ptr);
}
~BufferFromPtr() override {
_cb(_user_data.get(), _ptr);
}
bool cacheAble() const override {
return _cache_able;
}
bool keyFrame() const override {
return _flags & MK_FRAME_FLAG_IS_KEY;
}
bool configFrame() const override {
return _flags & MK_FRAME_FLAG_IS_CONFIG;
}
//默认返回false
bool dropAble() const override {
return _flags & MK_FRAME_FLAG_DROP_ABLE;
}
//默认返回true
bool decodeAble() const override {
return !(_flags & MK_FRAME_FLAG_NOT_DECODE_ABLE);
}
char *data() const override { return _ptr; }
size_t size() const override { return _size; }
private:
uint32_t _flags;
char *_ptr;
size_t _size;
on_mk_frame_data_release _cb;
std::shared_ptr<void> _user_data;
bool _cache_able;
};
}; // namespace
static mk_frame mk_frame_create_complex(int codec_id, uint64_t dts, uint64_t pts, uint32_t frame_flags, size_t prefix_size,
char *data, size_t size, on_mk_frame_data_release cb, std::shared_ptr<void> user_data) {
switch (codec_id) {
case CodecH264:
return (mk_frame)new Frame::Ptr(new H264FrameHelper<FrameFromPtrForC>(
cb, frame_flags, cb, std::move(user_data), (CodecId)codec_id, data, size, dts, pts, prefix_size));
case CodecH265:
return (mk_frame)new Frame::Ptr(new H265FrameHelper<FrameFromPtrForC>(
cb, frame_flags, cb, std::move(user_data), (CodecId)codec_id, data, size, dts, pts, prefix_size));
default:
return (mk_frame)new Frame::Ptr(new FrameFromPtrForC(
cb, frame_flags, cb, std::move(user_data), (CodecId)codec_id, data, size, dts, pts, prefix_size));
static mk_frame mk_frame_create_complex(int codec_id, uint64_t dts, uint64_t pts, const char *data, size_t size,
on_mk_frame_data_release cb, std::shared_ptr<void> user_data) {
if (!cb) {
// no cacheable
return (mk_frame) new Frame::Ptr(Factory::getFrameFromPtr((CodecId)codec_id, data, size, dts, pts));
}
// cacheable
auto buffer = std::make_shared<BufferFromPtr>((char *)data, size, cb, std::move(user_data));
return (mk_frame) new Frame::Ptr(Factory::getFrameFromBuffer((CodecId)codec_id, std::move(buffer), dts, pts));
}
API_EXPORT mk_frame API_CALL mk_frame_create(int codec_id, uint64_t dts, uint64_t pts, const char *data, size_t size,
on_mk_frame_data_release cb, void *user_data) {
on_mk_frame_data_release cb, void *user_data) {
return mk_frame_create2(codec_id, dts, pts, data, size, cb, user_data, nullptr);
}
API_EXPORT mk_frame API_CALL mk_frame_create2(int codec_id, uint64_t dts, uint64_t pts, const char *data, size_t size,
on_mk_frame_data_release cb, void *user_data, on_user_data_free user_data_free) {
on_mk_frame_data_release cb, void *user_data, on_user_data_free user_data_free) {
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
switch (codec_id) {
case CodecH264:
case CodecH265:
return mk_frame_create_complex(codec_id, dts, pts, 0, prefixSize(data, size), (char *)data, size, cb, std::move(ptr));
case CodecAAC: {
int prefix = 0;
if ((((uint8_t *) data)[0] == 0xFF && (((uint8_t *) data)[1] & 0xF0) == 0xF0) && size > ADTS_HEADER_LEN) {
prefix = ADTS_HEADER_LEN;
}
return mk_frame_create_complex(codec_id, dts, pts, 0, prefix, (char *)data, size, cb, std::move(ptr));
}
default:
return mk_frame_create_complex(codec_id, dts, pts, 0, 0, (char *)data, size, cb, std::move(ptr));
}
return mk_frame_create_complex(codec_id, dts, pts, data, size, cb, std::move(ptr));
}
API_EXPORT void API_CALL mk_frame_unref(mk_frame frame) {

View File

@@ -1,17 +1,16 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "mk_h264_splitter.h"
#include "Http/HttpRequestSplitter.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/Factory.h"
using namespace mediakit;
@@ -71,9 +70,9 @@ const char *H264Splitter::onSearchPacketTail(const char *data, size_t len) {
auto last_frame_len = next_frame - last_frame;
Frame::Ptr frame;
if (_h265) {
frame = std::make_shared<H265FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len));
frame = Factory::getFrameFromPtr(CodecH265, (char *)last_frame, last_frame_len, 0, 0);
} else {
frame = std::make_shared<H264FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len));
frame = Factory::getFrameFromPtr(CodecH264, (char *)last_frame, last_frame_len, 0, 0);
}
if (frame->decodeAble()) {
_search_pos = 0;

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,7 +11,6 @@
#include "mk_player.h"
#include "Util/logger.h"
#include "Player/MediaPlayer.h"
#include "Extension/H264.h"
using namespace std;
using namespace toolkit;
@@ -24,7 +23,6 @@ public:
MediaPlayerForC(){
_player = std::make_shared<MediaPlayer>();
}
~MediaPlayerForC() = default;
MediaPlayer *operator->(){
return _player.get();

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -33,9 +33,8 @@ private:
class SessionForC : public toolkit::Session {
public:
SessionForC(const toolkit::Socket::Ptr &pSock) ;
~SessionForC() override = default;
void onRecv(const toolkit::Buffer::Ptr &buffer) override ;
SessionForC(const toolkit::Socket::Ptr &pSock);
void onRecv(const toolkit::Buffer::Ptr &buffer) override;
void onError(const toolkit::SockException &err) override;
void onManager() override;
std::shared_ptr<void> _user_data;

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -80,8 +80,6 @@ public:
_user_data = std::move(user_data);
}
~TimerForC() = default;
uint64_t operator()(){
lock_guard<recursive_mutex> lck(_mxt);
if(!_cb){
@@ -135,8 +133,6 @@ API_EXPORT void API_CALL mk_timer_release(mk_timer ctx){
class WorkThreadPoolForC : public TaskExecutorGetterImp {
public:
~WorkThreadPoolForC() override = default;
WorkThreadPoolForC(const char *name, size_t n_thread, int priority) {
//最低优先级
addPoller(name, n_thread, (ThreadPool::Priority) priority, false);

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -27,8 +27,6 @@ public:
}
}
~VideoTrackForC() override = default;
int getVideoHeight() const override {
return _args.video.height;
}
@@ -45,16 +43,16 @@ public:
return _codec_id;
}
bool ready() override {
bool ready() const override {
return true;
}
Track::Ptr clone() override {
auto track_in = std::shared_ptr<Track>(shared_from_this());
Track::Ptr clone() const override {
auto track_in = std::shared_ptr<Track>(const_cast<VideoTrackForC *>(this)->shared_from_this());
return Factory::getTrackByAbstractTrack(track_in);
}
Sdp::Ptr getSdp() override {
Sdp::Ptr getSdp(uint8_t) const override {
return nullptr;
}
@@ -65,17 +63,15 @@ private:
class AudioTrackForC : public AudioTrackImp, public std::enable_shared_from_this<AudioTrackForC> {
public:
~AudioTrackForC() override = default;
AudioTrackForC(int codec_id, codec_args *args) :
AudioTrackImp((CodecId) codec_id, args->audio.sample_rate, args->audio.channels, 16) {}
Track::Ptr clone() override {
auto track_in = std::shared_ptr<Track>(shared_from_this());
Track::Ptr clone() const override {
auto track_in = std::shared_ptr<Track>(const_cast<AudioTrackForC *>(this)->shared_from_this());
return Factory::getTrackByAbstractTrack(track_in);
}
Sdp::Ptr getSdp() override {
Sdp::Ptr getSdp(uint8_t payload_type) const override {
return nullptr;
}
};

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -15,6 +15,8 @@ secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
snapRoot=./www/snap/
#默认截图图片在启动FFmpeg截图后但是截图还未生成时可以返回默认的预设图片
defaultSnap=./www/logo.png
#downloadFile http接口可访问文件的根目录支持多个目录不同目录通过分号(;)分隔
downloadRoot=./www
[ffmpeg]
#FFmpeg可执行程序路径,支持相对路径/绝对路径
@@ -50,6 +52,10 @@ auto_close=0
#此参数不应大于播放器超时时间;单位毫秒
continue_push_ms=15000
#平滑发送定时器间隔单位毫秒置0则关闭开启后影响cpu性能同时增加内存
#该配置开启后可以解决一些流发送不平滑导致zlmediakit转发也不平滑的问题
paced_sender_ms=0
#是否开启转换为hls(mpegts)
enable_hls=1
#是否开启转换为hls(fmp4)
@@ -140,48 +146,50 @@ deleteDelaySec=10
#0为不保留不起作用
#1为保留则不删除hls文件如果开启此功能注意磁盘大小或者定期手动清理hls文件
segKeep=0
#如果设置为1则第一个切片长度强制设置为1个GOP。当GOP小于segDur可以提高首屏速度
fastRegister=0
[hook]
#是否启用hook事件启用后推拉流都将进行鉴权
enable=0
#播放器或推流器使用流量事件,置空则关闭
on_flow_report=https://127.0.0.1/index/hook/on_flow_report
on_flow_report=
#访问http文件鉴权事件置空则关闭鉴权
on_http_access=https://127.0.0.1/index/hook/on_http_access
on_http_access=
#播放鉴权事件,置空则关闭鉴权
on_play=https://127.0.0.1/index/hook/on_play
on_play=
#推流鉴权事件,置空则关闭鉴权
on_publish=https://127.0.0.1/index/hook/on_publish
on_publish=
#录制mp4切片完成事件
on_record_mp4=https://127.0.0.1/index/hook/on_record_mp4
on_record_mp4=
# 录制 hls ts(或fmp4) 切片完成事件
on_record_ts=https://127.0.0.1/index/hook/on_record_ts
on_record_ts=
#rtsp播放鉴权事件此事件中比对rtsp的用户名密码
on_rtsp_auth=https://127.0.0.1/index/hook/on_rtsp_auth
on_rtsp_auth=
#rtsp播放是否开启专属鉴权事件置空则关闭rtsp鉴权。rtsp播放鉴权还支持url方式鉴权
#建议开发者统一采用url参数方式鉴权rtsp用户名密码鉴权一般在设备上用的比较多
#开启rtsp专属鉴权后将不再触发on_play鉴权事件
on_rtsp_realm=https://127.0.0.1/index/hook/on_rtsp_realm
on_rtsp_realm=
#远程telnet调试鉴权事件
on_shell_login=https://127.0.0.1/index/hook/on_shell_login
on_shell_login=
#直播流注册或注销事件
on_stream_changed=https://127.0.0.1/index/hook/on_stream_changed
on_stream_changed=
#过滤on_stream_changed hook的协议类型可以选择只监听某些感兴趣的协议置空则不过滤协议
stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4
#无人观看流事件通过该事件可以选择是否关闭无人观看的流。配合general.streamNoneReaderDelayMS选项一起使用
on_stream_none_reader=https://127.0.0.1/index/hook/on_stream_none_reader
on_stream_none_reader=
#播放时未找到流事件通过配合hook.on_stream_none_reader事件可以完成按需拉流
on_stream_not_found=https://127.0.0.1/index/hook/on_stream_not_found
on_stream_not_found=
#服务器启动报告,可以用于服务器的崩溃重启事件监听
on_server_started=https://127.0.0.1/index/hook/on_server_started
on_server_started=
#服务器退出报告,当服务器正常退出时触发
on_server_exited=https://127.0.0.1/index/hook/on_server_exited
on_server_exited=
#server保活上报
on_server_keepalive=https://127.0.0.1/index/hook/on_server_keepalive
on_server_keepalive=
#发送rtp(startSendRtp)被动关闭时回调
on_send_rtp_stopped=https://127.0.0.1/index/hook/on_send_rtp_stopped
on_send_rtp_stopped=
#rtp server 超时未收到数据
on_rtp_server_timeout=https://127.0.0.1/index/hook/on_rtp_server_timeout
on_rtp_server_timeout=
#hook api最大等待回复时间单位秒
timeoutSec=10
@@ -278,6 +286,10 @@ keepAliveSecond=15
port=1935
#rtmps服务器监听地址
sslport=0
# rtmp是否直接代理模式
directProxy=1
#h265 rtmp打包采用增强型rtmp标准还是国内拓展标准
enhanced=1
[rtp]
#音频mtu大小该参数限制rtp最大字节数推荐不要超过1400
@@ -339,6 +351,11 @@ preferredCodecA=PCMU,PCMA,opus,mpeg4-generic
#以下范例为所有支持的视频codec
preferredCodecV=H264,H265,AV1,VP9,VP8
#webrtc比特率设置
start_bitrate=0
max_bitrate=0
min_bitrate=0
[srt]
#srt播放推流、播放超时时间,单位秒
timeoutSec=5

24
conf/readme.md Normal file
View File

@@ -0,0 +1,24 @@
## 配置文件影响性能的参数
### 1、protocol.enable_xxx
控制转协议开关关闭某些协议节省cpu和内存。
### 2、protocol.xxx_demand
控制按需转协议开启转协议且按需转协议时无人观看时节省cpu和内存但是第一个播放器无法秒开影响体验
### 3、protocol.paced_sender_ms
平滑发送定时器频率,用于解决数据源发送不平滑导致转发不平滑播放器卡顿问题,开启后定时器根据数据时间戳驱动数据发送,提高用户体验。
但是增加cpu和内存使用。定时器间隔越小cpu占用越高但是平滑度越好建议设置30~100ms。此功能结合protocol.modify_stamp为2(抑制时间戳跳跃)最佳。
### 4、general.mergeWriteMS
开启合并写,减少发送数据时系统调用次数以及线程间数据共享频率,大大提高转发性能,但是牺牲播放延时和发送平滑度。
### 5、rtp_proxy.gop_cache
开启startSendRtp级联接口的gop缓存功能用于国标级联秒开。该选项不影响zlmediakit对外提供直播服务的秒开。
开启该选项后增加内存使用对cpu影响较小如果不调用startSendRtp接口建议关闭。
### 6、hls.fileBufSize
调整该配置可以提高hls协议写磁盘io性能。
### 7、record.fileBufSize
调整该配置可以提高mp4录制写磁盘io性能。

View File

@@ -94,7 +94,7 @@ RUN cd /opt \
&& make install
RUN cd /opt \
&& git clone --depth 1 https://github.com/xia-chu/ZLMediaKit.git \
&& git clone --depth 1 https://github.com/ZLMediaKit/ZLMediaKit.git \
&& cd ZLMediaKit \
&& git submodule update --init \
&& mkdir -p build release/linux/Release/ \
@@ -112,7 +112,7 @@ RUN mkdir -p /opt/build/opt/zlm/ /opt/build/usr/local/bin/ /opt/build/usr/bin/
&& /usr/bin/cp -ip /usr/bin/which ./usr/bin/
FROM centos:${Version}
LABEL maintainer="chengxiaosheng <kevin__cheng@outlook.com>" project-url="https://github.com/xia-chu/ZLMediaKit" description="一个基于C++11的高性能运营级流媒体服务框架"
LABEL maintainer="chengxiaosheng <kevin__cheng@outlook.com>" project-url="https://github.com/ZLMediaKit/ZLMediaKit" description="一个基于C++11的高性能运营级流媒体服务框架"
EXPOSE 9000/tcp \
1935/tcp \

View File

@@ -32,7 +32,7 @@ RUN apt-get update && \
RUN mkdir -p /opt/media
WORKDIR /opt/media
RUN git clone --depth=1 https://github.com/xia-chu/ZLMediaKit && \
RUN git clone --depth=1 https://github.com/ZLMediaKit/ZLMediaKit && \
cd ZLMediaKit && git submodule update --init --recursive && \
mkdir -p build release/linux/Release/

View File

@@ -31,7 +31,7 @@ RUN apt-get update && \
RUN mkdir -p /opt/media
WORKDIR /opt/media
RUN git clone --depth=1 https://github.com/xia-chu/ZLMediaKit && \
RUN git clone --depth=1 https://github.com/ZLMediaKit/ZLMediaKit && \
cd ZLMediaKit && git submodule update --init --recursive && \
mkdir -p build release/linux/Release/

View File

@@ -33,7 +33,7 @@ RUN apt-get update && \
RUN mkdir -p /opt/media
WORKDIR /opt/media
RUN git clone --depth=1 https://github.com/xia-chu/ZLMediaKit && \
RUN git clone --depth=1 https://github.com/ZLMediaKit/ZLMediaKit && \
cd ZLMediaKit && git submodule update --init --recursive && \
mkdir -p build release/linux/Release/

View File

@@ -31,7 +31,7 @@ RUN apt-get update && \
RUN mkdir -p /opt/media
WORKDIR /opt/media
RUN git clone --depth=1 https://github.com/xia-chu/ZLMediaKit && \
RUN git clone --depth=1 https://github.com/ZLMediaKit/ZLMediaKit && \
cd ZLMediaKit && git submodule update --init --recursive && \
mkdir -p build release/linux/Release/

View File

@@ -1,14 +1,18 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "AAC.h"
#include "AACRtp.h"
#include "AACRtmp.h"
#include "Common/Parser.h"
#include "Extension/Factory.h"
#ifdef ENABLE_MP4
#include "mpeg4-aac.h"
#endif
@@ -205,39 +209,31 @@ public:
/**
*
* @param aac_cfg aac两个字节的配置描述
* @param payload_type rtp payload type
* @param sample_rate
* @param payload_type rtp payload type 98
* @param channels
* @param bitrate
*/
AACSdp(const string &aac_cfg,
int sample_rate,
int channels,
int bitrate = 128,
int payload_type = 98) : Sdp(sample_rate,payload_type){
AACSdp(const string &aac_cfg, int payload_type, int sample_rate, int channels, int bitrate)
: Sdp(sample_rate, payload_type) {
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
_printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << sample_rate << "/" << channels << "\r\n";
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(CodecAAC) << "/" << sample_rate << "/" << channels << "\r\n";
string configStr;
char buf[4] = {0};
for(auto &ch : aac_cfg){
char buf[4] = { 0 };
for (auto &ch : aac_cfg) {
snprintf(buf, sizeof(buf), "%02X", (uint8_t)ch);
configStr.append(buf);
}
_printer << "a=fmtp:" << payload_type << " streamtype=5;profile-level-id=1;mode=AAC-hbr;"
<< "sizelength=13;indexlength=3;indexdeltalength=3;config=" << configStr << "\r\n";
_printer << "a=control:trackID=" << (int)TrackAudio << "\r\n";
}
string getSdp() const override {
return _printer;
}
string getSdp() const override { return _printer; }
CodecId getCodecId() const override {
return CodecAAC;
}
private:
_StrPrinter _printer;
};
@@ -249,18 +245,14 @@ AACTrack::AACTrack(const string &aac_cfg) {
throw std::invalid_argument("adts配置必须最少2个字节");
}
_cfg = aac_cfg;
onReady();
}
const string &AACTrack::getConfig() const {
return _cfg;
update();
}
CodecId AACTrack::getCodecId() const {
return CodecAAC;
}
bool AACTrack::ready() {
bool AACTrack::ready() const {
return !_cfg.empty();
}
@@ -276,9 +268,25 @@ int AACTrack::getAudioChannel() const {
return _channel;
}
static Frame::Ptr addADTSHeader(const Frame::Ptr &frame_in, const std::string &aac_config) {
auto frame = FrameImp::create();
frame->_codec_id = CodecAAC;
// 生成adts头
char adts_header[32] = { 0 };
auto size = dumpAacConfig(aac_config, frame_in->size(), (uint8_t *)adts_header, sizeof(adts_header));
CHECK(size > 0, "Invalid adts config");
frame->_prefix_size = size;
frame->_dts = frame_in->dts();
frame->_buffer.assign(adts_header, size);
frame->_buffer.append(frame_in->data(), frame_in->size());
frame->setIndex(frame_in->getIndex());
return frame;
}
bool AACTrack::inputFrame(const Frame::Ptr &frame) {
if (!frame->prefixSize()) {
return inputFrame_l(frame);
CHECK(ready());
return inputFrame_l(addADTSHeader(frame, _cfg));
}
bool ret = false;
@@ -289,70 +297,137 @@ bool AACTrack::inputFrame(const Frame::Ptr &frame) {
auto ptr = frame->data();
auto end = frame->data() + frame->size();
while (ptr < end) {
auto frame_len = getAacFrameLength((uint8_t *) ptr, end - ptr);
auto frame_len = getAacFrameLength((uint8_t *)ptr, end - ptr);
if (frame_len < ADTS_HEADER_LEN) {
break;
}
if (frame_len == (int)frame->size()) {
return inputFrame_l(frame);
}
auto sub_frame = std::make_shared<FrameTSInternal<FrameFromPtr> >(frame, (char *) ptr, frame_len, ADTS_HEADER_LEN,dts,pts);
auto sub_frame = std::make_shared<FrameInternalBase<FrameFromPtr>>(frame, (char *)ptr, frame_len, dts, pts, ADTS_HEADER_LEN);
ptr += frame_len;
if (ptr > end) {
WarnL << "invalid aac length in adts header: " << frame_len
<< ", remain data size: " << end - (ptr - frame_len);
break;
}
sub_frame->setCodecId(CodecAAC);
if (inputFrame_l(sub_frame)) {
ret = true;
}
dts += 1024*1000/getAudioSampleRate();
pts += 1024*1000/getAudioSampleRate();
dts += 1024 * 1000 / getAudioSampleRate();
pts += 1024 * 1000 / getAudioSampleRate();
}
return ret;
}
bool AACTrack::inputFrame_l(const Frame::Ptr &frame) {
if (_cfg.empty()) {
//未获取到aac_cfg信息
if (frame->prefixSize()) {
//根据7个字节的adts头生成aac config
_cfg = makeAacConfig((uint8_t *) (frame->data()), frame->prefixSize());
onReady();
} else {
WarnL << "无法获取adts头!";
}
if (_cfg.empty() && frame->prefixSize()) {
// 未获取到aac_cfg信息根据7个字节的adts头生成aac config
_cfg = makeAacConfig((uint8_t *)(frame->data()), frame->prefixSize());
update();
}
if (frame->size() > frame->prefixSize()) {
//除adts头外有实际负载
// 除adts头外有实际负载
return AudioTrack::inputFrame(frame);
}
return false;
}
toolkit::Buffer::Ptr AACTrack::getExtraData() const {
CHECK(ready());
return std::make_shared<BufferString>(_cfg);
}
void AACTrack::setExtraData(const uint8_t *data, size_t size) {
CHECK(size >= 2);
_cfg.assign((char *)data, size);
update();
}
bool AACTrack::update() {
return parseAacConfig(_cfg, _sampleRate, _channel);
}
void AACTrack::onReady() {
if (!parseAacConfig(_cfg, _sampleRate, _channel)) {
_cfg.clear();
}
Track::Ptr AACTrack::clone() const {
return std::make_shared<AACTrack>(*this);
}
Track::Ptr AACTrack::clone() {
return std::make_shared<std::remove_reference<decltype(*this)>::type>(*this);
}
Sdp::Ptr AACTrack::getSdp() {
if(!ready()){
Sdp::Ptr AACTrack::getSdp(uint8_t payload_type) const {
if (!ready()) {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
update();
return std::make_shared<AACSdp>(getConfig(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
return std::make_shared<AACSdp>(getExtraData()->toString(), payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}
}//namespace mediakit
namespace {
CodecId getCodec() {
return CodecAAC;
}
Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) {
return std::make_shared<AACTrack>();
}
Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
string aac_cfg_str = findSubString(track->_fmtp.data(), "config=", ";");
if (aac_cfg_str.empty()) {
aac_cfg_str = findSubString(track->_fmtp.data(), "config=", nullptr);
}
if (aac_cfg_str.empty()) {
// 如果sdp中获取不到aac config信息那么在rtp也无法获取那么忽略该Track
return nullptr;
}
string aac_cfg;
for (size_t i = 0; i < aac_cfg_str.size() / 2; ++i) {
unsigned int cfg;
sscanf(aac_cfg_str.substr(i * 2, 2).data(), "%02X", &cfg);
cfg &= 0x00FF;
aac_cfg.push_back((char)cfg);
}
return std::make_shared<AACTrack>(aac_cfg);
}
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
return std::make_shared<AACRtpEncoder>();
}
RtpCodec::Ptr getRtpDecoderByCodecId() {
return std::make_shared<AACRtpDecoder>();
}
RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) {
return std::make_shared<AACRtmpEncoder>(track);
}
RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) {
return std::make_shared<AACRtmpDecoder>(track);
}
size_t aacPrefixSize(const char *data, size_t bytes) {
uint8_t *ptr = (uint8_t *)data;
size_t prefix = 0;
if (!(bytes > ADTS_HEADER_LEN && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0)) {
return 0;
}
return ADTS_HEADER_LEN;
}
Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return std::make_shared<FrameFromPtr>(CodecAAC, (char *)data, bytes, dts, pts, aacPrefixSize(data, bytes));
}
} // namespace
CodecPlugin aac_plugin = { getCodec,
getTrackByCodecId,
getTrackBySdp,
getRtpEncoderByCodecId,
getRtpDecoderByCodecId,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtr };
} // namespace mediakit

57
ext-codec/AAC.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_AAC_H
#define ZLMEDIAKIT_AAC_H
#include "Extension/Frame.h"
#include "Extension/Track.h"
#define ADTS_HEADER_LEN 7
namespace mediakit{
/**
* aac音频通道
*/
class AACTrack : public AudioTrack {
public:
using Ptr = std::shared_ptr<AACTrack>;
AACTrack() = default;
/**
* 通过aac extra data 构造对象
*/
AACTrack(const std::string &aac_cfg);
bool ready() const override;
CodecId getCodecId() const override;
int getAudioChannel() const override;
int getAudioSampleRate() const override;
int getAudioSampleBit() const override;
bool inputFrame(const Frame::Ptr &frame) override;
toolkit::Buffer::Ptr getExtraData() const override;
void setExtraData(const uint8_t *data, size_t size) override;
bool update() override;
private:
Sdp::Ptr getSdp(uint8_t payload_type) const override;
Track::Ptr clone() const override;
bool inputFrame_l(const Frame::Ptr &frame);
private:
std::string _cfg;
int _channel = 0;
int _sampleRate = 0;
int _sampleBit = 16;
};
}//namespace mediakit
#endif //ZLMEDIAKIT_AAC_H

66
ext-codec/AACRtmp.cpp Normal file
View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "AACRtmp.h"
#include "Rtmp/Rtmp.h"
using namespace std;
using namespace toolkit;
namespace mediakit {
void AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt) {
CHECK(pkt->size() > 2);
if (pkt->isConfigFrame()) {
getTrack()->setExtraData((uint8_t *)pkt->data() + 2, pkt->size() - 2);
return;
}
RtmpCodec::inputFrame(std::make_shared<FrameFromPtr>(CodecAAC, pkt->buffer.data() + 2, pkt->buffer.size() - 2, pkt->time_stamp));
}
/////////////////////////////////////////////////////////////////////////////////////
bool AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
auto pkt = RtmpPacket::create();
// header
pkt->buffer.push_back(_audio_flv_flags);
pkt->buffer.push_back((uint8_t)RtmpAACPacketType::aac_raw);
// aac data
pkt->buffer.append(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize());
pkt->body_size = pkt->buffer.size();
pkt->chunk_id = CHUNK_AUDIO;
pkt->stream_index = STREAM_MEDIA;
pkt->time_stamp = frame->dts();
pkt->type_id = MSG_AUDIO;
RtmpCodec::inputRtmp(pkt);
return true;
}
void AACRtmpEncoder::makeConfigPacket() {
_audio_flv_flags = getAudioRtmpFlags(getTrack());
auto pkt = RtmpPacket::create();
// header
pkt->buffer.push_back(_audio_flv_flags);
pkt->buffer.push_back((uint8_t)RtmpAACPacketType::aac_config_header);
// aac config
auto extra_data = getTrack()->getExtraData();
CHECK(extra_data);
pkt->buffer.append(extra_data->data(), extra_data->size());
pkt->body_size = pkt->buffer.size();
pkt->chunk_id = CHUNK_AUDIO;
pkt->stream_index = STREAM_MEDIA;
pkt->time_stamp = 0;
pkt->type_id = MSG_AUDIO;
RtmpCodec::inputRtmp(pkt);
}
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,43 +11,31 @@
#ifndef ZLMEDIAKIT_AACRTMPCODEC_H
#define ZLMEDIAKIT_AACRTMPCODEC_H
#include "AAC.h"
#include "Rtmp/RtmpCodec.h"
#include "Extension/Track.h"
#include "Extension/AAC.h"
namespace mediakit{
namespace mediakit {
/**
* aac Rtmp转adts类
*/
class AACRtmpDecoder : public RtmpCodec{
class AACRtmpDecoder : public RtmpCodec {
public:
using Ptr = std::shared_ptr<AACRtmpDecoder>;
AACRtmpDecoder() {}
~AACRtmpDecoder() {}
AACRtmpDecoder(const Track::Ptr &track) : RtmpCodec(track) {}
/**
* Rtmp并解码
* @param rtmp Rtmp数据包
*/
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
CodecId getCodecId() const override{
return CodecAAC;
}
private:
void onGetAAC(const char *data, size_t len, uint32_t stamp);
private:
std::string _aac_cfg;
};
/**
* aac adts转Rtmp类
*/
class AACRtmpEncoder : public AACRtmpDecoder{
class AACRtmpEncoder : public RtmpCodec {
public:
using Ptr = std::shared_ptr<AACRtmpEncoder>;
@@ -57,8 +45,7 @@ public:
* inputFrame时可以不输入adts头
* @param track
*/
AACRtmpEncoder(const Track::Ptr &track);
~AACRtmpEncoder() {}
AACRtmpEncoder(const Track::Ptr &track) : RtmpCodec(track) {}
/**
* aac adts头
@@ -72,12 +59,7 @@ public:
void makeConfigPacket() override;
private:
void makeAudioConfigPkt();
private:
uint8_t _audio_flv_flags;
AACTrack::Ptr _track;
std::string _aac_cfg;
uint8_t _audio_flv_flags {0};
};
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -12,63 +12,36 @@
namespace mediakit{
AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
uint32_t ui32MtuSize,
uint32_t ui32SampleRate,
uint8_t ui8PayloadType,
uint8_t ui8Interleaved) :
RtpInfo(ui32Ssrc,
ui32MtuSize,
ui32SampleRate,
ui8PayloadType,
ui8Interleaved){
}
bool AACRtpEncoder::inputFrame(const Frame::Ptr &frame) {
auto stamp = frame->dts();
auto data = frame->data() + frame->prefixSize();
auto len = frame->size() - frame->prefixSize();
auto ptr = (char *) data;
auto remain_size = len;
auto max_size = getMaxSize() - 4;
auto ptr = (char *)frame->data() + frame->prefixSize();
auto size = frame->size() - frame->prefixSize();
auto remain_size = size;
auto max_size = getRtpInfo().getMaxSize() - 4;
while (remain_size > 0) {
if (remain_size <= max_size) {
_section_buf[0] = 0;
_section_buf[1] = 16;
_section_buf[2] = (len >> 5) & 0xFF;
_section_buf[3] = ((len & 0x1F) << 3) & 0xFF;
memcpy(_section_buf + 4, ptr, remain_size);
makeAACRtp(_section_buf, remain_size + 4, true, stamp);
outputRtp(ptr, remain_size, size, true, frame->dts());
break;
}
_section_buf[0] = 0;
_section_buf[1] = 16;
_section_buf[2] = ((len) >> 5) & 0xFF;
_section_buf[3] = ((len & 0x1F) << 3) & 0xFF;
memcpy(_section_buf + 4, ptr, max_size);
makeAACRtp(_section_buf, max_size + 4, false, stamp);
outputRtp(ptr, max_size, size, false, frame->dts());
ptr += max_size;
remain_size -= max_size;
}
return len > 0;
return true;
}
void AACRtpEncoder::makeAACRtp(const void *data, size_t len, bool mark, uint64_t stamp) {
RtpCodec::inputRtp(makeRtp(getTrackType(), data, len, mark, stamp), false);
void AACRtpEncoder::outputRtp(const char *data, size_t len, size_t total_len, bool mark, uint64_t stamp) {
auto rtp = getRtpInfo().makeRtp(TrackAudio, nullptr, len + 4, mark, stamp);
auto payload = rtp->data() + RtpPacket::kRtpTcpHeaderSize + RtpPacket::kRtpHeaderSize;
payload[0] = 0;
payload[1] = 16;
payload[2] = ((total_len) >> 5) & 0xFF;
payload[3] = ((total_len & 0x1F) << 3) & 0xFF;
memcpy(payload + 4, data, len);
RtpCodec::inputRtp(std::move(rtp), false);
}
/////////////////////////////////////////////////////////////////////////////////////
AACRtpDecoder::AACRtpDecoder(const Track::Ptr &track) {
auto aacTrack = std::dynamic_pointer_cast<AACTrack>(track);
if (!aacTrack || !aacTrack->ready()) {
WarnL << "该aac track无效!";
} else {
_aac_cfg = aacTrack->getConfig();
}
obtainFrame();
}
AACRtpDecoder::AACRtpDecoder() {
obtainFrame();
}
@@ -145,17 +118,8 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
void AACRtpDecoder::flushData() {
auto ptr = reinterpret_cast<const uint8_t *>(_frame->data());
if ((ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0) && _frame->size() > ADTS_HEADER_LEN) {
//adts头打入了rtp包不符合规范兼容EasyPusher的bug
// adts头打入了rtp包不符合规范兼容EasyPusher的bug
_frame->_prefix_size = ADTS_HEADER_LEN;
} else {
//没有adts头则插入adts头
char adts_header[128] = {0};
auto size = dumpAacConfig(_aac_cfg, _frame->_buffer.size(), (uint8_t *) adts_header, sizeof(adts_header));
if (size > 0) {
//插入adts头
_frame->_buffer.insert(0, adts_header, size);
_frame->_prefix_size = size;
}
}
RtpCodec::inputFrame(_frame);
obtainFrame();

64
ext-codec/AACRtp.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_AACRTPCODEC_H
#define ZLMEDIAKIT_AACRTPCODEC_H
#include "AAC.h"
#include "Rtsp/RtpCodec.h"
namespace mediakit {
/**
* aac rtp转adts类
*/
class AACRtpDecoder : public RtpCodec {
public:
using Ptr = std::shared_ptr<AACRtpDecoder>;
AACRtpDecoder();
/**
* 输入rtp并解码
* @param rtp rtp数据包
* @param key_pos 此参数内部强制转换为false,请忽略之
*/
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = false) override;
private:
void obtainFrame();
void flushData();
private:
uint64_t _last_dts = 0;
FrameImp::Ptr _frame;
};
/**
* aac adts转rtp类
*/
class AACRtpEncoder : public RtpCodec {
public:
using Ptr = std::shared_ptr<AACRtpEncoder>;
/**
* 输入aac 数据必须带dats头
* @param frame 带dats头的aac数据
*/
bool inputFrame(const Frame::Ptr &frame) override;
private:
void outputRtp(const char *data, size_t len, size_t total_len, bool mark, uint64_t stamp);
};
}//namespace mediakit
#endif //ZLMEDIAKIT_AACRTPCODEC_H

48
ext-codec/CMakeLists.txt Normal file
View File

@@ -0,0 +1,48 @@
# MIT License
#
# Copyright (c) 2016-2022 The ZLMediaKit project authors. All Rights Reserved.
#
# 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.
#
set(COMPILE_DEFINITIONS)
set(INCLUDE_DIRECTORIES)
file(GLOB EXT_SRC_LIST
${CMAKE_CURRENT_SOURCE_DIR}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
add_library(ext-codec STATIC ${EXT_SRC_LIST})
add_library(ZLMediaKit::ext-codec ALIAS ext-codec)
target_compile_options(ext-codec PRIVATE ${COMPILE_OPTIONS_DEFAULT})
target_compile_definitions(ext-codec PUBLIC ${COMPILE_DEFINITIONS})
target_link_libraries(ext-codec PRIVATE ZLMediaKit::MediaKit ZLMediaKit::ToolKit ${LINK_LIBRARIES})
target_include_directories(ext-codec
PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>"
${INCLUDE_DIRECTORIES})
update_cached_list(MK_LINK_LIBRARIES ZLMediaKit::ext-codec ${LINK_LIBRARIES})

188
ext-codec/G711.cpp Normal file
View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "G711.h"
#include "G711Rtp.h"
#include "Extension/Factory.h"
#include "Extension/CommonRtp.h"
#include "Extension/CommonRtmp.h"
using namespace std;
using namespace toolkit;
namespace mediakit {
/**
* G711类型SDP
*/
class G711Sdp : public Sdp {
public:
/**
* G711采样率固定为8000
* @param codecId G711A G711U
* @param payload_type rtp payload type
* @param sample_rate 音频采样率
* @param channels 通道数
* @param bitrate 比特率
*/
G711Sdp(CodecId codecId, int payload_type, int sample_rate, int channels, int bitrate)
: Sdp(sample_rate, payload_type) {
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(codecId) << "/" << sample_rate << "/" << channels << "\r\n";
}
string getSdp() const override {
return _printer;
}
private:
_StrPrinter _printer;
};
Track::Ptr G711Track::clone() const {
return std::make_shared<G711Track>(*this);
}
Sdp::Ptr G711Track::getSdp(uint8_t payload_type) const {
if (!ready()) {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
const auto codec = getCodecId();
const auto sample_rate = getAudioSampleRate();
const auto audio_channel = getAudioChannel();
const auto bitrate = getBitRate() >> 10;
if (sample_rate == 8000 && audio_channel == 1) {
// https://datatracker.ietf.org/doc/html/rfc3551#section-6
payload_type = (codec == CodecG711U) ? Rtsp::PT_PCMU : Rtsp::PT_PCMA;
}
return std::make_shared<G711Sdp>(codec, payload_type, sample_rate, audio_channel, bitrate);
}
namespace {
CodecId getCodecA() {
return CodecG711A;
}
CodecId getCodecU() {
return CodecG711U;
}
Track::Ptr getTrackByCodecId_l(CodecId codec, int sample_rate, int channels, int sample_bit) {
return (sample_rate && channels && sample_bit) ? std::make_shared<G711Track>(codec, sample_rate, channels, sample_bit) : nullptr;
}
Track::Ptr getTrackByCodecIdA(int sample_rate, int channels, int sample_bit) {
return getTrackByCodecId_l(CodecG711A, sample_rate, channels, sample_bit);
}
Track::Ptr getTrackByCodecIdU(int sample_rate, int channels, int sample_bit) {
return getTrackByCodecId_l(CodecG711U, sample_rate, channels, sample_bit);
}
Track::Ptr getTrackBySdp_l(CodecId codec, const SdpTrack::Ptr &track) {
return std::make_shared<G711Track>(codec, track->_samplerate, track->_channel, 16);
}
Track::Ptr getTrackBySdpA(const SdpTrack::Ptr &track) {
return getTrackBySdp_l(CodecG711A, track);
}
Track::Ptr getTrackBySdpU(const SdpTrack::Ptr &track) {
return getTrackBySdp_l(CodecG711U, track);
}
RtpCodec::Ptr getRtpEncoderByCodecId_l(CodecId codec, uint8_t pt) {
if (pt == Rtsp::PT_PCMA || pt == Rtsp::PT_PCMU) {
return std::make_shared<G711RtpEncoder>(codec, 1);
}
return std::make_shared<CommonRtpEncoder>();
}
RtpCodec::Ptr getRtpEncoderByCodecIdA(uint8_t pt) {
return getRtpEncoderByCodecId_l(CodecG711A, pt);
}
RtpCodec::Ptr getRtpEncoderByCodecIdU(uint8_t pt) {
return getRtpEncoderByCodecId_l(CodecG711U, pt);
}
RtpCodec::Ptr getRtpDecoderByCodecId_l(CodecId codec) {
return std::make_shared<CommonRtpDecoder>(codec);
}
RtpCodec::Ptr getRtpDecoderByCodecIdA() {
return getRtpDecoderByCodecId_l(CodecG711A);
}
RtpCodec::Ptr getRtpDecoderByCodecIdU() {
return getRtpDecoderByCodecId_l(CodecG711U);
}
RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) {
auto audio_track = dynamic_pointer_cast<AudioTrack>(track);
if (audio_track->getAudioSampleRate() != 8000 || audio_track->getAudioChannel() != 1 || audio_track->getAudioSampleBit() != 16) {
//rtmp对g711只支持8000/1/16规格但是ZLMediaKit可以解析其他规格的G711
WarnL << "RTMP only support G711 with 8000/1/16, now is"
<< audio_track->getAudioSampleRate() << "/"
<< audio_track->getAudioChannel() << "/"
<< audio_track->getAudioSampleBit()
<< ", ignored it";
return nullptr;
}
return std::make_shared<CommonRtmpEncoder>(track);
}
RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) {
return std::make_shared<CommonRtmpDecoder>(track);
}
Frame::Ptr getFrameFromPtr_l(CodecId codec, const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return std::make_shared<FrameFromPtr>(codec, (char *)data, bytes, dts, pts);
}
Frame::Ptr getFrameFromPtrA(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return getFrameFromPtr_l(CodecG711A, (char *)data, bytes, dts, pts);
}
Frame::Ptr getFrameFromPtrU(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return getFrameFromPtr_l(CodecG711U, (char *)data, bytes, dts, pts);
}
} // namespace
CodecPlugin g711a_plugin = { getCodecA,
getTrackByCodecIdA,
getTrackBySdpA,
getRtpEncoderByCodecIdA,
getRtpDecoderByCodecIdA,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtrA };
CodecPlugin g711u_plugin = { getCodecU,
getTrackByCodecIdU,
getTrackBySdpU,
getRtpEncoderByCodecIdU,
getRtpDecoderByCodecIdU,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtrU };
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,8 +11,8 @@
#ifndef ZLMEDIAKIT_G711_H
#define ZLMEDIAKIT_G711_H
#include "Frame.h"
#include "Track.h"
#include "Extension/Frame.h"
#include "Extension/Track.h"
namespace mediakit{
@@ -25,8 +25,8 @@ public:
G711Track(CodecId codecId, int sample_rate, int channels, int sample_bit) : AudioTrackImp(codecId, 8000, 1, 16) {}
private:
Sdp::Ptr getSdp() override;
Track::Ptr clone() override;
Sdp::Ptr getSdp(uint8_t payload_type) const override;
Track::Ptr clone() const override;
};
}//namespace mediakit

View File

@@ -2,11 +2,7 @@
namespace mediakit {
G711RtpEncoder::G711RtpEncoder(
CodecId codec, uint32_t ssrc, uint32_t mtu_size, uint32_t sample_rate, uint8_t payload_type, uint8_t interleaved,
uint32_t channels)
: CommonRtpDecoder(codec)
, RtpInfo(ssrc, mtu_size, sample_rate, payload_type, interleaved) {
G711RtpEncoder::G711RtpEncoder(CodecId codec, uint32_t channels){
_cache_frame = FrameImp::create();
_cache_frame->_codec_id = codec;
_channels = channels;
@@ -40,7 +36,7 @@ bool G711RtpEncoder::inputFrame(const Frame::Ptr &frame) {
}
n++;
stamp += 20;
RtpCodec::inputRtp(makeRtp(getTrackType(), ptr, rtp_size, mark, stamp), false);
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackAudio, ptr, rtp_size, mark, stamp), false);
ptr += rtp_size;
remain_size -= rtp_size;
}

45
ext-codec/G711Rtp.h Normal file
View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_G711RTP_H
#define ZLMEDIAKIT_G711RTP_H
#include "Rtsp/RtpCodec.h"
#include "Extension/Frame.h"
#include "Extension/CommonRtp.h"
namespace mediakit {
/**
* G711 rtp编码类
*/
class G711RtpEncoder : public RtpCodec {
public:
using Ptr = std::shared_ptr<G711RtpEncoder>;
/**
* 构造函数
* @param codec 编码类型
* @param channels 通道数
*/
G711RtpEncoder(CodecId codec, uint32_t channels);
/**
* 输入帧数据并编码成rtp
*/
bool inputFrame(const Frame::Ptr &frame) override;
private:
uint32_t _channels = 1;
FrameImp::Ptr _cache_frame;
};
}//namespace mediakit
#endif //ZLMEDIAKIT_G711RTP_H

View File

@@ -1,18 +1,26 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "H264.h"
#include "H264Rtmp.h"
#include "H264Rtp.h"
#include "SPSParser.h"
#include "Util/logger.h"
#include "Util/base64.h"
#include "Common/Parser.h"
#include "Common/config.h"
#include "Extension/Factory.h"
#ifdef ENABLE_MP4
#include "mpeg4-avc.h"
#endif
using namespace std;
using namespace toolkit;
@@ -109,24 +117,7 @@ size_t prefixSize(const char *ptr, size_t len) {
H264Track::H264Track(const string &sps, const string &pps, int sps_prefix_len, int pps_prefix_len) {
_sps = sps.substr(sps_prefix_len);
_pps = pps.substr(pps_prefix_len);
onReady();
}
H264Track::H264Track(const Frame::Ptr &sps, const Frame::Ptr &pps) {
if (sps->getCodecId() != CodecH264 || pps->getCodecId() != CodecH264) {
throw std::invalid_argument("必须输入H264类型的帧");
}
_sps = string(sps->data() + sps->prefixSize(), sps->size() - sps->prefixSize());
_pps = string(pps->data() + pps->prefixSize(), pps->size() - pps->prefixSize());
onReady();
}
const string &H264Track::getSps() const {
return _sps;
}
const string &H264Track::getPps() const {
return _pps;
update();
}
CodecId H264Track::getCodecId() const {
@@ -145,7 +136,7 @@ float H264Track::getVideoFps() const {
return _fps;
}
bool H264Track::ready() {
bool H264Track::ready() const {
return !_sps.empty() && !_pps.empty();
}
@@ -168,19 +159,87 @@ bool H264Track::inputFrame(const Frame::Ptr &frame) {
return ret;
}
toolkit::Buffer::Ptr H264Track::getExtraData() const {
CHECK(ready());
#ifdef ENABLE_MP4
struct mpeg4_avc_t avc;
memset(&avc, 0, sizeof(avc));
string sps_pps = string("\x00\x00\x00\x01", 4) + _sps + string("\x00\x00\x00\x01", 4) + _pps;
h264_annexbtomp4(&avc, sps_pps.data(), (int)sps_pps.size(), NULL, 0, NULL, NULL);
std::string extra_data;
extra_data.resize(1024);
auto extra_data_size = mpeg4_avc_decoder_configuration_record_save(&avc, (uint8_t *)extra_data.data(), extra_data.size());
if (extra_data_size == -1) {
WarnL << "生成H264 extra_data 失败";
return nullptr;
}
extra_data.resize(extra_data_size);
return std::make_shared<BufferString>(std::move(extra_data));
#else
std::string extra_data;
// AVCDecoderConfigurationRecord start
extra_data.push_back(1); // version
extra_data.push_back(_sps[1]); // profile
extra_data.push_back(_sps[2]); // compat
extra_data.push_back(_sps[3]); // level
extra_data.push_back((char)0xff); // 6 bits reserved + 2 bits nal size length - 1 (11)
extra_data.push_back((char)0xe1); // 3 bits reserved + 5 bits number of sps (00001)
// sps
uint16_t size = (uint16_t)_sps.size();
size = htons(size);
extra_data.append((char *)&size, 2);
extra_data.append(_sps);
// pps
extra_data.push_back(1); // version
size = (uint16_t)_pps.size();
size = htons(size);
extra_data.append((char *)&size, 2);
extra_data.append(_pps);
return std::make_shared<BufferString>(std::move(extra_data));
#endif
}
void H264Track::setExtraData(const uint8_t *data, size_t bytes) {
#ifdef ENABLE_MP4
struct mpeg4_avc_t avc;
memset(&avc, 0, sizeof(avc));
if (mpeg4_avc_decoder_configuration_record_load(data, bytes, &avc) > 0) {
std::vector<uint8_t> config(bytes * 2);
int size = mpeg4_avc_to_nalu(&avc, config.data(), bytes * 2);
if (size > 4) {
splitH264((char *)config.data(), size, 4, [&](const char *ptr, size_t len, size_t prefix) {
inputFrame_l(std::make_shared<H264FrameNoCacheAble>((char *)ptr, len, 0, 0, prefix));
});
update();
}
}
#else
CHECK(bytes >= 8); // 6 + 2
size_t offset = 6;
uint16_t sps_size = data[offset] << 8 | data[offset + 1];
auto sps_ptr = data + offset + 2;
offset += (2 + sps_size);
CHECK(bytes >= offset + 2); // + pps_size
_sps.assign((char *)sps_ptr, sps_size);
uint16_t pps_size = data[offset] << 8 | data[offset + 1];
auto pps_ptr = data + offset + 2;
offset += (2 + pps_size);
CHECK(bytes >= offset);
_pps.assign((char *)pps_ptr, pps_size);
update();
#endif
}
bool H264Track::update() {
return getAVCInfo(_sps, _width, _height, _fps);
}
void H264Track::onReady() {
if (!getAVCInfo(_sps, _width, _height, _fps)) {
_sps.clear();
_pps.clear();
}
}
Track::Ptr H264Track::clone() {
return std::make_shared<std::remove_reference<decltype(*this)>::type>(*this);
Track::Ptr H264Track::clone() const {
return std::make_shared<H264Track>(*this);
}
bool H264Track::inputFrame_l(const Frame::Ptr &frame) {
@@ -218,7 +277,7 @@ bool H264Track::inputFrame_l(const Frame::Ptr &frame) {
}
if (_width == 0 && ready()) {
onReady();
update();
}
return ret;
}
@@ -230,6 +289,7 @@ void H264Track::insertConfigFrame(const Frame::Ptr &frame) {
spsFrame->_buffer.assign("\x00\x00\x00\x01", 4);
spsFrame->_buffer.append(_sps);
spsFrame->_dts = frame->dts();
spsFrame->setIndex(frame->getIndex());
VideoTrack::inputFrame(spsFrame);
}
@@ -239,20 +299,19 @@ void H264Track::insertConfigFrame(const Frame::Ptr &frame) {
ppsFrame->_buffer.assign("\x00\x00\x00\x01", 4);
ppsFrame->_buffer.append(_pps);
ppsFrame->_dts = frame->dts();
ppsFrame->setIndex(frame->getIndex());
VideoTrack::inputFrame(ppsFrame);
}
}
class H264Sdp : public Sdp {
public:
H264Sdp(const string &strSPS, const string &strPPS, int bitrate, int payload_type = 96)
: Sdp(90000, payload_type) {
//视频通道
H264Sdp(const string &strSPS, const string &strPPS, int payload_type, int bitrate) : Sdp(90000, payload_type) {
_printer << "m=video 0 RTP/AVP " << payload_type << "\r\n";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
_printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << 90000 << "\r\n";
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(CodecH264) << "/" << 90000 << "\r\n";
/**
Single NAI Unit Mode = 0. // Single NAI mode (Only nals from 1-23 are allowed)
@@ -275,23 +334,76 @@ public:
_printer << "; sprop-parameter-sets=";
_printer << encodeBase64(strSPS) << ",";
_printer << encodeBase64(strPPS) << "\r\n";
_printer << "a=control:trackID=" << (int)TrackVideo << "\r\n";
}
string getSdp() const { return _printer; }
CodecId getCodecId() const { return CodecH264; }
private:
_StrPrinter _printer;
};
Sdp::Ptr H264Track::getSdp() {
Sdp::Ptr H264Track::getSdp(uint8_t payload_type) const {
if (!ready()) {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<H264Sdp>(getSps(), getPps(), getBitRate() / 1024);
return std::make_shared<H264Sdp>(_sps, _pps, payload_type, getBitRate() / 1024);
}
namespace {
CodecId getCodec() {
return CodecH264;
}
Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) {
return std::make_shared<H264Track>();
}
Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
//a=fmtp:96 packetization-mode=1;profile-level-id=42C01F;sprop-parameter-sets=Z0LAH9oBQBboQAAAAwBAAAAPI8YMqA==,aM48gA==
auto map = Parser::parseArgs(track->_fmtp, ";", "=");
auto sps_pps = map["sprop-parameter-sets"];
string base64_SPS = findSubString(sps_pps.data(), NULL, ",");
string base64_PPS = findSubString(sps_pps.data(), ",", NULL);
auto sps = decodeBase64(base64_SPS);
auto pps = decodeBase64(base64_PPS);
if (sps.empty() || pps.empty()) {
//如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps
return std::make_shared<H264Track>();
}
return std::make_shared<H264Track>(sps, pps, 0, 0);
}
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
return std::make_shared<H264RtpEncoder>();
}
RtpCodec::Ptr getRtpDecoderByCodecId() {
return std::make_shared<H264RtpDecoder>();
}
RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) {
return std::make_shared<H264RtmpEncoder>(track);
}
RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) {
return std::make_shared<H264RtmpDecoder>(track);
}
Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return std::make_shared<H264FrameNoCacheAble>((char *)data, bytes, dts, pts, prefixSize(data, bytes));
}
} // namespace
CodecPlugin h264_plugin = { getCodec,
getTrackByCodecId,
getTrackBySdp,
getRtpEncoderByCodecId,
getRtpDecoderByCodecId,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtr };
} // namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,14 +11,13 @@
#ifndef ZLMEDIAKIT_H264_H
#define ZLMEDIAKIT_H264_H
#include "Frame.h"
#include "Track.h"
#include "Extension/Frame.h"
#include "Extension/Track.h"
#define H264_TYPE(v) ((uint8_t)(v) & 0x1F)
namespace mediakit{
bool getAVCInfo(const std::string &strSps,int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
void splitH264(const char *ptr, size_t len, size_t prefix, const std::function<void(const char *, size_t, size_t)> &cb);
size_t prefixSize(const char *ptr, size_t len);
@@ -43,8 +42,6 @@ public:
this->_codec_id = CodecH264;
}
~H264FrameHelper() override = default;
bool keyFrame() const override {
auto nal_ptr = (uint8_t *) this->data() + this->prefixSize();
return H264_TYPE(*nal_ptr) == NAL_IDR && decodeAble();
@@ -107,33 +104,21 @@ public:
* @param sps_prefix_len 264340x00 00 00 01
* @param pps_prefix_len 264340x00 00 00 01
*/
H264Track(const std::string &sps,const std::string &pps,int sps_prefix_len = 4,int pps_prefix_len = 4);
H264Track(const std::string &sps, const std::string &pps, int sps_prefix_len = 4, int pps_prefix_len = 4);
/**
* h264类型的媒体
* @param sps sps帧
* @param pps pps帧
*/
H264Track(const Frame::Ptr &sps,const Frame::Ptr &pps);
/**
* 0x00 00 00 01sps/pps
*/
const std::string &getSps() const;
const std::string &getPps() const;
bool ready() override;
bool ready() const override;
CodecId getCodecId() const override;
int getVideoHeight() const override;
int getVideoWidth() const override;
float getVideoFps() const override;
bool inputFrame(const Frame::Ptr &frame) override;
toolkit::Buffer::Ptr getExtraData() const override;
void setExtraData(const uint8_t *data, size_t size) override;
bool update() override;
private:
void onReady();
Sdp::Ptr getSdp() override;
Track::Ptr clone() override;
Sdp::Ptr getSdp(uint8_t payload_type) const override;
Track::Ptr clone() const override;
bool inputFrame_l(const Frame::Ptr &frame);
void insertConfigFrame(const Frame::Ptr &frame);

109
ext-codec/H264Rtmp.cpp Normal file
View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "Rtmp/utils.h"
#include "H264Rtmp.h"
using namespace std;
using namespace toolkit;
namespace mediakit {
void H264RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt) {
if (pkt->isConfigFrame()) {
CHECK(pkt->size() > 5);
getTrack()->setExtraData((uint8_t *)pkt->data() + 5, pkt->size() - 5);
return;
}
CHECK(pkt->size() > 9);
uint8_t *cts_ptr = (uint8_t *)(pkt->buffer.data() + 2);
int32_t cts = (((cts_ptr[0] << 16) | (cts_ptr[1] << 8) | (cts_ptr[2])) + 0xff800000) ^ 0xff800000;
auto pts = pkt->time_stamp + cts;
splitFrame((uint8_t *)pkt->data() + 5, pkt->size() - 5, pkt->time_stamp, pts);
}
void H264RtmpDecoder::splitFrame(const uint8_t *data, size_t size, uint32_t dts, uint32_t pts) {
auto end = data + size;
while (data + 4 < end) {
uint32_t frame_len = load_be32(data);
data += 4;
if (data + frame_len > end) {
break;
}
outputFrame((const char *)data, frame_len, dts, pts);
data += frame_len;
}
}
void H264RtmpDecoder::outputFrame(const char *data, size_t len, uint32_t dts, uint32_t pts) {
auto frame = FrameImp::create<H264Frame>();
frame->_prefix_size = 4;
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign("\x00\x00\x00\x01", 4); // 添加264头
frame->_buffer.append(data, len);
RtmpCodec::inputFrame(frame);
}
////////////////////////////////////////////////////////////////////////
void H264RtmpEncoder::flush() {
inputFrame(nullptr);
}
bool H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
if (!_rtmp_packet) {
_rtmp_packet = RtmpPacket::create();
//flags/not config/cts预占位
_rtmp_packet->buffer.resize(5);
}
return _merger.inputFrame(frame, [this](uint64_t dts, uint64_t pts, const Buffer::Ptr &, bool have_key_frame) {
// flags
_rtmp_packet->buffer[0] = (uint8_t)RtmpVideoCodec::h264 | ((uint8_t)(have_key_frame ? RtmpFrameType::key_frame : RtmpFrameType::inter_frame) << 4);
_rtmp_packet->buffer[1] = (uint8_t)RtmpH264PacketType::h264_nalu;
int32_t cts = pts - dts;
// cts
set_be24(&_rtmp_packet->buffer[2], cts);
_rtmp_packet->time_stamp = dts;
_rtmp_packet->body_size = _rtmp_packet->buffer.size();
_rtmp_packet->chunk_id = CHUNK_VIDEO;
_rtmp_packet->stream_index = STREAM_MEDIA;
_rtmp_packet->type_id = MSG_VIDEO;
// 输出rtmp packet
RtmpCodec::inputRtmp(_rtmp_packet);
_rtmp_packet = nullptr;
}, &_rtmp_packet->buffer);
}
void H264RtmpEncoder::makeConfigPacket() {
auto flags = (uint8_t)RtmpVideoCodec::h264;
flags |= ((uint8_t)RtmpFrameType::key_frame << 4);
auto pkt = RtmpPacket::create();
// header
pkt->buffer.push_back(flags);
pkt->buffer.push_back((uint8_t)RtmpH264PacketType::h264_config_header);
// cts
pkt->buffer.append("\x0\x0\x0", 3);
// AVCDecoderConfigurationRecord start
auto extra_data = getTrack()->getExtraData();
CHECK(extra_data);
pkt->buffer.append(extra_data->data(), extra_data->size());
pkt->body_size = pkt->buffer.size();
pkt->chunk_id = CHUNK_VIDEO;
pkt->stream_index = STREAM_MEDIA;
pkt->time_stamp = 0;
pkt->type_id = MSG_VIDEO;
RtmpCodec::inputRtmp(pkt);
}
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,11 +11,11 @@
#ifndef ZLMEDIAKIT_H264RTMPCODEC_H
#define ZLMEDIAKIT_H264RTMPCODEC_H
#include "H264.h"
#include "Rtmp/RtmpCodec.h"
#include "Extension/Track.h"
#include "Extension/H264.h"
namespace mediakit{
namespace mediakit {
/**
* h264 Rtmp解码类
* h264 over rtmp h264-Frame
@@ -24,8 +24,7 @@ class H264RtmpDecoder : public RtmpCodec {
public:
using Ptr = std::shared_ptr<H264RtmpDecoder>;
H264RtmpDecoder();
~H264RtmpDecoder() {}
H264RtmpDecoder(const Track::Ptr &track) : RtmpCodec(track) {}
/**
* 264 Rtmp包
@@ -33,24 +32,15 @@ public:
*/
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
CodecId getCodecId() const override{
return CodecH264;
}
protected:
void onGetH264(const char *data, size_t len, uint32_t dts, uint32_t pts);
H264Frame::Ptr obtainFrame();
protected:
H264Frame::Ptr _h264frame;
std::string _sps;
std::string _pps;
private:
void outputFrame(const char *data, size_t len, uint32_t dts, uint32_t pts);
void splitFrame(const uint8_t *data, size_t size, uint32_t dts, uint32_t pts);
};
/**
* 264 Rtmp打包类
*/
class H264RtmpEncoder : public H264RtmpDecoder{
class H264RtmpEncoder : public RtmpCodec {
public:
using Ptr = std::shared_ptr<H264RtmpEncoder>;
@@ -60,8 +50,7 @@ public:
* inputFrame时可以不输入sps pps
* @param track
*/
H264RtmpEncoder(const Track::Ptr &track);
~H264RtmpEncoder() = default;
H264RtmpEncoder(const Track::Ptr &track) : RtmpCodec(track) {}
/**
* 264sps pps
@@ -80,13 +69,8 @@ public:
void makeConfigPacket() override;
private:
void makeVideoConfigPkt();
private:
bool _got_config_frame = false;
H264Track::Ptr _track;
RtmpPacket::Ptr _rtmp_packet;
FrameMerger _merger{FrameMerger::mp4_nal_size};
FrameMerger _merger { FrameMerger::mp4_nal_size };
};
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -192,10 +192,6 @@ void H264RtpDecoder::outputFrame(const RtpPacket::Ptr &rtp, const H264Frame::Ptr
////////////////////////////////////////////////////////////////////////
H264RtpEncoder::H264RtpEncoder(uint32_t ssrc, uint32_t mtu, uint32_t sample_rate, uint8_t pt, uint8_t interleaved)
: RtpInfo(ssrc, mtu, sample_rate, pt, interleaved) {
}
void H264RtpEncoder::insertConfigFrame(uint64_t pts){
if (!_sps || !_pps) {
return;
@@ -206,7 +202,7 @@ void H264RtpEncoder::insertConfigFrame(uint64_t pts){
}
void H264RtpEncoder::packRtp(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){
if (len + 3 <= getMaxSize()) {
if (len + 3 <= getRtpInfo().getMaxSize()) {
// 采用STAP-A/Single NAL unit packet per H.264 模式
packRtpSmallFrame(ptr, len, pts, is_mark, gop_pos);
} else {
@@ -216,7 +212,7 @@ void H264RtpEncoder::packRtp(const char *ptr, size_t len, uint64_t pts, bool is_
}
void H264RtpEncoder::packRtpFu(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){
auto packet_size = getMaxSize() - 2;
auto packet_size = getRtpInfo().getMaxSize() - 2;
if (len <= packet_size + 1) {
// 小于FU-A打包最小字节长度要求采用STAP-A/Single NAL unit packet per H.264 模式
packRtpSmallFrame(ptr, len, pts, is_mark, gop_pos);
@@ -238,7 +234,7 @@ void H264RtpEncoder::packRtpFu(const char *ptr, size_t len, uint64_t pts, bool i
}
//传入nullptr先不做payload的内存拷贝
auto rtp = makeRtp(getTrackType(), nullptr, packet_size + 2, fu_flags->end_bit && is_mark, pts);
auto rtp = getRtpInfo().makeRtp(TrackVideo, nullptr, packet_size + 2, fu_flags->end_bit && is_mark, pts);
//rtp payload 负载部分
uint8_t *payload = rtp->getPayload();
//FU-A 第1个字节
@@ -266,7 +262,7 @@ void H264RtpEncoder::packRtpSmallFrame(const char *data, size_t len, uint64_t pt
void H264RtpEncoder::packRtpStapA(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){
// 如果帧长度不超过mtu,为了兼容性 webrtc采用STAP-A模式打包
auto rtp = makeRtp(getTrackType(), nullptr, len + 3, is_mark, pts);
auto rtp = getRtpInfo().makeRtp(TrackVideo, nullptr, len + 3, is_mark, pts);
uint8_t *payload = rtp->getPayload();
//STAP-A
payload[0] = (ptr[0] & (~0x1F)) | 24;
@@ -279,7 +275,7 @@ void H264RtpEncoder::packRtpStapA(const char *ptr, size_t len, uint64_t pts, boo
void H264RtpEncoder::packRtpSingleNalu(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos) {
// Single NAL unit packet per H.264 模式
RtpCodec::inputRtp(makeRtp(getTrackType(), data, len, is_mark, pts), gop_pos);
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackVideo, data, len, is_mark, pts), gop_pos);
}
bool H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,12 +11,12 @@
#ifndef ZLMEDIAKIT_H264RTPCODEC_H
#define ZLMEDIAKIT_H264RTPCODEC_H
#include "Rtsp/RtpCodec.h"
#include "Extension/H264.h"
#include "H264.h"
// for DtsGenerator
#include "Common/Stamp.h"
#include "Rtsp/RtpCodec.h"
namespace mediakit{
namespace mediakit {
/**
* h264 rtp解码类
@@ -28,7 +28,6 @@ public:
using Ptr = std::shared_ptr<H264RtpDecoder>;
H264RtpDecoder();
~H264RtpDecoder() override = default;
/**
* 264 rtp包
@@ -37,10 +36,6 @@ public:
*/
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override;
CodecId getCodecId() const override{
return CodecH264;
}
private:
bool singleFrame(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssize_t size, uint64_t stamp);
bool unpackStapA(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssize_t size, uint64_t stamp);
@@ -62,26 +57,11 @@ private:
/**
* 264 rtp打包类
*/
class H264RtpEncoder : public H264RtpDecoder ,public RtpInfo{
class H264RtpEncoder : public RtpCodec {
public:
using Ptr = std::shared_ptr<H264RtpEncoder>;
/**
* @param ssrc ssrc
* @param mtu mtu大小
* @param sample_rate 90000
* @param pt pt类型
* @param interleaved rtsp interleaved
*/
H264RtpEncoder(uint32_t ssrc,
uint32_t mtu = 1400,
uint32_t sample_rate = 90000,
uint8_t pt = 96,
uint8_t interleaved = TrackVideo * 2);
~H264RtpEncoder() override = default;
/**
* 264
* @param frame
*/

View File

@@ -1,16 +1,24 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "H265.h"
#include "H265Rtp.h"
#include "H265Rtmp.h"
#include "SPSParser.h"
#include "Util/base64.h"
#include "Common/Parser.h"
#include "Extension/Factory.h"
#ifdef ENABLE_MP4
#include "mpeg4-hevc.h"
#endif
using namespace std;
using namespace toolkit;
@@ -58,19 +66,7 @@ H265Track::H265Track(const string &vps,const string &sps, const string &pps,int
_vps = vps.substr(vps_prefix_len);
_sps = sps.substr(sps_prefix_len);
_pps = pps.substr(pps_prefix_len);
onReady();
}
const string &H265Track::getVps() const {
return _vps;
}
const string &H265Track::getSps() const {
return _sps;
}
const string &H265Track::getPps() const {
return _pps;
update();
}
CodecId H265Track::getCodecId() const {
@@ -89,7 +85,7 @@ float H265Track::getVideoFps() const {
return _fps;
}
bool H265Track::ready() {
bool H265Track::ready() const {
return !_vps.empty() && !_sps.empty() && !_pps.empty();
}
@@ -139,25 +135,58 @@ bool H265Track::inputFrame_l(const Frame::Ptr &frame) {
}
}
if (_width == 0 && ready()) {
onReady();
update();
}
return ret;
}
toolkit::Buffer::Ptr H265Track::getExtraData() const {
CHECK(ready());
#ifdef ENABLE_MP4
struct mpeg4_hevc_t hevc;
memset(&hevc, 0, sizeof(hevc));
string vps_sps_pps = string("\x00\x00\x00\x01", 4) + _vps + string("\x00\x00\x00\x01", 4) + _sps + string("\x00\x00\x00\x01", 4) + _pps;
h265_annexbtomp4(&hevc, vps_sps_pps.data(), (int) vps_sps_pps.size(), NULL, 0, NULL, NULL);
std::string extra_data;
extra_data.resize(1024);
auto extra_data_size = mpeg4_hevc_decoder_configuration_record_save(&hevc, (uint8_t *)extra_data.data(), extra_data.size());
if (extra_data_size == -1) {
WarnL << "生成H265 extra_data 失败";
return nullptr;
}
return std::make_shared<BufferString>(std::move(extra_data));
#else
WarnL << "请开启MP4相关功能并使能\"ENABLE_MP4\",否则对H265的支持不完善";
return nullptr;
#endif
}
void H265Track::setExtraData(const uint8_t *data, size_t bytes) {
#ifdef ENABLE_MP4
struct mpeg4_hevc_t hevc;
memset(&hevc, 0, sizeof(hevc));
if (mpeg4_hevc_decoder_configuration_record_load(data, bytes, &hevc) > 0) {
std::vector<uint8_t> config(bytes * 2);
int size = mpeg4_hevc_to_nalu(&hevc, config.data(), bytes * 2);
if (size > 4) {
splitH264((char *)config.data(), size, 4, [&](const char *ptr, size_t len, size_t prefix) {
inputFrame_l(std::make_shared<H265FrameNoCacheAble>((char *)ptr, len, 0, 0, prefix));
});
update();
}
}
#else
WarnL << "请开启MP4相关功能并使能\"ENABLE_MP4\",否则对H265的支持不完善";
#endif
}
bool H265Track::update() {
return getHEVCInfo(_vps, _sps, _width, _height, _fps);
}
void H265Track::onReady() {
if (!getHEVCInfo(_vps, _sps, _width, _height, _fps)) {
_vps.clear();
_sps.clear();
_pps.clear();
}
}
Track::Ptr H265Track::clone() {
return std::make_shared<std::remove_reference<decltype(*this)>::type>(*this);
Track::Ptr H265Track::clone() const {
return std::make_shared<H265Track>(*this);
}
void H265Track::insertConfigFrame(const Frame::Ptr &frame) {
@@ -170,6 +199,7 @@ void H265Track::insertConfigFrame(const Frame::Ptr &frame) {
vpsFrame->_buffer.assign("\x00\x00\x00\x01", 4);
vpsFrame->_buffer.append(_vps);
vpsFrame->_dts = frame->dts();
vpsFrame->setIndex(frame->getIndex());
VideoTrack::inputFrame(vpsFrame);
}
if (!_sps.empty()) {
@@ -178,6 +208,7 @@ void H265Track::insertConfigFrame(const Frame::Ptr &frame) {
spsFrame->_buffer.assign("\x00\x00\x00\x01", 4);
spsFrame->_buffer.append(_sps);
spsFrame->_dts = frame->dts();
spsFrame->setIndex(frame->getIndex());
VideoTrack::inputFrame(spsFrame);
}
@@ -187,6 +218,7 @@ void H265Track::insertConfigFrame(const Frame::Ptr &frame) {
ppsFrame->_buffer.assign("\x00\x00\x00\x01", 4);
ppsFrame->_buffer.append(_pps);
ppsFrame->_dts = frame->dts();
ppsFrame->setIndex(frame->getIndex());
VideoTrack::inputFrame(ppsFrame);
}
}
@@ -205,17 +237,13 @@ public:
* @param payload_type rtp payload type 96
* @param bitrate
*/
H265Sdp(const string &strVPS,
const string &strSPS,
const string &strPPS,
int bitrate = 4000,
int payload_type = 96) : Sdp(90000,payload_type) {
H265Sdp(const string &strVPS, const string &strSPS, const string &strPPS, int payload_type, int bitrate) : Sdp(90000, payload_type) {
//视频通道
_printer << "m=video 0 RTP/AVP " << payload_type << "\r\n";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
_printer << "a=rtpmap:" << payload_type << " " << getCodecName() << "/" << 90000 << "\r\n";
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(CodecH265) << "/" << 90000 << "\r\n";
_printer << "a=fmtp:" << payload_type << " ";
_printer << "sprop-vps=";
_printer << encodeBase64(strVPS) << "; ";
@@ -223,27 +251,75 @@ public:
_printer << encodeBase64(strSPS) << "; ";
_printer << "sprop-pps=";
_printer << encodeBase64(strPPS) << "\r\n";
_printer << "a=control:trackID=" << (int)TrackVideo << "\r\n";
}
string getSdp() const override {
return _printer;
}
string getSdp() const override { return _printer; }
CodecId getCodecId() const override {
return CodecH265;
}
private:
_StrPrinter _printer;
};
Sdp::Ptr H265Track::getSdp() {
if(!ready()){
Sdp::Ptr H265Track::getSdp(uint8_t payload_type) const {
if (!ready()) {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<H265Sdp>(getVps(), getSps(), getPps(), getBitRate() / 1024);
return std::make_shared<H265Sdp>(_vps, _sps, _pps, payload_type, getBitRate() / 1024);
}
namespace {
CodecId getCodec() {
return CodecH265;
}
Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) {
return std::make_shared<H265Track>();
}
Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
// a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBdoAKAgC0WNrkky/AIAAADAAgAAAMBlQg=; sprop-pps=RAHA8vA8kAA=
auto map = Parser::parseArgs(track->_fmtp, ";", "=");
auto vps = decodeBase64(map["sprop-vps"]);
auto sps = decodeBase64(map["sprop-sps"]);
auto pps = decodeBase64(map["sprop-pps"]);
if (sps.empty() || pps.empty()) {
// 如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps
return std::make_shared<H265Track>();
}
return std::make_shared<H265Track>(vps, sps, pps, 0, 0, 0);
}
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
return std::make_shared<H265RtpEncoder>();
}
RtpCodec::Ptr getRtpDecoderByCodecId() {
return std::make_shared<H265RtpDecoder>();
}
RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) {
return std::make_shared<H265RtmpEncoder>(track);
}
RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) {
return std::make_shared<H265RtmpDecoder>(track);
}
Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return std::make_shared<H265FrameNoCacheAble>((char *)data, bytes, dts, pts, prefixSize(data, bytes));
}
} // namespace
CodecPlugin h265_plugin = { getCodec,
getTrackByCodecId,
getTrackBySdp,
getRtpEncoderByCodecId,
getRtpDecoderByCodecId,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtr };
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,16 +11,14 @@
#ifndef ZLMEDIAKIT_H265_H
#define ZLMEDIAKIT_H265_H
#include "Frame.h"
#include "Track.h"
#include "H264.h"
#include "Extension/Track.h"
#include "Extension/Frame.h"
#define H265_TYPE(v) (((uint8_t)(v) >> 1) & 0x3f)
namespace mediakit {
bool getHEVCInfo(const std::string &strVps, const std::string &strSps, int &iVideoWidth, int &iVideoHeight, float &iVideoFps);
template<typename Parent>
class H265FrameHelper : public Parent{
public:
@@ -64,8 +62,6 @@ public:
this->_codec_id = CodecH265;
}
~H265FrameHelper() override = default;
bool keyFrame() const override {
auto nal_ptr = (uint8_t *) this->data() + this->prefixSize();
auto type = H265_TYPE(*nal_ptr);
@@ -137,25 +133,19 @@ public:
*/
H265Track(const std::string &vps,const std::string &sps, const std::string &pps,int vps_prefix_len = 4, int sps_prefix_len = 4, int pps_prefix_len = 4);
/**
* 0x00 00 00 01vps/sps/pps
*/
const std::string &getVps() const;
const std::string &getSps() const;
const std::string &getPps() const;
bool ready() override;
bool ready() const override;
CodecId getCodecId() const override;
int getVideoWidth() const override;
int getVideoHeight() const override;
float getVideoFps() const override;
bool inputFrame(const Frame::Ptr &frame) override;
toolkit::Buffer::Ptr getExtraData() const override;
void setExtraData(const uint8_t *data, size_t size) override;
bool update() override;
private:
void onReady();
Sdp::Ptr getSdp() override;
Track::Ptr clone() override;
Sdp::Ptr getSdp(uint8_t payload_type) const override;
Track::Ptr clone() const override;
bool inputFrame_l(const Frame::Ptr &frame);
void insertConfigFrame(const Frame::Ptr &frame);

174
ext-codec/H265Rtmp.cpp Normal file
View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "H265Rtmp.h"
#include "Rtmp/utils.h"
#include "Common/config.h"
#ifdef ENABLE_MP4
#include "mpeg4-hevc.h"
#endif // ENABLE_MP4
using namespace std;
using namespace toolkit;
namespace mediakit {
void H265RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt) {
if (_info.codec == CodecInvalid) {
// 先判断是否为增强型rtmp
parseVideoRtmpPacket((uint8_t *)pkt->data(), pkt->size(), &_info);
}
if (_info.is_enhanced) {
// 增强型rtmp
parseVideoRtmpPacket((uint8_t *)pkt->data(), pkt->size(), &_info);
if (!_info.is_enhanced || _info.codec != CodecH265) {
throw std::invalid_argument("Invalid enhanced-rtmp hevc packet!");
}
switch (_info.video.pkt_type) {
case RtmpPacketType::PacketTypeSequenceStart: {
getTrack()->setExtraData((uint8_t *)pkt->data() + RtmpPacketInfo::kEnhancedRtmpHeaderSize, pkt->size() - RtmpPacketInfo::kEnhancedRtmpHeaderSize);
break;
}
case RtmpPacketType::PacketTypeCodedFramesX:
case RtmpPacketType::PacketTypeCodedFrames: {
auto data = (uint8_t *)pkt->data() + RtmpPacketInfo::kEnhancedRtmpHeaderSize;
auto size = pkt->size() - RtmpPacketInfo::kEnhancedRtmpHeaderSize;
auto pts = pkt->time_stamp;
CHECK(size > 3);
if (RtmpPacketType::PacketTypeCodedFrames == _info.video.pkt_type) {
// SI24 = [CompositionTime Offset]
int32_t cts = (((data[0] << 16) | (data[1] << 8) | (data[2])) + 0xff800000) ^ 0xff800000;
pts += cts;
data += 3;
size -= 3;
}
CHECK(size > 4);
splitFrame(data, size, pkt->time_stamp, pts);
break;
}
default: WarnL << "Unknown pkt_type: " << (int)_info.video.pkt_type; break;
}
return;
}
// 国内扩展(12) H265 rtmp
if (pkt->isConfigFrame()) {
CHECK(pkt->size() > 5);
getTrack()->setExtraData((uint8_t *)pkt->data() + 5, pkt->size() - 5);
return;
}
CHECK(pkt->size() > 9);
uint8_t *cts_ptr = (uint8_t *)(pkt->buffer.data() + 2);
int32_t cts = (((cts_ptr[0] << 16) | (cts_ptr[1] << 8) | (cts_ptr[2])) + 0xff800000) ^ 0xff800000;
auto pts = pkt->time_stamp + cts;
splitFrame((uint8_t *)pkt->data() + 5, pkt->size() - 5, pkt->time_stamp, pts);
}
void H265RtmpDecoder::splitFrame(const uint8_t *data, size_t size, uint32_t dts, uint32_t pts) {
auto end = data + size;
while (data + 4 < end) {
uint32_t frame_len = load_be32(data);
data += 4;
if (data + frame_len > end) {
break;
}
outputFrame((const char *)data, frame_len, dts, pts);
data += frame_len;
}
}
inline void H265RtmpDecoder::outputFrame(const char *data, size_t size, uint32_t dts, uint32_t pts) {
auto frame = FrameImp::create<H265Frame>();
frame->_prefix_size = 4;
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign("\x00\x00\x00\x01", 4); // 添加265头
frame->_buffer.append(data, size);
RtmpCodec::inputFrame(frame);
}
////////////////////////////////////////////////////////////////////////
void H265RtmpEncoder::flush() {
inputFrame(nullptr);
}
bool H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
if (!_rtmp_packet) {
_rtmp_packet = RtmpPacket::create();
GET_CONFIG(bool, enhanced, Rtmp::kEnhanced);
_rtmp_packet->buffer.resize((enhanced ? RtmpPacketInfo::kEnhancedRtmpHeaderSize : 2) + 3);
}
return _merger.inputFrame(frame, [this](uint64_t dts, uint64_t pts, const Buffer::Ptr &, bool have_key_frame) {
GET_CONFIG(bool, enhanced, Rtmp::kEnhanced);
if (enhanced) {
auto header = (RtmpVideoHeaderEnhanced *)_rtmp_packet->data();
header->enhanced = 1;
header->pkt_type = (int)RtmpPacketType::PacketTypeCodedFrames;
header->frame_type = have_key_frame ? (int)RtmpFrameType::key_frame : (int)RtmpFrameType::inter_frame;
header->fourcc = htonl((uint32_t)RtmpVideoCodec::fourcc_hevc);
} else {
// flags
_rtmp_packet->buffer[0] = (uint8_t)RtmpVideoCodec::h265 | ((uint8_t)(have_key_frame ? RtmpFrameType::key_frame : RtmpFrameType::inter_frame) << 4);
_rtmp_packet->buffer[1] = (uint8_t)RtmpH264PacketType::h264_nalu;
}
int32_t cts = pts - dts;
// cts
set_be24(&_rtmp_packet->buffer[enhanced ? 5 : 2], cts);
_rtmp_packet->time_stamp = dts;
_rtmp_packet->body_size = _rtmp_packet->buffer.size();
_rtmp_packet->chunk_id = CHUNK_VIDEO;
_rtmp_packet->stream_index = STREAM_MEDIA;
_rtmp_packet->type_id = MSG_VIDEO;
// 输出rtmp packet
RtmpCodec::inputRtmp(_rtmp_packet);
_rtmp_packet = nullptr;
}, &_rtmp_packet->buffer);
}
void H265RtmpEncoder::makeConfigPacket() {
auto pkt = RtmpPacket::create();
GET_CONFIG(bool, enhanced, Rtmp::kEnhanced);
if (enhanced) {
pkt->buffer.resize(RtmpPacketInfo::kEnhancedRtmpHeaderSize);
auto header = (RtmpVideoHeaderEnhanced *)pkt->data();
header->enhanced = 1;
header->pkt_type = (int)RtmpPacketType::PacketTypeSequenceStart;
header->frame_type = (int)RtmpFrameType::key_frame;
header->fourcc = htonl((uint32_t)RtmpVideoCodec::fourcc_hevc);
} else {
auto flags = (uint8_t)RtmpVideoCodec::h265;
flags |= ((uint8_t)RtmpFrameType::key_frame << 4);
// header
pkt->buffer.push_back(flags);
pkt->buffer.push_back((uint8_t)RtmpH264PacketType::h264_config_header);
// cts
pkt->buffer.append("\x0\x0\x0", 3);
}
// HEVCDecoderConfigurationRecord
auto extra_data = getTrack()->getExtraData();
CHECK(extra_data);
pkt->buffer.append(extra_data->data(), extra_data->size());
pkt->body_size = pkt->buffer.size();
pkt->chunk_id = CHUNK_VIDEO;
pkt->stream_index = STREAM_MEDIA;
pkt->time_stamp = 0;
pkt->type_id = MSG_VIDEO;
RtmpCodec::inputRtmp(pkt);
}
} // namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,9 +11,9 @@
#ifndef ZLMEDIAKIT_H265RTMPCODEC_H
#define ZLMEDIAKIT_H265RTMPCODEC_H
#include "H265.h"
#include "Rtmp/RtmpCodec.h"
#include "Extension/Track.h"
#include "Extension/H265.h"
namespace mediakit {
/**
@@ -24,8 +24,7 @@ class H265RtmpDecoder : public RtmpCodec {
public:
using Ptr = std::shared_ptr<H265RtmpDecoder>;
H265RtmpDecoder();
~H265RtmpDecoder() = default;
H265RtmpDecoder(const Track::Ptr &track) : RtmpCodec(track) {}
/**
* 265 Rtmp包
@@ -33,23 +32,18 @@ public:
*/
void inputRtmp(const RtmpPacket::Ptr &rtmp) override;
CodecId getCodecId() const override { return CodecH265; }
protected:
H265Frame::Ptr obtainFrame();
void onGetH265(const char *data, size_t size, uint32_t dts, uint32_t pts);
void outputFrame(const char *data, size_t size, uint32_t dts, uint32_t pts);
void splitFrame(const uint8_t *data, size_t size, uint32_t dts, uint32_t pts);
protected:
RtmpPacketInfo _info;
H265Frame::Ptr _h265frame;
};
/**
* 265 Rtmp打包类
*/
class H265RtmpEncoder : public H265RtmpDecoder {
class H265RtmpEncoder : public RtmpCodec {
public:
using Ptr = std::shared_ptr<H265RtmpEncoder>;
@@ -59,8 +53,7 @@ public:
* inputFrame时可以不输入sps pps
* @param track
*/
H265RtmpEncoder(const Track::Ptr &track);
~H265RtmpEncoder() = default;
H265RtmpEncoder(const Track::Ptr &track) : RtmpCodec(track) {}
/**
* 265sps pps
@@ -79,14 +72,6 @@ public:
void makeConfigPacket() override;
private:
void makeVideoConfigPkt();
private:
bool _got_config_frame = false;
std::string _vps;
std::string _sps;
std::string _pps;
H265Track::Ptr _track;
RtmpPacket::Ptr _rtmp_packet;
FrameMerger _merger { FrameMerger::mp4_nal_size };
};

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -248,20 +248,8 @@ void H265RtpDecoder::outputFrame(const RtpPacket::Ptr &rtp, const H265Frame::Ptr
////////////////////////////////////////////////////////////////////////
H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
uint32_t ui32MtuSize,
uint32_t ui32SampleRate,
uint8_t ui8PayloadType,
uint8_t ui8Interleaved) :
RtpInfo(ui32Ssrc,
ui32MtuSize,
ui32SampleRate,
ui8PayloadType,
ui8Interleaved) {
}
void H265RtpEncoder::packRtpFu(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){
auto max_size = getMaxSize() - 3;
auto max_size = getRtpInfo().getMaxSize() - 3;
auto nal_type = H265_TYPE(ptr[0]); //获取NALU的5bit 帧类型
unsigned char s_e_flags;
bool fu_start = true;
@@ -283,7 +271,7 @@ void H265RtpEncoder::packRtpFu(const char *ptr, size_t len, uint64_t pts, bool i
{
// 传入nullptr先不做payload的内存拷贝
auto rtp = makeRtp(getTrackType(), nullptr, max_size + 3, mark_bit, pts);
auto rtp = getRtpInfo().makeRtp(TrackVideo, nullptr, max_size + 3, mark_bit, pts);
// rtp payload 负载部分
uint8_t *payload = rtp->getPayload();
// FU 第1个字节表明为FU
@@ -304,9 +292,9 @@ void H265RtpEncoder::packRtpFu(const char *ptr, size_t len, uint64_t pts, bool i
}
void H265RtpEncoder::packRtp(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){
if (len <= getMaxSize()) {
if (len <= getRtpInfo().getMaxSize()) {
//signal-nalu
RtpCodec::inputRtp(makeRtp(getTrackType(), ptr, len, is_mark, pts), gop_pos);
RtpCodec::inputRtp(getRtpInfo().makeRtp(TrackVideo, ptr, len, is_mark, pts), gop_pos);
} else {
//FU-A模式
packRtpFu(ptr, len, pts, is_mark, gop_pos);

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,12 +11,12 @@
#ifndef ZLMEDIAKIT_H265RTPCODEC_H
#define ZLMEDIAKIT_H265RTPCODEC_H
#include "H265.h"
#include "Rtsp/RtpCodec.h"
#include "Extension/H265.h"
// for DtsGenerator
#include "Common/Stamp.h"
namespace mediakit{
namespace mediakit {
/**
* h265 rtp解码类
@@ -28,7 +28,6 @@ public:
using Ptr = std::shared_ptr<H265RtpDecoder>;
H265RtpDecoder();
~H265RtpDecoder() {}
/**
* 265 rtp包
@@ -37,10 +36,6 @@ public:
*/
bool inputRtp(const RtpPacket::Ptr &rtp, bool key_pos = true) override;
CodecId getCodecId() const override{
return CodecH265;
}
private:
bool unpackAp(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssize_t size, uint64_t stamp);
bool mergeFu(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssize_t size, uint64_t stamp, uint16_t seq);
@@ -63,24 +58,10 @@ private:
/**
* 265 rtp打包类
*/
class H265RtpEncoder : public H265RtpDecoder ,public RtpInfo{
class H265RtpEncoder : public RtpCodec {
public:
using Ptr = std::shared_ptr<H265RtpEncoder>;
/**
* @param ui32Ssrc ssrc
* @param ui32MtuSize mtu大小
* @param ui32SampleRate 90000
* @param ui8PayloadType pt类型
* @param ui8Interleaved rtsp interleaved
*/
H265RtpEncoder(uint32_t ui32Ssrc,
uint32_t ui32MtuSize = 1400,
uint32_t ui32SampleRate = 90000,
uint8_t ui8PayloadType = 96,
uint8_t ui8Interleaved = TrackVideo * 2);
~H265RtpEncoder() {}
/**
* 265
* @param frame

101
ext-codec/JPEG.cpp Normal file
View File

@@ -0,0 +1,101 @@
#include "JPEG.h"
#include "JPEGRtp.h"
#include "Rtsp/Rtsp.h"
#include "Util/util.h"
#include "Extension/Factory.h"
using namespace toolkit;
namespace mediakit {
bool JPEGTrack::inputFrame(const Frame::Ptr &frame) {
if (!ready()) {
if (_height > 0 && _width > 0) {
if (_tmp == 0) _tmp = frame->dts();
else _fps = 1000.0 / (frame->dts() - _tmp);
} else getVideoResolution((uint8_t*)frame->data(), frame->size());
return false;
}
return VideoTrack::inputFrame(frame);
}
void JPEGTrack::getVideoResolution(const uint8_t *buf, int len) {
for (int i = 0; i < len - 8; i++) {
if (buf[i] != 0xff)
continue;
if (buf[i + 1] == 0xC0 /*SOF0*/) {
_height = buf[i + 5] * 256 + buf[i + 6];
_width = buf[i + 7] * 256 + buf[i + 8];
return;
}
}
}
class JPEGSdp : public Sdp {
public:
JPEGSdp(int bitrate) : Sdp(90000, Rtsp::PT_JPEG) {
_printer << "m=video 0 RTP/AVP " << (int)getPayloadType() << "\r\n";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
}
std::string getSdp() const { return _printer; }
private:
_StrPrinter _printer;
};
Sdp::Ptr JPEGTrack::getSdp(uint8_t) const {
return std::make_shared<JPEGSdp>(getBitRate() / 1024);
}
namespace {
CodecId getCodec() {
return CodecJPEG;
}
Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) {
return std::make_shared<JPEGTrack>();
}
Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
return std::make_shared<JPEGTrack>();
}
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
return std::make_shared<JPEGRtpEncoder>();
}
RtpCodec::Ptr getRtpDecoderByCodecId() {
return std::make_shared<JPEGRtpDecoder>();
}
RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) {
WarnL << "Unsupported jpeg rtmp encoder";
return nullptr;
}
RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) {
WarnL << "Unsupported jpeg rtmp decoder";
return nullptr;
}
Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return std::make_shared<JPEGFrame<FrameFromPtr>>(0, CodecJPEG, (char *)data, bytes, dts, pts);
}
} // namespace
CodecPlugin jpeg_plugin = { getCodec,
getTrackByCodecId,
getTrackBySdp,
getRtpEncoderByCodecId,
getRtpDecoderByCodecId,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtr };
} // namespace mediakit

View File

@@ -1,8 +1,8 @@
#ifndef ZLMEDIAKIT_JPEG_H
#define ZLMEDIAKIT_JPEG_H
#include "Frame.h"
#include "Track.h"
#include "Extension/Frame.h"
#include "Extension/Track.h"
namespace mediakit {
@@ -14,12 +14,12 @@ public:
int getVideoHeight() const override { return _height; }
int getVideoWidth() const override { return _width; }
float getVideoFps() const override { return _fps; }
bool ready() override { return _fps > 0; }
bool ready() const override { return _fps > 0; }
bool inputFrame(const Frame::Ptr &frame) override;
private:
Sdp::Ptr getSdp() override;
Track::Ptr clone() override { return std::make_shared<std::remove_reference<decltype(*this)>::type>(*this); }
Sdp::Ptr getSdp(uint8_t payload_type) const override;
Track::Ptr clone() const override { return std::make_shared<JPEGTrack>(*this); }
void getVideoResolution(const uint8_t *buf, int len);
private:
@@ -29,39 +29,34 @@ private:
uint64_t _tmp = 0;
};
class JPEGFrame : public Frame {
class JPEGFrameType {
public:
virtual ~JPEGFrameType() = default;
virtual uint8_t pixType() const = 0;
};
template <typename Parent>
class JPEGFrame : public Parent, public JPEGFrameType {
public:
static constexpr auto kJFIFSize = 20u;
/**
* JPEG/MJPEG帧
* @param buffer
* @param dts ,
* @param pix_type pixel format type; AV_PIX_FMT_YUVJ422P || (AVCOL_RANGE_JPEG && AV_PIX_FMT_YUV422P) : 1; AV_PIX_FMT_YUVJ420P || (AVCOL_RANGE_JPEG && AV_PIX_FMT_YUV420P) : 0
* @param prefix_size JFIF头大小
*/
JPEGFrame(toolkit::Buffer::Ptr buffer, uint64_t dts, uint8_t pix_type = 0, size_t prefix_size = 0) {
_buffer = std::move(buffer);
_dts = dts;
template <typename... ARGS>
JPEGFrame(uint8_t pix_type, ARGS &&...args) : Parent(std::forward<ARGS>(args)...) {
_pix_type = pix_type;
_prefix_size = prefix_size;
// JFIF头固定20个字节长度
CHECK(this->size() > kJFIFSize);
}
~JPEGFrame() override = default;
uint64_t dts() const override { return _dts; }
size_t prefixSize() const override { return _prefix_size; }
size_t prefixSize() const override { return 0; }
bool keyFrame() const override { return true; }
bool configFrame() const override { return false; }
CodecId getCodecId() const override { return CodecJPEG; }
char *data() const override { return _buffer->data(); }
size_t size() const override { return _buffer->size(); }
uint8_t pixType() const {return _pix_type; }
uint8_t pixType() const override { return _pix_type; }
private:
uint8_t _pix_type;
size_t _prefix_size;
uint64_t _dts;
toolkit::Buffer::Ptr _buffer;
};
}//namespace mediakit

View File

@@ -745,10 +745,10 @@ void JPEGRtpEncoder::rtpSendJpeg(const uint8_t *buf, int size, uint64_t pts, uin
hdr_size += 4 + 64 * nb_qtables;
/* payload max in one packet */
len = MIN(size, (int)getMaxSize() - hdr_size);
len = MIN(size, (int)getRtpInfo().getMaxSize() - hdr_size);
/* marker bit is last packet in frame */
auto rtp_packet = makeRtp(getTrackType(), nullptr, len + hdr_size, size == len, pts);
auto rtp_packet = getRtpInfo().makeRtp(TrackVideo, nullptr, len + hdr_size, size == len, pts);
p = rtp_packet->getPayload();
/* set main header */
@@ -788,9 +788,7 @@ JPEGRtpDecoder::JPEGRtpDecoder() {
memset(&_ctx.timestamp, 0, sizeof(_ctx) - offsetof(decltype(_ctx), timestamp));
}
CodecId JPEGRtpDecoder::getCodecId() const {
return CodecJPEG;
}
using JPEGFrameImp = JPEGFrame<FrameFromBuffer<FrameFromPtr> >;
bool JPEGRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool) {
auto payload = rtp->getPayload();
@@ -806,8 +804,7 @@ bool JPEGRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool) {
uint8_t type;
if (0 == jpeg_parse_packet(nullptr, &_ctx, &stamp, payload, size, seq, marker ? RTP_FLAG_MARKER : 0, &type)) {
auto buffer = std::make_shared<toolkit::BufferString>(std::move(_ctx.frame));
// JFIF头固定20个字节长度
auto frame = std::make_shared<JPEGFrame>(std::move(buffer), stamp / 90, type, 20);
auto frame = std::make_shared<JPEGFrameImp>(type, std::move(buffer), stamp / 90, 0);
_ctx.frame.clear();
RtpCodec::inputFrame(std::move(frame));
}
@@ -817,17 +814,13 @@ bool JPEGRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool) {
////////////////////////////////////////////////////////////////////////
JPEGRtpEncoder::JPEGRtpEncoder(
uint32_t ssrc, uint32_t mtu, uint32_t sample_rate, uint8_t payload_type, uint8_t interleaved)
: RtpInfo(ssrc, mtu, sample_rate, payload_type, interleaved) {}
bool JPEGRtpEncoder::inputFrame(const Frame::Ptr &frame) {
auto ptr = (uint8_t *)frame->data() + frame->prefixSize();
auto len = frame->size() - frame->prefixSize();
// JFIF头固定20个字节长度
auto ptr = (uint8_t *)frame->data() + frame->prefixSize() + JPEGFrameImp::kJFIFSize;
auto len = frame->size() - frame->prefixSize() - JPEGFrameImp::kJFIFSize;
auto pts = frame->pts();
auto type = 1;
auto jpeg = dynamic_pointer_cast<JPEGFrame>(frame);
auto jpeg = dynamic_pointer_cast<JPEGFrameType>(frame);
if (jpeg) {
type = jpeg->pixType();
}

View File

@@ -1,10 +1,10 @@
#ifndef ZLMEDIAKIT_JPEGRTP_H
#define ZLMEDIAKIT_JPEGRTP_H
#include "Frame.h"
#include "Rtsp/RtpCodec.h"
#include "Extension/Frame.h"
namespace mediakit{
namespace mediakit {
/**
* RTP/JPEG specific private data.
@@ -25,12 +25,6 @@ public:
typedef std::shared_ptr <JPEGRtpDecoder> Ptr;
JPEGRtpDecoder();
~JPEGRtpDecoder() override = default;
/**
* ID
*/
CodecId getCodecId() const override;
/**
* rtp并解码
@@ -43,13 +37,10 @@ private:
struct PayloadContext _ctx;
};
class JPEGRtpEncoder : public JPEGRtpDecoder, public RtpInfo {
class JPEGRtpEncoder : public RtpCodec {
public:
using Ptr = std::shared_ptr<JPEGRtpEncoder>;
JPEGRtpEncoder(uint32_t ssrc, uint32_t mtu = 1400, uint32_t sample_rate = 90000, uint8_t payload_type = 96, uint8_t interleaved = TrackVideo * 2);
~JPEGRtpEncoder() = default;
bool inputFrame(const Frame::Ptr &frame) override;
private:

109
ext-codec/L16.cpp Normal file
View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "L16.h"
#include "Extension/Factory.h"
#include "Extension/CommonRtp.h"
#include "Extension/CommonRtmp.h"
using namespace std;
using namespace toolkit;
namespace mediakit {
/**
* L16类型SDP
*/
class L16Sdp : public Sdp {
public:
/**
* L16采样位数固定为16位
* @param payload_type rtp payload type
* @param channels 通道数
* @param sample_rate 音频采样率
* @param bitrate 比特率
*/
L16Sdp(int payload_type, int sample_rate, int channels, int bitrate) : Sdp(sample_rate, payload_type) {
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(CodecL16) << "/" << sample_rate << "/" << channels << "\r\n";
}
string getSdp() const override { return _printer; }
private:
_StrPrinter _printer;
};
Sdp::Ptr L16Track::getSdp(uint8_t payload_type) const {
WarnL << "Enter L16Track::getSdp function";
if (!ready()) {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<L16Sdp>(payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}
Track::Ptr L16Track::clone() const {
return std::make_shared<L16Track>(*this);
}
namespace {
CodecId getCodec() {
return CodecL16;
}
Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) {
return std::make_shared<L16Track>(sample_rate, channels);
}
Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
return std::make_shared<L16Track>(track->_samplerate, track->_channel);
}
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
return std::make_shared<CommonRtpEncoder>();
}
RtpCodec::Ptr getRtpDecoderByCodecId() {
return std::make_shared<CommonRtpDecoder>(CodecL16);
}
RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) {
WarnL << "Unsupported L16 rtmp encoder";
return nullptr;
}
RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) {
WarnL << "Unsupported L16 rtmp decoder";
return nullptr;
}
Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return std::make_shared<FrameFromPtr>(CodecL16, (char *)data, bytes, dts, pts);
}
} // namespace
CodecPlugin l16_plugin = { getCodec,
getTrackByCodecId,
getTrackBySdp,
getRtpEncoderByCodecId,
getRtpDecoderByCodecId,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtr };
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,10 +11,10 @@
#ifndef ZLMEDIAKIT_L16_H
#define ZLMEDIAKIT_L16_H
#include "Frame.h"
#include "Track.h"
#include "Extension/Frame.h"
#include "Extension/Track.h"
namespace mediakit{
namespace mediakit {
/**
* L16音频通道
@@ -25,8 +25,8 @@ public:
L16Track(int sample_rate, int channels) : AudioTrackImp(CodecL16,sample_rate,channels,16){}
private:
Sdp::Ptr getSdp() override;
Track::Ptr clone() override;
Sdp::Ptr getSdp(uint8_t payload_type) const override;
Track::Ptr clone() const override;
};
}//namespace mediakit

102
ext-codec/Opus.cpp Normal file
View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "Opus.h"
#include "Extension/Factory.h"
#include "Extension/CommonRtp.h"
#include "Extension/CommonRtmp.h"
using namespace std;
using namespace toolkit;
namespace mediakit {
/**
* Opus类型SDP
*/
class OpusSdp : public Sdp {
public:
/**
* 构造opus sdp
* @param payload_type rtp payload type
* @param sample_rate 音频采样率
* @param channels 通道数
* @param bitrate 比特率
*/
OpusSdp(int payload_type, int sample_rate, int channels, int bitrate) : Sdp(sample_rate, payload_type) {
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
_printer << "a=rtpmap:" << payload_type << " " << getCodecName(CodecOpus) << "/" << sample_rate << "/" << channels << "\r\n";
}
string getSdp() const override {
return _printer;
}
private:
_StrPrinter _printer;
};
Sdp::Ptr OpusTrack::getSdp(uint8_t payload_type) const {
if (!ready()) {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<OpusSdp>(payload_type, getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}
namespace {
CodecId getCodec() {
return CodecOpus;
}
Track::Ptr getTrackByCodecId(int sample_rate, int channels, int sample_bit) {
return std::make_shared<OpusTrack>();
}
Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
return std::make_shared<OpusTrack>();
}
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
return std::make_shared<CommonRtpEncoder>();
}
RtpCodec::Ptr getRtpDecoderByCodecId() {
return std::make_shared<CommonRtpDecoder>(CodecOpus);
}
RtmpCodec::Ptr getRtmpEncoderByTrack(const Track::Ptr &track) {
return std::make_shared<CommonRtmpEncoder>(track);
}
RtmpCodec::Ptr getRtmpDecoderByTrack(const Track::Ptr &track) {
return std::make_shared<CommonRtmpDecoder>(track);
}
Frame::Ptr getFrameFromPtr(const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
return std::make_shared<FrameFromPtr>(CodecOpus, (char *)data, bytes, dts, pts);
}
} // namespace
CodecPlugin opus_plugin = { getCodec,
getTrackByCodecId,
getTrackBySdp,
getRtpEncoderByCodecId,
getRtpDecoderByCodecId,
getRtmpEncoderByTrack,
getRtmpDecoderByTrack,
getFrameFromPtr };
}//namespace mediakit

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
@@ -11,10 +11,10 @@
#ifndef ZLMEDIAKIT_OPUS_H
#define ZLMEDIAKIT_OPUS_H
#include "Frame.h"
#include "Track.h"
#include "Extension/Frame.h"
#include "Extension/Track.h"
namespace mediakit{
namespace mediakit {
/**
* Opus帧音频通道
@@ -26,11 +26,11 @@ public:
private:
//克隆该Track
Track::Ptr clone() override {
return std::make_shared<std::remove_reference<decltype(*this)>::type >(*this);
Track::Ptr clone() const override {
return std::make_shared<OpusTrack>(*this);
}
//生成sdp
Sdp::Ptr getSdp() override ;
Sdp::Ptr getSdp(uint8_t payload_type) const override ;
};
}//namespace mediakit

View File

@@ -24,7 +24,7 @@ Summary: A lightweight, high performance and stable stream server and client fra
Group: development
License: MIT
URL: https://github.com/xia-chu/ZLMediaKit
URL: https://github.com/ZLMediaKit/ZLMediaKit
Source0: %{name}-%{version}.tar.xz
%if %{with openssl}

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
 /*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/

View File

@@ -2184,6 +2184,38 @@
}
},
"response": []
},
{
"name": "下载文件(downloadFile)",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{ZLMediaKit_URL}}/index/api/downloadFile?file_path=/path/to/file.ext",
"host": [
"{{ZLMediaKit_URL}}"
],
"path": [
"index",
"api",
"downloadFile"
],
"query": [
{
"key": "file_path",
"value": "/path/to/file.ext",
"description": "文件绝对路径根据文件名生成Content-Type该接口将触发on_http_access hook"
},
{
"key": "save_name",
"value": "test",
"description": "浏览器下载文件后保存文件名;可选参数",
"disabled": true
}
]
}
},
"response": []
}
],
"event": [

Some files were not shown because too many files have changed in this diff Show More