commit 05a551d523320d5bf604b0b793e9686818b29011 Author: asxalex Date: Fri Aug 22 13:52:24 2025 +0800 first commit diff --git a/.args.yaml b/.args.yaml new file mode 100644 index 0000000..10a474b --- /dev/null +++ b/.args.yaml @@ -0,0 +1,2 @@ +service_type: config +target_dir: /usr/bin diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73c366a --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +mpp_test +.vscode +.*.swp +*.h264 +/build +*.cmake +CMakeFiles +efka-flow +*.exe +*.jpg +*.png diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..c04832e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.5.1) + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) + +#set(tools /usr/local/cross-compile/aarch64-cc/) +set(tools /home/alex/work/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu) +set(CMAKE_C_COMPILER ${tools}/bin/aarch64-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER ${tools}/bin/aarch64-linux-gnu-g++) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +project(mpp_test) + +set(CMAKE_CXX_STANDARD 14) + +# include_directories("${PROJECT_SOURCE_DIR}/utils") +# add_subdirectory(utils) + +set(CMAKE_CXX_FLAGS "-O0 -g") + +include_directories( + /usr/include/aarch64-linux-gnu + /env/platforms/aarch64/include + ${CMAKE_CURRENT_LIST_DIR}/ffmpeg/inc + ${CMAKE_CURRENT_LIST_DIR}/mpp/inc + # ${CMAKE_CURRENT_LIST_DIR}/rockx/include + ${CMAKE_CURRENT_LIST_DIR}/rga/inc + ${CMAKE_CURRENT_LIST_DIR}/cjson + ${CMAKE_CURRENT_LIST_DIR}/rknn/inc + # ${CMAKE_CURRENT_LIST_DIR}/turbojpeg + # ${CMAKE_CURRENT_LIST_DIR}/utils +) + + +link_directories( + /env/platforms/aarch64/so + /env/platforms/aarch64/static + /usr/local/lib + # /home/alex/work/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/lib + ${CMAKE_CURRENT_LIST_DIR}/mpp/lib + # ${CMAKE_CURRENT_LIST_DIR}/ffm_lib + ${CMAKE_CURRENT_LIST_DIR}/ffmpeg/lib + ${CMAKE_CURRENT_LIST_DIR}/opencv_lib + ${CMAKE_CURRENT_LIST_DIR}/rockx/lib64 + ${CMAKE_CURRENT_LIST_DIR}/rga/lib + ${CMAKE_CURRENT_LIST_DIR}/turbojpeg + ${CMAKE_CURRENT_LIST_DIR}/rknn/lib +) + + +add_executable(yolov5 + MppDecode.cpp + main.cpp + pose_body.cpp + myrga.cpp + cjson/cJSON.c + utils.cpp + rknn.cpp + action.cpp + yolov5.cc + postprocess.cc + vertix.cpp +) + +target_link_libraries(yolov5 + rockchip_mpp + avformat + avcodec + avutil + pthread + swresample + m + dl + rknn_api + rga +) diff --git a/MppDecode.cpp b/MppDecode.cpp new file mode 100755 index 0000000..5eec712 --- /dev/null +++ b/MppDecode.cpp @@ -0,0 +1,420 @@ +// +// Created by LX on 2020/4/25. +// + +#include "MppDecode.h" +#include "myrga.h" +#include "pose_body.h" +#include "rknn.h" + +extern long max_time_elapsed; + +volatile int origin_height, origin_width; +volatile float resize_width_scale; +volatile float resize_height_scale; + +pthread_mutex_t frame_mutex = PTHREAD_MUTEX_INITIALIZER; + +// rknn_t *rknn = get_rknn("fall_5n.rknn"); + +/* +int print_messgae(rknn_t *rk, detect_result_group_t *group) { + printf("got group->count = %d\n", group->count); + for (int i = 0; i < group->count; i++) { + printf("%d th result: %s at [%d, %d, %d, %d] with score %f\n", i, group->results[i].name, + group->results[i].box.left, group->results[i].box.right, + group->results[i].box.top, group->results[i].box.bottom, group->results[i].prop); + } + +} + +int rknn_pose_body(char *out, int width, int height) { + struct timeval tpend1, tpend2; + long usec1 = 0; + gettimeofday(&tpend1, NULL); + + rknn->do_judge(rknn, out, width, height, print_messgae); + + gettimeofday(&tpend2, NULL); + usec1 = 1000 * (tpend2.tv_sec - tpend1.tv_sec) + (tpend2.tv_usec - tpend1.tv_usec) / 1000; + // printf("rknn cost_time=%ld ms\n", usec1); + + free(out); + // printf("in pose_body_thread ok\n"); + pthread_mutex_unlock(&frame_mutex); +} +*/ + +void set_resize_ratio(int imgwidth, int imgheight) +{ + origin_width = imgwidth; + origin_height = imgheight; + resize_height_scale = (float)DSTHeight / (float)imgheight; + resize_width_scale = (float)DSTWidth / (float)imgwidth; +} + +void *pose_body_thread(void *arg) +{ + char *out = (char *)arg; + // printf("in pose_body_thread\n"); + + // process_a_frame(out, DSTWidth, DSTHeight); + process_a_frame(out, 640, 640); + // rknn_pose_body(out, DSTWidth, DSTHeight); +} + +void convert_a_frame(MppFrame frame) +{ + RK_U32 width = 0; + RK_U32 height = 0; + RK_U32 h_stride = 0; + RK_U32 v_stride = 0; + + MppBuffer buffer = NULL; + RK_U8 *base = NULL; + + width = mpp_frame_get_width(frame); + height = mpp_frame_get_height(frame); + h_stride = mpp_frame_get_hor_stride(frame); + v_stride = mpp_frame_get_ver_stride(frame); + buffer = mpp_frame_get_buffer(frame); + + char *out = (char *)malloc(DSTWidth * DSTHeight * 3 * sizeof(char)); + if (out == NULL) + { + printf("failed to allocate a frame"); + return; + } + base = (RK_U8 *)mpp_buffer_get_ptr(buffer); + rga_client.convert(base, width, height, h_stride, v_stride, out); + // printf("convert a frame ok"); + if (pthread_mutex_trylock(&frame_mutex) == 0) + { + // lock acquired, should create thread and use pose_body + + pthread_t pose_body_handler; + pthread_create(&pose_body_handler, NULL, pose_body_thread, (void *)out); + pthread_detach(pose_body_handler); + } + else + { + free(out); + } + // free(out); +} + +int frame_null = 0; +int count = 0; +void dump_mpp_frame_to_file(MppFrame frame, FILE *fp) +{ + RK_U32 width = 0; + RK_U32 height = 0; + RK_U32 h_stride = 0; + RK_U32 v_stride = 0; + + MppBuffer buffer = NULL; + RK_U8 *base = NULL; + + width = mpp_frame_get_width(frame); + height = mpp_frame_get_height(frame); + h_stride = mpp_frame_get_hor_stride(frame); + v_stride = mpp_frame_get_ver_stride(frame); + buffer = mpp_frame_get_buffer(frame); + + base = (RK_U8 *)mpp_buffer_get_ptr(buffer); + RK_U32 buf_size = mpp_frame_get_buf_size(frame); + size_t base_length = mpp_buffer_get_size(buffer); + mpp_log("base_length = %d\n", base_length); + + RK_U32 i; + RK_U8 *base_y = base; + RK_U8 *base_c = base + h_stride * v_stride; + + // 保存为YUV420sp格式 + /*for (i = 0; i < height; i++, base_y += h_stride) + { + fwrite(base_y, 1, width, fp); + } + for (i = 0; i < height / 2; i++, base_c += h_stride) + { + fwrite(base_c, 1, width, fp); + }*/ + + // 保存为YUV420p格式 + for (i = 0; i < height; i++, base_y += h_stride) + { + fwrite(base_y, 1, width, fp); + } + for (i = 0; i < height * width / 2; i += 2) + { + fwrite((base_c + i), 1, 1, fp); + } + for (i = 1; i < height * width / 2; i += 2) + { + fwrite((base_c + i), 1, 1, fp); + } +} + +size_t mpp_buffer_group_usage(MppBufferGroup group) +{ + if (NULL == group) + { + mpp_err_f("input invalid group %p\n", group); + return MPP_BUFFER_MODE_BUTT; + } + + MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; + return p->usage; +} + +void dump_frame_to_file(MppFrame frame) +{ + FILE *out_fp = fopen("single.yuv", "w+b"); + RK_U32 width = 0; + RK_U32 height = 0; + RK_U32 h_stride = 0; + RK_U32 v_stride = 0; + MppFrameFormat fmt = MPP_FMT_YUV420SP; + MppBuffer buffer = NULL; + RK_U8 *base = NULL; + + width = mpp_frame_get_width(frame); + height = mpp_frame_get_height(frame); + h_stride = mpp_frame_get_hor_stride(frame); + v_stride = mpp_frame_get_ver_stride(frame); + fmt = mpp_frame_get_fmt(frame); + buffer = mpp_frame_get_buffer(frame); + + RK_U32 buf_size = mpp_frame_get_buf_size(frame); + printf("w x h: %dx%d hor_stride:%d ver_stride:%d buf_size:%d\n", + width, height, h_stride, v_stride, buf_size); + + if (NULL == buffer) + { + printf("buffer is null\n"); + return; + } + + base = (RK_U8 *)mpp_buffer_get_ptr(buffer); + + // MPP_FMT_YUV420SP + if (fmt != MPP_FMT_YUV420SP) + { + printf("fmt %d not supported\n", fmt); + return; + } + + RK_U32 i; + RK_U8 *base_y = base; + RK_U8 *base_c = base + h_stride * v_stride; + + for (i = 0; i < height; i++, base_y += h_stride) + { + fwrite(base_y, 1, width, out_fp); + } + for (i = 0; i < height / 2; i++, base_c += h_stride) + { + fwrite(base_c, 1, width, out_fp); + } + + fclose(out_fp); +} + +int decode_simple(MpiDecLoopData *data, AVPacket *av_packet) +{ + RK_U32 pkt_done = 0; + RK_U32 pkt_eos = 0; + RK_U32 err_info = 0; + MPP_RET ret = MPP_OK; + MppCtx ctx = data->ctx; + MppApi *mpi = data->mpi; + // char *buf = data->buf; + MppPacket packet = NULL; + MppFrame frame = NULL; + size_t read_size = 0; + size_t packet_size = data->packet_size; + + /* + if ((av_packet->data[4] & 0x1f) != 0x01) { + printf("sending data: %02x %02x[", av_packet->data[4], (av_packet->data[4] & 0x1f)); + for (int i = 0; i < av_packet->size; i++) { + printf("%02x ", av_packet->data[i]); + } + printf("]\n"); + } + */ + ret = mpp_packet_init(&packet, av_packet->data, av_packet->size); + mpp_packet_set_pts(packet, av_packet->pts); + + do + { + RK_S32 times = 5; + clock_t start, end; + // send the packet first if packet is not done + start = clock(); + if (!pkt_done) + { + ret = mpi->decode_put_packet(ctx, packet); + if (MPP_OK == ret) + pkt_done = 1; + } + + // then get all available frame and release + do + { + RK_S32 get_frm = 0; + RK_U32 frm_eos = 0; + + try_again: + ret = mpi->decode_get_frame(ctx, &frame); + if (MPP_ERR_TIMEOUT == ret) + { + if (times > 0) + { + times--; + msleep(2); + goto try_again; + } + mpp_err("decode_get_frame failed too much time\n"); + } + if (MPP_OK != ret) + { + mpp_err("decode_get_frame failed ret %d\n", ret); + break; + } + if (frame) + { + end = clock(); + if ((end - start) > max_time_elapsed) + { + max_time_elapsed = end - start; + } + MppFrameFormat fmt = mpp_frame_get_fmt(frame); + + // printf("vpu cost_time=%f ms\n", (float)(end - start) / CLOCKS_PER_SEC * 1000); + if (mpp_frame_get_info_change(frame)) + { + RK_U32 width = mpp_frame_get_width(frame); + RK_U32 height = mpp_frame_get_height(frame); + RK_U32 hor_stride = mpp_frame_get_hor_stride(frame); + RK_U32 ver_stride = mpp_frame_get_ver_stride(frame); + RK_U32 buf_size = mpp_frame_get_buf_size(frame); + + mpp_log("decode_get_frame get info changed found\n"); + mpp_log("decoder require buffer w:h [%d:%d] stride [%d:%d] buf_size %d", + width, height, hor_stride, ver_stride, buf_size); + + set_resize_ratio(hor_stride, ver_stride); + + ret = mpp_buffer_group_get_internal(&data->frm_grp, MPP_BUFFER_TYPE_ION); + if (ret) + { + mpp_err("get mpp buffer group failed ret %d\n", ret); + break; + } + mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, data->frm_grp); + + mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); + } + else + { + err_info = mpp_frame_get_errinfo(frame) | mpp_frame_get_discard(frame); + if (err_info) + { + mpp_log("decoder_get_frame get err info:%d discard:%d.\n", + mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame)); + } + data->frame_count++; + RK_U32 buf_size = mpp_frame_get_buf_size(frame); + // mpp_log("decode_get_frame get frame %d: size: %d\n", data->frame_count, buf_size); + if (!err_info) + { + printf("convert a frame\n"); + convert_a_frame(frame); + // cv::Mat rgbImg; + // YUV420SP2Mat(frame, rgbImg); + // cv::imwrite("./"+std::to_string(count++)+".jpg", rgbImg); + // dump_mpp_frame_to_file(frame, data->fp_output); + } + } + frm_eos = mpp_frame_get_eos(frame); + mpp_frame_deinit(&frame); + frame = NULL; + get_frm = 1; + + /* + int locked = pthread_mutex_trylock(&frame_mutex); + if (locked == 0) + { + // no one is using current frame, replace the global_frame + if (global_frame != NULL) + { + mpp_frame_deinit(&global_frame); + } + global_frame = frame; + pthread_mutex_unlock(&frame_mutex); + } + else + { + // destory the frame + mpp_frame_deinit(&frame); + } + */ + } + + // try get runtime frame memory usage + if (data->frm_grp) + { + size_t usage = mpp_buffer_group_usage(data->frm_grp); + if (usage > data->max_usage) + data->max_usage = usage; + } + + // if last packet is send but last frame is not found continue + if (pkt_eos && pkt_done && !frm_eos) + { + msleep(10); + continue; + } + + if (frm_eos) + { + mpp_log("found last frame\n"); + break; + } + + if (data->frame_num > 0 && data->frame_count >= data->frame_num) + { + data->eos = 1; + break; + } + + if (get_frm) + continue; + break; + } while (1); + + if (data->frame_num > 0 && data->frame_count >= data->frame_num) + { + data->eos = 1; + mpp_log("reach max frame number %d\n", data->frame_count); + break; + } + + if (pkt_done) + break; + + /* + * why sleep here: + * mpi->decode_put_packet will failed when packet in internal queue is + * full,waiting the package is consumed .Usually hardware decode one + * frame which resolution is 1080p needs 2 ms,so here we sleep 3ms + * * is enough. + */ + msleep(3); + } while (1); + mpp_packet_deinit(&packet); + packet = NULL; + + return ret; +} diff --git a/MppDecode.h b/MppDecode.h new file mode 100755 index 0000000..90cf4a9 --- /dev/null +++ b/MppDecode.h @@ -0,0 +1,93 @@ +// +// Created by LX on 2020/4/25. +// + +#ifndef LIVERTSPCLIENT_MPPDECODE_H +#define LIVERTSPCLIENT_MPPDECODE_H + +#define MODULE_TAG "mpi_dec_test" + +#include + +#include "utils.h" +#include "rk_mpi.h" +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_time.h" +#include "mpp_common.h" + +#include "mpp_frame.h" +#include "mpp_buffer_impl.h" +#include "mpp_frame_impl.h" +#include +#include + +// #include +// #include +// #include +// #include + + +#define MPI_DEC_STREAM_SIZE (SZ_4K) +#define MPI_DEC_LOOP_COUNT 4 +#define MAX_FILE_NAME_LENGTH 256 + +typedef struct +{ + MppCtx ctx; + MppApi *mpi; + RK_U32 eos; + char *buf; + + MppBufferGroup frm_grp; + MppBufferGroup pkt_grp; + MppPacket packet; + size_t packet_size; + MppFrame frame; + + FILE *fp_input; + FILE *fp_output; + RK_S32 frame_count; + RK_S32 frame_num; + size_t max_usage; +} MpiDecLoopData; + +typedef struct +{ + char file_input[MAX_FILE_NAME_LENGTH]; + char file_output[MAX_FILE_NAME_LENGTH]; + MppCodingType type; + MppFrameFormat format; + RK_U32 width; + RK_U32 height; + RK_U32 debug; + + RK_U32 have_input; + RK_U32 have_output; + + RK_U32 simple; + RK_S32 timeout; + RK_S32 frame_num; + size_t max_usage; +} MpiDecTestCmd; + + + +size_t mpp_frame_get_buf_size(const MppFrame s); +void dump_mpp_frame_to_file(MppFrame frame, FILE *fp); +size_t mpp_buffer_group_usage(MppBufferGroup group); + +int decode_simple(MpiDecLoopData *data, AVPacket* av_packet); + +extern pthread_mutex_t frame_mutex; +extern MppFrame global_frame; + +extern volatile int origin_height; +extern volatile int origin_width; +extern volatile float resize_width_scale; +extern volatile float resize_height_scale; + +// void YUV420SP2Mat(MppFrame frames, cv::Mat rgbImg ); + +#endif //LIVERTSPCLIENT_MPPDECODE_H diff --git a/README.md b/README.md new file mode 100644 index 0000000..914317c --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# ffmpeg_rtsp_mpp +ffmpeg 拉取rtsp h264流, 使用mpp解码, 目前在firefly 板子上跑通了 + +保存的yuv文件可以用yuvplayer.exe文件打开, 设置文件大小, 就可以正常显示了 +![](./yuv.jpg) + + +# change log +重新添加了一个整的YUV420SP2Mat()函数, 修改了内存泄露的bug, 根据release 版本的mpp精简了一点代码 + + +# reference +mpp 硬编码, 从文件中读取yuv一帧图片, 硬编码 + +该接口也可以直接传入yuv的void* 内存地址, 编码成h264的文件, 具体地址如下 +https://github.com/MUZLATAN/MPP_ENCODE + +## 关于模型的微服务 +模型目前上传到`./models`目录下,假定模型名为`abc`,则模型文件需要包含`abc.rknn`和`abc.txt`,此时目录结构如下所示: + +```bash +$ tree models +models +└── abc + ├── abc.rknn + └── abc.txt +``` \ No newline at end of file diff --git a/action.cpp b/action.cpp new file mode 100644 index 0000000..2dcb511 --- /dev/null +++ b/action.cpp @@ -0,0 +1,2 @@ +#include "action.h" +#include diff --git a/action.h b/action.h new file mode 100644 index 0000000..60c4ee0 --- /dev/null +++ b/action.h @@ -0,0 +1,7 @@ +#ifndef _ACTION_H_ +#define _ACTION_H_ + +#include +#include "pose_body.h" + +#endif \ No newline at end of file diff --git a/cjson/cJSON.c b/cjson/cJSON.c new file mode 100644 index 0000000..030311c --- /dev/null +++ b/cjson/cJSON.c @@ -0,0 +1,3110 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + 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. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#ifdef true +#undef true +#endif +#define true ((cJSON_bool)1) + +#ifdef false +#undef false +#endif +#define false ((cJSON_bool)0) + +/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ +#ifndef isinf +#define isinf(d) (isnan((d - d)) && !isnan(d)) +#endif +#ifndef isnan +#define isnan(d) (d != d) +#endif + +#ifndef NAN +#ifdef _WIN32 +#define NAN sqrt(-1.0) +#else +#define NAN 0.0/0.0 +#endif +#endif + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +{ + if (!cJSON_IsString(item)) + { + return NULL; + } + + return item->valuestring; +} + +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +{ + if (!cJSON_IsNumber(item)) + { + return (double) NAN; + } + + return item->valuedouble; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 14) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(CJSON_CDECL *allocate)(size_t size); + void (CJSON_CDECL *deallocate)(void *pointer); + void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ +static void * CJSON_CDECL internal_malloc(size_t size) +{ + return malloc(size); +} +static void CJSON_CDECL internal_free(void *pointer) +{ + free(pointer); +} +static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +/* strlen of character literals resolved at compile time */ +#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; + break; + + case '.': + number_c_string[i] = decimal_point; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) +{ + char *copy = NULL; + /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ + if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + { + return NULL; + } + if (strlen(valuestring) <= strlen(object->valuestring)) + { + strcpy(object->valuestring, valuestring); + return object->valuestring; + } + copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); + if (copy == NULL) + { + return NULL; + } + if (object->valuestring != NULL) + { + cJSON_free(object->valuestring); + } + object->valuestring = copy; + + return copy; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + + memcpy(newbuffer, p->buffer, p->offset + 1); + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* securely comparison of floating-point variables */ +static cJSON_bool compare_double(double a, double b) +{ + double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); + return (fabs(a - b) <= maxVal * DBL_EPSILON); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test = 0.0; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if (isnan(d) || isinf(d)) + { + length = sprintf((char*)number_buffer, "null"); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occurred */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + if (cannot_access_at_index(buffer, 0)) + { + return buffer; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + size_t buffer_length; + + if (NULL == value) + { + return NULL; + } + + /* Adding null character size due to require_null_terminated. */ + buffer_length = strlen(value) + sizeof(""); + + return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL || 0 == buffer_length) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = buffer_length; + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) +{ + return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); +} + +#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((length < 0) || (buffer == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buffer; + p.length = (size_t)length; + p.offset = 0; + p.noalloc = true; + p.format = format; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* failed to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + if ((current_element == NULL) || (current_element->string == NULL)) { + return NULL; + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL) || (array == item)) + { + return false; + } + + child = array->child; + /* + * To find the last item in array quickly, we use prev in array + */ + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + item->prev = item; + item->next = NULL; + } + else + { + /* append to the end */ + if (child->prev) + { + suffix_object(child->prev, item); + array->child->prev = item; + } + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + return add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return false; + } + + return add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return false; + } + + return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item != parent->child) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + else if (item->next == NULL) + { + /* last element */ + parent->child->prev = item->prev; + } + + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0) + { + return false; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + return add_item_to_array(array, newitem); + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (parent->child == item) + { + if (parent->child->prev == parent->child) + { + replacement->prev = replacement; + } + parent->child = replacement; + } + else + { /* + * To find the last item in array quickly, we use prev in array. + * We can't modify the last item's next pointer where this item was the parent's child + */ + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (replacement->next == NULL) + { + parent->child->prev = replacement; + } + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return false; + } + + return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + replacement->type &= ~cJSON_StringIsConst; + + return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = boolean ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + if (newitem && newitem->child) + { + newitem->child->prev = newchild; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +static void skip_oneline_comment(char **input) +{ + *input += static_strlen("//"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if ((*input)[0] == '\n') { + *input += static_strlen("\n"); + return; + } + } +} + +static void skip_multiline_comment(char **input) +{ + *input += static_strlen("/*"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if (((*input)[0] == '*') && ((*input)[1] == '/')) + { + *input += static_strlen("*/"); + return; + } + } +} + +static void minify_string(char **input, char **output) { + (*output)[0] = (*input)[0]; + *input += static_strlen("\""); + *output += static_strlen("\""); + + + for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { + (*output)[0] = (*input)[0]; + + if ((*input)[0] == '\"') { + (*output)[0] = '\"'; + *input += static_strlen("\""); + *output += static_strlen("\""); + return; + } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { + (*output)[1] = (*input)[1]; + *input += static_strlen("\""); + *output += static_strlen("\""); + } + } +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + char *into = json; + + if (json == NULL) + { + return; + } + + while (json[0] != '\0') + { + switch (json[0]) + { + case ' ': + case '\t': + case '\r': + case '\n': + json++; + break; + + case '/': + if (json[1] == '/') + { + skip_oneline_comment(&json); + } + else if (json[1] == '*') + { + skip_multiline_comment(&json); + } else { + json++; + } + break; + + case '\"': + minify_string(&json, (char**)&into); + break; + + default: + into[0] = json[0]; + json++; + into++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (compare_double(a->valuedouble, b->valuedouble)) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/cjson/cJSON.h b/cjson/cJSON.h new file mode 100644 index 0000000..e97e5f4 --- /dev/null +++ b/cjson/cJSON.h @@ -0,0 +1,293 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + 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. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif + +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +#define CJSON_CDECL __cdecl +#define CJSON_STDCALL __stdcall + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type CJSON_STDCALL +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +#endif +#else /* !__WINDOWS__ */ +#define CJSON_CDECL +#define CJSON_STDCALL + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 14 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ + void *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check item type and return its value */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detach items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + +/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable adress area. */ +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) +/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/codes.md b/codes.md new file mode 100644 index 0000000..7ac3533 --- /dev/null +++ b/codes.md @@ -0,0 +1,49 @@ +# 模型文件说明 +## 1. 说明 +在`efka_flow`程序指定的模型目录下(`-m`参数指定),需要有一下三个文件(下面的模型名称以`mymodel`为例): + +* mymodel.rknn - 实际模型文件 +* mymodel.txt - 模型类别名称,一行一个名称,分别代表模型识别出的第0类,第1类...的名称 +* mymodel_code.txt - 模型识别之后,上传的事件编码。该编码如果是0,表示不需要上传 + +# 2. 实例 +这里举了几个例子,用以表示不同情况。 + +## 2.1. 工服识别 +工服识别的情况,是工服可能有多样性,比如,`mymodel.rknn`识别出来的`0,1,2,3`都是不同类型的工服,而第4类,识别出的是普通没穿工服的情况。 + +此时,我们会希望`0,1,2,3`类都判定为工服,而`4`判定为未穿工服。如果有未穿工服的人进入,就报警(假设事件编码是123,表示人员违规进入);如果是正常工服,就生成一条巡检记录(假设事件编码是124,表示正常巡检),则此时`mymodel.txt`如下: + +``` +// mymodel.txt +clothes1 +clothes2 +clothes3 +clothes4 +abnormal +``` + +而`mymodel_code.txt`应该如下: + +``` +// mymodel_code.txt +124 +124 +124 +124 +123 +``` + +如果`mymodel_code.txt`里面的编码相同,则在上报事件的时候,会被合并。比如视频里面四种类别的工服都有一个,则实际上报的时候,上报的内容如下(这里是举个例子,并不是实际的数据格式): + +``` +{ + "class_idx": 124, + "number": 4, + // 这里的名称,会合并为第一个出现该编码的类别的名称。 + "name": "clothes1" +} +``` + +## 2.2. 其他例子 +待补充。其实,其他例子,均可以由上面的例子推断出来。 diff --git a/common.h b/common.h new file mode 100755 index 0000000..e02d1b2 --- /dev/null +++ b/common.h @@ -0,0 +1,54 @@ +#ifndef _RKNN_MODEL_ZOO_COMMON_H_ +#define _RKNN_MODEL_ZOO_COMMON_H_ + +/** + * @brief Image pixel format + * + */ +typedef enum { + IMAGE_FORMAT_GRAY8, + IMAGE_FORMAT_RGB888, + IMAGE_FORMAT_RGBA8888, + IMAGE_FORMAT_YUV420SP_NV21, + IMAGE_FORMAT_YUV420SP_NV12, +} image_format_t; + +/** + * @brief Image buffer + * + */ +typedef struct { + int width; + int height; + int width_stride; + int height_stride; + image_format_t format; + unsigned char* virt_addr; + int size; + int fd; +} image_buffer_t; + +/** + * @brief Image rectangle + * + */ +typedef struct { + int left; + int top; + int right; + int bottom; +} image_rect_t; + +/** + * @brief Image obb rectangle + * + */ +typedef struct { + int x; + int y; + int w; + int h; + float angle; +} image_obb_box_t; + +#endif //_RKNN_MODEL_ZOO_COMMON_H_ diff --git a/docs/doc.md b/docs/doc.md new file mode 100644 index 0000000..7829978 --- /dev/null +++ b/docs/doc.md @@ -0,0 +1,128 @@ +# 视频测试 +该程序用于加载rknn模型,从rtsp视频流或者.h264文件中读取每一帧图像,然后交给mpp解码,rga进行格式和尺寸的转换,然后交给npu进行yolov5的推理。 + +## 1. 切换到正确的分支 +用yolov5模型进行推理的代码在`yolo-changed`分支上,拉取代码之后,使用以下命令切换到合适的分支 + +```shell +git checkout -b yolo-changed origin/yolo-changed +``` + +## 2. 环境设置 +项目使用c/cpp编写,首先需要安装缺少的组件: + +```shell +apt install cmake make +``` + +然后,将`gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu`仓库也克隆下来,打开本项目的`CMakeList.txt`,根据实际情况修改该文件的第7行的tools的编译工具地址。 + +## 3. 编译 +在本项目的根目录下,执行以下命令: + +```shell +## 创建build目录 +mkdir build && cd build + +## 生成makefile, 注意后面是两个点 +cmake .. + +## 编译 +make +``` + +执行完成之后,该目录下应该会有个`efka_flow`程序,该程序就是在1808上运行的模型推理程序。 + +## 4. 部署 +将`efka_flow`程序复制到开发板的`./models`目录下,同样地,模型推理的模型也需要放到这个目录下。 + +一般,模型是一个目录,比如老鼠识别叫`mouse_rec`,在在开发板的`./models`目录下常见一个`mouse_rec`目录: + +```shell +mkdir ./models/mouse_rec +``` + +之后,把模型的rknn文件,也该名称`mouse_rec.rknn`,放到该目录下: + +```shell +cp ~/mouse_rec.rknn ./models/mouse_rec/mouse_rec.rknn +``` + +另外,在该目录下,还需要一个模型类型文件和模型编码文件。模型类型文件名为`mouse_rec.txt`,里面对应一个类别就是一行,比如,老鼠识别模型只识别老鼠这一类,捺`mouse_rec.txt`里面就只有`mouse`一行。 + +模型编码文件,命名格式为`mouse_rec_code.txt`,比模型类型文件后面多加一个`_code`,该文件目前可以不用管,主要用于在模型识别结果往服务端传递的时候指明类别,`mouse_rec.txt`里面有一行,`mouse_rec_code.txt`里面就写几行0。 + +在把推理程序和模型文件都准备好之后,就可以进行推理了,推理程序用法如下: + +``` +./efka_flow --help + +Usage: ./efka_flow [OPTION] + +Getting help: + -s, -server rtsp server URL + -e, -example show example server + -m, -model model name from ./models/ + -c, -camera-id camera id + -t, -type-id type id + -p, -upload-port upload port + -r, -threshold threshold +``` + +一般,运行的命令如下: + +```shell +./efka_flow -s rtsp://127.0.0.1 -m mouse_rec -c camid -t 11 +``` + +* -s之后,传递rtsp视频流的url,或者也可以传递一个.h264的视频 +* -m传递`./models/`目录下的模型的目录名,这里是[`mouse_rec`](https://git2.asxalex.pw/rk1808/mouse_rec) +* -c传递一个摄像头的唯一标识,可以任意起名字,生成的运行信息会存放在`/usr/data/camera/camid`下面,里面的picsave目录用于存放识别的图片rgb信息。 + +# 测试流程 +实际测试流程,首先是将需要标注的视频打包发送给智驱力,等待他们训练好模型,然后,会收到他们训练好的模型,然后,在我们的4070台式机上对模型进行预编译,然后使用ffmpeg将需要测试的视频转换成h264格式的,然后部署模型(放到板子上对应的内容),然后运行识别程序(efka_flow),然后获取识别结果,将结果放到4070台式机上,通过台式机上面的程序,将识别结果转换成图片,然后查看图片,看实际运行的结果是否满意。 + +## 准备物料 +准备物料阶段,主要通过ffmpeg命令,去实际的摄像头上截取视频,然后打包,发给智驱力,实际的ffmpeg命令为: + +``` +ffmpeg -i rtsp://dizhi -an -c copy out.mp4 +``` + +## 模型预编译 +在登录到台式机上之后,首先使用`conda activate rknn`进入python的rknn环境。 + +登录4070台式机,进入`/home/jihe/work/model_test/pre_compile`,将模型上传到这里,然后使用命令: + +``` +python rknn_pre_compile.py input.rknn out_compiled.rknn +``` + +将`input.rknn`预编译,输出到`out_compiled.rknn`。完成预编译工作。 + +## 准备需要测试的视频 +需要测试的视频一般都是mp4格式的,使用如下ffmpeg将mp4格式转换为h264格式: + +``` +ffmpeg -i input.mp4 -vcodec copy -f h164 output.h264 +``` + +## 部署模型 +参考第一部分视频测试的模型部署说明,主要准备`model.rknn`,`model_code.txt`和`model.txt`三个文件 + +## 实际测试 +登录开发板,进入到`./models`目录,然后使用 + +``` +./efka_flow -s input.h264 -m model -c camid +``` + +上面的命令会使用model模型,把识别结果保存在`/usr/data/camera/camid/frames`目录下,每一个识别图片都会有一个`frame.rgb`和`frame.txt`,然后将该目录(`/usr/local/camera/camid/frames`)复制到4070台式机的`/home/jihe/work/model_test/result`目录下,然后运行 + +``` +python convert_store.py +``` + +之后,在该目录下的`frames`目录下,会生成对应的frame*.jpg(需要在`conda activate rknn`进入python rknn环境之后才可以)。 + +之后,可以将frames目录下的`*.jpg`复制过来,然后查看是否正常。 \ No newline at end of file diff --git a/docs/model_example/README.md b/docs/model_example/README.md new file mode 100644 index 0000000..819d608 --- /dev/null +++ b/docs/model_example/README.md @@ -0,0 +1,5 @@ +模型一般存放在`./`目录下,在该目录下,创建一个模型目录,在该目录下,需要有`模型名称.rknn`, `模型名称.txt`以及`模型名称_code.txt`。三者的说明如下: + +* `模型名称.rknn`,训练好的yolov5转换出来的rknn权重文件。 +* `模型名称.txt`,记录每一种类型对应的名称,一行一个,表示识别出来的各个类型代表的中文名称 +* `模型名称_code.txt`,记录每一种类型对应的typeid,一行一个,表示识别出来的类型要转换成哪一个id diff --git a/docs/model_example/mouse_0408_1808.rknn b/docs/model_example/mouse_0408_1808.rknn new file mode 100644 index 0000000..8da1343 Binary files /dev/null and b/docs/model_example/mouse_0408_1808.rknn differ diff --git a/docs/model_example/mouse_0408_1808.txt b/docs/model_example/mouse_0408_1808.txt new file mode 100644 index 0000000..3e41be9 --- /dev/null +++ b/docs/model_example/mouse_0408_1808.txt @@ -0,0 +1 @@ +mouse diff --git a/docs/model_example/mouse_0408_1808_code.txt b/docs/model_example/mouse_0408_1808_code.txt new file mode 100644 index 0000000..d2718a2 --- /dev/null +++ b/docs/model_example/mouse_0408_1808_code.txt @@ -0,0 +1 @@ +20161 diff --git a/docs/yolov5s.txt b/docs/yolov5s.txt new file mode 100644 index 0000000..a3aeeb5 --- /dev/null +++ b/docs/yolov5s.txt @@ -0,0 +1,80 @@ +person +bicycle +car +motorcycle +airplane +bus +train +truck +boat +trafficlight +firehydrant +stopsign +parkingmeter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sportsball +kite +baseballbat +baseballglove +skateboard +surfboard +tennisracket +bottle +wineglass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hotdog +pizza +donut +cake +chair +couch +pottedplant +bed +diningtable +toilet +tv +laptop +mouse +remote +keyboard +cellphone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddybear +hairdrier +toothbrush \ No newline at end of file diff --git a/ffmpeg/inc/libavcodec/ac3_parser.h b/ffmpeg/inc/libavcodec/ac3_parser.h new file mode 100644 index 0000000..ff8cc4c --- /dev/null +++ b/ffmpeg/inc/libavcodec/ac3_parser.h @@ -0,0 +1,36 @@ +/* + * AC-3 parser prototypes + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3_PARSER_H +#define AVCODEC_AC3_PARSER_H + +#include +#include + +/** + * Extract the bitstream ID and the frame size from AC-3 data. + */ +int av_ac3_parse_header(const uint8_t *buf, size_t size, + uint8_t *bitstream_id, uint16_t *frame_size); + + +#endif /* AVCODEC_AC3_PARSER_H */ diff --git a/ffmpeg/inc/libavcodec/adts_parser.h b/ffmpeg/inc/libavcodec/adts_parser.h new file mode 100644 index 0000000..f85becd --- /dev/null +++ b/ffmpeg/inc/libavcodec/adts_parser.h @@ -0,0 +1,37 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ADTS_PARSER_H +#define AVCODEC_ADTS_PARSER_H + +#include +#include + +#define AV_AAC_ADTS_HEADER_SIZE 7 + +/** + * Extract the number of samples and frames from AAC data. + * @param[in] buf pointer to AAC data buffer + * @param[out] samples Pointer to where number of samples is written + * @param[out] frames Pointer to where number of frames is written + * @return Returns 0 on success, error code on failure. + */ +int av_adts_header_parse(const uint8_t *buf, uint32_t *samples, + uint8_t *frames); + +#endif /* AVCODEC_ADTS_PARSER_H */ diff --git a/ffmpeg/inc/libavcodec/avcodec.h b/ffmpeg/inc/libavcodec/avcodec.h new file mode 100644 index 0000000..c91b2fd --- /dev/null +++ b/ffmpeg/inc/libavcodec/avcodec.h @@ -0,0 +1,4142 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVCODEC_H +#define AVCODEC_AVCODEC_H + +/** + * @file + * @ingroup libavc + * Libavcodec external API header + */ + +#include +#include "libavutil/samplefmt.h" +#include "libavutil/attributes.h" +#include "libavutil/avutil.h" +#include "libavutil/buffer.h" +#include "libavutil/cpu.h" +#include "libavutil/channel_layout.h" +#include "libavutil/dict.h" +#include "libavutil/frame.h" +#include "libavutil/hwcontext.h" +#include "libavutil/log.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" + +#include "bsf.h" +#include "codec.h" +#include "codec_desc.h" +#include "codec_par.h" +#include "codec_id.h" +#include "packet.h" +#include "version.h" + +/** + * @defgroup libavc libavcodec + * Encoding/Decoding Library + * + * @{ + * + * @defgroup lavc_decoding Decoding + * @{ + * @} + * + * @defgroup lavc_encoding Encoding + * @{ + * @} + * + * @defgroup lavc_codec Codecs + * @{ + * @defgroup lavc_codec_native Native Codecs + * @{ + * @} + * @defgroup lavc_codec_wrappers External library wrappers + * @{ + * @} + * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge + * @{ + * @} + * @} + * @defgroup lavc_internal Internal + * @{ + * @} + * @} + */ + +/** + * @ingroup libavc + * @defgroup lavc_encdec send/receive encoding and decoding API overview + * @{ + * + * The avcodec_send_packet()/avcodec_receive_frame()/avcodec_send_frame()/ + * avcodec_receive_packet() functions provide an encode/decode API, which + * decouples input and output. + * + * The API is very similar for encoding/decoding and audio/video, and works as + * follows: + * - Set up and open the AVCodecContext as usual. + * - Send valid input: + * - For decoding, call avcodec_send_packet() to give the decoder raw + * compressed data in an AVPacket. + * - For encoding, call avcodec_send_frame() to give the encoder an AVFrame + * containing uncompressed audio or video. + * + * In both cases, it is recommended that AVPackets and AVFrames are + * refcounted, or libavcodec might have to copy the input data. (libavformat + * always returns refcounted AVPackets, and av_frame_get_buffer() allocates + * refcounted AVFrames.) + * - Receive output in a loop. Periodically call one of the avcodec_receive_*() + * functions and process their output: + * - For decoding, call avcodec_receive_frame(). On success, it will return + * an AVFrame containing uncompressed audio or video data. + * - For encoding, call avcodec_receive_packet(). On success, it will return + * an AVPacket with a compressed frame. + * + * Repeat this call until it returns AVERROR(EAGAIN) or an error. The + * AVERROR(EAGAIN) return value means that new input data is required to + * return new output. In this case, continue with sending input. For each + * input frame/packet, the codec will typically return 1 output frame/packet, + * but it can also be 0 or more than 1. + * + * At the beginning of decoding or encoding, the codec might accept multiple + * input frames/packets without returning a frame, until its internal buffers + * are filled. This situation is handled transparently if you follow the steps + * outlined above. + * + * In theory, sending input can result in EAGAIN - this should happen only if + * not all output was received. You can use this to structure alternative decode + * or encode loops other than the one suggested above. For example, you could + * try sending new input on each iteration, and try to receive output if that + * returns EAGAIN. + * + * End of stream situations. These require "flushing" (aka draining) the codec, + * as the codec might buffer multiple frames or packets internally for + * performance or out of necessity (consider B-frames). + * This is handled as follows: + * - Instead of valid input, send NULL to the avcodec_send_packet() (decoding) + * or avcodec_send_frame() (encoding) functions. This will enter draining + * mode. + * - Call avcodec_receive_frame() (decoding) or avcodec_receive_packet() + * (encoding) in a loop until AVERROR_EOF is returned. The functions will + * not return AVERROR(EAGAIN), unless you forgot to enter draining mode. + * - Before decoding can be resumed again, the codec has to be reset with + * avcodec_flush_buffers(). + * + * Using the API as outlined above is highly recommended. But it is also + * possible to call functions outside of this rigid schema. For example, you can + * call avcodec_send_packet() repeatedly without calling + * avcodec_receive_frame(). In this case, avcodec_send_packet() will succeed + * until the codec's internal buffer has been filled up (which is typically of + * size 1 per output frame, after initial input), and then reject input with + * AVERROR(EAGAIN). Once it starts rejecting input, you have no choice but to + * read at least some output. + * + * Not all codecs will follow a rigid and predictable dataflow; the only + * guarantee is that an AVERROR(EAGAIN) return value on a send/receive call on + * one end implies that a receive/send call on the other end will succeed, or + * at least will not fail with AVERROR(EAGAIN). In general, no codec will + * permit unlimited buffering of input or output. + * + * This API replaces the following legacy functions: + * - avcodec_decode_video2() and avcodec_decode_audio4(): + * Use avcodec_send_packet() to feed input to the decoder, then use + * avcodec_receive_frame() to receive decoded frames after each packet. + * Unlike with the old video decoding API, multiple frames might result from + * a packet. For audio, splitting the input packet into frames by partially + * decoding packets becomes transparent to the API user. You never need to + * feed an AVPacket to the API twice (unless it is rejected with AVERROR(EAGAIN) - then + * no data was read from the packet). + * Additionally, sending a flush/draining packet is required only once. + * - avcodec_encode_video2()/avcodec_encode_audio2(): + * Use avcodec_send_frame() to feed input to the encoder, then use + * avcodec_receive_packet() to receive encoded packets. + * Providing user-allocated buffers for avcodec_receive_packet() is not + * possible. + * - The new API does not handle subtitles yet. + * + * Mixing new and old function calls on the same AVCodecContext is not allowed, + * and will result in undefined behavior. + * + * Some codecs might require using the new API; using the old API will return + * an error when calling it. All codecs support the new API. + * + * A codec is not allowed to return AVERROR(EAGAIN) for both sending and receiving. This + * would be an invalid state, which could put the codec user into an endless + * loop. The API has no concept of time either: it cannot happen that trying to + * do avcodec_send_packet() results in AVERROR(EAGAIN), but a repeated call 1 second + * later accepts the packet (with no other receive/flush API calls involved). + * The API is a strict state machine, and the passage of time is not supposed + * to influence it. Some timing-dependent behavior might still be deemed + * acceptable in certain cases. But it must never result in both send/receive + * returning EAGAIN at the same time at any point. It must also absolutely be + * avoided that the current state is "unstable" and can "flip-flop" between + * the send/receive APIs allowing progress. For example, it's not allowed that + * the codec randomly decides that it actually wants to consume a packet now + * instead of returning a frame, after it just returned AVERROR(EAGAIN) on an + * avcodec_send_packet() call. + * @} + */ + +/** + * @defgroup lavc_core Core functions/structures. + * @ingroup libavc + * + * Basic definitions, functions for querying libavcodec capabilities, + * allocating core structures, etc. + * @{ + */ + +/** + * @ingroup lavc_decoding + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.
+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + */ +#define AV_INPUT_BUFFER_PADDING_SIZE 64 + +/** + * @ingroup lavc_encoding + * minimum encoding buffer size + * Used to avoid some checks during header writing. + */ +#define AV_INPUT_BUFFER_MIN_SIZE 16384 + +/** + * @ingroup lavc_decoding + */ +enum AVDiscard{ + /* We leave some space between them for extensions (drop some + * keyframes for intra-only or drop just some bidir frames). */ + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONINTRA= 24, ///< discard all non intra frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + +enum AVAudioServiceType { + AV_AUDIO_SERVICE_TYPE_MAIN = 0, + AV_AUDIO_SERVICE_TYPE_EFFECTS = 1, + AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2, + AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3, + AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4, + AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5, + AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6, + AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7, + AV_AUDIO_SERVICE_TYPE_KARAOKE = 8, + AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI +}; + +/** + * @ingroup lavc_encoding + */ +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // If this is 0 then quality_factor will be used instead. + float quality_factor; +} RcOverride; + +/* encoding support + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. +*/ + +/** + * Allow decoders to produce frames with data planes that are not aligned + * to CPU requirements (e.g. due to cropping). + */ +#define AV_CODEC_FLAG_UNALIGNED (1 << 0) +/** + * Use fixed qscale. + */ +#define AV_CODEC_FLAG_QSCALE (1 << 1) +/** + * 4 MV per MB allowed / advanced prediction for H.263. + */ +#define AV_CODEC_FLAG_4MV (1 << 2) +/** + * Output even those frames that might be corrupted. + */ +#define AV_CODEC_FLAG_OUTPUT_CORRUPT (1 << 3) +/** + * Use qpel MC. + */ +#define AV_CODEC_FLAG_QPEL (1 << 4) +/** + * Don't output frames whose parameters differ from first + * decoded frame in stream. + */ +#define AV_CODEC_FLAG_DROPCHANGED (1 << 5) +/** + * Use internal 2pass ratecontrol in first pass mode. + */ +#define AV_CODEC_FLAG_PASS1 (1 << 9) +/** + * Use internal 2pass ratecontrol in second pass mode. + */ +#define AV_CODEC_FLAG_PASS2 (1 << 10) +/** + * loop filter. + */ +#define AV_CODEC_FLAG_LOOP_FILTER (1 << 11) +/** + * Only decode/encode grayscale. + */ +#define AV_CODEC_FLAG_GRAY (1 << 13) +/** + * error[?] variables will be set during encoding. + */ +#define AV_CODEC_FLAG_PSNR (1 << 15) +/** + * Input bitstream might be truncated at a random location + * instead of only at frame boundaries. + */ +#define AV_CODEC_FLAG_TRUNCATED (1 << 16) +/** + * Use interlaced DCT. + */ +#define AV_CODEC_FLAG_INTERLACED_DCT (1 << 18) +/** + * Force low delay. + */ +#define AV_CODEC_FLAG_LOW_DELAY (1 << 19) +/** + * Place global headers in extradata instead of every keyframe. + */ +#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22) +/** + * Use only bitexact stuff (except (I)DCT). + */ +#define AV_CODEC_FLAG_BITEXACT (1 << 23) +/* Fx : Flag for H.263+ extra options */ +/** + * H.263 advanced intra coding / MPEG-4 AC prediction + */ +#define AV_CODEC_FLAG_AC_PRED (1 << 24) +/** + * interlaced motion estimation + */ +#define AV_CODEC_FLAG_INTERLACED_ME (1 << 29) +#define AV_CODEC_FLAG_CLOSED_GOP (1U << 31) + +/** + * Allow non spec compliant speedup tricks. + */ +#define AV_CODEC_FLAG2_FAST (1 << 0) +/** + * Skip bitstream encoding. + */ +#define AV_CODEC_FLAG2_NO_OUTPUT (1 << 2) +/** + * Place global headers at every keyframe instead of in extradata. + */ +#define AV_CODEC_FLAG2_LOCAL_HEADER (1 << 3) + +/** + * timecode is in drop frame format. DEPRECATED!!!! + */ +#define AV_CODEC_FLAG2_DROP_FRAME_TIMECODE (1 << 13) + +/** + * Input bitstream might be truncated at a packet boundaries + * instead of only at frame boundaries. + */ +#define AV_CODEC_FLAG2_CHUNKS (1 << 15) +/** + * Discard cropping information from SPS. + */ +#define AV_CODEC_FLAG2_IGNORE_CROP (1 << 16) + +/** + * Show all frames before the first keyframe + */ +#define AV_CODEC_FLAG2_SHOW_ALL (1 << 22) +/** + * Export motion vectors through frame side data + */ +#define AV_CODEC_FLAG2_EXPORT_MVS (1 << 28) +/** + * Do not skip samples and export skip information as frame side data + */ +#define AV_CODEC_FLAG2_SKIP_MANUAL (1 << 29) +/** + * Do not reset ASS ReadOrder field on flush (subtitles decoding) + */ +#define AV_CODEC_FLAG2_RO_FLUSH_NOOP (1 << 30) + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independent Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +/* Exported side data. + These flags can be passed in AVCodecContext.export_side_data before initialization. +*/ +/** + * Export motion vectors through frame side data + */ +#define AV_CODEC_EXPORT_DATA_MVS (1 << 0) +/** + * Export encoder Producer Reference Time through packet side data + */ +#define AV_CODEC_EXPORT_DATA_PRFT (1 << 1) +/** + * Decoding only. + * Export the AVVideoEncParams structure through frame side data. + */ +#define AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS (1 << 2) + +/** + * Pan Scan area. + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. + */ +typedef struct AVPanScan { + /** + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int16_t position[3][2]; +} AVPanScan; + +/** + * This structure describes the bitrate properties of an encoded bitstream. It + * roughly corresponds to a subset the VBV parameters for MPEG-2 or HRD + * parameters for H.264/HEVC. + */ +typedef struct AVCPBProperties { + /** + * Maximum bitrate of the stream, in bits per second. + * Zero if unknown or unspecified. + */ +#if FF_API_UNSANITIZED_BITRATES + int max_bitrate; +#else + int64_t max_bitrate; +#endif + /** + * Minimum bitrate of the stream, in bits per second. + * Zero if unknown or unspecified. + */ +#if FF_API_UNSANITIZED_BITRATES + int min_bitrate; +#else + int64_t min_bitrate; +#endif + /** + * Average bitrate of the stream, in bits per second. + * Zero if unknown or unspecified. + */ +#if FF_API_UNSANITIZED_BITRATES + int avg_bitrate; +#else + int64_t avg_bitrate; +#endif + + /** + * The size of the buffer to which the ratecontrol is applied, in bits. + * Zero if unknown or unspecified. + */ + int buffer_size; + + /** + * The delay between the time the packet this structure is associated with + * is received and the time when it should be decoded, in periods of a 27MHz + * clock. + * + * UINT64_MAX when unknown or unspecified. + */ + uint64_t vbv_delay; +} AVCPBProperties; + +/** + * This structure supplies correlation between a packet timestamp and a wall clock + * production time. The definition follows the Producer Reference Time ('prft') + * as defined in ISO/IEC 14496-12 + */ +typedef struct AVProducerReferenceTime { + /** + * A UTC timestamp, in microseconds, since Unix epoch (e.g, av_gettime()). + */ + int64_t wallclock; + int flags; +} AVProducerReferenceTime; + +/** + * The decoder will keep a reference to the frame and may reuse it later. + */ +#define AV_GET_BUFFER_FLAG_REF (1 << 0) + +struct AVCodecInternal; + +/** + * main external API structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user + * applications. + * The name string for AVOptions options matches the associated command line + * parameter name and can be found in libavcodec/options_table.h + * The AVOption/command line parameter names differ in some cases from the C + * structure field names for historic reasons or brevity. + * sizeof(AVCodecContext) must not be used outside libav*. + */ +typedef struct AVCodecContext { + /** + * information on struct for av_log + * - set by avcodec_alloc_context3 + */ + const AVClass *av_class; + int log_level_offset; + + enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ + const struct AVCodec *codec; + enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * A demuxer should set this to what is stored in the field used to identify the codec. + * If there are multiple such fields in a container then the demuxer should choose the one + * which maximizes the information about the used codec. + * If the codec tag field in a container is larger than 32 bits then the demuxer should + * remap the longer ID to 32 bits with a table or other structure. Alternatively a new + * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated + * first. + * - encoding: Set by user, if not then the default based on codec_id will be used. + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int codec_tag; + + void *priv_data; + + /** + * Private context used for internal data. + * + * Unlike priv_data, this is not codec-specific. It is used in general + * libavcodec functions. + */ + struct AVCodecInternal *internal; + + /** + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. + */ + void *opaque; + + /** + * the average bitrate + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: Set by user, may be overwritten by libavcodec + * if this info is available in the stream + */ + int64_t bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: unused + */ + int bit_rate_tolerance; + + /** + * Global quality for codecs which cannot change it per frame. + * This should be proportional to MPEG-1/2/4 qscale. + * - encoding: Set by user. + * - decoding: unused + */ + int global_quality; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int compression_level; +#define FF_COMPRESSION_DEFAULT -1 + + /** + * AV_CODEC_FLAG_*. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags; + + /** + * AV_CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags2; + + /** + * some codecs need / can use extradata like Huffman tables. + * MJPEG: Huffman tables + * rv10: additional flags + * MPEG-4: global headers (they can be in the bitstream or here) + * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid problems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * Must be allocated with the av_malloc() family of functions. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. + */ + uint8_t *extradata; + int extradata_size; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * timebase should be 1/framerate and timestamp increments should be + * identically 1. + * This often, but not always is the inverse of the frame rate or field rate + * for video. 1/time_base is not the average frame rate if the frame rate is not + * constant. + * + * Like containers, elementary streams also can store timestamps, 1/time_base + * is the unit in which these timestamps are specified. + * As example of such codec time base see ISO/IEC 14496-2:2001(E) + * vop_time_increment_resolution and fixed_vop_rate + * (fixed_vop_rate == 0 implies that it is different from the framerate) + * + * - encoding: MUST be set by user. + * - decoding: the use of this field for decoding is deprecated. + * Use framerate instead. + */ + AVRational time_base; + + /** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + */ + int ticks_per_frame; + + /** + * Codec delay. + * + * Encoding: Number of frames delay there will be from the encoder input to + * the decoder output. (we assume the decoder matches the spec) + * Decoding: Number of frames delay in addition to what a standard decoder + * as specified in the spec would produce. + * + * Video: + * Number of frames the decoded output will be delayed relative to the + * encoded input. + * + * Audio: + * For encoding, this field is unused (see initial_padding). + * + * For decoding, this is the number of samples the decoder needs to + * output before the decoder's output is valid. When seeking, you should + * start decoding this many samples prior to your desired seek point. + * + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int delay; + + + /* video only */ + /** + * picture width / height. + * + * @note Those fields may not match the values of the last + * AVFrame output by avcodec_decode_video2 due frame + * reordering. + * + * - encoding: MUST be set by user. + * - decoding: May be set by the user before opening the decoder if known e.g. + * from the container. Some decoders will require the dimensions + * to be set by the caller. During decoding, the decoder may + * overwrite those values as required while parsing the data. + */ + int width, height; + + /** + * Bitstream width / height, may be different from width/height e.g. when + * the decoded frame is cropped before being output or lowres is enabled. + * + * @note Those field may not match the value of the last + * AVFrame output by avcodec_receive_frame() due frame + * reordering. + * + * - encoding: unused + * - decoding: May be set by the user before opening the decoder if known + * e.g. from the container. During decoding, the decoder may + * overwrite those values as required while parsing the data. + */ + int coded_width, coded_height; + + /** + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. + * - decoding: unused + */ + int gop_size; + + /** + * Pixel format, see AV_PIX_FMT_xxx. + * May be set by the demuxer if known from headers. + * May be overridden by the decoder if it knows better. + * + * @note This field may not match the value of the last + * AVFrame output by avcodec_receive_frame() due frame + * reordering. + * + * - encoding: Set by user. + * - decoding: Set by user if known, overridden by libavcodec while + * parsing the data. + */ + enum AVPixelFormat pix_fmt; + + /** + * If non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw a horizontal band. It improves cache usage. Not + * all codecs can do that. You must check the codec capabilities + * beforehand. + * When multithreading is used, it may be called from multiple threads + * at the same time; threads might draw different parts of the same AVFrame, + * or multiple AVFrames, and there is no guarantee that slices will be drawn + * in order. + * The function is also used by hardware acceleration APIs. + * It is called at least once during frame decoding to pass + * the data needed for hardware render. + * In that mode instead of pixel data, AVFrame points to + * a structure specific to the acceleration API. The application + * reads the structure and can change some fields to indicate progress + * or mark state. + * - encoding: unused + * - decoding: Set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + void (*draw_horiz_band)(struct AVCodecContext *s, + const AVFrame *src, int offset[AV_NUM_DATA_POINTERS], + int y, int type, int height); + + /** + * callback to negotiate the pixelFormat + * @param fmt is the list of formats which are supported by the codec, + * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. + * The first is always the native one. + * @note The callback may be called again immediately if initialization for + * the selected (hardware-accelerated) pixel format failed. + * @warning Behavior is undefined if the callback returns a value not + * in the fmt list of formats. + * @return the chosen format + * - encoding: unused + * - decoding: Set by user, if not set the native format will be chosen. + */ + enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt); + + /** + * maximum number of B-frames between non-B-frames + * Note: The output will be delayed by max_b_frames+1 relative to the input. + * - encoding: Set by user. + * - decoding: unused + */ + int max_b_frames; + + /** + * qscale factor between IP and B-frames + * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_factor; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int b_frame_strategy; +#endif + + /** + * qscale offset between IP and B-frames + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * Size of the frame reordering buffer in the decoder. + * For MPEG-2 it is 1 IPB or 0 low delay IP. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int has_b_frames; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int mpeg_quant; +#endif + + /** + * qscale factor between P- and I-frames + * If > 0 then the last P-frame quantizer will be used (q = lastp_q * factor + offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_factor; + + /** + * qscale offset between P and I-frames + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * luminance masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float lumi_masking; + + /** + * temporary complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float spatial_cplx_masking; + + /** + * p block masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float p_masking; + + /** + * darkness masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float dark_masking; + + /** + * slice count + * - encoding: Set by libavcodec. + * - decoding: Set by user (or 0). + */ + int slice_count; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 +#endif + + /** + * slice offsets in the frame in bytes + * - encoding: Set/allocated by libavcodec. + * - decoding: Set/allocated by user (or NULL). + */ + int *slice_offset; + + /** + * sample aspect ratio (0 if unknown) + * That is the width of a pixel divided by the height of the pixel. + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVRational sample_aspect_ratio; + + /** + * motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_cmp; + /** + * subpixel motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_sub_cmp; + /** + * macroblock comparison function (not supported yet) + * - encoding: Set by user. + * - decoding: unused + */ + int mb_cmp; + /** + * interlaced DCT comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 +#define FF_CMP_DCTMAX 13 +#define FF_CMP_DCT264 14 +#define FF_CMP_MEDIAN_SAD 15 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square) + * - encoding: Set by user. + * - decoding: unused + */ + int last_predictor_count; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int pre_me; +#endif + + /** + * motion estimation prepass comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME prepass diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality + * - encoding: Set by user. + * - decoding: unused + */ + int me_subpel_quality; + + /** + * maximum motion estimation search range in subpel units + * If 0 then no limit. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_range; + + /** + * slice flags + * - encoding: unused + * - decoding: Set by user. + */ + int slice_flags; +#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display +#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics) +#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) + + /** + * macroblock decision mode + * - encoding: Set by user. + * - decoding: unused + */ + int mb_decision; +#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp +#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits +#define FF_MB_DECISION_RD 2 ///< rate distortion + + /** + * custom intra quantization matrix + * Must be allocated with the av_malloc() family of functions, and will be freed in + * avcodec_free_context(). + * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. + * - decoding: Set/allocated/freed by libavcodec. + */ + uint16_t *intra_matrix; + + /** + * custom inter quantization matrix + * Must be allocated with the av_malloc() family of functions, and will be freed in + * avcodec_free_context(). + * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL. + * - decoding: Set/allocated/freed by libavcodec. + */ + uint16_t *inter_matrix; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int scenechange_threshold; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int noise_reduction; +#endif + + /** + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. + * - decoding: Set by libavcodec + */ + int intra_dc_precision; + + /** + * Number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_top; + + /** + * Number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_bottom; + + /** + * minimum MB Lagrange multiplier + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmin; + + /** + * maximum MB Lagrange multiplier + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmax; + +#if FF_API_PRIVATE_OPT + /** + * @deprecated use encoder private options instead + */ + attribute_deprecated + int me_penalty_compensation; +#endif + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int bidir_refine; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int brd_scale; +#endif + + /** + * minimum GOP size + * - encoding: Set by user. + * - decoding: unused + */ + int keyint_min; + + /** + * number of reference frames + * - encoding: Set by user. + * - decoding: Set by lavc. + */ + int refs; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int chromaoffset; +#endif + + /** + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. + * - decoding: unused + */ + int mv0_threshold; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int b_sensitivity; +#endif + + /** + * Chromaticity coordinates of the source primaries. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorPrimaries color_primaries; + + /** + * Color Transfer Characteristic. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + /** + * This defines the location of chroma samples. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVChromaLocation chroma_sample_location; + + /** + * Number of slices. + * Indicates number of picture subdivisions. Used for parallelized + * decoding. + * - encoding: Set by user + * - decoding: unused + */ + int slices; + + /** Field order + * - encoding: set by libavcodec + * - decoding: Set by user. + */ + enum AVFieldOrder field_order; + + /* audio only */ + int sample_rate; ///< samples per second + int channels; ///< number of audio channels + + /** + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum AVSampleFormat sample_fmt; ///< sample format + + /* The following data should not be initialized. */ + /** + * Number of samples per channel in an audio frame. + * + * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame + * except the last must contain exactly frame_size samples per channel. + * May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the + * frame size is not restricted. + * - decoding: may be set by some decoders to indicate constant frame size + */ + int frame_size; + + /** + * Frame counter, set by libavcodec. + * + * - decoding: total number of frames returned from the decoder so far. + * - encoding: total number of frames passed to the encoder so far. + * + * @note the counter is not incremented if encoding/decoding resulted in + * an error. + */ + int frame_number; + + /** + * number of bytes per packet if constant and known or 0 + * Used by some WAV based audio codecs. + */ + int block_align; + + /** + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. + * - decoding: unused + */ + int cutoff; + + /** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by user, may be overwritten by libavcodec. + */ + uint64_t channel_layout; + + /** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ + uint64_t request_channel_layout; + + /** + * Type of service that the audio stream conveys. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum AVAudioServiceType audio_service_type; + + /** + * desired sample format + * - encoding: Not used. + * - decoding: Set by user. + * Decoder will decode to this format if it can. + */ + enum AVSampleFormat request_sample_fmt; + + /** + * This callback is called at the beginning of each frame to get data + * buffer(s) for it. There may be one contiguous buffer for all the data or + * there may be a buffer per each data plane or anything in between. What + * this means is, you may set however many entries in buf[] you feel necessary. + * Each buffer must be reference-counted using the AVBuffer API (see description + * of buf[] below). + * + * The following fields will be set in the frame before this callback is + * called: + * - format + * - width, height (video only) + * - sample_rate, channel_layout, nb_samples (audio only) + * Their values may differ from the corresponding values in + * AVCodecContext. This callback must use the frame values, not the codec + * context values, to calculate the required buffer size. + * + * This callback must fill the following fields in the frame: + * - data[] + * - linesize[] + * - extended_data: + * * if the data is planar audio with more than 8 channels, then this + * callback must allocate and fill extended_data to contain all pointers + * to all data planes. data[] must hold as many pointers as it can. + * extended_data must be allocated with av_malloc() and will be freed in + * av_frame_unref(). + * * otherwise extended_data must point to data + * - buf[] must contain one or more pointers to AVBufferRef structures. Each of + * the frame's data and extended_data pointers must be contained in these. That + * is, one AVBufferRef for each allocated chunk of memory, not necessarily one + * AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(), + * and av_buffer_ref(). + * - extended_buf and nb_extended_buf must be allocated with av_malloc() by + * this callback and filled with the extra buffers if there are more + * buffers than buf[] can hold. extended_buf will be freed in + * av_frame_unref(). + * + * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call + * avcodec_default_get_buffer2() instead of providing buffers allocated by + * some other means. + * + * Each data plane must be aligned to the maximum required by the target + * CPU. + * + * @see avcodec_default_get_buffer2() + * + * Video: + * + * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused + * (read and/or written to if it is writable) later by libavcodec. + * + * avcodec_align_dimensions2() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16. + * + * Some decoders do not support linesizes changing between frames. + * + * If frame multithreading is used and thread_safe_callbacks is set, + * this callback may be called from a different thread, but not from more + * than one at once. Does not need to be reentrant. + * + * @see avcodec_align_dimensions2() + * + * Audio: + * + * Decoders request a buffer of a particular size by setting + * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may, + * however, utilize only part of the buffer by setting AVFrame.nb_samples + * to a smaller value in the output frame. + * + * As a convenience, av_samples_get_buffer_size() and + * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2() + * functions to find the required data size and to fill data pointers and + * linesize. In AVFrame.linesize, only linesize[0] may be set for audio + * since all planes must be the same size. + * + * @see av_samples_get_buffer_size(), av_samples_fill_arrays() + * + * - encoding: unused + * - decoding: Set by libavcodec, user can override. + */ + int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags); + + /** + * If non-zero, the decoded audio and video frames returned from + * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted + * and are valid indefinitely. The caller must free them with + * av_frame_unref() when they are not needed anymore. + * Otherwise, the decoded frames must not be freed by the caller and are + * only valid until the next decode call. + * + * This is always automatically enabled if avcodec_receive_frame() is used. + * + * - encoding: unused + * - decoding: set by the caller before avcodec_open2(). + */ + attribute_deprecated + int refcounted_frames; + + /* - encoding parameters */ + float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) + float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmin; + + /** + * maximum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference between frames + * - encoding: Set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * decoder bitstream buffer size + * - encoding: Set by user. + * - decoding: unused + */ + int rc_buffer_size; + + /** + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + int rc_override_count; + RcOverride *rc_override; + + /** + * maximum bitrate + * - encoding: Set by user. + * - decoding: Set by user, may be overwritten by libavcodec. + */ + int64_t rc_max_rate; + + /** + * minimum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int64_t rc_min_rate; + + /** + * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_max_available_vbv_use; + + /** + * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_min_vbv_overflow_use; + + /** + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + +#if FF_API_CODER_TYPE +#define FF_CODER_TYPE_VLC 0 +#define FF_CODER_TYPE_AC 1 +#define FF_CODER_TYPE_RAW 2 +#define FF_CODER_TYPE_RLE 3 + /** + * @deprecated use encoder private options instead + */ + attribute_deprecated + int coder_type; +#endif /* FF_API_CODER_TYPE */ + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int context_model; +#endif + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_threshold; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_factor; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_exp; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int frame_skip_cmp; +#endif /* FF_API_PRIVATE_OPT */ + + /** + * trellis RD quantization + * - encoding: Set by user. + * - decoding: unused + */ + int trellis; + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int min_prediction_order; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int max_prediction_order; + + /** @deprecated use encoder private options instead */ + attribute_deprecated + int64_t timecode_frame_start; +#endif + +#if FF_API_RTP_CALLBACK + /** + * @deprecated unused + */ + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send. */ + /* It depends on the encoder if the data starts */ + /* with a Start Code (it should). H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload. */ + attribute_deprecated + void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); +#endif + +#if FF_API_PRIVATE_OPT + /** @deprecated use encoder private options instead */ + attribute_deprecated + int rtp_payload_size; /* The size of the RTP payload: the coder will */ + /* do its best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263. */ + /* This doesn't take account of any particular */ + /* headers inside the transmitted RTP payload. */ +#endif + +#if FF_API_STAT_BITS + /* statistics, used for 2-pass encoding */ + attribute_deprecated + int mv_bits; + attribute_deprecated + int header_bits; + attribute_deprecated + int i_tex_bits; + attribute_deprecated + int p_tex_bits; + attribute_deprecated + int i_count; + attribute_deprecated + int p_count; + attribute_deprecated + int skip_count; + attribute_deprecated + int misc_bits; + + /** @deprecated this field is unused */ + attribute_deprecated + int frame_bits; +#endif + + /** + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + char *stats_in; + + /** + * Work around bugs in encoders which sometimes cannot be detected automatically. + * - encoding: Set by user + * - decoding: Set by user + */ + int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AMV 32 +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +#define FF_BUG_HPEL_CHROMA 2048 +#define FF_BUG_DC_CLIP 4096 +#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. +#define FF_BUG_TRUNCATED 16384 +#define FF_BUG_IEDGE 32768 + + /** + * strictly follow the standard (MPEG-4, ...). + * - encoding: Set by user. + * - decoding: Set by user. + * Setting this to STRICT or higher means the encoder and decoder will + * generally do stupid things, whereas setting it to unofficial or lower + * will mean the encoder might produce output that is not supported by all + * spec-compliant decoders. Decoders don't differentiate between normal, + * unofficial and experimental (that is, they always try to decode things + * when they can) unless they are explicitly asked to behave stupidly + * (=strictly conform to the specs) + */ + int strict_std_compliance; +#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software. +#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. +#define FF_COMPLIANCE_NORMAL 0 +#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. + + /** + * error concealment flags + * - encoding: unused + * - decoding: Set by user. + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 +#define FF_EC_FAVOR_INTER 256 + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#if FF_API_DEBUG_MV +/** + * @deprecated this option does nothing + */ +#define FF_DEBUG_MV 32 +#endif +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#if FF_API_DEBUG_MV +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#endif +#define FF_DEBUG_BUFFERS 0x00008000 +#define FF_DEBUG_THREADS 0x00010000 +#define FF_DEBUG_GREEN_MD 0x00800000 +#define FF_DEBUG_NOMC 0x01000000 + +#if FF_API_DEBUG_MV + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 // visualize forward predicted MVs of P-frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 // visualize forward predicted MVs of B-frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 // visualize backward predicted MVs of B-frames +#endif + + /** + * Error recognition; may misdetect some more or less valid parts as errors. + * - encoding: unused + * - decoding: Set by user. + */ + int err_recognition; + +/** + * Verify checksums embedded in the bitstream (could be of either encoded or + * decoded data, depending on the codec) and print an error message on mismatch. + * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the + * decoder returning an error. + */ +#define AV_EF_CRCCHECK (1<<0) +#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations +#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length +#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection + +#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue +#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors +#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors +#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error + + + /** + * opaque 64-bit number (generally a PTS) that will be reordered and + * output in AVFrame.reordered_opaque + * - encoding: Set by libavcodec to the reordered_opaque of the input + * frame corresponding to the last returned packet. Only + * supported by encoders with the + * AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability. + * - decoding: Set by user. + */ + int64_t reordered_opaque; + + /** + * Hardware accelerator in use + * - encoding: unused. + * - decoding: Set by libavcodec + */ + const struct AVHWAccel *hwaccel; + + /** + * Hardware accelerator context. + * For some hardware accelerators, a global context needs to be + * provided by the user. In that case, this holds display-dependent + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this + * is. e.g. for VA API, this is a struct vaapi_context. + * - encoding: unused + * - decoding: Set by user + */ + void *hwaccel_context; + + /** + * error + * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR. + * - decoding: unused + */ + uint64_t error[AV_NUM_DATA_POINTERS]; + + /** + * DCT algorithm, see FF_DCT_* below + * - encoding: Set by user. + * - decoding: unused + */ + int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_XVID 14 +#define FF_IDCT_SIMPLEARMV5TE 16 +#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_FAAN 20 +#define FF_IDCT_SIMPLENEON 22 +#define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */ +#define FF_IDCT_SIMPLEAUTO 128 + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: Set by libavcodec. + * - decoding: Set by user. + */ + int bits_per_coded_sample; + + /** + * Bits per sample/pixel of internal libavcodec pixel/sample format. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int bits_per_raw_sample; + +#if FF_API_LOWRES + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; +#endif + +#if FF_API_CODED_FRAME + /** + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: unused + * + * @deprecated use the quality factor packet side data instead + */ + attribute_deprecated AVFrame *coded_frame; +#endif + + /** + * thread count + * is used to decide how many independent tasks should be passed to execute() + * - encoding: Set by user. + * - decoding: Set by user. + */ + int thread_count; + + /** + * Which multithreading methods to use. + * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread, + * so clients which cannot provide future frames should not use it. + * + * - encoding: Set by user, otherwise the default is used. + * - decoding: Set by user, otherwise the default is used. + */ + int thread_type; +#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once +#define FF_THREAD_SLICE 2 ///< Decode more than one part of a single frame at once + + /** + * Which multithreading methods are in use by the codec. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int active_thread_type; + + /** + * Set by the client if its custom get_buffer() callback can be called + * synchronously from another thread, which allows faster multithreaded decoding. + * draw_horiz_band() will be called from other threads regardless of this setting. + * Ignored if the default get_buffer() is used. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int thread_safe_callbacks; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * @param count the number of things to execute + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. + * @param c context passed also to func + * @param count the number of things to execute + * @param arg2 argument passed unchanged to func + * @param ret return values of executed functions, must have space for "count" values. May be NULL. + * @param func function that will be called count times, with jobnr from 0 to count-1. + * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no + * two instances of func executing at the same time will have the same threadnr. + * @return always 0 currently, but code should handle a future improvement where when any call to func + * returns < 0 no further calls to func may be done and < 0 is returned. + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); + + /** + * noise vs. sse weight for the nsse comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int nsse_weight; + + /** + * profile + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int profile; +#define FF_PROFILE_UNKNOWN -99 +#define FF_PROFILE_RESERVED -100 + +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 +#define FF_PROFILE_AAC_HE 4 +#define FF_PROFILE_AAC_HE_V2 28 +#define FF_PROFILE_AAC_LD 22 +#define FF_PROFILE_AAC_ELD 38 +#define FF_PROFILE_MPEG2_AAC_LOW 128 +#define FF_PROFILE_MPEG2_AAC_HE 131 + +#define FF_PROFILE_DNXHD 0 +#define FF_PROFILE_DNXHR_LB 1 +#define FF_PROFILE_DNXHR_SQ 2 +#define FF_PROFILE_DNXHR_HQ 3 +#define FF_PROFILE_DNXHR_HQX 4 +#define FF_PROFILE_DNXHR_444 5 + +#define FF_PROFILE_DTS 20 +#define FF_PROFILE_DTS_ES 30 +#define FF_PROFILE_DTS_96_24 40 +#define FF_PROFILE_DTS_HD_HRA 50 +#define FF_PROFILE_DTS_HD_MA 60 +#define FF_PROFILE_DTS_EXPRESS 70 + +#define FF_PROFILE_MPEG2_422 0 +#define FF_PROFILE_MPEG2_HIGH 1 +#define FF_PROFILE_MPEG2_SS 2 +#define FF_PROFILE_MPEG2_SNR_SCALABLE 3 +#define FF_PROFILE_MPEG2_MAIN 4 +#define FF_PROFILE_MPEG2_SIMPLE 5 + +#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag +#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag + +#define FF_PROFILE_H264_BASELINE 66 +#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED) +#define FF_PROFILE_H264_MAIN 77 +#define FF_PROFILE_H264_EXTENDED 88 +#define FF_PROFILE_H264_HIGH 100 +#define FF_PROFILE_H264_HIGH_10 110 +#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_MULTIVIEW_HIGH 118 +#define FF_PROFILE_H264_HIGH_422 122 +#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_STEREO_HIGH 128 +#define FF_PROFILE_H264_HIGH_444 144 +#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244 +#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA) +#define FF_PROFILE_H264_CAVLC_444 44 + +#define FF_PROFILE_VC1_SIMPLE 0 +#define FF_PROFILE_VC1_MAIN 1 +#define FF_PROFILE_VC1_COMPLEX 2 +#define FF_PROFILE_VC1_ADVANCED 3 + +#define FF_PROFILE_MPEG4_SIMPLE 0 +#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1 +#define FF_PROFILE_MPEG4_CORE 2 +#define FF_PROFILE_MPEG4_MAIN 3 +#define FF_PROFILE_MPEG4_N_BIT 4 +#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5 +#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6 +#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7 +#define FF_PROFILE_MPEG4_HYBRID 8 +#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9 +#define FF_PROFILE_MPEG4_CORE_SCALABLE 10 +#define FF_PROFILE_MPEG4_ADVANCED_CODING 11 +#define FF_PROFILE_MPEG4_ADVANCED_CORE 12 +#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 +#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14 +#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15 + +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 1 +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 2 +#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 32768 +#define FF_PROFILE_JPEG2000_DCINEMA_2K 3 +#define FF_PROFILE_JPEG2000_DCINEMA_4K 4 + +#define FF_PROFILE_VP9_0 0 +#define FF_PROFILE_VP9_1 1 +#define FF_PROFILE_VP9_2 2 +#define FF_PROFILE_VP9_3 3 + +#define FF_PROFILE_HEVC_MAIN 1 +#define FF_PROFILE_HEVC_MAIN_10 2 +#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 +#define FF_PROFILE_HEVC_REXT 4 + +#define FF_PROFILE_AV1_MAIN 0 +#define FF_PROFILE_AV1_HIGH 1 +#define FF_PROFILE_AV1_PROFESSIONAL 2 + +#define FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT 0xc0 +#define FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT 0xc1 +#define FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT 0xc2 +#define FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS 0xc3 +#define FF_PROFILE_MJPEG_JPEG_LS 0xf7 + +#define FF_PROFILE_SBC_MSBC 1 + +#define FF_PROFILE_PRORES_PROXY 0 +#define FF_PROFILE_PRORES_LT 1 +#define FF_PROFILE_PRORES_STANDARD 2 +#define FF_PROFILE_PRORES_HQ 3 +#define FF_PROFILE_PRORES_4444 4 +#define FF_PROFILE_PRORES_XQ 5 + +#define FF_PROFILE_ARIB_PROFILE_A 0 +#define FF_PROFILE_ARIB_PROFILE_C 1 + +#define FF_PROFILE_KLVA_SYNC 0 +#define FF_PROFILE_KLVA_ASYNC 1 + + /** + * level + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * Skip loop filtering for selected frames. + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_loop_filter; + + /** + * Skip IDCT/dequantization for selected frames. + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_idct; + + /** + * Skip decoding for selected frames. + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_frame; + + /** + * Header containing style information for text subtitles. + * For SUBTITLE_ASS subtitle type, it should contain the whole ASS + * [Script Info] and [V4+ Styles] section, plus the [Events] line and + * the Format line following. It shouldn't include any Dialogue line. + * - encoding: Set/allocated/freed by user (before avcodec_open2()) + * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2()) + */ + uint8_t *subtitle_header; + int subtitle_header_size; + +#if FF_API_VBV_DELAY + /** + * VBV delay coded in the last frame (in periods of a 27 MHz clock). + * Used for compliant TS muxing. + * - encoding: Set by libavcodec. + * - decoding: unused. + * @deprecated this value is now exported as a part of + * AV_PKT_DATA_CPB_PROPERTIES packet side data + */ + attribute_deprecated + uint64_t vbv_delay; +#endif + +#if FF_API_SIDEDATA_ONLY_PKT + /** + * Encoding only and set by default. Allow encoders to output packets + * that do not contain any encoded data, only side data. + * + * Some encoders need to output such packets, e.g. to update some stream + * parameters at the end of encoding. + * + * @deprecated this field disables the default behaviour and + * it is kept only for compatibility. + */ + attribute_deprecated + int side_data_only_packets; +#endif + + /** + * Audio only. The number of "priming" samples (padding) inserted by the + * encoder at the beginning of the audio. I.e. this number of leading + * decoded samples must be discarded by the caller to get the original audio + * without leading padding. + * + * - decoding: unused + * - encoding: Set by libavcodec. The timestamps on the output packets are + * adjusted by the encoder so that they always refer to the + * first sample of the data actually contained in the packet, + * including any added padding. E.g. if the timebase is + * 1/samplerate and the timestamp of the first input sample is + * 0, the timestamp of the first output packet will be + * -initial_padding. + */ + int initial_padding; + + /** + * - decoding: For codecs that store a framerate value in the compressed + * bitstream, the decoder may export it here. { 0, 1} when + * unknown. + * - encoding: May be used to signal the framerate of CFR content to an + * encoder. + */ + AVRational framerate; + + /** + * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx. + * - encoding: unused. + * - decoding: Set by libavcodec before calling get_format() + */ + enum AVPixelFormat sw_pix_fmt; + + /** + * Timebase in which pkt_dts/pts and AVPacket.dts/pts are. + * - encoding unused. + * - decoding set by user. + */ + AVRational pkt_timebase; + + /** + * AVCodecDescriptor + * - encoding: unused. + * - decoding: set by libavcodec. + */ + const AVCodecDescriptor *codec_descriptor; + +#if !FF_API_LOWRES + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; +#endif + + /** + * Current statistics for PTS correction. + * - decoding: maintained and used by libavcodec, not intended to be used by user apps + * - encoding: unused + */ + int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far + int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far + int64_t pts_correction_last_pts; /// PTS of the last frame + int64_t pts_correction_last_dts; /// DTS of the last frame + + /** + * Character encoding of the input subtitles file. + * - decoding: set by user + * - encoding: unused + */ + char *sub_charenc; + + /** + * Subtitles character encoding mode. Formats or codecs might be adjusting + * this setting (if they are doing the conversion themselves for instance). + * - decoding: set by libavcodec + * - encoding: unused + */ + int sub_charenc_mode; +#define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance) +#define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself +#define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv +#define FF_SUB_CHARENC_MODE_IGNORE 2 ///< neither convert the subtitles, nor check them for valid UTF-8 + + /** + * Skip processing alpha if supported by codec. + * Note that if the format uses pre-multiplied alpha (common with VP6, + * and recommended due to better video quality/compression) + * the image will look as if alpha-blended onto a black background. + * However for formats that do not use pre-multiplied alpha + * there might be serious artefacts (though e.g. libswscale currently + * assumes pre-multiplied alpha anyway). + * + * - decoding: set by user + * - encoding: unused + */ + int skip_alpha; + + /** + * Number of samples to skip after a discontinuity + * - decoding: unused + * - encoding: set by libavcodec + */ + int seek_preroll; + +#if !FF_API_DEBUG_MV + /** + * debug motion vectors + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames +#endif + + /** + * custom intra quantization matrix + * - encoding: Set by user, can be NULL. + * - decoding: unused. + */ + uint16_t *chroma_intra_matrix; + + /** + * dump format separator. + * can be ", " or "\n " or anything else + * - encoding: Set by user. + * - decoding: Set by user. + */ + uint8_t *dump_separator; + + /** + * ',' separated list of allowed decoders. + * If NULL then all are allowed + * - encoding: unused + * - decoding: set by user + */ + char *codec_whitelist; + + /** + * Properties of the stream that gets decoded + * - encoding: unused + * - decoding: set by libavcodec + */ + unsigned properties; +#define FF_CODEC_PROPERTY_LOSSLESS 0x00000001 +#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002 + + /** + * Additional data associated with the entire coded stream. + * + * - decoding: unused + * - encoding: may be set by libavcodec after avcodec_open2(). + */ + AVPacketSideData *coded_side_data; + int nb_coded_side_data; + + /** + * A reference to the AVHWFramesContext describing the input (for encoding) + * or output (decoding) frames. The reference is set by the caller and + * afterwards owned (and freed) by libavcodec - it should never be read by + * the caller after being set. + * + * - decoding: This field should be set by the caller from the get_format() + * callback. The previous reference (if any) will always be + * unreffed by libavcodec before the get_format() call. + * + * If the default get_buffer2() is used with a hwaccel pixel + * format, then this AVHWFramesContext will be used for + * allocating the frame buffers. + * + * - encoding: For hardware encoders configured to use a hwaccel pixel + * format, this field should be set by the caller to a reference + * to the AVHWFramesContext describing input frames. + * AVHWFramesContext.format must be equal to + * AVCodecContext.pix_fmt. + * + * This field should be set before avcodec_open2() is called. + */ + AVBufferRef *hw_frames_ctx; + + /** + * Control the form of AVSubtitle.rects[N]->ass + * - decoding: set by user + * - encoding: unused + */ + int sub_text_format; +#define FF_SUB_TEXT_FMT_ASS 0 +#if FF_API_ASS_TIMING +#define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1 +#endif + + /** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + * + * - decoding: unused + * - encoding: unused + */ + int trailing_padding; + + /** + * The number of pixels per image to maximally accept. + * + * - decoding: set by user + * - encoding: set by user + */ + int64_t max_pixels; + + /** + * A reference to the AVHWDeviceContext describing the device which will + * be used by a hardware encoder/decoder. The reference is set by the + * caller and afterwards owned (and freed) by libavcodec. + * + * This should be used if either the codec device does not require + * hardware frames or any that are used are to be allocated internally by + * libavcodec. If the user wishes to supply any of the frames used as + * encoder input or decoder output then hw_frames_ctx should be used + * instead. When hw_frames_ctx is set in get_format() for a decoder, this + * field will be ignored while decoding the associated stream segment, but + * may again be used on a following one after another get_format() call. + * + * For both encoders and decoders this field should be set before + * avcodec_open2() is called and must not be written to thereafter. + * + * Note that some decoders may require this field to be set initially in + * order to support hw_frames_ctx at all - in that case, all frames + * contexts used must be created on the same device. + */ + AVBufferRef *hw_device_ctx; + + /** + * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated + * decoding (if active). + * - encoding: unused + * - decoding: Set by user (either before avcodec_open2(), or in the + * AVCodecContext.get_format callback) + */ + int hwaccel_flags; + + /** + * Video decoding only. Certain video codecs support cropping, meaning that + * only a sub-rectangle of the decoded frame is intended for display. This + * option controls how cropping is handled by libavcodec. + * + * When set to 1 (the default), libavcodec will apply cropping internally. + * I.e. it will modify the output frame width/height fields and offset the + * data pointers (only by as much as possible while preserving alignment, or + * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that + * the frames output by the decoder refer only to the cropped area. The + * crop_* fields of the output frames will be zero. + * + * When set to 0, the width/height fields of the output frames will be set + * to the coded dimensions and the crop_* fields will describe the cropping + * rectangle. Applying the cropping is left to the caller. + * + * @warning When hardware acceleration with opaque output frames is used, + * libavcodec is unable to apply cropping from the top/left border. + * + * @note when this option is set to zero, the width/height fields of the + * AVCodecContext and output AVFrames have different meanings. The codec + * context fields store display dimensions (with the coded dimensions in + * coded_width/height), while the frame fields store the coded dimensions + * (with the display dimensions being determined by the crop_* fields). + */ + int apply_cropping; + + /* + * Video decoding only. Sets the number of extra hardware frames which + * the decoder will allocate for use by the caller. This must be set + * before avcodec_open2() is called. + * + * Some hardware decoders require all frames that they will use for + * output to be defined in advance before decoding starts. For such + * decoders, the hardware frame pool must therefore be of a fixed size. + * The extra frames set here are on top of any number that the decoder + * needs internally in order to operate normally (for example, frames + * used as reference pictures). + */ + int extra_hw_frames; + + /** + * The percentage of damaged samples to discard a frame. + * + * - decoding: set by user + * - encoding: unused + */ + int discard_damaged_percentage; + + /** + * The number of samples per frame to maximally accept. + * + * - decoding: set by user + * - encoding: set by user + */ + int64_t max_samples; + + /** + * Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of + * metadata exported in frame, packet, or coded stream side data by + * decoders and encoders. + * + * - decoding: set by user + * - encoding: set by user + */ + int export_side_data; +} AVCodecContext; + +#if FF_API_CODEC_GET_SET +/** + * Accessors for some AVCodecContext fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated +AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational val); + +attribute_deprecated +const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc); + +attribute_deprecated +unsigned av_codec_get_codec_properties(const AVCodecContext *avctx); + +#if FF_API_LOWRES +attribute_deprecated +int av_codec_get_lowres(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_lowres(AVCodecContext *avctx, int val); +#endif + +attribute_deprecated +int av_codec_get_seek_preroll(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_seek_preroll(AVCodecContext *avctx, int val); + +attribute_deprecated +uint16_t *av_codec_get_chroma_intra_matrix(const AVCodecContext *avctx); +attribute_deprecated +void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val); +#endif + +struct AVSubtitle; + +#if FF_API_CODEC_GET_SET +attribute_deprecated +int av_codec_get_max_lowres(const AVCodec *codec); +#endif + +struct MpegEncContext; + +/** + * @defgroup lavc_hwaccel AVHWAccel + * + * @note Nothing in this structure should be accessed by the user. At some + * point in future it will not be externally visible at all. + * + * @{ + */ +typedef struct AVHWAccel { + /** + * Name of the hardware accelerated codec. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + */ + const char *name; + + /** + * Type of codec implemented by the hardware accelerator. + * + * See AVMEDIA_TYPE_xxx + */ + enum AVMediaType type; + + /** + * Codec implemented by the hardware accelerator. + * + * See AV_CODEC_ID_xxx + */ + enum AVCodecID id; + + /** + * Supported pixel format. + * + * Only hardware accelerated formats are supported here. + */ + enum AVPixelFormat pix_fmt; + + /** + * Hardware accelerated codec capabilities. + * see AV_HWACCEL_CODEC_CAP_* + */ + int capabilities; + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavcodec and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + + /** + * Allocate a custom buffer + */ + int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame); + + /** + * Called at the beginning of each frame or field picture. + * + * Meaningful frame information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * Note that buf can be NULL along with buf_size set to 0. + * Otherwise, this means the whole frame is available at this point. + * + * @param avctx the codec context + * @param buf the frame data buffer base + * @param buf_size the size of the frame in bytes + * @return zero if successful, a negative value otherwise + */ + int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for parameter data (SPS/PPS/VPS etc). + * + * Useful for hardware decoders which keep persistent state about the + * video parameters, and need to receive any changes to update that state. + * + * @param avctx the codec context + * @param type the nal unit type + * @param buf the nal unit data buffer + * @param buf_size the size of the nal unit in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_params)(AVCodecContext *avctx, int type, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for each slice. + * + * Meaningful slice information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * The only exception is XvMC, that works on MB level. + * + * @param avctx the codec context + * @param buf the slice data buffer base + * @param buf_size the size of the slice in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Called at the end of each frame or field picture. + * + * The whole picture is parsed at this point and can now be sent + * to the hardware accelerator. This function is mandatory. + * + * @param avctx the codec context + * @return zero if successful, a negative value otherwise + */ + int (*end_frame)(AVCodecContext *avctx); + + /** + * Size of per-frame hardware accelerator private data. + * + * Private data is allocated with av_mallocz() before + * AVCodecContext.get_buffer() and deallocated after + * AVCodecContext.release_buffer(). + */ + int frame_priv_data_size; + + /** + * Called for every Macroblock in a slice. + * + * XvMC uses it to replace the ff_mpv_reconstruct_mb(). + * Instead of decoding to raw picture, MB parameters are + * stored in an array provided by the video driver. + * + * @param s the mpeg context + */ + void (*decode_mb)(struct MpegEncContext *s); + + /** + * Initialize the hwaccel private data. + * + * This will be called from ff_get_format(), after hwaccel and + * hwaccel_context are set and the hwaccel private data in AVCodecInternal + * is allocated. + */ + int (*init)(AVCodecContext *avctx); + + /** + * Uninitialize the hwaccel private data. + * + * This will be called from get_format() or avcodec_close(), after hwaccel + * and hwaccel_context are already uninitialized. + */ + int (*uninit)(AVCodecContext *avctx); + + /** + * Size of the private data to allocate in + * AVCodecInternal.hwaccel_priv_data. + */ + int priv_data_size; + + /** + * Internal hwaccel capabilities. + */ + int caps_internal; + + /** + * Fill the given hw_frames context with current codec parameters. Called + * from get_format. Refer to avcodec_get_hw_frames_parameters() for + * details. + * + * This CAN be called before AVHWAccel.init is called, and you must assume + * that avctx->hwaccel_priv_data is invalid. + */ + int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); +} AVHWAccel; + +/** + * HWAccel is experimental and is thus avoided in favor of non experimental + * codecs + */ +#define AV_HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200 + +/** + * Hardware acceleration should be used for decoding even if the codec level + * used is unknown or higher than the maximum supported level reported by the + * hardware driver. + * + * It's generally a good idea to pass this flag unless you have a specific + * reason not to, as hardware tends to under-report supported levels. + */ +#define AV_HWACCEL_FLAG_IGNORE_LEVEL (1 << 0) + +/** + * Hardware acceleration can output YUV pixel formats with a different chroma + * sampling than 4:2:0 and/or other than 8 bits per component. + */ +#define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1) + +/** + * Hardware acceleration should still be attempted for decoding when the + * codec profile does not match the reported capabilities of the hardware. + * + * For example, this can be used to try to decode baseline profile H.264 + * streams in hardware - it will often succeed, because many streams marked + * as baseline profile actually conform to constrained baseline profile. + * + * @warning If the stream is actually not supported then the behaviour is + * undefined, and may include returning entirely incorrect output + * while indicating success. + */ +#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH (1 << 2) + +/** + * @} + */ + +#if FF_API_AVPICTURE +/** + * @defgroup lavc_picture AVPicture + * + * Functions for working with AVPicture + * @{ + */ + +/** + * Picture data structure. + * + * Up to four components can be stored into it, the last component is + * alpha. + * @deprecated use AVFrame or imgutils functions instead + */ +typedef struct AVPicture { + attribute_deprecated + uint8_t *data[AV_NUM_DATA_POINTERS]; ///< pointers to the image data planes + attribute_deprecated + int linesize[AV_NUM_DATA_POINTERS]; ///< number of bytes per line +} AVPicture; + +/** + * @} + */ +#endif + +enum AVSubtitleType { + SUBTITLE_NONE, + + SUBTITLE_BITMAP, ///< A bitmap, pict will be set + + /** + * Plain text, the text field must be set by the decoder and is + * authoritative. ass and pict fields may contain approximations. + */ + SUBTITLE_TEXT, + + /** + * Formatted text, the ass field must be set by the decoder and is + * authoritative. pict and text fields may contain approximations. + */ + SUBTITLE_ASS, +}; + +#define AV_SUBTITLE_FLAG_FORCED 0x00000001 + +typedef struct AVSubtitleRect { + int x; ///< top left corner of pict, undefined when pict is not set + int y; ///< top left corner of pict, undefined when pict is not set + int w; ///< width of pict, undefined when pict is not set + int h; ///< height of pict, undefined when pict is not set + int nb_colors; ///< number of colors in pict, undefined when pict is not set + +#if FF_API_AVPICTURE + /** + * @deprecated unused + */ + attribute_deprecated + AVPicture pict; +#endif + /** + * data+linesize for the bitmap of this subtitle. + * Can be set for text/ass as well once they are rendered. + */ + uint8_t *data[4]; + int linesize[4]; + + enum AVSubtitleType type; + + char *text; ///< 0 terminated plain UTF-8 text + + /** + * 0 terminated ASS/SSA compatible event line. + * The presentation of this is unaffected by the other values in this + * struct. + */ + char *ass; + + int flags; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + unsigned num_rects; + AVSubtitleRect **rects; + int64_t pts; ///< Same as packet pts, in AV_TIME_BASE +} AVSubtitle; + +#if FF_API_NEXT +/** + * If c is NULL, returns the first registered codec, + * if c is non-NULL, returns the next registered codec after c, + * or NULL if c is the last one. + */ +attribute_deprecated +AVCodec *av_codec_next(const AVCodec *c); +#endif + +/** + * Return the LIBAVCODEC_VERSION_INT constant. + */ +unsigned avcodec_version(void); + +/** + * Return the libavcodec build-time configuration. + */ +const char *avcodec_configuration(void); + +/** + * Return the libavcodec license. + */ +const char *avcodec_license(void); + +#if FF_API_NEXT +/** + * Register the codec codec and initialize libavcodec. + * + * @warning either this function or avcodec_register_all() must be called + * before any other libavcodec functions. + * + * @see avcodec_register_all() + */ +attribute_deprecated +void avcodec_register(AVCodec *codec); + +/** + * Register all the codecs, parsers and bitstream filters which were enabled at + * configuration time. If you do not call this function you can select exactly + * which formats you want to support, by using the individual registration + * functions. + * + * @see avcodec_register + * @see av_register_codec_parser + * @see av_register_bitstream_filter + */ +attribute_deprecated +void avcodec_register_all(void); +#endif + +/** + * Allocate an AVCodecContext and set its fields to default values. The + * resulting struct should be freed with avcodec_free_context(). + * + * @param codec if non-NULL, allocate private data and initialize defaults + * for the given codec. It is illegal to then call avcodec_open2() + * with a different codec. + * If NULL, then the codec-specific defaults won't be initialized, + * which may result in suboptimal default settings (this is + * important mainly for encoders, e.g. libx264). + * + * @return An AVCodecContext filled with default values or NULL on failure. + */ +AVCodecContext *avcodec_alloc_context3(const AVCodec *codec); + +/** + * Free the codec context and everything associated with it and write NULL to + * the provided pointer. + */ +void avcodec_free_context(AVCodecContext **avctx); + +#if FF_API_GET_CONTEXT_DEFAULTS +/** + * @deprecated This function should not be used, as closing and opening a codec + * context multiple time is not supported. A new codec context should be + * allocated for each new use. + */ +int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec); +#endif + +/** + * Get the AVClass for AVCodecContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avcodec_get_class(void); + +#if FF_API_COPY_CONTEXT +/** + * Get the AVClass for AVFrame. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avcodec_get_frame_class(void); + +/** + * Get the AVClass for AVSubtitleRect. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avcodec_get_subtitle_rect_class(void); + +/** + * Copy the settings of the source AVCodecContext into the destination + * AVCodecContext. The resulting destination codec context will be + * unopened, i.e. you are required to call avcodec_open2() before you + * can use this AVCodecContext to decode/encode video/audio data. + * + * @param dest target codec context, should be initialized with + * avcodec_alloc_context3(NULL), but otherwise uninitialized + * @param src source codec context + * @return AVERROR() on error (e.g. memory allocation error), 0 on success + * + * @deprecated The semantics of this function are ill-defined and it should not + * be used. If you need to transfer the stream parameters from one codec context + * to another, use an intermediate AVCodecParameters instance and the + * avcodec_parameters_from_context() / avcodec_parameters_to_context() + * functions. + */ +attribute_deprecated +int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); +#endif + +/** + * Fill the parameters struct based on the values from the supplied codec + * context. Any allocated fields in par are freed and replaced with duplicates + * of the corresponding fields in codec. + * + * @return >= 0 on success, a negative AVERROR code on failure + */ +int avcodec_parameters_from_context(AVCodecParameters *par, + const AVCodecContext *codec); + +/** + * Fill the codec context based on the values from the supplied codec + * parameters. Any allocated fields in codec that have a corresponding field in + * par are freed and replaced with duplicates of the corresponding field in par. + * Fields in codec that do not have a counterpart in par are not touched. + * + * @return >= 0 on success, a negative AVERROR code on failure. + */ +int avcodec_parameters_to_context(AVCodecContext *codec, + const AVCodecParameters *par); + +/** + * Initialize the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated with avcodec_alloc_context3(). + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @note Always call this function before using decoding routines (such as + * @ref avcodec_receive_frame()). + * + * @code + * avcodec_register_all(); + * av_dict_set(&opts, "b", "2.5M", 0); + * codec = avcodec_find_decoder(AV_CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context3(codec); + * + * if (avcodec_open2(context, codec, opts) < 0) + * exit(1); + * @endcode + * + * @param avctx The context to initialize. + * @param codec The codec to open this context for. If a non-NULL codec has been + * previously passed to avcodec_alloc_context3() or + * for this context, then this parameter MUST be either NULL or + * equal to the previously passed codec. + * @param options A dictionary filled with AVCodecContext and codec-private options. + * On return this object will be filled with options that were not found. + * + * @return zero on success, a negative value on error + * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(), + * av_dict_set(), av_opt_find(). + */ +int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); + +/** + * Close a given AVCodecContext and free all the data associated with it + * (but not the AVCodecContext itself). + * + * Calling this function on an AVCodecContext that hasn't been opened will free + * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL + * codec. Subsequent calls will do nothing. + * + * @note Do not use this function. Use avcodec_free_context() to destroy a + * codec context (either open or closed). Opening and closing a codec context + * multiple times is not supported anymore -- use multiple codec contexts + * instead. + */ +int avcodec_close(AVCodecContext *avctx); + +/** + * Free all allocated data in the given subtitle struct. + * + * @param sub AVSubtitle to free. + */ +void avsubtitle_free(AVSubtitle *sub); + +/** + * @} + */ + +/** + * @addtogroup lavc_decoding + * @{ + */ + +/** + * The default callback for AVCodecContext.get_buffer2(). It is made public so + * it can be called by custom get_buffer2() implementations for decoders without + * AV_CODEC_CAP_DR1 set. + */ +int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); + +/** + * Modify width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you do not use any horizontal + * padding. + * + * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. + */ +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); + +/** + * Modify width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you also ensure that all + * line sizes are a multiple of the respective linesize_align[i]. + * + * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened. + */ +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, + int linesize_align[AV_NUM_DATA_POINTERS]); + +/** + * Converts AVChromaLocation to swscale x/y chroma position. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos); + +/** + * Converts swscale x/y chroma position to AVChromaLocation. + * + * The positions represent the chroma (0,0) position in a coordinates system + * with luma (0,0) representing the origin and luma(1,1) representing 256,256 + * + * @param xpos horizontal chroma sample position + * @param ypos vertical chroma sample position + */ +enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos); + +/** + * Decode the audio frame of size avpkt->size from avpkt->data into frame. + * + * Some decoders may support multiple frames in a single AVPacket. Such + * decoders would then just decode the first frame and the return value would be + * less than the packet size. In this case, avcodec_decode_audio4 has to be + * called again with an AVPacket containing the remaining data in order to + * decode the second frame, etc... Even if no frames are returned, the packet + * needs to be fed to the decoder with remaining data until it is completely + * consumed or an error occurs. + * + * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning samples. It is safe to flush even those decoders that are not + * marked with AV_CODEC_CAP_DELAY, then no samples will be returned. + * + * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE + * larger than the actual read bytes because some optimized bitstream + * readers read 32 or 64 bits at once and could read over the end. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx the codec context + * @param[out] frame The AVFrame in which to store decoded audio samples. + * The decoder will allocate a buffer for the decoded frame by + * calling the AVCodecContext.get_buffer2() callback. + * When AVCodecContext.refcounted_frames is set to 1, the frame is + * reference counted and the returned reference belongs to the + * caller. The caller must release the frame using av_frame_unref() + * when the frame is no longer needed. The caller may safely write + * to the frame if av_frame_is_writable() returns 1. + * When AVCodecContext.refcounted_frames is set to 0, the returned + * reference belongs to the decoder and is valid only until the + * next call to this function or until closing or flushing the + * decoder. The caller may not write to it. + * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is + * non-zero. Note that this field being set to zero + * does not mean that an error has occurred. For + * decoders with AV_CODEC_CAP_DELAY set, no given decode + * call is guaranteed to produce a frame. + * @param[in] avpkt The input AVPacket containing the input buffer. + * At least avpkt->data and avpkt->size should be set. Some + * decoders might also require additional fields to be set. + * @return A negative error code is returned if an error occurred during + * decoding, otherwise the number of bytes consumed from the input + * AVPacket is returned. + * +* @deprecated Use avcodec_send_packet() and avcodec_receive_frame(). + */ +attribute_deprecated +int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, + int *got_frame_ptr, const AVPacket *avpkt); + +/** + * Decode the video frame of size avpkt->size from avpkt->data into picture. + * Some decoders may support multiple frames in a single AVPacket, such + * decoders would then just decode the first frame. + * + * @warning The input buffer must be AV_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note Codecs which have the AV_CODEC_CAP_DELAY capability set have a delay + * between input and output, these need to be fed with avpkt->data=NULL, + * avpkt->size=0 at the end to return the remaining frames. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * Use av_frame_alloc() to get an AVFrame. The codec will + * allocate memory for the actual bitmap by calling the + * AVCodecContext.get_buffer2() callback. + * When AVCodecContext.refcounted_frames is set to 1, the frame is + * reference counted and the returned reference belongs to the + * caller. The caller must release the frame using av_frame_unref() + * when the frame is no longer needed. The caller may safely write + * to the frame if av_frame_is_writable() returns 1. + * When AVCodecContext.refcounted_frames is set to 0, the returned + * reference belongs to the decoder and is valid only until the + * next call to this function or until closing or flushing the + * decoder. The caller may not write to it. + * + * @param[in] avpkt The input AVPacket containing the input buffer. + * You can create such packet with av_init_packet() and by then setting + * data and size, some decoders might in addition need other fields like + * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least + * fields possible. + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + * + * @deprecated Use avcodec_send_packet() and avcodec_receive_frame(). + */ +attribute_deprecated +int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const AVPacket *avpkt); + +/** + * Decode a subtitle message. + * Return a negative value on error, otherwise return the number of bytes used. + * If no subtitle could be decompressed, got_sub_ptr is zero. + * Otherwise, the subtitle is stored in *sub. + * Note that AV_CODEC_CAP_DR1 is not available for subtitle codecs. This is for + * simplicity, because the performance difference is expected to be negligible + * and reusing a get_buffer written for video codecs would probably perform badly + * due to a potentially very different allocation pattern. + * + * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning subtitles. It is safe to flush even those decoders that are not + * marked with AV_CODEC_CAP_DELAY, then no subtitles will be returned. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx the codec context + * @param[out] sub The preallocated AVSubtitle in which the decoded subtitle will be stored, + * must be freed with avsubtitle_free if *got_sub_ptr is set. + * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. + * @param[in] avpkt The input AVPacket containing the input buffer. + */ +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt); + +/** + * Supply raw packet data as input to a decoder. + * + * Internally, this call will copy relevant AVCodecContext fields, which can + * influence decoding per-packet, and apply them when the packet is actually + * decoded. (For example AVCodecContext.skip_frame, which might direct the + * decoder to drop the frame contained by the packet sent with this function.) + * + * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE + * larger than the actual read bytes because some optimized bitstream + * readers read 32 or 64 bits at once and could read over the end. + * + * @warning Do not mix this API with the legacy API (like avcodec_decode_video2()) + * on the same AVCodecContext. It will return unexpected results now + * or in future libavcodec versions. + * + * @note The AVCodecContext MUST have been opened with @ref avcodec_open2() + * before packets may be fed to the decoder. + * + * @param avctx codec context + * @param[in] avpkt The input AVPacket. Usually, this will be a single video + * frame, or several complete audio frames. + * Ownership of the packet remains with the caller, and the + * decoder will not write to the packet. The decoder may create + * a reference to the packet data (or copy it if the packet is + * not reference-counted). + * Unlike with older APIs, the packet is always fully consumed, + * and if it contains multiple frames (e.g. some audio codecs), + * will require you to call avcodec_receive_frame() multiple + * times afterwards before you can send a new packet. + * It can be NULL (or an AVPacket with data set to NULL and + * size set to 0); in this case, it is considered a flush + * packet, which signals the end of the stream. Sending the + * first flush packet will return success. Subsequent ones are + * unnecessary and will return AVERROR_EOF. If the decoder + * still has frames buffered, it will return them after sending + * a flush packet. + * + * @return 0 on success, otherwise negative error code: + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_frame() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). + * AVERROR_EOF: the decoder has been flushed, and no new packets can + * be sent to it (also returned if more than 1 flush + * packet is sent) + * AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush + * AVERROR(ENOMEM): failed to add packet to internal queue, or similar + * other errors: legitimate decoding errors + */ +int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); + +/** + * Return decoded output data from a decoder. + * + * @param avctx codec context + * @param frame This will be set to a reference-counted video or audio + * frame (depending on the decoder type) allocated by the + * decoder. Note that the function will always call + * av_frame_unref(frame) before doing anything else. + * + * @return + * 0: success, a frame was returned + * AVERROR(EAGAIN): output is not available in this state - user must try + * to send new input + * AVERROR_EOF: the decoder has been fully flushed, and there will be + * no more output frames + * AVERROR(EINVAL): codec not opened, or it is an encoder + * AVERROR_INPUT_CHANGED: current decoded frame has changed parameters + * with respect to first decoded frame. Applicable + * when flag AV_CODEC_FLAG_DROPCHANGED is set. + * other negative values: legitimate decoding errors + */ +int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame); + +/** + * Supply a raw video or audio frame to the encoder. Use avcodec_receive_packet() + * to retrieve buffered output packets. + * + * @param avctx codec context + * @param[in] frame AVFrame containing the raw audio or video frame to be encoded. + * Ownership of the frame remains with the caller, and the + * encoder will not write to the frame. The encoder may create + * a reference to the frame data (or copy it if the frame is + * not reference-counted). + * It can be NULL, in which case it is considered a flush + * packet. This signals the end of the stream. If the encoder + * still has packets buffered, it will return them after this + * call. Once flushing mode has been entered, additional flush + * packets are ignored, and sending frames will return + * AVERROR_EOF. + * + * For audio: + * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame + * can have any number of samples. + * If it is not set, frame->nb_samples must be equal to + * avctx->frame_size for all frames except the last. + * The final frame may be smaller than avctx->frame_size. + * @return 0 on success, otherwise negative error code: + * AVERROR(EAGAIN): input is not accepted in the current state - user + * must read output with avcodec_receive_packet() (once + * all output is read, the packet should be resent, and + * the call will not fail with EAGAIN). + * AVERROR_EOF: the encoder has been flushed, and no new frames can + * be sent to it + * AVERROR(EINVAL): codec not opened, refcounted_frames not set, it is a + * decoder, or requires flush + * AVERROR(ENOMEM): failed to add packet to internal queue, or similar + * other errors: legitimate encoding errors + */ +int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); + +/** + * Read encoded data from the encoder. + * + * @param avctx codec context + * @param avpkt This will be set to a reference-counted packet allocated by the + * encoder. Note that the function will always call + * av_packet_unref(avpkt) before doing anything else. + * @return 0 on success, otherwise negative error code: + * AVERROR(EAGAIN): output is not available in the current state - user + * must try to send input + * AVERROR_EOF: the encoder has been fully flushed, and there will be + * no more output packets + * AVERROR(EINVAL): codec not opened, or it is a decoder + * other errors: legitimate encoding errors + */ +int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); + +/** + * Create and return a AVHWFramesContext with values adequate for hardware + * decoding. This is meant to get called from the get_format callback, and is + * a helper for preparing a AVHWFramesContext for AVCodecContext.hw_frames_ctx. + * This API is for decoding with certain hardware acceleration modes/APIs only. + * + * The returned AVHWFramesContext is not initialized. The caller must do this + * with av_hwframe_ctx_init(). + * + * Calling this function is not a requirement, but makes it simpler to avoid + * codec or hardware API specific details when manually allocating frames. + * + * Alternatively to this, an API user can set AVCodecContext.hw_device_ctx, + * which sets up AVCodecContext.hw_frames_ctx fully automatically, and makes + * it unnecessary to call this function or having to care about + * AVHWFramesContext initialization at all. + * + * There are a number of requirements for calling this function: + * + * - It must be called from get_format with the same avctx parameter that was + * passed to get_format. Calling it outside of get_format is not allowed, and + * can trigger undefined behavior. + * - The function is not always supported (see description of return values). + * Even if this function returns successfully, hwaccel initialization could + * fail later. (The degree to which implementations check whether the stream + * is actually supported varies. Some do this check only after the user's + * get_format callback returns.) + * - The hw_pix_fmt must be one of the choices suggested by get_format. If the + * user decides to use a AVHWFramesContext prepared with this API function, + * the user must return the same hw_pix_fmt from get_format. + * - The device_ref passed to this function must support the given hw_pix_fmt. + * - After calling this API function, it is the user's responsibility to + * initialize the AVHWFramesContext (returned by the out_frames_ref parameter), + * and to set AVCodecContext.hw_frames_ctx to it. If done, this must be done + * before returning from get_format (this is implied by the normal + * AVCodecContext.hw_frames_ctx API rules). + * - The AVHWFramesContext parameters may change every time time get_format is + * called. Also, AVCodecContext.hw_frames_ctx is reset before get_format. So + * you are inherently required to go through this process again on every + * get_format call. + * - It is perfectly possible to call this function without actually using + * the resulting AVHWFramesContext. One use-case might be trying to reuse a + * previously initialized AVHWFramesContext, and calling this API function + * only to test whether the required frame parameters have changed. + * - Fields that use dynamically allocated values of any kind must not be set + * by the user unless setting them is explicitly allowed by the documentation. + * If the user sets AVHWFramesContext.free and AVHWFramesContext.user_opaque, + * the new free callback must call the potentially set previous free callback. + * This API call may set any dynamically allocated fields, including the free + * callback. + * + * The function will set at least the following fields on AVHWFramesContext + * (potentially more, depending on hwaccel API): + * + * - All fields set by av_hwframe_ctx_alloc(). + * - Set the format field to hw_pix_fmt. + * - Set the sw_format field to the most suited and most versatile format. (An + * implication is that this will prefer generic formats over opaque formats + * with arbitrary restrictions, if possible.) + * - Set the width/height fields to the coded frame size, rounded up to the + * API-specific minimum alignment. + * - Only _if_ the hwaccel requires a pre-allocated pool: set the initial_pool_size + * field to the number of maximum reference surfaces possible with the codec, + * plus 1 surface for the user to work (meaning the user can safely reference + * at most 1 decoded surface at a time), plus additional buffering introduced + * by frame threading. If the hwaccel does not require pre-allocation, the + * field is left to 0, and the decoder will allocate new surfaces on demand + * during decoding. + * - Possibly AVHWFramesContext.hwctx fields, depending on the underlying + * hardware API. + * + * Essentially, out_frames_ref returns the same as av_hwframe_ctx_alloc(), but + * with basic frame parameters set. + * + * The function is stateless, and does not change the AVCodecContext or the + * device_ref AVHWDeviceContext. + * + * @param avctx The context which is currently calling get_format, and which + * implicitly contains all state needed for filling the returned + * AVHWFramesContext properly. + * @param device_ref A reference to the AVHWDeviceContext describing the device + * which will be used by the hardware decoder. + * @param hw_pix_fmt The hwaccel format you are going to return from get_format. + * @param out_frames_ref On success, set to a reference to an _uninitialized_ + * AVHWFramesContext, created from the given device_ref. + * Fields will be set to values required for decoding. + * Not changed if an error is returned. + * @return zero on success, a negative value on error. The following error codes + * have special semantics: + * AVERROR(ENOENT): the decoder does not support this functionality. Setup + * is always manual, or it is a decoder which does not + * support setting AVCodecContext.hw_frames_ctx at all, + * or it is a software format. + * AVERROR(EINVAL): it is known that hardware decoding is not supported for + * this configuration, or the device_ref is not supported + * for the hwaccel referenced by hw_pix_fmt. + */ +int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, + AVBufferRef *device_ref, + enum AVPixelFormat hw_pix_fmt, + AVBufferRef **out_frames_ref); + + + +/** + * @defgroup lavc_parsing Frame parsing + * @{ + */ + +enum AVPictureStructure { + AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown + AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field + AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field + AV_PICTURE_STRUCTURE_FRAME, //< coded as frame +}; + +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t next_frame_offset; /* offset of the next frame */ + /* video info */ + int pict_type; /* XXX: Put it back in AVCodecContext. */ + /** + * This field is used for proper frame duration computation in lavf. + * It signals, how much longer the frame duration of the current frame + * is compared to normal frame duration. + * + * frame_duration = (1 + repeat_pict) * time_base + * + * It is used by codecs like H.264 to display telecined material. + */ + int repeat_pict; /* XXX: Put it back in AVCodecContext. */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + int fetch_timestamp; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; + + int flags; +#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 +#define PARSER_FLAG_ONCE 0x0002 +/// Set if the parser has a valid file offset +#define PARSER_FLAG_FETCHED_OFFSET 0x0004 +#define PARSER_FLAG_USE_CODEC_TS 0x1000 + + int64_t offset; ///< byte offset from starting packet start + int64_t cur_frame_end[AV_PARSER_PTS_NB]; + + /** + * Set by parser to 1 for key frames and 0 for non-key frames. + * It is initialized to -1, so if the parser doesn't set this flag, + * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames + * will be used. + */ + int key_frame; + +#if FF_API_CONVERGENCE_DURATION + /** + * @deprecated unused + */ + attribute_deprecated + int64_t convergence_duration; +#endif + + // Timestamp generation support: + /** + * Synchronization point for start of timestamp generation. + * + * Set to >0 for sync point, 0 for no sync point and <0 for undefined + * (default). + * + * For example, this corresponds to presence of H.264 buffering period + * SEI message. + */ + int dts_sync_point; + + /** + * Offset of the current timestamp against last timestamp sync point in + * units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain a valid timestamp offset. + * + * Note that the timestamp of sync point has usually a nonzero + * dts_ref_dts_delta, which refers to the previous sync point. Offset of + * the next frame after timestamp sync point will be usually 1. + * + * For example, this corresponds to H.264 cpb_removal_delay. + */ + int dts_ref_dts_delta; + + /** + * Presentation delay of current frame in units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain valid non-negative timestamp delta (presentation time of a frame + * must not lie in the past). + * + * This delay represents the difference between decoding and presentation + * time of the frame. + * + * For example, this corresponds to H.264 dpb_output_delay. + */ + int pts_dts_delta; + + /** + * Position of the packet in file. + * + * Analogous to cur_frame_pts/dts + */ + int64_t cur_frame_pos[AV_PARSER_PTS_NB]; + + /** + * Byte position of currently parsed frame in stream. + */ + int64_t pos; + + /** + * Previous frame byte position. + */ + int64_t last_pos; + + /** + * Duration of the current frame. + * For audio, this is in units of 1 / AVCodecContext.sample_rate. + * For all other types, this is in units of AVCodecContext.time_base. + */ + int duration; + + enum AVFieldOrder field_order; + + /** + * Indicate whether a picture is coded as a frame, top field or bottom field. + * + * For example, H.264 field_pic_flag equal to 0 corresponds to + * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag + * equal to 1 and bottom_field_flag equal to 0 corresponds to + * AV_PICTURE_STRUCTURE_TOP_FIELD. + */ + enum AVPictureStructure picture_structure; + + /** + * Picture number incremented in presentation or output order. + * This field may be reinitialized at the first picture of a new sequence. + * + * For example, this corresponds to H.264 PicOrderCnt. + */ + int output_picture_number; + + /** + * Dimensions of the decoded video intended for presentation. + */ + int width; + int height; + + /** + * Dimensions of the coded video. + */ + int coded_width; + int coded_height; + + /** + * The format of the coded data, corresponds to enum AVPixelFormat for video + * and for enum AVSampleFormat for audio. + * + * Note that a decoder can have considerable freedom in how exactly it + * decodes the data, so the format reported here might be different from the + * one returned by a decoder. + */ + int format; +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[5]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + /* This callback never returns an error, a negative value means that + * the frame start was in a previous packet. */ + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); + struct AVCodecParser *next; +} AVCodecParser; + +/** + * Iterate over all registered codec parsers. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered codec parser or NULL when the iteration is + * finished + */ +const AVCodecParser *av_parser_iterate(void **opaque); + +attribute_deprecated +AVCodecParser *av_parser_next(const AVCodecParser *c); + +attribute_deprecated +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); + +/** + * Parse a packet. + * + * @param s parser context. + * @param avctx codec context. + * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. + * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. + * @param buf input buffer. + * @param buf_size buffer size in bytes without the padding. I.e. the full buffer + size is assumed to be buf_size + AV_INPUT_BUFFER_PADDING_SIZE. + To signal EOF, this should be 0 (so that the last frame + can be output). + * @param pts input presentation timestamp. + * @param dts input decoding timestamp. + * @param pos input byte position in stream. + * @return the number of bytes of the input bitstream used. + * + * Example: + * @code + * while(in_len){ + * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, + * in_data, in_len, + * pts, dts, pos); + * in_data += len; + * in_len -= len; + * + * if(size) + * decode_frame(data, size); + * } + * @endcode + */ +int av_parser_parse2(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, + int64_t pos); + +/** + * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed + * @deprecated use AVBitStreamFilter + */ +int av_parser_change(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_parser_close(AVCodecParserContext *s); + +/** + * @} + * @} + */ + +/** + * @addtogroup lavc_encoding + * @{ + */ + +/** + * Encode a frame of audio. + * + * Takes input samples from frame and writes the next output packet, if + * available, to avpkt. The output packet does not necessarily contain data for + * the most recent frame, as encoders can delay, split, and combine input frames + * internally as needed. + * + * @param avctx codec context + * @param avpkt output AVPacket. + * The user can supply an output buffer by setting + * avpkt->data and avpkt->size prior to calling the + * function, but if the size of the user-provided data is not + * large enough, encoding will fail. If avpkt->data and + * avpkt->size are set, avpkt->destruct must also be set. All + * other AVPacket fields will be reset by the encoder using + * av_init_packet(). If avpkt->data is NULL, the encoder will + * allocate it. The encoder will set avpkt->size to the size + * of the output packet. + * + * If this function fails or produces no output, avpkt will be + * freed using av_packet_unref(). + * @param[in] frame AVFrame containing the raw audio data to be encoded. + * May be NULL when flushing an encoder that has the + * AV_CODEC_CAP_DELAY capability set. + * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame + * can have any number of samples. + * If it is not set, frame->nb_samples must be equal to + * avctx->frame_size for all frames except the last. + * The final frame may be smaller than avctx->frame_size. + * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the + * output packet is non-empty, and to 0 if it is + * empty. If the function returns an error, the + * packet can be assumed to be invalid, and the + * value of got_packet_ptr is undefined and should + * not be used. + * @return 0 on success, negative error code on failure + * + * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead + */ +attribute_deprecated +int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr); + +/** + * Encode a frame of video. + * + * Takes input raw video data from frame and writes the next output packet, if + * available, to avpkt. The output packet does not necessarily contain data for + * the most recent frame, as encoders can delay and reorder input frames + * internally as needed. + * + * @param avctx codec context + * @param avpkt output AVPacket. + * The user can supply an output buffer by setting + * avpkt->data and avpkt->size prior to calling the + * function, but if the size of the user-provided data is not + * large enough, encoding will fail. All other AVPacket fields + * will be reset by the encoder using av_init_packet(). If + * avpkt->data is NULL, the encoder will allocate it. + * The encoder will set avpkt->size to the size of the + * output packet. The returned data (if any) belongs to the + * caller, he is responsible for freeing it. + * + * If this function fails or produces no output, avpkt will be + * freed using av_packet_unref(). + * @param[in] frame AVFrame containing the raw video data to be encoded. + * May be NULL when flushing an encoder that has the + * AV_CODEC_CAP_DELAY capability set. + * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the + * output packet is non-empty, and to 0 if it is + * empty. If the function returns an error, the + * packet can be assumed to be invalid, and the + * value of got_packet_ptr is undefined and should + * not be used. + * @return 0 on success, negative error code on failure + * + * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead + */ +attribute_deprecated +int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr); + +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub); + + +/** + * @} + */ + +#if FF_API_AVPICTURE +/** + * @addtogroup lavc_picture + * @{ + */ + +/** + * @deprecated unused + */ +attribute_deprecated +int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated unused + */ +attribute_deprecated +void avpicture_free(AVPicture *picture); + +/** + * @deprecated use av_image_fill_arrays() instead. + */ +attribute_deprecated +int avpicture_fill(AVPicture *picture, const uint8_t *ptr, + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated use av_image_copy_to_buffer() instead. + */ +attribute_deprecated +int avpicture_layout(const AVPicture *src, enum AVPixelFormat pix_fmt, + int width, int height, + unsigned char *dest, int dest_size); + +/** + * @deprecated use av_image_get_buffer_size() instead. + */ +attribute_deprecated +int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated av_image_copy() instead. + */ +attribute_deprecated +void av_picture_copy(AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * @deprecated unused + */ +attribute_deprecated +int av_picture_crop(AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pix_fmt, int top_band, int left_band); + +/** + * @deprecated unused + */ +attribute_deprecated +int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color); + +/** + * @} + */ +#endif + +/** + * @defgroup lavc_misc Utility functions + * @ingroup libavc + * + * Miscellaneous utility functions related to both encoding and decoding + * (or neither). + * @{ + */ + +/** + * @defgroup lavc_misc_pixfmt Pixel formats + * + * Functions for working with pixel formats. + * @{ + */ + +#if FF_API_GETCHROMA +/** + * @deprecated Use av_pix_fmt_get_chroma_sub_sample + */ + +attribute_deprecated +void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift); +#endif + +/** + * Return a value representing the fourCC code associated to the + * pixel format pix_fmt, or 0 if no associated fourCC code can be + * found. + */ +unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat pix_fmt); + +/** + * @deprecated see av_get_pix_fmt_loss() + */ +int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, + int has_alpha); + +/** + * Find the best pixel format to convert to given a certain source pixel + * format. When converting from one pixel format to another, information loss + * may occur. For example, when converting from RGB24 to GRAY, the color + * information will be lost. Similarly, other losses occur when converting from + * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches which of + * the given pixel formats should be used to suffer the least amount of loss. + * The pixel formats from which it chooses one, are determined by the + * pix_fmt_list parameter. + * + * + * @param[in] pix_fmt_list AV_PIX_FMT_NONE terminated array of pixel formats to choose from + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. + * @return The best pixel format to convert to or -1 if none was found. + */ +enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list, + enum AVPixelFormat src_pix_fmt, + int has_alpha, int *loss_ptr); + +/** + * @deprecated see av_find_best_pix_fmt_of_2() + */ +enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + +attribute_deprecated +enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat * fmt); + +/** + * @} + */ + +#if FF_API_TAG_STRING +/** + * Put a string representing the codec tag codec_tag in buf. + * + * @param buf buffer to place codec tag in + * @param buf_size size in bytes of buf + * @param codec_tag codec tag to assign + * @return the length of the string that would have been generated if + * enough space had been available, excluding the trailing null + * + * @deprecated see av_fourcc_make_string() and av_fourcc2str(). + */ +attribute_deprecated +size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag); +#endif + +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +/** + * Return a name for the specified profile, if available. + * + * @param codec the codec that is searched for the given profile + * @param profile the profile value for which a name is requested + * @return A name for the profile if found, NULL otherwise. + */ +const char *av_get_profile_name(const AVCodec *codec, int profile); + +/** + * Return a name for the specified profile, if available. + * + * @param codec_id the ID of the codec to which the requested profile belongs + * @param profile the profile value for which a name is requested + * @return A name for the profile if found, NULL otherwise. + * + * @note unlike av_get_profile_name(), which searches a list of profiles + * supported by a specific decoder or encoder implementation, this + * function searches the list of profiles from the AVCodecDescriptor + */ +const char *avcodec_profile_name(enum AVCodecID codec_id, int profile); + +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); +//FIXME func typedef + +/** + * Fill AVFrame audio data and linesize pointers. + * + * The buffer buf must be a preallocated buffer with a size big enough + * to contain the specified samples amount. The filled AVFrame data + * pointers will point to this buffer. + * + * AVFrame extended_data channel pointers are allocated if necessary for + * planar audio. + * + * @param frame the AVFrame + * frame->nb_samples must be set prior to calling the + * function. This function fills in frame->data, + * frame->extended_data, frame->linesize[0]. + * @param nb_channels channel count + * @param sample_fmt sample format + * @param buf buffer to use for frame data + * @param buf_size size of buffer + * @param align plane size sample alignment (0 = default) + * @return >=0 on success, negative error code on failure + * @todo return the size in bytes required to store the samples in + * case of success, at the next libavutil bump + */ +int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, + enum AVSampleFormat sample_fmt, const uint8_t *buf, + int buf_size, int align); + +/** + * Reset the internal codec state / flush internal buffers. Should be called + * e.g. when seeking or when switching to a different stream. + * + * @note for decoders, when refcounted frames are not used + * (i.e. avctx->refcounted_frames is 0), this invalidates the frames previously + * returned from the decoder. When refcounted frames are used, the decoder just + * releases any references it might keep internally, but the caller's reference + * remains valid. + * + * @note for encoders, this function will only do something if the encoder + * declares support for AV_CODEC_CAP_ENCODER_FLUSH. When called, the encoder + * will drain any remaining packets, and can then be re-used for a different + * stream (as opposed to sending a null frame which will leave the encoder + * in a permanent EOF state after draining). This can be desirable if the + * cost of tearing down and replacing the encoder instance is high. + */ +void avcodec_flush_buffers(AVCodecContext *avctx); + +/** + * Return codec bits per sample. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_bits_per_sample(enum AVCodecID codec_id); + +/** + * Return the PCM codec associated with a sample format. + * @param be endianness, 0 for little, 1 for big, + * -1 (or anything else) for native + * @return AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE + */ +enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be); + +/** + * Return codec bits per sample. + * Only return non-zero if the bits per sample is exactly correct, not an + * approximation. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_exact_bits_per_sample(enum AVCodecID codec_id); + +/** + * Return audio frame duration. + * + * @param avctx codec context + * @param frame_bytes size of the frame, or 0 if unknown + * @return frame duration, in samples, if known. 0 if not able to + * determine. + */ +int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes); + +/** + * This function is the same as av_get_audio_frame_duration(), except it works + * with AVCodecParameters instead of an AVCodecContext. + */ +int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes); + +#if FF_API_OLD_BSF +typedef struct AVBitStreamFilterContext { + void *priv_data; + const struct AVBitStreamFilter *filter; + AVCodecParserContext *parser; + struct AVBitStreamFilterContext *next; + /** + * Internal default arguments, used if NULL is passed to av_bitstream_filter_filter(). + * Not for access by library users. + */ + char *args; +} AVBitStreamFilterContext; + +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use the new bitstream filtering API (using AVBSFContext). + */ +attribute_deprecated +void av_register_bitstream_filter(AVBitStreamFilter *bsf); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_get_by_name(), av_bsf_alloc(), and av_bsf_init() + * from the new bitstream filtering API (using AVBSFContext). + */ +attribute_deprecated +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_send_packet() and av_bsf_receive_packet() from the + * new bitstream filtering API (using AVBSFContext). + */ +attribute_deprecated +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_free() from the new bitstream filtering API (using + * AVBSFContext). + */ +attribute_deprecated +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); +/** + * @deprecated the old bitstream filtering API (using AVBitStreamFilterContext) + * is deprecated. Use av_bsf_iterate() from the new bitstream filtering API (using + * AVBSFContext). + */ +attribute_deprecated +const AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f); +#endif + +#if FF_API_NEXT +attribute_deprecated +const AVBitStreamFilter *av_bsf_next(void **opaque); +#endif + +/* memory */ + +/** + * Same behaviour av_fast_malloc but the buffer has additional + * AV_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0. + * + * In addition the whole buffer will initially and after resizes + * be 0-initialized so that no uninitialized data will ever appear. + */ +void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Same behaviour av_fast_padded_malloc except that buffer will always + * be 0-initialized after call. + */ +void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size); + +/** + * Encode extradata length to a buffer. Used by xiph codecs. + * + * @param s buffer to write to; must be at least (v/255+1) bytes long + * @param v size of extradata in bytes + * @return number of bytes written to the buffer. + */ +unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + +#if FF_API_USER_VISIBLE_AVHWACCEL +/** + * Register the hardware accelerator hwaccel. + * + * @deprecated This function doesn't do anything. + */ +attribute_deprecated +void av_register_hwaccel(AVHWAccel *hwaccel); + +/** + * If hwaccel is NULL, returns the first registered hardware accelerator, + * if hwaccel is non-NULL, returns the next registered hardware accelerator + * after hwaccel, or NULL if hwaccel is the last one. + * + * @deprecated AVHWaccel structures contain no user-serviceable parts, so + * this function should not be used. + */ +attribute_deprecated +AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel); +#endif + +#if FF_API_LOCKMGR +/** + * Lock operation used by lockmgr + * + * @deprecated Deprecated together with av_lockmgr_register(). + */ +enum AVLockOp { + AV_LOCK_CREATE, ///< Create a mutex + AV_LOCK_OBTAIN, ///< Lock the mutex + AV_LOCK_RELEASE, ///< Unlock the mutex + AV_LOCK_DESTROY, ///< Free mutex resources +}; + +/** + * Register a user provided lock manager supporting the operations + * specified by AVLockOp. The "mutex" argument to the function points + * to a (void *) where the lockmgr should store/get a pointer to a user + * allocated mutex. It is NULL upon AV_LOCK_CREATE and equal to the + * value left by the last call for all other ops. If the lock manager is + * unable to perform the op then it should leave the mutex in the same + * state as when it was called and return a non-zero value. However, + * when called with AV_LOCK_DESTROY the mutex will always be assumed to + * have been successfully destroyed. If av_lockmgr_register succeeds + * it will return a non-negative value, if it fails it will return a + * negative value and destroy all mutex and unregister all callbacks. + * av_lockmgr_register is not thread-safe, it must be called from a + * single thread before any calls which make use of locking are used. + * + * @param cb User defined callback. av_lockmgr_register invokes calls + * to this callback and the previously registered callback. + * The callback will be used to create more than one mutex + * each of which must be backed by its own underlying locking + * mechanism (i.e. do not use a single static object to + * implement your lock manager). If cb is set to NULL the + * lockmgr will be unregistered. + * + * @deprecated This function does nothing, and always returns 0. Be sure to + * build with thread support to get basic thread safety. + */ +attribute_deprecated +int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); +#endif + +/** + * @return a positive value if s is open (i.e. avcodec_open2() was called on it + * with no corresponding avcodec_close()), 0 otherwise. + */ +int avcodec_is_open(AVCodecContext *s); + +/** + * Allocate a CPB properties structure and initialize its fields to default + * values. + * + * @param size if non-NULL, the size of the allocated struct will be written + * here. This is useful for embedding it in side data. + * + * @return the newly allocated struct or NULL on failure + */ +AVCPBProperties *av_cpb_properties_alloc(size_t *size); + +/** + * @} + */ + +#endif /* AVCODEC_AVCODEC_H */ diff --git a/ffmpeg/inc/libavcodec/avdct.h b/ffmpeg/inc/libavcodec/avdct.h new file mode 100644 index 0000000..6411fab --- /dev/null +++ b/ffmpeg/inc/libavcodec/avdct.h @@ -0,0 +1,88 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVDCT_H +#define AVCODEC_AVDCT_H + +#include "libavutil/opt.h" + +/** + * AVDCT context. + * @note function pointers can be NULL if the specific features have been + * disabled at build time. + */ +typedef struct AVDCT { + const AVClass *av_class; + + void (*idct)(int16_t *block /* align 16 */); + + /** + * IDCT input permutation. + * Several optimized IDCTs need a permutated input (relative to the + * normal order of the reference IDCT). + * This permutation must be performed before the idct_put/add. + * Note, normally this can be merged with the zigzag/alternate scan
+ * An example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference IDCT -> ...) + * - (x -> reference DCT -> reference IDCT -> x) + * - (x -> reference DCT -> simple_mmx_perm = idct_permutation + * -> simple_idct_mmx -> x) + * - (-> decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant + * -> simple_idct_mmx -> ...) + */ + uint8_t idct_permutation[64]; + + void (*fdct)(int16_t *block /* align 16 */); + + + /** + * DCT algorithm. + * must use AVOptions to set this field. + */ + int dct_algo; + + /** + * IDCT algorithm. + * must use AVOptions to set this field. + */ + int idct_algo; + + void (*get_pixels)(int16_t *block /* align 16 */, + const uint8_t *pixels /* align 8 */, + ptrdiff_t line_size); + + int bits_per_sample; + + void (*get_pixels_unaligned)(int16_t *block /* align 16 */, + const uint8_t *pixels, + ptrdiff_t line_size); +} AVDCT; + +/** + * Allocates a AVDCT context. + * This needs to be initialized with avcodec_dct_init() after optionally + * configuring it with AVOptions. + * + * To free it use av_free() + */ +AVDCT *avcodec_dct_alloc(void); +int avcodec_dct_init(AVDCT *); + +const AVClass *avcodec_dct_get_class(void); + +#endif /* AVCODEC_AVDCT_H */ diff --git a/ffmpeg/inc/libavcodec/avfft.h b/ffmpeg/inc/libavcodec/avfft.h new file mode 100644 index 0000000..0c0f9b8 --- /dev/null +++ b/ffmpeg/inc/libavcodec/avfft.h @@ -0,0 +1,118 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVFFT_H +#define AVCODEC_AVFFT_H + +/** + * @file + * @ingroup lavc_fft + * FFT functions + */ + +/** + * @defgroup lavc_fft FFT functions + * @ingroup lavc_misc + * + * @{ + */ + +typedef float FFTSample; + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef struct FFTContext FFTContext; + +/** + * Set up a complex FFT. + * @param nbits log2 of the length of the input array + * @param inverse if 0 perform the forward transform, if 1 perform the inverse + */ +FFTContext *av_fft_init(int nbits, int inverse); + +/** + * Do the permutation needed BEFORE calling ff_fft_calc(). + */ +void av_fft_permute(FFTContext *s, FFTComplex *z); + +/** + * Do a complex FFT with the parameters defined in av_fft_init(). The + * input data must be permuted before. No 1.0/sqrt(n) normalization is done. + */ +void av_fft_calc(FFTContext *s, FFTComplex *z); + +void av_fft_end(FFTContext *s); + +FFTContext *av_mdct_init(int nbits, int inverse, double scale); +void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); +void av_mdct_end(FFTContext *s); + +/* Real Discrete Fourier Transform */ + +enum RDFTransformType { + DFT_R2C, + IDFT_C2R, + IDFT_R2C, + DFT_C2R, +}; + +typedef struct RDFTContext RDFTContext; + +/** + * Set up a real FFT. + * @param nbits log2 of the length of the input array + * @param trans the type of transform + */ +RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans); +void av_rdft_calc(RDFTContext *s, FFTSample *data); +void av_rdft_end(RDFTContext *s); + +/* Discrete Cosine Transform */ + +typedef struct DCTContext DCTContext; + +enum DCTTransformType { + DCT_II = 0, + DCT_III, + DCT_I, + DST_I, +}; + +/** + * Set up DCT. + * + * @param nbits size of the input array: + * (1 << nbits) for DCT-II, DCT-III and DST-I + * (1 << nbits) + 1 for DCT-I + * @param type the type of transform + * + * @note the first element of the input of DST-I is ignored + */ +DCTContext *av_dct_init(int nbits, enum DCTTransformType type); +void av_dct_calc(DCTContext *s, FFTSample *data); +void av_dct_end (DCTContext *s); + +/** + * @} + */ + +#endif /* AVCODEC_AVFFT_H */ diff --git a/ffmpeg/inc/libavcodec/bsf.h b/ffmpeg/inc/libavcodec/bsf.h new file mode 100644 index 0000000..7ed5167 --- /dev/null +++ b/ffmpeg/inc/libavcodec/bsf.h @@ -0,0 +1,325 @@ +/* + * Bitstream filters public API + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_BSF_H +#define AVCODEC_BSF_H + +#include "libavutil/dict.h" +#include "libavutil/log.h" +#include "libavutil/rational.h" + +#include "codec_id.h" +#include "codec_par.h" +#include "packet.h" + +/** + * @addtogroup lavc_core + * @{ + */ + +typedef struct AVBSFInternal AVBSFInternal; + +/** + * The bitstream filter state. + * + * This struct must be allocated with av_bsf_alloc() and freed with + * av_bsf_free(). + * + * The fields in the struct will only be changed (by the caller or by the + * filter) as described in their documentation, and are to be considered + * immutable otherwise. + */ +typedef struct AVBSFContext { + /** + * A class for logging and AVOptions + */ + const AVClass *av_class; + + /** + * The bitstream filter this context is an instance of. + */ + const struct AVBitStreamFilter *filter; + + /** + * Opaque libavcodec internal data. Must not be touched by the caller in any + * way. + */ + AVBSFInternal *internal; + + /** + * Opaque filter-specific private data. If filter->priv_class is non-NULL, + * this is an AVOptions-enabled struct. + */ + void *priv_data; + + /** + * Parameters of the input stream. This field is allocated in + * av_bsf_alloc(), it needs to be filled by the caller before + * av_bsf_init(). + */ + AVCodecParameters *par_in; + + /** + * Parameters of the output stream. This field is allocated in + * av_bsf_alloc(), it is set by the filter in av_bsf_init(). + */ + AVCodecParameters *par_out; + + /** + * The timebase used for the timestamps of the input packets. Set by the + * caller before av_bsf_init(). + */ + AVRational time_base_in; + + /** + * The timebase used for the timestamps of the output packets. Set by the + * filter in av_bsf_init(). + */ + AVRational time_base_out; +} AVBSFContext; + +typedef struct AVBitStreamFilter { + const char *name; + + /** + * A list of codec ids supported by the filter, terminated by + * AV_CODEC_ID_NONE. + * May be NULL, in that case the bitstream filter works with any codec id. + */ + const enum AVCodecID *codec_ids; + + /** + * A class for the private data, used to declare bitstream filter private + * AVOptions. This field is NULL for bitstream filters that do not declare + * any options. + * + * If this field is non-NULL, the first member of the filter private data + * must be a pointer to AVClass, which will be set by libavcodec generic + * code to this class. + */ + const AVClass *priv_class; + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavcodec and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + + int priv_data_size; + int (*init)(AVBSFContext *ctx); + int (*filter)(AVBSFContext *ctx, AVPacket *pkt); + void (*close)(AVBSFContext *ctx); + void (*flush)(AVBSFContext *ctx); +} AVBitStreamFilter; + +/** + * @return a bitstream filter with the specified name or NULL if no such + * bitstream filter exists. + */ +const AVBitStreamFilter *av_bsf_get_by_name(const char *name); + +/** + * Iterate over all registered bitstream filters. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered bitstream filter or NULL when the iteration is + * finished + */ +const AVBitStreamFilter *av_bsf_iterate(void **opaque); + +/** + * Allocate a context for a given bitstream filter. The caller must fill in the + * context parameters as described in the documentation and then call + * av_bsf_init() before sending any data to the filter. + * + * @param filter the filter for which to allocate an instance. + * @param ctx a pointer into which the pointer to the newly-allocated context + * will be written. It must be freed with av_bsf_free() after the + * filtering is done. + * + * @return 0 on success, a negative AVERROR code on failure + */ +int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx); + +/** + * Prepare the filter for use, after all the parameters and options have been + * set. + */ +int av_bsf_init(AVBSFContext *ctx); + +/** + * Submit a packet for filtering. + * + * After sending each packet, the filter must be completely drained by calling + * av_bsf_receive_packet() repeatedly until it returns AVERROR(EAGAIN) or + * AVERROR_EOF. + * + * @param pkt the packet to filter. The bitstream filter will take ownership of + * the packet and reset the contents of pkt. pkt is not touched if an error occurs. + * If pkt is empty (i.e. NULL, or pkt->data is NULL and pkt->side_data_elems zero), + * it signals the end of the stream (i.e. no more non-empty packets will be sent; + * sending more empty packets does nothing) and will cause the filter to output + * any packets it may have buffered internally. + * + * @return 0 on success. AVERROR(EAGAIN) if packets need to be retrieved from the + * filter (using av_bsf_receive_packet()) before new input can be consumed. Another + * negative AVERROR value if an error occurs. + */ +int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt); + +/** + * Retrieve a filtered packet. + * + * @param[out] pkt this struct will be filled with the contents of the filtered + * packet. It is owned by the caller and must be freed using + * av_packet_unref() when it is no longer needed. + * This parameter should be "clean" (i.e. freshly allocated + * with av_packet_alloc() or unreffed with av_packet_unref()) + * when this function is called. If this function returns + * successfully, the contents of pkt will be completely + * overwritten by the returned data. On failure, pkt is not + * touched. + * + * @return 0 on success. AVERROR(EAGAIN) if more packets need to be sent to the + * filter (using av_bsf_send_packet()) to get more output. AVERROR_EOF if there + * will be no further output from the filter. Another negative AVERROR value if + * an error occurs. + * + * @note one input packet may result in several output packets, so after sending + * a packet with av_bsf_send_packet(), this function needs to be called + * repeatedly until it stops returning 0. It is also possible for a filter to + * output fewer packets than were sent to it, so this function may return + * AVERROR(EAGAIN) immediately after a successful av_bsf_send_packet() call. + */ +int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt); + +/** + * Reset the internal bitstream filter state / flush internal buffers. + */ +void av_bsf_flush(AVBSFContext *ctx); + +/** + * Free a bitstream filter context and everything associated with it; write NULL + * into the supplied pointer. + */ +void av_bsf_free(AVBSFContext **ctx); + +/** + * Get the AVClass for AVBSFContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *av_bsf_get_class(void); + +/** + * Structure for chain/list of bitstream filters. + * Empty list can be allocated by av_bsf_list_alloc(). + */ +typedef struct AVBSFList AVBSFList; + +/** + * Allocate empty list of bitstream filters. + * The list must be later freed by av_bsf_list_free() + * or finalized by av_bsf_list_finalize(). + * + * @return Pointer to @ref AVBSFList on success, NULL in case of failure + */ +AVBSFList *av_bsf_list_alloc(void); + +/** + * Free list of bitstream filters. + * + * @param lst Pointer to pointer returned by av_bsf_list_alloc() + */ +void av_bsf_list_free(AVBSFList **lst); + +/** + * Append bitstream filter to the list of bitstream filters. + * + * @param lst List to append to + * @param bsf Filter context to be appended + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_append(AVBSFList *lst, AVBSFContext *bsf); + +/** + * Construct new bitstream filter context given it's name and options + * and append it to the list of bitstream filters. + * + * @param lst List to append to + * @param bsf_name Name of the bitstream filter + * @param options Options for the bitstream filter, can be set to NULL + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_append2(AVBSFList *lst, const char * bsf_name, AVDictionary **options); +/** + * Finalize list of bitstream filters. + * + * This function will transform @ref AVBSFList to single @ref AVBSFContext, + * so the whole chain of bitstream filters can be treated as single filter + * freshly allocated by av_bsf_alloc(). + * If the call is successful, @ref AVBSFList structure is freed and lst + * will be set to NULL. In case of failure, caller is responsible for + * freeing the structure by av_bsf_list_free() + * + * @param lst Filter list structure to be transformed + * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext structure + * representing the chain of bitstream filters + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_finalize(AVBSFList **lst, AVBSFContext **bsf); + +/** + * Parse string describing list of bitstream filters and create single + * @ref AVBSFContext describing the whole chain of bitstream filters. + * Resulting @ref AVBSFContext can be treated as any other @ref AVBSFContext freshly + * allocated by av_bsf_alloc(). + * + * @param str String describing chain of bitstream filters in format + * `bsf1[=opt1=val1:opt2=val2][,bsf2]` + * @param[out] bsf Pointer to be set to newly created @ref AVBSFContext structure + * representing the chain of bitstream filters + * + * @return >=0 on success, negative AVERROR in case of failure + */ +int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf); + +/** + * Get null/pass-through bitstream filter. + * + * @param[out] bsf Pointer to be set to new instance of pass-through bitstream filter + * + * @return + */ +int av_bsf_get_null_filter(AVBSFContext **bsf); + +/** + * @} + */ + +#endif // AVCODEC_BSF_H diff --git a/ffmpeg/inc/libavcodec/codec.h b/ffmpeg/inc/libavcodec/codec.h new file mode 100644 index 0000000..1fda619 --- /dev/null +++ b/ffmpeg/inc/libavcodec/codec.h @@ -0,0 +1,462 @@ +/* + * AVCodec public API + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CODEC_H +#define AVCODEC_CODEC_H + +#include + +#include "libavutil/avutil.h" +#include "libavutil/hwcontext.h" +#include "libavutil/log.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" +#include "libavutil/samplefmt.h" + +#include "libavcodec/codec_id.h" +#include "libavcodec/version.h" + +/** + * @addtogroup lavc_core + * @{ + */ + +/** + * Decoder can use draw_horiz_band callback. + */ +#define AV_CODEC_CAP_DRAW_HORIZ_BAND (1 << 0) +/** + * Codec uses get_buffer() for allocating buffers and supports custom allocators. + * If not set, it might not use get_buffer() at all or use operations that + * assume the buffer was allocated by avcodec_default_get_buffer. + */ +#define AV_CODEC_CAP_DR1 (1 << 1) +#define AV_CODEC_CAP_TRUNCATED (1 << 3) +/** + * Encoder or decoder requires flushing with NULL input at the end in order to + * give the complete and correct output. + * + * NOTE: If this flag is not set, the codec is guaranteed to never be fed with + * with NULL data. The user can still send NULL data to the public encode + * or decode function, but libavcodec will not pass it along to the codec + * unless this flag is set. + * + * Decoders: + * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL, + * avpkt->size=0 at the end to get the delayed data until the decoder no longer + * returns frames. + * + * Encoders: + * The encoder needs to be fed with NULL data at the end of encoding until the + * encoder no longer returns data. + * + * NOTE: For encoders implementing the AVCodec.encode2() function, setting this + * flag also means that the encoder must set the pts and duration for + * each output packet. If this flag is not set, the pts and duration will + * be determined by libavcodec from the input frame. + */ +#define AV_CODEC_CAP_DELAY (1 << 5) +/** + * Codec can be fed a final frame with a smaller size. + * This can be used to prevent truncation of the last audio samples. + */ +#define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6) + +/** + * Codec can output multiple frames per AVPacket + * Normally demuxers return one frame at a time, demuxers which do not do + * are connected to a parser to split what they return into proper frames. + * This flag is reserved to the very rare category of codecs which have a + * bitstream that cannot be split into frames without timeconsuming + * operations like full decoding. Demuxers carrying such bitstreams thus + * may return multiple frames in a packet. This has many disadvantages like + * prohibiting stream copy in many cases thus it should only be considered + * as a last resort. + */ +#define AV_CODEC_CAP_SUBFRAMES (1 << 8) +/** + * Codec is experimental and is thus avoided in favor of non experimental + * encoders + */ +#define AV_CODEC_CAP_EXPERIMENTAL (1 << 9) +/** + * Codec should fill in channel configuration and samplerate instead of container + */ +#define AV_CODEC_CAP_CHANNEL_CONF (1 << 10) +/** + * Codec supports frame-level multithreading. + */ +#define AV_CODEC_CAP_FRAME_THREADS (1 << 12) +/** + * Codec supports slice-based (or partition-based) multithreading. + */ +#define AV_CODEC_CAP_SLICE_THREADS (1 << 13) +/** + * Codec supports changed parameters at any point. + */ +#define AV_CODEC_CAP_PARAM_CHANGE (1 << 14) +/** + * Codec supports avctx->thread_count == 0 (auto). + */ +#define AV_CODEC_CAP_AUTO_THREADS (1 << 15) +/** + * Audio encoder supports receiving a different number of samples in each call. + */ +#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE (1 << 16) +/** + * Decoder is not a preferred choice for probing. + * This indicates that the decoder is not a good choice for probing. + * It could for example be an expensive to spin up hardware decoder, + * or it could simply not provide a lot of useful information about + * the stream. + * A decoder marked with this flag should only be used as last resort + * choice for probing. + */ +#define AV_CODEC_CAP_AVOID_PROBING (1 << 17) + +#if FF_API_UNUSED_CODEC_CAPS +/** + * Deprecated and unused. Use AVCodecDescriptor.props instead + */ +#define AV_CODEC_CAP_INTRA_ONLY 0x40000000 +/** + * Deprecated and unused. Use AVCodecDescriptor.props instead + */ +#define AV_CODEC_CAP_LOSSLESS 0x80000000 +#endif + +/** + * Codec is backed by a hardware implementation. Typically used to + * identify a non-hwaccel hardware decoder. For information about hwaccels, use + * avcodec_get_hw_config() instead. + */ +#define AV_CODEC_CAP_HARDWARE (1 << 18) + +/** + * Codec is potentially backed by a hardware implementation, but not + * necessarily. This is used instead of AV_CODEC_CAP_HARDWARE, if the + * implementation provides some sort of internal fallback. + */ +#define AV_CODEC_CAP_HYBRID (1 << 19) + +/** + * This codec takes the reordered_opaque field from input AVFrames + * and returns it in the corresponding field in AVCodecContext after + * encoding. + */ +#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20) + +/** + * This encoder can be flushed using avcodec_flush_buffers(). If this flag is + * not set, the encoder must be closed and reopened to ensure that no frames + * remain pending. + */ +#define AV_CODEC_CAP_ENCODER_FLUSH (1 << 21) + +/** + * AVProfile. + */ +typedef struct AVProfile { + int profile; + const char *name; ///< short name for the profile +} AVProfile; + +typedef struct AVCodecDefault AVCodecDefault; + +struct AVCodecContext; +struct AVSubtitle; +struct AVPacket; + +/** + * AVCodec. + */ +typedef struct AVCodec { + /** + * Name of the codec implementation. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + * This is the primary way to find a codec from the user perspective. + */ + const char *name; + /** + * Descriptive name for the codec, meant to be more human readable than name. + * You should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *long_name; + enum AVMediaType type; + enum AVCodecID id; + /** + * Codec capabilities. + * see AV_CODEC_CAP_* + */ + int capabilities; + const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} + const enum AVPixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 + const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 + const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 + uint8_t max_lowres; ///< maximum value for lowres supported by the decoder + const AVClass *priv_class; ///< AVClass for the private context + const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN} + + /** + * Group name of the codec implementation. + * This is a short symbolic name of the wrapper backing this codec. A + * wrapper uses some kind of external implementation for the codec, such + * as an external library, or a codec implementation provided by the OS or + * the hardware. + * If this field is NULL, this is a builtin, libavcodec native codec. + * If non-NULL, this will be the suffix in AVCodec.name in most cases + * (usually AVCodec.name will be of the form "_"). + */ + const char *wrapper_name; + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavcodec and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + int priv_data_size; + struct AVCodec *next; + /** + * @name Frame-level threading support functions + * @{ + */ + /** + * Copy necessary context variables from a previous thread context to the current one. + * If not defined, the next thread will start automatically; otherwise, the codec + * must call ff_thread_finish_setup(). + * + * dst and src will (rarely) point to the same context, in which case memcpy should be skipped. + */ + int (*update_thread_context)(struct AVCodecContext *dst, const struct AVCodecContext *src); + /** @} */ + + /** + * Private codec-specific defaults. + */ + const AVCodecDefault *defaults; + + /** + * Initialize codec static data, called from avcodec_register(). + * + * This is not intended for time consuming operations as it is + * run for every codec regardless of that codec being used. + */ + void (*init_static_data)(struct AVCodec *codec); + + int (*init)(struct AVCodecContext *); + int (*encode_sub)(struct AVCodecContext *, uint8_t *buf, int buf_size, + const struct AVSubtitle *sub); + /** + * Encode data to an AVPacket. + * + * @param avctx codec context + * @param avpkt output AVPacket (may contain a user-provided buffer) + * @param[in] frame AVFrame containing the raw data to be encoded + * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a + * non-empty packet was returned in avpkt. + * @return 0 on success, negative error code on failure + */ + int (*encode2)(struct AVCodecContext *avctx, struct AVPacket *avpkt, + const struct AVFrame *frame, int *got_packet_ptr); + int (*decode)(struct AVCodecContext *, void *outdata, int *outdata_size, struct AVPacket *avpkt); + int (*close)(struct AVCodecContext *); + /** + * Encode API with decoupled packet/frame dataflow. The API is the + * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except + * that: + * - never called if the codec is closed or the wrong type, + * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent, + * - only one drain frame is ever passed down, + */ + int (*send_frame)(struct AVCodecContext *avctx, const struct AVFrame *frame); + int (*receive_packet)(struct AVCodecContext *avctx, struct AVPacket *avpkt); + + /** + * Decode API with decoupled packet/frame dataflow. This function is called + * to get one output frame. It should call ff_decode_get_packet() to obtain + * input data. + */ + int (*receive_frame)(struct AVCodecContext *avctx, struct AVFrame *frame); + /** + * Flush buffers. + * Will be called when seeking + */ + void (*flush)(struct AVCodecContext *); + /** + * Internal codec capabilities. + * See FF_CODEC_CAP_* in internal.h + */ + int caps_internal; + + /** + * Decoding only, a comma-separated list of bitstream filters to apply to + * packets before decoding. + */ + const char *bsfs; + + /** + * Array of pointers to hardware configurations supported by the codec, + * or NULL if no hardware supported. The array is terminated by a NULL + * pointer. + * + * The user can only access this field via avcodec_get_hw_config(). + */ + const struct AVCodecHWConfigInternal **hw_configs; + + /** + * List of supported codec_tags, terminated by FF_CODEC_TAGS_END. + */ + const uint32_t *codec_tags; +} AVCodec; + +/** + * Iterate over all registered codecs. + * + * @param opaque a pointer where libavcodec will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered codec or NULL when the iteration is + * finished + */ +const AVCodec *av_codec_iterate(void **opaque); + +/** + * Find a registered decoder with a matching codec ID. + * + * @param id AVCodecID of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder(enum AVCodecID id); + +/** + * Find a registered decoder with the specified name. + * + * @param name name of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder_by_name(const char *name); + +/** + * Find a registered encoder with a matching codec ID. + * + * @param id AVCodecID of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder(enum AVCodecID id); + +/** + * Find a registered encoder with the specified name. + * + * @param name name of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder_by_name(const char *name); +/** + * @return a non-zero number if codec is an encoder, zero otherwise + */ +int av_codec_is_encoder(const AVCodec *codec); + +/** + * @return a non-zero number if codec is a decoder, zero otherwise + */ +int av_codec_is_decoder(const AVCodec *codec); + +enum { + /** + * The codec supports this format via the hw_device_ctx interface. + * + * When selecting this format, AVCodecContext.hw_device_ctx should + * have been set to a device of the specified type before calling + * avcodec_open2(). + */ + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01, + /** + * The codec supports this format via the hw_frames_ctx interface. + * + * When selecting this format for a decoder, + * AVCodecContext.hw_frames_ctx should be set to a suitable frames + * context inside the get_format() callback. The frames context + * must have been created on a device of the specified type. + * + * When selecting this format for an encoder, + * AVCodecContext.hw_frames_ctx should be set to the context which + * will be used for the input frames before calling avcodec_open2(). + */ + AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX = 0x02, + /** + * The codec supports this format by some internal method. + * + * This format can be selected without any additional configuration - + * no device or frames context is required. + */ + AV_CODEC_HW_CONFIG_METHOD_INTERNAL = 0x04, + /** + * The codec supports this format by some ad-hoc method. + * + * Additional settings and/or function calls are required. See the + * codec-specific documentation for details. (Methods requiring + * this sort of configuration are deprecated and others should be + * used in preference.) + */ + AV_CODEC_HW_CONFIG_METHOD_AD_HOC = 0x08, +}; + +typedef struct AVCodecHWConfig { + /** + * For decoders, a hardware pixel format which that decoder may be + * able to decode to if suitable hardware is available. + * + * For encoders, a pixel format which the encoder may be able to + * accept. If set to AV_PIX_FMT_NONE, this applies to all pixel + * formats supported by the codec. + */ + enum AVPixelFormat pix_fmt; + /** + * Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible + * setup methods which can be used with this configuration. + */ + int methods; + /** + * The device type associated with the configuration. + * + * Must be set for AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX and + * AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX, otherwise unused. + */ + enum AVHWDeviceType device_type; +} AVCodecHWConfig; + +/** + * Retrieve supported hardware configurations for a codec. + * + * Values of index from zero to some maximum return the indexed configuration + * descriptor; all other values return NULL. If the codec does not support + * any hardware configurations then it will always return NULL. + */ +const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index); + +/** + * @} + */ + +#endif /* AVCODEC_CODEC_H */ diff --git a/ffmpeg/inc/libavcodec/codec_desc.h b/ffmpeg/inc/libavcodec/codec_desc.h new file mode 100644 index 0000000..126b52d --- /dev/null +++ b/ffmpeg/inc/libavcodec/codec_desc.h @@ -0,0 +1,128 @@ +/* + * Codec descriptors public API + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CODEC_DESC_H +#define AVCODEC_CODEC_DESC_H + +#include "libavutil/avutil.h" + +#include "codec_id.h" + +/** + * @addtogroup lavc_core + * @{ + */ + +/** + * This struct describes the properties of a single codec described by an + * AVCodecID. + * @see avcodec_descriptor_get() + */ +typedef struct AVCodecDescriptor { + enum AVCodecID id; + enum AVMediaType type; + /** + * Name of the codec described by this descriptor. It is non-empty and + * unique for each codec descriptor. It should contain alphanumeric + * characters and '_' only. + */ + const char *name; + /** + * A more descriptive name for this codec. May be NULL. + */ + const char *long_name; + /** + * Codec properties, a combination of AV_CODEC_PROP_* flags. + */ + int props; + /** + * MIME type(s) associated with the codec. + * May be NULL; if not, a NULL-terminated array of MIME types. + * The first item is always non-NULL and is the preferred MIME type. + */ + const char *const *mime_types; + /** + * If non-NULL, an array of profiles recognized for this codec. + * Terminated with FF_PROFILE_UNKNOWN. + */ + const struct AVProfile *profiles; +} AVCodecDescriptor; + +/** + * Codec uses only intra compression. + * Video and audio codecs only. + */ +#define AV_CODEC_PROP_INTRA_ONLY (1 << 0) +/** + * Codec supports lossy compression. Audio and video codecs only. + * @note a codec may support both lossy and lossless + * compression modes + */ +#define AV_CODEC_PROP_LOSSY (1 << 1) +/** + * Codec supports lossless compression. Audio and video codecs only. + */ +#define AV_CODEC_PROP_LOSSLESS (1 << 2) +/** + * Codec supports frame reordering. That is, the coded order (the order in which + * the encoded packets are output by the encoders / stored / input to the + * decoders) may be different from the presentation order of the corresponding + * frames. + * + * For codecs that do not have this property set, PTS and DTS should always be + * equal. + */ +#define AV_CODEC_PROP_REORDER (1 << 3) +/** + * Subtitle codec is bitmap based + * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field. + */ +#define AV_CODEC_PROP_BITMAP_SUB (1 << 16) +/** + * Subtitle codec is text based. + * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field. + */ +#define AV_CODEC_PROP_TEXT_SUB (1 << 17) + +/** + * @return descriptor for given codec ID or NULL if no descriptor exists. + */ +const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id); + +/** + * Iterate over all codec descriptors known to libavcodec. + * + * @param prev previous descriptor. NULL to get the first descriptor. + * + * @return next descriptor or NULL after the last descriptor + */ +const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev); + +/** + * @return codec descriptor with the given name or NULL if no such descriptor + * exists. + */ +const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name); + +/** + * @} + */ + +#endif // AVCODEC_CODEC_DESC_H diff --git a/ffmpeg/inc/libavcodec/codec_id.h b/ffmpeg/inc/libavcodec/codec_id.h new file mode 100644 index 0000000..d885962 --- /dev/null +++ b/ffmpeg/inc/libavcodec/codec_id.h @@ -0,0 +1,577 @@ +/* + * Codec IDs + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CODEC_ID_H +#define AVCODEC_CODEC_ID_H + +#include "libavutil/avutil.h" + +/** + * @addtogroup lavc_core + * @{ + */ + +/** + * Identify the syntax and semantics of the bitstream. + * The principle is roughly: + * Two decoders with the same ID can decode the same streams. + * Two encoders with the same ID can encode compatible streams. + * There may be slight deviations from the principle due to implementation + * details. + * + * If you add a codec ID to this list, add it so that + * 1. no value of an existing codec ID changes (that would break ABI), + * 2. it is as close as possible to similar codecs + * + * After adding new codec IDs, do not forget to add an entry to the codec + * descriptor list and bump libavcodec minor version. + */ +enum AVCodecID { + AV_CODEC_ID_NONE, + + /* video codecs */ + AV_CODEC_ID_MPEG1VIDEO, + AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding + AV_CODEC_ID_H261, + AV_CODEC_ID_H263, + AV_CODEC_ID_RV10, + AV_CODEC_ID_RV20, + AV_CODEC_ID_MJPEG, + AV_CODEC_ID_MJPEGB, + AV_CODEC_ID_LJPEG, + AV_CODEC_ID_SP5X, + AV_CODEC_ID_JPEGLS, + AV_CODEC_ID_MPEG4, + AV_CODEC_ID_RAWVIDEO, + AV_CODEC_ID_MSMPEG4V1, + AV_CODEC_ID_MSMPEG4V2, + AV_CODEC_ID_MSMPEG4V3, + AV_CODEC_ID_WMV1, + AV_CODEC_ID_WMV2, + AV_CODEC_ID_H263P, + AV_CODEC_ID_H263I, + AV_CODEC_ID_FLV1, + AV_CODEC_ID_SVQ1, + AV_CODEC_ID_SVQ3, + AV_CODEC_ID_DVVIDEO, + AV_CODEC_ID_HUFFYUV, + AV_CODEC_ID_CYUV, + AV_CODEC_ID_H264, + AV_CODEC_ID_INDEO3, + AV_CODEC_ID_VP3, + AV_CODEC_ID_THEORA, + AV_CODEC_ID_ASV1, + AV_CODEC_ID_ASV2, + AV_CODEC_ID_FFV1, + AV_CODEC_ID_4XM, + AV_CODEC_ID_VCR1, + AV_CODEC_ID_CLJR, + AV_CODEC_ID_MDEC, + AV_CODEC_ID_ROQ, + AV_CODEC_ID_INTERPLAY_VIDEO, + AV_CODEC_ID_XAN_WC3, + AV_CODEC_ID_XAN_WC4, + AV_CODEC_ID_RPZA, + AV_CODEC_ID_CINEPAK, + AV_CODEC_ID_WS_VQA, + AV_CODEC_ID_MSRLE, + AV_CODEC_ID_MSVIDEO1, + AV_CODEC_ID_IDCIN, + AV_CODEC_ID_8BPS, + AV_CODEC_ID_SMC, + AV_CODEC_ID_FLIC, + AV_CODEC_ID_TRUEMOTION1, + AV_CODEC_ID_VMDVIDEO, + AV_CODEC_ID_MSZH, + AV_CODEC_ID_ZLIB, + AV_CODEC_ID_QTRLE, + AV_CODEC_ID_TSCC, + AV_CODEC_ID_ULTI, + AV_CODEC_ID_QDRAW, + AV_CODEC_ID_VIXL, + AV_CODEC_ID_QPEG, + AV_CODEC_ID_PNG, + AV_CODEC_ID_PPM, + AV_CODEC_ID_PBM, + AV_CODEC_ID_PGM, + AV_CODEC_ID_PGMYUV, + AV_CODEC_ID_PAM, + AV_CODEC_ID_FFVHUFF, + AV_CODEC_ID_RV30, + AV_CODEC_ID_RV40, + AV_CODEC_ID_VC1, + AV_CODEC_ID_WMV3, + AV_CODEC_ID_LOCO, + AV_CODEC_ID_WNV1, + AV_CODEC_ID_AASC, + AV_CODEC_ID_INDEO2, + AV_CODEC_ID_FRAPS, + AV_CODEC_ID_TRUEMOTION2, + AV_CODEC_ID_BMP, + AV_CODEC_ID_CSCD, + AV_CODEC_ID_MMVIDEO, + AV_CODEC_ID_ZMBV, + AV_CODEC_ID_AVS, + AV_CODEC_ID_SMACKVIDEO, + AV_CODEC_ID_NUV, + AV_CODEC_ID_KMVC, + AV_CODEC_ID_FLASHSV, + AV_CODEC_ID_CAVS, + AV_CODEC_ID_JPEG2000, + AV_CODEC_ID_VMNC, + AV_CODEC_ID_VP5, + AV_CODEC_ID_VP6, + AV_CODEC_ID_VP6F, + AV_CODEC_ID_TARGA, + AV_CODEC_ID_DSICINVIDEO, + AV_CODEC_ID_TIERTEXSEQVIDEO, + AV_CODEC_ID_TIFF, + AV_CODEC_ID_GIF, + AV_CODEC_ID_DXA, + AV_CODEC_ID_DNXHD, + AV_CODEC_ID_THP, + AV_CODEC_ID_SGI, + AV_CODEC_ID_C93, + AV_CODEC_ID_BETHSOFTVID, + AV_CODEC_ID_PTX, + AV_CODEC_ID_TXD, + AV_CODEC_ID_VP6A, + AV_CODEC_ID_AMV, + AV_CODEC_ID_VB, + AV_CODEC_ID_PCX, + AV_CODEC_ID_SUNRAST, + AV_CODEC_ID_INDEO4, + AV_CODEC_ID_INDEO5, + AV_CODEC_ID_MIMIC, + AV_CODEC_ID_RL2, + AV_CODEC_ID_ESCAPE124, + AV_CODEC_ID_DIRAC, + AV_CODEC_ID_BFI, + AV_CODEC_ID_CMV, + AV_CODEC_ID_MOTIONPIXELS, + AV_CODEC_ID_TGV, + AV_CODEC_ID_TGQ, + AV_CODEC_ID_TQI, + AV_CODEC_ID_AURA, + AV_CODEC_ID_AURA2, + AV_CODEC_ID_V210X, + AV_CODEC_ID_TMV, + AV_CODEC_ID_V210, + AV_CODEC_ID_DPX, + AV_CODEC_ID_MAD, + AV_CODEC_ID_FRWU, + AV_CODEC_ID_FLASHSV2, + AV_CODEC_ID_CDGRAPHICS, + AV_CODEC_ID_R210, + AV_CODEC_ID_ANM, + AV_CODEC_ID_BINKVIDEO, + AV_CODEC_ID_IFF_ILBM, +#define AV_CODEC_ID_IFF_BYTERUN1 AV_CODEC_ID_IFF_ILBM + AV_CODEC_ID_KGV1, + AV_CODEC_ID_YOP, + AV_CODEC_ID_VP8, + AV_CODEC_ID_PICTOR, + AV_CODEC_ID_ANSI, + AV_CODEC_ID_A64_MULTI, + AV_CODEC_ID_A64_MULTI5, + AV_CODEC_ID_R10K, + AV_CODEC_ID_MXPEG, + AV_CODEC_ID_LAGARITH, + AV_CODEC_ID_PRORES, + AV_CODEC_ID_JV, + AV_CODEC_ID_DFA, + AV_CODEC_ID_WMV3IMAGE, + AV_CODEC_ID_VC1IMAGE, + AV_CODEC_ID_UTVIDEO, + AV_CODEC_ID_BMV_VIDEO, + AV_CODEC_ID_VBLE, + AV_CODEC_ID_DXTORY, + AV_CODEC_ID_V410, + AV_CODEC_ID_XWD, + AV_CODEC_ID_CDXL, + AV_CODEC_ID_XBM, + AV_CODEC_ID_ZEROCODEC, + AV_CODEC_ID_MSS1, + AV_CODEC_ID_MSA1, + AV_CODEC_ID_TSCC2, + AV_CODEC_ID_MTS2, + AV_CODEC_ID_CLLC, + AV_CODEC_ID_MSS2, + AV_CODEC_ID_VP9, + AV_CODEC_ID_AIC, + AV_CODEC_ID_ESCAPE130, + AV_CODEC_ID_G2M, + AV_CODEC_ID_WEBP, + AV_CODEC_ID_HNM4_VIDEO, + AV_CODEC_ID_HEVC, +#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC + AV_CODEC_ID_FIC, + AV_CODEC_ID_ALIAS_PIX, + AV_CODEC_ID_BRENDER_PIX, + AV_CODEC_ID_PAF_VIDEO, + AV_CODEC_ID_EXR, + AV_CODEC_ID_VP7, + AV_CODEC_ID_SANM, + AV_CODEC_ID_SGIRLE, + AV_CODEC_ID_MVC1, + AV_CODEC_ID_MVC2, + AV_CODEC_ID_HQX, + AV_CODEC_ID_TDSC, + AV_CODEC_ID_HQ_HQA, + AV_CODEC_ID_HAP, + AV_CODEC_ID_DDS, + AV_CODEC_ID_DXV, + AV_CODEC_ID_SCREENPRESSO, + AV_CODEC_ID_RSCC, + AV_CODEC_ID_AVS2, + + AV_CODEC_ID_Y41P = 0x8000, + AV_CODEC_ID_AVRP, + AV_CODEC_ID_012V, + AV_CODEC_ID_AVUI, + AV_CODEC_ID_AYUV, + AV_CODEC_ID_TARGA_Y216, + AV_CODEC_ID_V308, + AV_CODEC_ID_V408, + AV_CODEC_ID_YUV4, + AV_CODEC_ID_AVRN, + AV_CODEC_ID_CPIA, + AV_CODEC_ID_XFACE, + AV_CODEC_ID_SNOW, + AV_CODEC_ID_SMVJPEG, + AV_CODEC_ID_APNG, + AV_CODEC_ID_DAALA, + AV_CODEC_ID_CFHD, + AV_CODEC_ID_TRUEMOTION2RT, + AV_CODEC_ID_M101, + AV_CODEC_ID_MAGICYUV, + AV_CODEC_ID_SHEERVIDEO, + AV_CODEC_ID_YLC, + AV_CODEC_ID_PSD, + AV_CODEC_ID_PIXLET, + AV_CODEC_ID_SPEEDHQ, + AV_CODEC_ID_FMVC, + AV_CODEC_ID_SCPR, + AV_CODEC_ID_CLEARVIDEO, + AV_CODEC_ID_XPM, + AV_CODEC_ID_AV1, + AV_CODEC_ID_BITPACKED, + AV_CODEC_ID_MSCC, + AV_CODEC_ID_SRGC, + AV_CODEC_ID_SVG, + AV_CODEC_ID_GDV, + AV_CODEC_ID_FITS, + AV_CODEC_ID_IMM4, + AV_CODEC_ID_PROSUMER, + AV_CODEC_ID_MWSC, + AV_CODEC_ID_WCMV, + AV_CODEC_ID_RASC, + AV_CODEC_ID_HYMT, + AV_CODEC_ID_ARBC, + AV_CODEC_ID_AGM, + AV_CODEC_ID_LSCR, + AV_CODEC_ID_VP4, + AV_CODEC_ID_IMM5, + AV_CODEC_ID_MVDV, + AV_CODEC_ID_MVHA, + AV_CODEC_ID_CDTOONS, + AV_CODEC_ID_MV30, + AV_CODEC_ID_NOTCHLC, + AV_CODEC_ID_PFM, + + /* various PCM "codecs" */ + AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs + AV_CODEC_ID_PCM_S16LE = 0x10000, + AV_CODEC_ID_PCM_S16BE, + AV_CODEC_ID_PCM_U16LE, + AV_CODEC_ID_PCM_U16BE, + AV_CODEC_ID_PCM_S8, + AV_CODEC_ID_PCM_U8, + AV_CODEC_ID_PCM_MULAW, + AV_CODEC_ID_PCM_ALAW, + AV_CODEC_ID_PCM_S32LE, + AV_CODEC_ID_PCM_S32BE, + AV_CODEC_ID_PCM_U32LE, + AV_CODEC_ID_PCM_U32BE, + AV_CODEC_ID_PCM_S24LE, + AV_CODEC_ID_PCM_S24BE, + AV_CODEC_ID_PCM_U24LE, + AV_CODEC_ID_PCM_U24BE, + AV_CODEC_ID_PCM_S24DAUD, + AV_CODEC_ID_PCM_ZORK, + AV_CODEC_ID_PCM_S16LE_PLANAR, + AV_CODEC_ID_PCM_DVD, + AV_CODEC_ID_PCM_F32BE, + AV_CODEC_ID_PCM_F32LE, + AV_CODEC_ID_PCM_F64BE, + AV_CODEC_ID_PCM_F64LE, + AV_CODEC_ID_PCM_BLURAY, + AV_CODEC_ID_PCM_LXF, + AV_CODEC_ID_S302M, + AV_CODEC_ID_PCM_S8_PLANAR, + AV_CODEC_ID_PCM_S24LE_PLANAR, + AV_CODEC_ID_PCM_S32LE_PLANAR, + AV_CODEC_ID_PCM_S16BE_PLANAR, + + AV_CODEC_ID_PCM_S64LE = 0x10800, + AV_CODEC_ID_PCM_S64BE, + AV_CODEC_ID_PCM_F16LE, + AV_CODEC_ID_PCM_F24LE, + AV_CODEC_ID_PCM_VIDC, + + /* various ADPCM codecs */ + AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, + AV_CODEC_ID_ADPCM_IMA_WAV, + AV_CODEC_ID_ADPCM_IMA_DK3, + AV_CODEC_ID_ADPCM_IMA_DK4, + AV_CODEC_ID_ADPCM_IMA_WS, + AV_CODEC_ID_ADPCM_IMA_SMJPEG, + AV_CODEC_ID_ADPCM_MS, + AV_CODEC_ID_ADPCM_4XM, + AV_CODEC_ID_ADPCM_XA, + AV_CODEC_ID_ADPCM_ADX, + AV_CODEC_ID_ADPCM_EA, + AV_CODEC_ID_ADPCM_G726, + AV_CODEC_ID_ADPCM_CT, + AV_CODEC_ID_ADPCM_SWF, + AV_CODEC_ID_ADPCM_YAMAHA, + AV_CODEC_ID_ADPCM_SBPRO_4, + AV_CODEC_ID_ADPCM_SBPRO_3, + AV_CODEC_ID_ADPCM_SBPRO_2, + AV_CODEC_ID_ADPCM_THP, + AV_CODEC_ID_ADPCM_IMA_AMV, + AV_CODEC_ID_ADPCM_EA_R1, + AV_CODEC_ID_ADPCM_EA_R3, + AV_CODEC_ID_ADPCM_EA_R2, + AV_CODEC_ID_ADPCM_IMA_EA_SEAD, + AV_CODEC_ID_ADPCM_IMA_EA_EACS, + AV_CODEC_ID_ADPCM_EA_XAS, + AV_CODEC_ID_ADPCM_EA_MAXIS_XA, + AV_CODEC_ID_ADPCM_IMA_ISS, + AV_CODEC_ID_ADPCM_G722, + AV_CODEC_ID_ADPCM_IMA_APC, + AV_CODEC_ID_ADPCM_VIMA, + + AV_CODEC_ID_ADPCM_AFC = 0x11800, + AV_CODEC_ID_ADPCM_IMA_OKI, + AV_CODEC_ID_ADPCM_DTK, + AV_CODEC_ID_ADPCM_IMA_RAD, + AV_CODEC_ID_ADPCM_G726LE, + AV_CODEC_ID_ADPCM_THP_LE, + AV_CODEC_ID_ADPCM_PSX, + AV_CODEC_ID_ADPCM_AICA, + AV_CODEC_ID_ADPCM_IMA_DAT4, + AV_CODEC_ID_ADPCM_MTAF, + AV_CODEC_ID_ADPCM_AGM, + AV_CODEC_ID_ADPCM_ARGO, + AV_CODEC_ID_ADPCM_IMA_SSI, + AV_CODEC_ID_ADPCM_ZORK, + AV_CODEC_ID_ADPCM_IMA_APM, + AV_CODEC_ID_ADPCM_IMA_ALP, + AV_CODEC_ID_ADPCM_IMA_MTF, + AV_CODEC_ID_ADPCM_IMA_CUNNING, + + /* AMR */ + AV_CODEC_ID_AMR_NB = 0x12000, + AV_CODEC_ID_AMR_WB, + + /* RealAudio codecs*/ + AV_CODEC_ID_RA_144 = 0x13000, + AV_CODEC_ID_RA_288, + + /* various DPCM codecs */ + AV_CODEC_ID_ROQ_DPCM = 0x14000, + AV_CODEC_ID_INTERPLAY_DPCM, + AV_CODEC_ID_XAN_DPCM, + AV_CODEC_ID_SOL_DPCM, + + AV_CODEC_ID_SDX2_DPCM = 0x14800, + AV_CODEC_ID_GREMLIN_DPCM, + AV_CODEC_ID_DERF_DPCM, + + /* audio codecs */ + AV_CODEC_ID_MP2 = 0x15000, + AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 + AV_CODEC_ID_AAC, + AV_CODEC_ID_AC3, + AV_CODEC_ID_DTS, + AV_CODEC_ID_VORBIS, + AV_CODEC_ID_DVAUDIO, + AV_CODEC_ID_WMAV1, + AV_CODEC_ID_WMAV2, + AV_CODEC_ID_MACE3, + AV_CODEC_ID_MACE6, + AV_CODEC_ID_VMDAUDIO, + AV_CODEC_ID_FLAC, + AV_CODEC_ID_MP3ADU, + AV_CODEC_ID_MP3ON4, + AV_CODEC_ID_SHORTEN, + AV_CODEC_ID_ALAC, + AV_CODEC_ID_WESTWOOD_SND1, + AV_CODEC_ID_GSM, ///< as in Berlin toast format + AV_CODEC_ID_QDM2, + AV_CODEC_ID_COOK, + AV_CODEC_ID_TRUESPEECH, + AV_CODEC_ID_TTA, + AV_CODEC_ID_SMACKAUDIO, + AV_CODEC_ID_QCELP, + AV_CODEC_ID_WAVPACK, + AV_CODEC_ID_DSICINAUDIO, + AV_CODEC_ID_IMC, + AV_CODEC_ID_MUSEPACK7, + AV_CODEC_ID_MLP, + AV_CODEC_ID_GSM_MS, /* as found in WAV */ + AV_CODEC_ID_ATRAC3, + AV_CODEC_ID_APE, + AV_CODEC_ID_NELLYMOSER, + AV_CODEC_ID_MUSEPACK8, + AV_CODEC_ID_SPEEX, + AV_CODEC_ID_WMAVOICE, + AV_CODEC_ID_WMAPRO, + AV_CODEC_ID_WMALOSSLESS, + AV_CODEC_ID_ATRAC3P, + AV_CODEC_ID_EAC3, + AV_CODEC_ID_SIPR, + AV_CODEC_ID_MP1, + AV_CODEC_ID_TWINVQ, + AV_CODEC_ID_TRUEHD, + AV_CODEC_ID_MP4ALS, + AV_CODEC_ID_ATRAC1, + AV_CODEC_ID_BINKAUDIO_RDFT, + AV_CODEC_ID_BINKAUDIO_DCT, + AV_CODEC_ID_AAC_LATM, + AV_CODEC_ID_QDMC, + AV_CODEC_ID_CELT, + AV_CODEC_ID_G723_1, + AV_CODEC_ID_G729, + AV_CODEC_ID_8SVX_EXP, + AV_CODEC_ID_8SVX_FIB, + AV_CODEC_ID_BMV_AUDIO, + AV_CODEC_ID_RALF, + AV_CODEC_ID_IAC, + AV_CODEC_ID_ILBC, + AV_CODEC_ID_OPUS, + AV_CODEC_ID_COMFORT_NOISE, + AV_CODEC_ID_TAK, + AV_CODEC_ID_METASOUND, + AV_CODEC_ID_PAF_AUDIO, + AV_CODEC_ID_ON2AVC, + AV_CODEC_ID_DSS_SP, + AV_CODEC_ID_CODEC2, + + AV_CODEC_ID_FFWAVESYNTH = 0x15800, + AV_CODEC_ID_SONIC, + AV_CODEC_ID_SONIC_LS, + AV_CODEC_ID_EVRC, + AV_CODEC_ID_SMV, + AV_CODEC_ID_DSD_LSBF, + AV_CODEC_ID_DSD_MSBF, + AV_CODEC_ID_DSD_LSBF_PLANAR, + AV_CODEC_ID_DSD_MSBF_PLANAR, + AV_CODEC_ID_4GV, + AV_CODEC_ID_INTERPLAY_ACM, + AV_CODEC_ID_XMA1, + AV_CODEC_ID_XMA2, + AV_CODEC_ID_DST, + AV_CODEC_ID_ATRAC3AL, + AV_CODEC_ID_ATRAC3PAL, + AV_CODEC_ID_DOLBY_E, + AV_CODEC_ID_APTX, + AV_CODEC_ID_APTX_HD, + AV_CODEC_ID_SBC, + AV_CODEC_ID_ATRAC9, + AV_CODEC_ID_HCOM, + AV_CODEC_ID_ACELP_KELVIN, + AV_CODEC_ID_MPEGH_3D_AUDIO, + AV_CODEC_ID_SIREN, + AV_CODEC_ID_HCA, + + /* subtitle codecs */ + AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. + AV_CODEC_ID_DVD_SUBTITLE = 0x17000, + AV_CODEC_ID_DVB_SUBTITLE, + AV_CODEC_ID_TEXT, ///< raw UTF-8 text + AV_CODEC_ID_XSUB, + AV_CODEC_ID_SSA, + AV_CODEC_ID_MOV_TEXT, + AV_CODEC_ID_HDMV_PGS_SUBTITLE, + AV_CODEC_ID_DVB_TELETEXT, + AV_CODEC_ID_SRT, + + AV_CODEC_ID_MICRODVD = 0x17800, + AV_CODEC_ID_EIA_608, + AV_CODEC_ID_JACOSUB, + AV_CODEC_ID_SAMI, + AV_CODEC_ID_REALTEXT, + AV_CODEC_ID_STL, + AV_CODEC_ID_SUBVIEWER1, + AV_CODEC_ID_SUBVIEWER, + AV_CODEC_ID_SUBRIP, + AV_CODEC_ID_WEBVTT, + AV_CODEC_ID_MPL2, + AV_CODEC_ID_VPLAYER, + AV_CODEC_ID_PJS, + AV_CODEC_ID_ASS, + AV_CODEC_ID_HDMV_TEXT_SUBTITLE, + AV_CODEC_ID_TTML, + AV_CODEC_ID_ARIB_CAPTION, + + /* other specific kind of codecs (generally used for attachments) */ + AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. + AV_CODEC_ID_TTF = 0x18000, + + AV_CODEC_ID_SCTE_35, ///< Contain timestamp estimated through PCR of program stream. + AV_CODEC_ID_EPG, + AV_CODEC_ID_BINTEXT = 0x18800, + AV_CODEC_ID_XBIN, + AV_CODEC_ID_IDF, + AV_CODEC_ID_OTF, + AV_CODEC_ID_SMPTE_KLV, + AV_CODEC_ID_DVD_NAV, + AV_CODEC_ID_TIMED_ID3, + AV_CODEC_ID_BIN_DATA, + + + AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it + + AV_CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS + * stream (only used by libavformat) */ + AV_CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems + * stream (only used by libavformat) */ + AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information. + AV_CODEC_ID_WRAPPED_AVFRAME = 0x21001, ///< Passthrough codec, AVFrames wrapped in AVPacket +}; + +/** + * Get the type of the given codec. + */ +enum AVMediaType avcodec_get_type(enum AVCodecID codec_id); + +/** + * Get the name of a codec. + * @return a static string identifying the codec; never NULL + */ +const char *avcodec_get_name(enum AVCodecID id); + +/** + * @} + */ + +#endif // AVCODEC_CODEC_ID_H diff --git a/ffmpeg/inc/libavcodec/codec_par.h b/ffmpeg/inc/libavcodec/codec_par.h new file mode 100644 index 0000000..948758e --- /dev/null +++ b/ffmpeg/inc/libavcodec/codec_par.h @@ -0,0 +1,229 @@ +/* + * Codec parameters public API + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CODEC_PAR_H +#define AVCODEC_CODEC_PAR_H + +#include + +#include "libavutil/avutil.h" +#include "libavutil/rational.h" +#include "libavutil/pixfmt.h" + +#include "codec_id.h" + +/** + * @addtogroup lavc_core + */ + +enum AVFieldOrder { + AV_FIELD_UNKNOWN, + AV_FIELD_PROGRESSIVE, + AV_FIELD_TT, //< Top coded_first, top displayed first + AV_FIELD_BB, //< Bottom coded first, bottom displayed first + AV_FIELD_TB, //< Top coded first, bottom displayed first + AV_FIELD_BT, //< Bottom coded first, top displayed first +}; + +/** + * This struct describes the properties of an encoded stream. + * + * sizeof(AVCodecParameters) is not a part of the public ABI, this struct must + * be allocated with avcodec_parameters_alloc() and freed with + * avcodec_parameters_free(). + */ +typedef struct AVCodecParameters { + /** + * General type of the encoded data. + */ + enum AVMediaType codec_type; + /** + * Specific type of the encoded data (the codec used). + */ + enum AVCodecID codec_id; + /** + * Additional information about the codec (corresponds to the AVI FOURCC). + */ + uint32_t codec_tag; + + /** + * Extra binary data needed for initializing the decoder, codec-dependent. + * + * Must be allocated with av_malloc() and will be freed by + * avcodec_parameters_free(). The allocated size of extradata must be at + * least extradata_size + AV_INPUT_BUFFER_PADDING_SIZE, with the padding + * bytes zeroed. + */ + uint8_t *extradata; + /** + * Size of the extradata content in bytes. + */ + int extradata_size; + + /** + * - video: the pixel format, the value corresponds to enum AVPixelFormat. + * - audio: the sample format, the value corresponds to enum AVSampleFormat. + */ + int format; + + /** + * The average bitrate of the encoded data (in bits per second). + */ + int64_t bit_rate; + + /** + * The number of bits per sample in the codedwords. + * + * This is basically the bitrate per sample. It is mandatory for a bunch of + * formats to actually decode them. It's the number of bits for one sample in + * the actual coded bitstream. + * + * This could be for example 4 for ADPCM + * For PCM formats this matches bits_per_raw_sample + * Can be 0 + */ + int bits_per_coded_sample; + + /** + * This is the number of valid bits in each output sample. If the + * sample format has more bits, the least significant bits are additional + * padding bits, which are always 0. Use right shifts to reduce the sample + * to its actual size. For example, audio formats with 24 bit samples will + * have bits_per_raw_sample set to 24, and format set to AV_SAMPLE_FMT_S32. + * To get the original sample use "(int32_t)sample >> 8"." + * + * For ADPCM this might be 12 or 16 or similar + * Can be 0 + */ + int bits_per_raw_sample; + + /** + * Codec-specific bitstream restrictions that the stream conforms to. + */ + int profile; + int level; + + /** + * Video only. The dimensions of the video frame in pixels. + */ + int width; + int height; + + /** + * Video only. The aspect ratio (width / height) which a single pixel + * should have when displayed. + * + * When the aspect ratio is unknown / undefined, the numerator should be + * set to 0 (the denominator may have any value). + */ + AVRational sample_aspect_ratio; + + /** + * Video only. The order of the fields in interlaced video. + */ + enum AVFieldOrder field_order; + + /** + * Video only. Additional colorspace characteristics. + */ + enum AVColorRange color_range; + enum AVColorPrimaries color_primaries; + enum AVColorTransferCharacteristic color_trc; + enum AVColorSpace color_space; + enum AVChromaLocation chroma_location; + + /** + * Video only. Number of delayed frames. + */ + int video_delay; + + /** + * Audio only. The channel layout bitmask. May be 0 if the channel layout is + * unknown or unspecified, otherwise the number of bits set must be equal to + * the channels field. + */ + uint64_t channel_layout; + /** + * Audio only. The number of audio channels. + */ + int channels; + /** + * Audio only. The number of audio samples per second. + */ + int sample_rate; + /** + * Audio only. The number of bytes per coded audio frame, required by some + * formats. + * + * Corresponds to nBlockAlign in WAVEFORMATEX. + */ + int block_align; + /** + * Audio only. Audio frame size, if known. Required by some formats to be static. + */ + int frame_size; + + /** + * Audio only. The amount of padding (in samples) inserted by the encoder at + * the beginning of the audio. I.e. this number of leading decoded samples + * must be discarded by the caller to get the original audio without leading + * padding. + */ + int initial_padding; + /** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + */ + int trailing_padding; + /** + * Audio only. Number of samples to skip after a discontinuity. + */ + int seek_preroll; +} AVCodecParameters; + +/** + * Allocate a new AVCodecParameters and set its fields to default values + * (unknown/invalid/0). The returned struct must be freed with + * avcodec_parameters_free(). + */ +AVCodecParameters *avcodec_parameters_alloc(void); + +/** + * Free an AVCodecParameters instance and everything associated with it and + * write NULL to the supplied pointer. + */ +void avcodec_parameters_free(AVCodecParameters **par); + +/** + * Copy the contents of src to dst. Any allocated fields in dst are freed and + * replaced with newly allocated duplicates of the corresponding fields in src. + * + * @return >= 0 on success, a negative AVERROR code on failure. + */ +int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src); + + +/** + * @} + */ + +#endif // AVCODEC_CODEC_PAR_H diff --git a/ffmpeg/inc/libavcodec/d3d11va.h b/ffmpeg/inc/libavcodec/d3d11va.h new file mode 100644 index 0000000..6816b6c --- /dev/null +++ b/ffmpeg/inc/libavcodec/d3d11va.h @@ -0,0 +1,112 @@ +/* + * Direct3D11 HW acceleration + * + * copyright (c) 2009 Laurent Aimar + * copyright (c) 2015 Steve Lhomme + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_D3D11VA_H +#define AVCODEC_D3D11VA_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_d3d11va + * Public libavcodec D3D11VA header. + */ + +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0602 +#endif + +#include +#include + +/** + * @defgroup lavc_codec_hwaccel_d3d11va Direct3D11 + * @ingroup lavc_codec_hwaccel + * + * @{ + */ + +#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for Direct3D11 and old UVD/UVD+ ATI video cards +#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO 2 ///< Work around for Direct3D11 and old Intel GPUs with ClearVideo interface + +/** + * This structure is used to provides the necessary configurations and data + * to the Direct3D11 FFmpeg HWAccel implementation. + * + * The application must make it available as AVCodecContext.hwaccel_context. + * + * Use av_d3d11va_alloc_context() exclusively to allocate an AVD3D11VAContext. + */ +typedef struct AVD3D11VAContext { + /** + * D3D11 decoder object + */ + ID3D11VideoDecoder *decoder; + + /** + * D3D11 VideoContext + */ + ID3D11VideoContext *video_context; + + /** + * D3D11 configuration used to create the decoder + */ + D3D11_VIDEO_DECODER_CONFIG *cfg; + + /** + * The number of surface in the surface array + */ + unsigned surface_count; + + /** + * The array of Direct3D surfaces used to create the decoder + */ + ID3D11VideoDecoderOutputView **surface; + + /** + * A bit field configuring the workarounds needed for using the decoder + */ + uint64_t workaround; + + /** + * Private to the FFmpeg AVHWAccel implementation + */ + unsigned report_id; + + /** + * Mutex to access video_context + */ + HANDLE context_mutex; +} AVD3D11VAContext; + +/** + * Allocate an AVD3D11VAContext. + * + * @return Newly-allocated AVD3D11VAContext or NULL on failure. + */ +AVD3D11VAContext *av_d3d11va_alloc_context(void); + +/** + * @} + */ + +#endif /* AVCODEC_D3D11VA_H */ diff --git a/ffmpeg/inc/libavcodec/dirac.h b/ffmpeg/inc/libavcodec/dirac.h new file mode 100644 index 0000000..e6d9d34 --- /dev/null +++ b/ffmpeg/inc/libavcodec/dirac.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2007 Marco Gerards + * Copyright (C) 2009 David Conrad + * Copyright (C) 2011 Jordi Ortiz + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DIRAC_H +#define AVCODEC_DIRAC_H + +/** + * @file + * Interface to Dirac Decoder/Encoder + * @author Marco Gerards + * @author David Conrad + * @author Jordi Ortiz + */ + +#include "avcodec.h" + +/** + * The spec limits the number of wavelet decompositions to 4 for both + * level 1 (VC-2) and 128 (long-gop default). + * 5 decompositions is the maximum before >16-bit buffers are needed. + * Schroedinger allows this for DD 9,7 and 13,7 wavelets only, limiting + * the others to 4 decompositions (or 3 for the fidelity filter). + * + * We use this instead of MAX_DECOMPOSITIONS to save some memory. + */ +#define MAX_DWT_LEVELS 5 + +/** + * Parse code values: + * + * Dirac Specification -> + * 9.6.1 Table 9.1 + * + * VC-2 Specification -> + * 10.4.1 Table 10.1 + */ + +enum DiracParseCodes { + DIRAC_PCODE_SEQ_HEADER = 0x00, + DIRAC_PCODE_END_SEQ = 0x10, + DIRAC_PCODE_AUX = 0x20, + DIRAC_PCODE_PAD = 0x30, + DIRAC_PCODE_PICTURE_CODED = 0x08, + DIRAC_PCODE_PICTURE_RAW = 0x48, + DIRAC_PCODE_PICTURE_LOW_DEL = 0xC8, + DIRAC_PCODE_PICTURE_HQ = 0xE8, + DIRAC_PCODE_INTER_NOREF_CO1 = 0x0A, + DIRAC_PCODE_INTER_NOREF_CO2 = 0x09, + DIRAC_PCODE_INTER_REF_CO1 = 0x0D, + DIRAC_PCODE_INTER_REF_CO2 = 0x0E, + DIRAC_PCODE_INTRA_REF_CO = 0x0C, + DIRAC_PCODE_INTRA_REF_RAW = 0x4C, + DIRAC_PCODE_INTRA_REF_PICT = 0xCC, + DIRAC_PCODE_MAGIC = 0x42424344, +}; + +typedef struct DiracVersionInfo { + int major; + int minor; +} DiracVersionInfo; + +typedef struct AVDiracSeqHeader { + unsigned width; + unsigned height; + uint8_t chroma_format; ///< 0: 444 1: 422 2: 420 + + uint8_t interlaced; + uint8_t top_field_first; + + uint8_t frame_rate_index; ///< index into dirac_frame_rate[] + uint8_t aspect_ratio_index; ///< index into dirac_aspect_ratio[] + + uint16_t clean_width; + uint16_t clean_height; + uint16_t clean_left_offset; + uint16_t clean_right_offset; + + uint8_t pixel_range_index; ///< index into dirac_pixel_range_presets[] + uint8_t color_spec_index; ///< index into dirac_color_spec_presets[] + + int profile; + int level; + + AVRational framerate; + AVRational sample_aspect_ratio; + + enum AVPixelFormat pix_fmt; + enum AVColorRange color_range; + enum AVColorPrimaries color_primaries; + enum AVColorTransferCharacteristic color_trc; + enum AVColorSpace colorspace; + + DiracVersionInfo version; + int bit_depth; +} AVDiracSeqHeader; + +/** + * Parse a Dirac sequence header. + * + * @param dsh this function will allocate and fill an AVDiracSeqHeader struct + * and write it into this pointer. The caller must free it with + * av_free(). + * @param buf the data buffer + * @param buf_size the size of the data buffer in bytes + * @param log_ctx if non-NULL, this function will log errors here + * @return 0 on success, a negative AVERROR code on failure + */ +int av_dirac_parse_sequence_header(AVDiracSeqHeader **dsh, + const uint8_t *buf, size_t buf_size, + void *log_ctx); + +#endif /* AVCODEC_DIRAC_H */ diff --git a/ffmpeg/inc/libavcodec/dv_profile.h b/ffmpeg/inc/libavcodec/dv_profile.h new file mode 100644 index 0000000..9380a66 --- /dev/null +++ b/ffmpeg/inc/libavcodec/dv_profile.h @@ -0,0 +1,83 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DV_PROFILE_H +#define AVCODEC_DV_PROFILE_H + +#include + +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" +#include "avcodec.h" + +/* minimum number of bytes to read from a DV stream in order to + * determine the profile */ +#define DV_PROFILE_BYTES (6 * 80) /* 6 DIF blocks */ + + +/* + * AVDVProfile is used to express the differences between various + * DV flavors. For now it's primarily used for differentiating + * 525/60 and 625/50, but the plans are to use it for various + * DV specs as well (e.g. SMPTE314M vs. IEC 61834). + */ +typedef struct AVDVProfile { + int dsf; /* value of the dsf in the DV header */ + int video_stype; /* stype for VAUX source pack */ + int frame_size; /* total size of one frame in bytes */ + int difseg_size; /* number of DIF segments per DIF channel */ + int n_difchan; /* number of DIF channels per frame */ + AVRational time_base; /* 1/framerate */ + int ltc_divisor; /* FPS from the LTS standpoint */ + int height; /* picture height in pixels */ + int width; /* picture width in pixels */ + AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */ + enum AVPixelFormat pix_fmt; /* picture pixel format */ + int bpm; /* blocks per macroblock */ + const uint8_t *block_sizes; /* AC block sizes, in bits */ + int audio_stride; /* size of audio_shuffle table */ + int audio_min_samples[3]; /* min amount of audio samples */ + /* for 48kHz, 44.1kHz and 32kHz */ + int audio_samples_dist[5]; /* how many samples are supposed to be */ + /* in each frame in a 5 frames window */ + const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */ +} AVDVProfile; + +/** + * Get a DV profile for the provided compressed frame. + * + * @param sys the profile used for the previous frame, may be NULL + * @param frame the compressed data buffer + * @param buf_size size of the buffer in bytes + * @return the DV profile for the supplied data or NULL on failure + */ +const AVDVProfile *av_dv_frame_profile(const AVDVProfile *sys, + const uint8_t *frame, unsigned buf_size); + +/** + * Get a DV profile for the provided stream parameters. + */ +const AVDVProfile *av_dv_codec_profile(int width, int height, enum AVPixelFormat pix_fmt); + +/** + * Get a DV profile for the provided stream parameters. + * The frame rate is used as a best-effort parameter. + */ +const AVDVProfile *av_dv_codec_profile2(int width, int height, enum AVPixelFormat pix_fmt, AVRational frame_rate); + +#endif /* AVCODEC_DV_PROFILE_H */ diff --git a/ffmpeg/inc/libavcodec/dxva2.h b/ffmpeg/inc/libavcodec/dxva2.h new file mode 100644 index 0000000..22c9399 --- /dev/null +++ b/ffmpeg/inc/libavcodec/dxva2.h @@ -0,0 +1,93 @@ +/* + * DXVA2 HW acceleration + * + * copyright (c) 2009 Laurent Aimar + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_DXVA2_H +#define AVCODEC_DXVA2_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_dxva2 + * Public libavcodec DXVA2 header. + */ + +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0602 +#endif + +#include +#include +#include + +/** + * @defgroup lavc_codec_hwaccel_dxva2 DXVA2 + * @ingroup lavc_codec_hwaccel + * + * @{ + */ + +#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards +#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO 2 ///< Work around for DXVA2 and old Intel GPUs with ClearVideo interface + +/** + * This structure is used to provides the necessary configurations and data + * to the DXVA2 FFmpeg HWAccel implementation. + * + * The application must make it available as AVCodecContext.hwaccel_context. + */ +struct dxva_context { + /** + * DXVA2 decoder object + */ + IDirectXVideoDecoder *decoder; + + /** + * DXVA2 configuration used to create the decoder + */ + const DXVA2_ConfigPictureDecode *cfg; + + /** + * The number of surface in the surface array + */ + unsigned surface_count; + + /** + * The array of Direct3D surfaces used to create the decoder + */ + LPDIRECT3DSURFACE9 *surface; + + /** + * A bit field configuring the workarounds needed for using the decoder + */ + uint64_t workaround; + + /** + * Private to the FFmpeg AVHWAccel implementation + */ + unsigned report_id; +}; + +/** + * @} + */ + +#endif /* AVCODEC_DXVA2_H */ diff --git a/ffmpeg/inc/libavcodec/jni.h b/ffmpeg/inc/libavcodec/jni.h new file mode 100644 index 0000000..dd99e92 --- /dev/null +++ b/ffmpeg/inc/libavcodec/jni.h @@ -0,0 +1,46 @@ +/* + * JNI public API functions + * + * Copyright (c) 2015-2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_JNI_H +#define AVCODEC_JNI_H + +/* + * Manually set a Java virtual machine which will be used to retrieve the JNI + * environment. Once a Java VM is set it cannot be changed afterwards, meaning + * you can call multiple times av_jni_set_java_vm with the same Java VM pointer + * however it will error out if you try to set a different Java VM. + * + * @param vm Java virtual machine + * @param log_ctx context used for logging, can be NULL + * @return 0 on success, < 0 otherwise + */ +int av_jni_set_java_vm(void *vm, void *log_ctx); + +/* + * Get the Java virtual machine which has been set with av_jni_set_java_vm. + * + * @param vm Java virtual machine + * @return a pointer to the Java virtual machine + */ +void *av_jni_get_java_vm(void *log_ctx); + +#endif /* AVCODEC_JNI_H */ diff --git a/ffmpeg/inc/libavcodec/mediacodec.h b/ffmpeg/inc/libavcodec/mediacodec.h new file mode 100644 index 0000000..4c8545d --- /dev/null +++ b/ffmpeg/inc/libavcodec/mediacodec.h @@ -0,0 +1,101 @@ +/* + * Android MediaCodec public API + * + * Copyright (c) 2016 Matthieu Bouron + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MEDIACODEC_H +#define AVCODEC_MEDIACODEC_H + +#include "libavcodec/avcodec.h" + +/** + * This structure holds a reference to a android/view/Surface object that will + * be used as output by the decoder. + * + */ +typedef struct AVMediaCodecContext { + + /** + * android/view/Surface object reference. + */ + void *surface; + +} AVMediaCodecContext; + +/** + * Allocate and initialize a MediaCodec context. + * + * When decoding with MediaCodec is finished, the caller must free the + * MediaCodec context with av_mediacodec_default_free. + * + * @return a pointer to a newly allocated AVMediaCodecContext on success, NULL otherwise + */ +AVMediaCodecContext *av_mediacodec_alloc_context(void); + +/** + * Convenience function that sets up the MediaCodec context. + * + * @param avctx codec context + * @param ctx MediaCodec context to initialize + * @param surface reference to an android/view/Surface + * @return 0 on success, < 0 otherwise + */ +int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface); + +/** + * This function must be called to free the MediaCodec context initialized with + * av_mediacodec_default_init(). + * + * @param avctx codec context + */ +void av_mediacodec_default_free(AVCodecContext *avctx); + +/** + * Opaque structure representing a MediaCodec buffer to render. + */ +typedef struct MediaCodecBuffer AVMediaCodecBuffer; + +/** + * Release a MediaCodec buffer and render it to the surface that is associated + * with the decoder. This function should only be called once on a given + * buffer, once released the underlying buffer returns to the codec, thus + * subsequent calls to this function will have no effect. + * + * @param buffer the buffer to render + * @param render 1 to release and render the buffer to the surface or 0 to + * discard the buffer + * @return 0 on success, < 0 otherwise + */ +int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render); + +/** + * Release a MediaCodec buffer and render it at the given time to the surface + * that is associated with the decoder. The timestamp must be within one second + * of the current java/lang/System#nanoTime() (which is implemented using + * CLOCK_MONOTONIC on Android). See the Android MediaCodec documentation + * of android/media/MediaCodec#releaseOutputBuffer(int,long) for more details. + * + * @param buffer the buffer to render + * @param time timestamp in nanoseconds of when to render the buffer + * @return 0 on success, < 0 otherwise + */ +int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time); + +#endif /* AVCODEC_MEDIACODEC_H */ diff --git a/ffmpeg/inc/libavcodec/packet.h b/ffmpeg/inc/libavcodec/packet.h new file mode 100644 index 0000000..41485f4 --- /dev/null +++ b/ffmpeg/inc/libavcodec/packet.h @@ -0,0 +1,722 @@ +/* + * AVPacket public API + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PACKET_H +#define AVCODEC_PACKET_H + +#include +#include + +#include "libavutil/attributes.h" +#include "libavutil/buffer.h" +#include "libavutil/dict.h" +#include "libavutil/rational.h" + +#include "libavcodec/version.h" + +/** + * @defgroup lavc_packet AVPacket + * + * Types and functions for working with AVPacket. + * @{ + */ +enum AVPacketSideDataType { + /** + * An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE + * bytes worth of palette. This side data signals that a new palette is + * present. + */ + AV_PKT_DATA_PALETTE, + + /** + * The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format + * that the extradata buffer was changed and the receiving side should + * act upon it appropriately. The new extradata is embedded in the side + * data buffer and should be immediately used for processing the current + * frame or packet. + */ + AV_PKT_DATA_NEW_EXTRADATA, + + /** + * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows: + * @code + * u32le param_flags + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) + * s32le channel_count + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) + * u64le channel_layout + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) + * s32le sample_rate + * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) + * s32le width + * s32le height + * @endcode + */ + AV_PKT_DATA_PARAM_CHANGE, + + /** + * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of + * structures with info about macroblocks relevant to splitting the + * packet into smaller packets on macroblock edges (e.g. as for RFC 2190). + * That is, it does not necessarily contain info about all macroblocks, + * as long as the distance between macroblocks in the info is smaller + * than the target payload size. + * Each MB info structure is 12 bytes, and is laid out as follows: + * @code + * u32le bit offset from the start of the packet + * u8 current quantizer at the start of the macroblock + * u8 GOB number + * u16le macroblock address within the GOB + * u8 horizontal MV predictor + * u8 vertical MV predictor + * u8 horizontal MV predictor for block number 3 + * u8 vertical MV predictor for block number 3 + * @endcode + */ + AV_PKT_DATA_H263_MB_INFO, + + /** + * This side data should be associated with an audio stream and contains + * ReplayGain information in form of the AVReplayGain struct. + */ + AV_PKT_DATA_REPLAYGAIN, + + /** + * This side data contains a 3x3 transformation matrix describing an affine + * transformation that needs to be applied to the decoded video frames for + * correct presentation. + * + * See libavutil/display.h for a detailed description of the data. + */ + AV_PKT_DATA_DISPLAYMATRIX, + + /** + * This side data should be associated with a video stream and contains + * Stereoscopic 3D information in form of the AVStereo3D struct. + */ + AV_PKT_DATA_STEREO3D, + + /** + * This side data should be associated with an audio stream and corresponds + * to enum AVAudioServiceType. + */ + AV_PKT_DATA_AUDIO_SERVICE_TYPE, + + /** + * This side data contains quality related information from the encoder. + * @code + * u32le quality factor of the compressed frame. Allowed range is between 1 (good) and FF_LAMBDA_MAX (bad). + * u8 picture type + * u8 error count + * u16 reserved + * u64le[error count] sum of squared differences between encoder in and output + * @endcode + */ + AV_PKT_DATA_QUALITY_STATS, + + /** + * This side data contains an integer value representing the stream index + * of a "fallback" track. A fallback track indicates an alternate + * track to use when the current track can not be decoded for some reason. + * e.g. no decoder available for codec. + */ + AV_PKT_DATA_FALLBACK_TRACK, + + /** + * This side data corresponds to the AVCPBProperties struct. + */ + AV_PKT_DATA_CPB_PROPERTIES, + + /** + * Recommmends skipping the specified number of samples + * @code + * u32le number of samples to skip from start of this packet + * u32le number of samples to skip from end of this packet + * u8 reason for start skip + * u8 reason for end skip (0=padding silence, 1=convergence) + * @endcode + */ + AV_PKT_DATA_SKIP_SAMPLES, + + /** + * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that + * the packet may contain "dual mono" audio specific to Japanese DTV + * and if it is true, recommends only the selected channel to be used. + * @code + * u8 selected channels (0=mail/left, 1=sub/right, 2=both) + * @endcode + */ + AV_PKT_DATA_JP_DUALMONO, + + /** + * A list of zero terminated key/value strings. There is no end marker for + * the list, so it is required to rely on the side data size to stop. + */ + AV_PKT_DATA_STRINGS_METADATA, + + /** + * Subtitle event position + * @code + * u32le x1 + * u32le y1 + * u32le x2 + * u32le y2 + * @endcode + */ + AV_PKT_DATA_SUBTITLE_POSITION, + + /** + * Data found in BlockAdditional element of matroska container. There is + * no end marker for the data, so it is required to rely on the side data + * size to recognize the end. 8 byte id (as found in BlockAddId) followed + * by data. + */ + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, + + /** + * The optional first identifier line of a WebVTT cue. + */ + AV_PKT_DATA_WEBVTT_IDENTIFIER, + + /** + * The optional settings (rendering instructions) that immediately + * follow the timestamp specifier of a WebVTT cue. + */ + AV_PKT_DATA_WEBVTT_SETTINGS, + + /** + * A list of zero terminated key/value strings. There is no end marker for + * the list, so it is required to rely on the side data size to stop. This + * side data includes updated metadata which appeared in the stream. + */ + AV_PKT_DATA_METADATA_UPDATE, + + /** + * MPEGTS stream ID as uint8_t, this is required to pass the stream ID + * information from the demuxer to the corresponding muxer. + */ + AV_PKT_DATA_MPEGTS_STREAM_ID, + + /** + * Mastering display metadata (based on SMPTE-2086:2014). This metadata + * should be associated with a video stream and contains data in the form + * of the AVMasteringDisplayMetadata struct. + */ + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + + /** + * This side data should be associated with a video stream and corresponds + * to the AVSphericalMapping structure. + */ + AV_PKT_DATA_SPHERICAL, + + /** + * Content light level (based on CTA-861.3). This metadata should be + * associated with a video stream and contains data in the form of the + * AVContentLightMetadata struct. + */ + AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + + /** + * ATSC A53 Part 4 Closed Captions. This metadata should be associated with + * a video stream. A53 CC bitstream is stored as uint8_t in AVPacketSideData.data. + * The number of bytes of CC data is AVPacketSideData.size. + */ + AV_PKT_DATA_A53_CC, + + /** + * This side data is encryption initialization data. + * The format is not part of ABI, use av_encryption_init_info_* methods to + * access. + */ + AV_PKT_DATA_ENCRYPTION_INIT_INFO, + + /** + * This side data contains encryption info for how to decrypt the packet. + * The format is not part of ABI, use av_encryption_info_* methods to access. + */ + AV_PKT_DATA_ENCRYPTION_INFO, + + /** + * Active Format Description data consisting of a single byte as specified + * in ETSI TS 101 154 using AVActiveFormatDescription enum. + */ + AV_PKT_DATA_AFD, + + /** + * Producer Reference Time data corresponding to the AVProducerReferenceTime struct, + * usually exported by some encoders (on demand through the prft flag set in the + * AVCodecContext export_side_data field). + */ + AV_PKT_DATA_PRFT, + + /** + * ICC profile data consisting of an opaque octet buffer following the + * format described by ISO 15076-1. + */ + AV_PKT_DATA_ICC_PROFILE, + + /** + * DOVI configuration + * ref: + * dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.1.2, section 2.2 + * dolby-vision-bitstreams-in-mpeg-2-transport-stream-multiplex-v1.2, section 3.3 + * Tags are stored in struct AVDOVIDecoderConfigurationRecord. + */ + AV_PKT_DATA_DOVI_CONF, + + /** + * The number of side data types. + * This is not part of the public API/ABI in the sense that it may + * change when new side data types are added. + * This must stay the last enum value. + * If its value becomes huge, some code using it + * needs to be updated as it assumes it to be smaller than other limits. + */ + AV_PKT_DATA_NB +}; + +#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED + +typedef struct AVPacketSideData { + uint8_t *data; + int size; + enum AVPacketSideDataType type; +} AVPacketSideData; + +/** + * This structure stores compressed data. It is typically exported by demuxers + * and then passed as input to decoders, or received as output from encoders and + * then passed to muxers. + * + * For video, it should typically contain one compressed frame. For audio it may + * contain several compressed frames. Encoders are allowed to output empty + * packets, with no compressed data, containing only side data + * (e.g. to update some stream parameters at the end of encoding). + * + * AVPacket is one of the few structs in FFmpeg, whose size is a part of public + * ABI. Thus it may be allocated on stack and no new fields can be added to it + * without libavcodec and libavformat major bump. + * + * The semantics of data ownership depends on the buf field. + * If it is set, the packet data is dynamically allocated and is + * valid indefinitely until a call to av_packet_unref() reduces the + * reference count to 0. + * + * If the buf field is not set av_packet_ref() would make a copy instead + * of increasing the reference count. + * + * The side data is always allocated with av_malloc(), copied by + * av_packet_ref() and freed by av_packet_unref(). + * + * @see av_packet_ref + * @see av_packet_unref + */ +typedef struct AVPacket { + /** + * A reference to the reference-counted buffer where the packet data is + * stored. + * May be NULL, then the packet data is not reference-counted. + */ + AVBufferRef *buf; + /** + * Presentation timestamp in AVStream->time_base units; the time at which + * the decompressed packet will be presented to the user. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + * pts MUST be larger or equal to dts as presentation cannot happen before + * decompression, unless one wants to view hex dumps. Some formats misuse + * the terms dts and pts/cts to mean something different. Such timestamps + * must be converted to true pts/dts before they are stored in AVPacket. + */ + int64_t pts; + /** + * Decompression timestamp in AVStream->time_base units; the time at which + * the packet is decompressed. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + */ + int64_t dts; + uint8_t *data; + int size; + int stream_index; + /** + * A combination of AV_PKT_FLAG values + */ + int flags; + /** + * Additional packet data that can be provided by the container. + * Packet can contain several types of side information. + */ + AVPacketSideData *side_data; + int side_data_elems; + + /** + * Duration of this packet in AVStream->time_base units, 0 if unknown. + * Equals next_pts - this_pts in presentation order. + */ + int64_t duration; + + int64_t pos; ///< byte position in stream, -1 if unknown + +#if FF_API_CONVERGENCE_DURATION + /** + * @deprecated Same as the duration field, but as int64_t. This was required + * for Matroska subtitles, whose duration values could overflow when the + * duration field was still an int. + */ + attribute_deprecated + int64_t convergence_duration; +#endif +} AVPacket; + +#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe +#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted +/** + * Flag is used to discard packets which are required to maintain valid + * decoder state but are not required for output and should be dropped + * after decoding. + **/ +#define AV_PKT_FLAG_DISCARD 0x0004 +/** + * The packet comes from a trusted source. + * + * Otherwise-unsafe constructs such as arbitrary pointers to data + * outside the packet may be followed. + */ +#define AV_PKT_FLAG_TRUSTED 0x0008 +/** + * Flag is used to indicate packets that contain frames that can + * be discarded by the decoder. I.e. Non-reference frames. + */ +#define AV_PKT_FLAG_DISPOSABLE 0x0010 + +enum AVSideDataParamChangeFlags { + AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, + AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002, + AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004, + AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008, +}; + +/** + * Allocate an AVPacket and set its fields to default values. The resulting + * struct must be freed using av_packet_free(). + * + * @return An AVPacket filled with default values or NULL on failure. + * + * @note this only allocates the AVPacket itself, not the data buffers. Those + * must be allocated through other means such as av_new_packet. + * + * @see av_new_packet + */ +AVPacket *av_packet_alloc(void); + +/** + * Create a new packet that references the same data as src. + * + * This is a shortcut for av_packet_alloc()+av_packet_ref(). + * + * @return newly created AVPacket on success, NULL on error. + * + * @see av_packet_alloc + * @see av_packet_ref + */ +AVPacket *av_packet_clone(const AVPacket *src); + +/** + * Free the packet, if the packet is reference counted, it will be + * unreferenced first. + * + * @param pkt packet to be freed. The pointer will be set to NULL. + * @note passing NULL is a no-op. + */ +void av_packet_free(AVPacket **pkt); + +/** + * Initialize optional fields of a packet with default values. + * + * Note, this does not touch the data and size members, which have to be + * initialized separately. + * + * @param pkt packet + */ +void av_init_packet(AVPacket *pkt); + +/** + * Allocate the payload of a packet and initialize its fields with + * default values. + * + * @param pkt packet + * @param size wanted payload size + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_new_packet(AVPacket *pkt, int size); + +/** + * Reduce packet size, correctly zeroing padding + * + * @param pkt packet + * @param size new size + */ +void av_shrink_packet(AVPacket *pkt, int size); + +/** + * Increase packet size, correctly zeroing padding + * + * @param pkt packet + * @param grow_by number of bytes by which to increase the size of the packet + */ +int av_grow_packet(AVPacket *pkt, int grow_by); + +/** + * Initialize a reference-counted packet from av_malloc()ed data. + * + * @param pkt packet to be initialized. This function will set the data, size, + * and buf fields, all others are left untouched. + * @param data Data allocated by av_malloc() to be used as packet data. If this + * function returns successfully, the data is owned by the underlying AVBuffer. + * The caller may not access the data through other means. + * @param size size of data in bytes, without the padding. I.e. the full buffer + * size is assumed to be size + AV_INPUT_BUFFER_PADDING_SIZE. + * + * @return 0 on success, a negative AVERROR on error + */ +int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size); + +#if FF_API_AVPACKET_OLD_API +/** + * @warning This is a hack - the packet memory allocation stuff is broken. The + * packet is allocated if it was not really allocated. + * + * @deprecated Use av_packet_ref or av_packet_make_refcounted + */ +attribute_deprecated +int av_dup_packet(AVPacket *pkt); +/** + * Copy packet, including contents + * + * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_ref + */ +attribute_deprecated +int av_copy_packet(AVPacket *dst, const AVPacket *src); + +/** + * Copy packet side data + * + * @return 0 on success, negative AVERROR on fail + * + * @deprecated Use av_packet_copy_props + */ +attribute_deprecated +int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src); + +/** + * Free a packet. + * + * @deprecated Use av_packet_unref + * + * @param pkt packet to free + */ +attribute_deprecated +void av_free_packet(AVPacket *pkt); +#endif +/** + * Allocate new information of a packet. + * + * @param pkt packet + * @param type side information type + * @param size side information size + * @return pointer to fresh allocated data or NULL otherwise + */ +uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + int size); + +/** + * Wrap an existing array as a packet side data. + * + * @param pkt packet + * @param type side information type + * @param data the side data array. It must be allocated with the av_malloc() + * family of functions. The ownership of the data is transferred to + * pkt. + * @param size side information size + * @return a non-negative number on success, a negative AVERROR code on + * failure. On failure, the packet is unchanged and the data remains + * owned by the caller. + */ +int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + uint8_t *data, size_t size); + +/** + * Shrink the already allocated side data buffer + * + * @param pkt packet + * @param type side information type + * @param size new side information size + * @return 0 on success, < 0 on failure + */ +int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, + int size); + +/** + * Get side information from packet. + * + * @param pkt packet + * @param type desired side information type + * @param size pointer for side information size to store (optional) + * @return pointer to data if present or NULL otherwise + */ +uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, + int *size); + +#if FF_API_MERGE_SD_API +attribute_deprecated +int av_packet_merge_side_data(AVPacket *pkt); + +attribute_deprecated +int av_packet_split_side_data(AVPacket *pkt); +#endif + +const char *av_packet_side_data_name(enum AVPacketSideDataType type); + +/** + * Pack a dictionary for use in side_data. + * + * @param dict The dictionary to pack. + * @param size pointer to store the size of the returned data + * @return pointer to data if successful, NULL otherwise + */ +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size); +/** + * Unpack a dictionary from side_data. + * + * @param data data from side_data + * @param size size of the data + * @param dict the metadata storage dictionary + * @return 0 on success, < 0 on failure + */ +int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict); + + +/** + * Convenience function to free all the side data stored. + * All the other fields stay untouched. + * + * @param pkt packet + */ +void av_packet_free_side_data(AVPacket *pkt); + +/** + * Setup a new reference to the data described by a given packet + * + * If src is reference-counted, setup dst as a new reference to the + * buffer in src. Otherwise allocate a new buffer in dst and copy the + * data from src into it. + * + * All the other fields are copied from src. + * + * @see av_packet_unref + * + * @param dst Destination packet. Will be completely overwritten. + * @param src Source packet + * + * @return 0 on success, a negative AVERROR on error. On error, dst + * will be blank (as if returned by av_packet_alloc()). + */ +int av_packet_ref(AVPacket *dst, const AVPacket *src); + +/** + * Wipe the packet. + * + * Unreference the buffer referenced by the packet and reset the + * remaining packet fields to their default values. + * + * @param pkt The packet to be unreferenced. + */ +void av_packet_unref(AVPacket *pkt); + +/** + * Move every field in src to dst and reset src. + * + * @see av_packet_unref + * + * @param src Source packet, will be reset + * @param dst Destination packet + */ +void av_packet_move_ref(AVPacket *dst, AVPacket *src); + +/** + * Copy only "properties" fields from src to dst. + * + * Properties for the purpose of this function are all the fields + * beside those related to the packet data (buf, data, size) + * + * @param dst Destination packet + * @param src Source packet + * + * @return 0 on success AVERROR on failure. + */ +int av_packet_copy_props(AVPacket *dst, const AVPacket *src); + +/** + * Ensure the data described by a given packet is reference counted. + * + * @note This function does not ensure that the reference will be writable. + * Use av_packet_make_writable instead for that purpose. + * + * @see av_packet_ref + * @see av_packet_make_writable + * + * @param pkt packet whose data should be made reference counted. + * + * @return 0 on success, a negative AVERROR on error. On failure, the + * packet is unchanged. + */ +int av_packet_make_refcounted(AVPacket *pkt); + +/** + * Create a writable reference for the data described by a given packet, + * avoiding data copy if possible. + * + * @param pkt Packet whose data should be made writable. + * + * @return 0 on success, a negative AVERROR on failure. On failure, the + * packet is unchanged. + */ +int av_packet_make_writable(AVPacket *pkt); + +/** + * Convert valid timing fields (timestamps / durations) in a packet from one + * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be + * ignored. + * + * @param pkt packet on which the conversion will be performed + * @param tb_src source timebase, in which the timing fields in pkt are + * expressed + * @param tb_dst destination timebase, to which the timing fields will be + * converted + */ +void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst); + +/** + * @} + */ + +#endif // AVCODEC_PACKET_H diff --git a/ffmpeg/inc/libavcodec/qsv.h b/ffmpeg/inc/libavcodec/qsv.h new file mode 100644 index 0000000..b77158e --- /dev/null +++ b/ffmpeg/inc/libavcodec/qsv.h @@ -0,0 +1,107 @@ +/* + * Intel MediaSDK QSV public API + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_QSV_H +#define AVCODEC_QSV_H + +#include + +#include "libavutil/buffer.h" + +/** + * This struct is used for communicating QSV parameters between libavcodec and + * the caller. It is managed by the caller and must be assigned to + * AVCodecContext.hwaccel_context. + * - decoding: hwaccel_context must be set on return from the get_format() + * callback + * - encoding: hwaccel_context must be set before avcodec_open2() + */ +typedef struct AVQSVContext { + /** + * If non-NULL, the session to use for encoding or decoding. + * Otherwise, libavcodec will try to create an internal session. + */ + mfxSession session; + + /** + * The IO pattern to use. + */ + int iopattern; + + /** + * Extra buffers to pass to encoder or decoder initialization. + */ + mfxExtBuffer **ext_buffers; + int nb_ext_buffers; + + /** + * Encoding only. If this field is set to non-zero by the caller, libavcodec + * will create an mfxExtOpaqueSurfaceAlloc extended buffer and pass it to + * the encoder initialization. This only makes sense if iopattern is also + * set to MFX_IOPATTERN_IN_OPAQUE_MEMORY. + * + * The number of allocated opaque surfaces will be the sum of the number + * required by the encoder and the user-provided value nb_opaque_surfaces. + * The array of the opaque surfaces will be exported to the caller through + * the opaque_surfaces field. + */ + int opaque_alloc; + + /** + * Encoding only, and only if opaque_alloc is set to non-zero. Before + * calling avcodec_open2(), the caller should set this field to the number + * of extra opaque surfaces to allocate beyond what is required by the + * encoder. + * + * On return from avcodec_open2(), this field will be set by libavcodec to + * the total number of allocated opaque surfaces. + */ + int nb_opaque_surfaces; + + /** + * Encoding only, and only if opaque_alloc is set to non-zero. On return + * from avcodec_open2(), this field will be used by libavcodec to export the + * array of the allocated opaque surfaces to the caller, so they can be + * passed to other parts of the pipeline. + * + * The buffer reference exported here is owned and managed by libavcodec, + * the callers should make their own reference with av_buffer_ref() and free + * it with av_buffer_unref() when it is no longer needed. + * + * The buffer data is an nb_opaque_surfaces-sized array of mfxFrameSurface1. + */ + AVBufferRef *opaque_surfaces; + + /** + * Encoding only, and only if opaque_alloc is set to non-zero. On return + * from avcodec_open2(), this field will be set to the surface type used in + * the opaque allocation request. + */ + int opaque_alloc_type; +} AVQSVContext; + +/** + * Allocate a new context. + * + * It must be freed by the caller with av_free(). + */ +AVQSVContext *av_qsv_alloc_context(void); + +#endif /* AVCODEC_QSV_H */ diff --git a/ffmpeg/inc/libavcodec/vaapi.h b/ffmpeg/inc/libavcodec/vaapi.h new file mode 100644 index 0000000..2cf7da5 --- /dev/null +++ b/ffmpeg/inc/libavcodec/vaapi.h @@ -0,0 +1,86 @@ +/* + * Video Acceleration API (shared data between FFmpeg and the video player) + * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 + * + * Copyright (C) 2008-2009 Splitted-Desktop Systems + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VAAPI_H +#define AVCODEC_VAAPI_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_vaapi + * Public libavcodec VA API header. + */ + +#include +#include "libavutil/attributes.h" +#include "version.h" + +#if FF_API_STRUCT_VAAPI_CONTEXT + +/** + * @defgroup lavc_codec_hwaccel_vaapi VA API Decoding + * @ingroup lavc_codec_hwaccel + * @{ + */ + +/** + * This structure is used to share data between the FFmpeg library and + * the client video application. + * This shall be zero-allocated and available as + * AVCodecContext.hwaccel_context. All user members can be set once + * during initialization or through each AVCodecContext.get_buffer() + * function call. In any case, they must be valid prior to calling + * decoding functions. + * + * Deprecated: use AVCodecContext.hw_frames_ctx instead. + */ +struct attribute_deprecated vaapi_context { + /** + * Window system dependent data + * + * - encoding: unused + * - decoding: Set by user + */ + void *display; + + /** + * Configuration ID + * + * - encoding: unused + * - decoding: Set by user + */ + uint32_t config_id; + + /** + * Context ID (video decode pipeline) + * + * - encoding: unused + * - decoding: Set by user + */ + uint32_t context_id; +}; + +/* @} */ + +#endif /* FF_API_STRUCT_VAAPI_CONTEXT */ + +#endif /* AVCODEC_VAAPI_H */ diff --git a/ffmpeg/inc/libavcodec/vdpau.h b/ffmpeg/inc/libavcodec/vdpau.h new file mode 100644 index 0000000..4d99943 --- /dev/null +++ b/ffmpeg/inc/libavcodec/vdpau.h @@ -0,0 +1,176 @@ +/* + * The Video Decode and Presentation API for UNIX (VDPAU) is used for + * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1. + * + * Copyright (C) 2008 NVIDIA + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VDPAU_H +#define AVCODEC_VDPAU_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_vdpau + * Public libavcodec VDPAU header. + */ + + +/** + * @defgroup lavc_codec_hwaccel_vdpau VDPAU Decoder and Renderer + * @ingroup lavc_codec_hwaccel + * + * VDPAU hardware acceleration has two modules + * - VDPAU decoding + * - VDPAU presentation + * + * The VDPAU decoding module parses all headers using FFmpeg + * parsing mechanisms and uses VDPAU for the actual decoding. + * + * As per the current implementation, the actual decoding + * and rendering (API calls) are done as part of the VDPAU + * presentation (vo_vdpau.c) module. + * + * @{ + */ + +#include + +#include "libavutil/avconfig.h" +#include "libavutil/attributes.h" + +#include "avcodec.h" +#include "version.h" + +struct AVCodecContext; +struct AVFrame; + +typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *, + const VdpPictureInfo *, uint32_t, + const VdpBitstreamBuffer *); + +/** + * This structure is used to share data between the libavcodec library and + * the client video application. + * The user shall allocate the structure via the av_alloc_vdpau_hwaccel + * function and make it available as + * AVCodecContext.hwaccel_context. Members can be set by the user once + * during initialization or through each AVCodecContext.get_buffer() + * function call. In any case, they must be valid prior to calling + * decoding functions. + * + * The size of this structure is not a part of the public ABI and must not + * be used outside of libavcodec. Use av_vdpau_alloc_context() to allocate an + * AVVDPAUContext. + */ +typedef struct AVVDPAUContext { + /** + * VDPAU decoder handle + * + * Set by user. + */ + VdpDecoder decoder; + + /** + * VDPAU decoder render callback + * + * Set by the user. + */ + VdpDecoderRender *render; + + AVVDPAU_Render2 render2; +} AVVDPAUContext; + +/** + * @brief allocation function for AVVDPAUContext + * + * Allows extending the struct without breaking API/ABI + */ +AVVDPAUContext *av_alloc_vdpaucontext(void); + +AVVDPAU_Render2 av_vdpau_hwaccel_get_render2(const AVVDPAUContext *); +void av_vdpau_hwaccel_set_render2(AVVDPAUContext *, AVVDPAU_Render2); + +/** + * Associate a VDPAU device with a codec context for hardware acceleration. + * This function is meant to be called from the get_format() codec callback, + * or earlier. It can also be called after avcodec_flush_buffers() to change + * the underlying VDPAU device mid-stream (e.g. to recover from non-transparent + * display preemption). + * + * @note get_format() must return AV_PIX_FMT_VDPAU if this function completes + * successfully. + * + * @param avctx decoding context whose get_format() callback is invoked + * @param device VDPAU device handle to use for hardware acceleration + * @param get_proc_address VDPAU device driver + * @param flags zero of more OR'd AV_HWACCEL_FLAG_* flags + * + * @return 0 on success, an AVERROR code on failure. + */ +int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device, + VdpGetProcAddress *get_proc_address, unsigned flags); + +/** + * Gets the parameters to create an adequate VDPAU video surface for the codec + * context using VDPAU hardware decoding acceleration. + * + * @note Behavior is undefined if the context was not successfully bound to a + * VDPAU device using av_vdpau_bind_context(). + * + * @param avctx the codec context being used for decoding the stream + * @param type storage space for the VDPAU video surface chroma type + * (or NULL to ignore) + * @param width storage space for the VDPAU video surface pixel width + * (or NULL to ignore) + * @param height storage space for the VDPAU video surface pixel height + * (or NULL to ignore) + * + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_vdpau_get_surface_parameters(AVCodecContext *avctx, VdpChromaType *type, + uint32_t *width, uint32_t *height); + +/** + * Allocate an AVVDPAUContext. + * + * @return Newly-allocated AVVDPAUContext or NULL on failure. + */ +AVVDPAUContext *av_vdpau_alloc_context(void); + +#if FF_API_VDPAU_PROFILE +/** + * Get a decoder profile that should be used for initializing a VDPAU decoder. + * Should be called from the AVCodecContext.get_format() callback. + * + * @deprecated Use av_vdpau_bind_context() instead. + * + * @param avctx the codec context being used for decoding the stream + * @param profile a pointer into which the result will be written on success. + * The contents of profile are undefined if this function returns + * an error. + * + * @return 0 on success (non-negative), a negative AVERROR on failure. + */ +attribute_deprecated +int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile); +#endif + +/* @}*/ + +#endif /* AVCODEC_VDPAU_H */ diff --git a/ffmpeg/inc/libavcodec/version.h b/ffmpeg/inc/libavcodec/version.h new file mode 100644 index 0000000..85fbe24 --- /dev/null +++ b/ffmpeg/inc/libavcodec/version.h @@ -0,0 +1,149 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VERSION_H +#define AVCODEC_VERSION_H + +/** + * @file + * @ingroup libavc + * Libavcodec version macros. + */ + +#include "libavutil/version.h" + +#define LIBAVCODEC_VERSION_MAJOR 58 +#define LIBAVCODEC_VERSION_MINOR 91 +#define LIBAVCODEC_VERSION_MICRO 100 + +#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) + +/** + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + * + * @note, when bumping the major version it is recommended to manually + * disable each FF_API_* in its own commit instead of disabling them all + * at once through the bump. This improves the git bisect-ability of the change. + */ + +#ifndef FF_API_LOWRES +#define FF_API_LOWRES (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_DEBUG_MV +#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 58) +#endif +#ifndef FF_API_AVCTX_TIMEBASE +#define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CODED_FRAME +#define FF_API_CODED_FRAME (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_SIDEDATA_ONLY_PKT +#define FF_API_SIDEDATA_ONLY_PKT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_VDPAU_PROFILE +#define FF_API_VDPAU_PROFILE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CONVERGENCE_DURATION +#define FF_API_CONVERGENCE_DURATION (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_AVPICTURE +#define FF_API_AVPICTURE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_AVPACKET_OLD_API +#define FF_API_AVPACKET_OLD_API (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_RTP_CALLBACK +#define FF_API_RTP_CALLBACK (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_VBV_DELAY +#define FF_API_VBV_DELAY (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CODER_TYPE +#define FF_API_CODER_TYPE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_STAT_BITS +#define FF_API_STAT_BITS (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_PRIVATE_OPT +#define FF_API_PRIVATE_OPT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_ASS_TIMING +#define FF_API_ASS_TIMING (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_BSF +#define FF_API_OLD_BSF (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_COPY_CONTEXT +#define FF_API_COPY_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_GET_CONTEXT_DEFAULTS +#define FF_API_GET_CONTEXT_DEFAULTS (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_NVENC_OLD_NAME +#define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_STRUCT_VAAPI_CONTEXT +#define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_MERGE_SD_API +#define FF_API_MERGE_SD_API (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_TAG_STRING +#define FF_API_TAG_STRING (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_GETCHROMA +#define FF_API_GETCHROMA (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_CODEC_GET_SET +#define FF_API_CODEC_GET_SET (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_USER_VISIBLE_AVHWACCEL +#define FF_API_USER_VISIBLE_AVHWACCEL (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LOCKMGR +#define FF_API_LOCKMGR (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_NEXT +#define FF_API_NEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_UNSANITIZED_BITRATES +#define FF_API_UNSANITIZED_BITRATES (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OPENH264_SLICE_MODE +#define FF_API_OPENH264_SLICE_MODE (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OPENH264_CABAC +#define FF_API_OPENH264_CABAC (LIBAVCODEC_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_UNUSED_CODEC_CAPS +#define FF_API_UNUSED_CODEC_CAPS (LIBAVCODEC_VERSION_MAJOR < 59) +#endif + + +#endif /* AVCODEC_VERSION_H */ diff --git a/ffmpeg/inc/libavcodec/videotoolbox.h b/ffmpeg/inc/libavcodec/videotoolbox.h new file mode 100644 index 0000000..af2db0d --- /dev/null +++ b/ffmpeg/inc/libavcodec/videotoolbox.h @@ -0,0 +1,127 @@ +/* + * Videotoolbox hardware acceleration + * + * copyright (c) 2012 Sebastien Zwickert + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VIDEOTOOLBOX_H +#define AVCODEC_VIDEOTOOLBOX_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_videotoolbox + * Public libavcodec Videotoolbox header. + */ + +#include + +#define Picture QuickdrawPicture +#include +#undef Picture + +#include "libavcodec/avcodec.h" + +/** + * This struct holds all the information that needs to be passed + * between the caller and libavcodec for initializing Videotoolbox decoding. + * Its size is not a part of the public ABI, it must be allocated with + * av_videotoolbox_alloc_context() and freed with av_free(). + */ +typedef struct AVVideotoolboxContext { + /** + * Videotoolbox decompression session object. + * Created and freed the caller. + */ + VTDecompressionSessionRef session; + + /** + * The output callback that must be passed to the session. + * Set by av_videottoolbox_default_init() + */ + VTDecompressionOutputCallback output_callback; + + /** + * CVPixelBuffer Format Type that Videotoolbox will use for decoded frames. + * set by the caller. If this is set to 0, then no specific format is + * requested from the decoder, and its native format is output. + */ + OSType cv_pix_fmt_type; + + /** + * CoreMedia Format Description that Videotoolbox will use to create the decompression session. + * Set by the caller. + */ + CMVideoFormatDescriptionRef cm_fmt_desc; + + /** + * CoreMedia codec type that Videotoolbox will use to create the decompression session. + * Set by the caller. + */ + int cm_codec_type; +} AVVideotoolboxContext; + +/** + * Allocate and initialize a Videotoolbox context. + * + * This function should be called from the get_format() callback when the caller + * selects the AV_PIX_FMT_VIDETOOLBOX format. The caller must then create + * the decoder object (using the output callback provided by libavcodec) that + * will be used for Videotoolbox-accelerated decoding. + * + * When decoding with Videotoolbox is finished, the caller must destroy the decoder + * object and free the Videotoolbox context using av_free(). + * + * @return the newly allocated context or NULL on failure + */ +AVVideotoolboxContext *av_videotoolbox_alloc_context(void); + +/** + * This is a convenience function that creates and sets up the Videotoolbox context using + * an internal implementation. + * + * @param avctx the corresponding codec context + * + * @return >= 0 on success, a negative AVERROR code on failure + */ +int av_videotoolbox_default_init(AVCodecContext *avctx); + +/** + * This is a convenience function that creates and sets up the Videotoolbox context using + * an internal implementation. + * + * @param avctx the corresponding codec context + * @param vtctx the Videotoolbox context to use + * + * @return >= 0 on success, a negative AVERROR code on failure + */ +int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx); + +/** + * This function must be called to free the Videotoolbox context initialized with + * av_videotoolbox_default_init(). + * + * @param avctx the corresponding codec context + */ +void av_videotoolbox_default_free(AVCodecContext *avctx); + +/** + * @} + */ + +#endif /* AVCODEC_VIDEOTOOLBOX_H */ diff --git a/ffmpeg/inc/libavcodec/vorbis_parser.h b/ffmpeg/inc/libavcodec/vorbis_parser.h new file mode 100644 index 0000000..789932a --- /dev/null +++ b/ffmpeg/inc/libavcodec/vorbis_parser.h @@ -0,0 +1,74 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * A public API for Vorbis parsing + * + * Determines the duration for each packet. + */ + +#ifndef AVCODEC_VORBIS_PARSER_H +#define AVCODEC_VORBIS_PARSER_H + +#include + +typedef struct AVVorbisParseContext AVVorbisParseContext; + +/** + * Allocate and initialize the Vorbis parser using headers in the extradata. + */ +AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata, + int extradata_size); + +/** + * Free the parser and everything associated with it. + */ +void av_vorbis_parse_free(AVVorbisParseContext **s); + +#define VORBIS_FLAG_HEADER 0x00000001 +#define VORBIS_FLAG_COMMENT 0x00000002 +#define VORBIS_FLAG_SETUP 0x00000004 + +/** + * Get the duration for a Vorbis packet. + * + * If @p flags is @c NULL, + * special frames are considered invalid. + * + * @param s Vorbis parser context + * @param buf buffer containing a Vorbis frame + * @param buf_size size of the buffer + * @param flags flags for special frames + */ +int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf, + int buf_size, int *flags); + +/** + * Get the duration for a Vorbis packet. + * + * @param s Vorbis parser context + * @param buf buffer containing a Vorbis frame + * @param buf_size size of the buffer + */ +int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf, + int buf_size); + +void av_vorbis_parse_reset(AVVorbisParseContext *s); + +#endif /* AVCODEC_VORBIS_PARSER_H */ diff --git a/ffmpeg/inc/libavcodec/xvmc.h b/ffmpeg/inc/libavcodec/xvmc.h new file mode 100644 index 0000000..465ee78 --- /dev/null +++ b/ffmpeg/inc/libavcodec/xvmc.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2003 Ivan Kalvachev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_XVMC_H +#define AVCODEC_XVMC_H + +/** + * @file + * @ingroup lavc_codec_hwaccel_xvmc + * Public libavcodec XvMC header. + */ + +#include + +#include "libavutil/attributes.h" +#include "version.h" +#include "avcodec.h" + +/** + * @defgroup lavc_codec_hwaccel_xvmc XvMC + * @ingroup lavc_codec_hwaccel + * + * @{ + */ + +#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct + the number is 1337 speak for the letters IDCT MCo (motion compensation) */ + +struct attribute_deprecated xvmc_pix_fmt { + /** The field contains the special constant value AV_XVMC_ID. + It is used as a test that the application correctly uses the API, + and that there is no corruption caused by pixel routines. + - application - set during initialization + - libavcodec - unchanged + */ + int xvmc_id; + + /** Pointer to the block array allocated by XvMCCreateBlocks(). + The array has to be freed by XvMCDestroyBlocks(). + Each group of 64 values represents one data block of differential + pixel information (in MoCo mode) or coefficients for IDCT. + - application - set the pointer during initialization + - libavcodec - fills coefficients/pixel data into the array + */ + short* data_blocks; + + /** Pointer to the macroblock description array allocated by + XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks(). + - application - set the pointer during initialization + - libavcodec - fills description data into the array + */ + XvMCMacroBlock* mv_blocks; + + /** Number of macroblock descriptions that can be stored in the mv_blocks + array. + - application - set during initialization + - libavcodec - unchanged + */ + int allocated_mv_blocks; + + /** Number of blocks that can be stored at once in the data_blocks array. + - application - set during initialization + - libavcodec - unchanged + */ + int allocated_data_blocks; + + /** Indicate that the hardware would interpret data_blocks as IDCT + coefficients and perform IDCT on them. + - application - set during initialization + - libavcodec - unchanged + */ + int idct; + + /** In MoCo mode it indicates that intra macroblocks are assumed to be in + unsigned format; same as the XVMC_INTRA_UNSIGNED flag. + - application - set during initialization + - libavcodec - unchanged + */ + int unsigned_intra; + + /** Pointer to the surface allocated by XvMCCreateSurface(). + It has to be freed by XvMCDestroySurface() on application exit. + It identifies the frame and its state on the video hardware. + - application - set during initialization + - libavcodec - unchanged + */ + XvMCSurface* p_surface; + +/** Set by the decoder before calling ff_draw_horiz_band(), + needed by the XvMCRenderSurface function. */ +//@{ + /** Pointer to the surface used as past reference + - application - unchanged + - libavcodec - set + */ + XvMCSurface* p_past_surface; + + /** Pointer to the surface used as future reference + - application - unchanged + - libavcodec - set + */ + XvMCSurface* p_future_surface; + + /** top/bottom field or frame + - application - unchanged + - libavcodec - set + */ + unsigned int picture_structure; + + /** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence + - application - unchanged + - libavcodec - set + */ + unsigned int flags; +//}@ + + /** Number of macroblock descriptions in the mv_blocks array + that have already been passed to the hardware. + - application - zeroes it on get_buffer(). + A successful ff_draw_horiz_band() may increment it + with filled_mb_block_num or zero both. + - libavcodec - unchanged + */ + int start_mv_blocks_num; + + /** Number of new macroblock descriptions in the mv_blocks array (after + start_mv_blocks_num) that are filled by libavcodec and have to be + passed to the hardware. + - application - zeroes it on get_buffer() or after successful + ff_draw_horiz_band(). + - libavcodec - increment with one of each stored MB + */ + int filled_mv_blocks_num; + + /** Number of the next free data block; one data block consists of + 64 short values in the data_blocks array. + All blocks before this one have already been claimed by placing their + position into the corresponding block description structure field, + that are part of the mv_blocks array. + - application - zeroes it on get_buffer(). + A successful ff_draw_horiz_band() may zero it together + with start_mb_blocks_num. + - libavcodec - each decoded macroblock increases it by the number + of coded blocks it contains. + */ + int next_free_data_block_num; +}; + +/** + * @} + */ + +#endif /* AVCODEC_XVMC_H */ diff --git a/ffmpeg/inc/libavdevice/avdevice.h b/ffmpeg/inc/libavdevice/avdevice.h new file mode 100644 index 0000000..ee94624 --- /dev/null +++ b/ffmpeg/inc/libavdevice/avdevice.h @@ -0,0 +1,514 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVDEVICE_AVDEVICE_H +#define AVDEVICE_AVDEVICE_H + +#include "version.h" + +/** + * @file + * @ingroup lavd + * Main libavdevice API header + */ + +/** + * @defgroup lavd libavdevice + * Special devices muxing/demuxing library. + * + * Libavdevice is a complementary library to @ref libavf "libavformat". It + * provides various "special" platform-specific muxers and demuxers, e.g. for + * grabbing devices, audio capture and playback etc. As a consequence, the + * (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own + * I/O functions). The filename passed to avformat_open_input() often does not + * refer to an actually existing file, but has some special device-specific + * meaning - e.g. for xcbgrab it is the display name. + * + * To use libavdevice, simply call avdevice_register_all() to register all + * compiled muxers and demuxers. They all use standard libavformat API. + * + * @{ + */ + +#include "libavutil/log.h" +#include "libavutil/opt.h" +#include "libavutil/dict.h" +#include "libavformat/avformat.h" + +/** + * Return the LIBAVDEVICE_VERSION_INT constant. + */ +unsigned avdevice_version(void); + +/** + * Return the libavdevice build-time configuration. + */ +const char *avdevice_configuration(void); + +/** + * Return the libavdevice license. + */ +const char *avdevice_license(void); + +/** + * Initialize libavdevice and register all the input and output devices. + */ +void avdevice_register_all(void); + +/** + * Audio input devices iterator. + * + * If d is NULL, returns the first registered input audio/video device, + * if d is non-NULL, returns the next registered input audio/video device after d + * or NULL if d is the last one. + */ +AVInputFormat *av_input_audio_device_next(AVInputFormat *d); + +/** + * Video input devices iterator. + * + * If d is NULL, returns the first registered input audio/video device, + * if d is non-NULL, returns the next registered input audio/video device after d + * or NULL if d is the last one. + */ +AVInputFormat *av_input_video_device_next(AVInputFormat *d); + +/** + * Audio output devices iterator. + * + * If d is NULL, returns the first registered output audio/video device, + * if d is non-NULL, returns the next registered output audio/video device after d + * or NULL if d is the last one. + */ +AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d); + +/** + * Video output devices iterator. + * + * If d is NULL, returns the first registered output audio/video device, + * if d is non-NULL, returns the next registered output audio/video device after d + * or NULL if d is the last one. + */ +AVOutputFormat *av_output_video_device_next(AVOutputFormat *d); + +typedef struct AVDeviceRect { + int x; /**< x coordinate of top left corner */ + int y; /**< y coordinate of top left corner */ + int width; /**< width */ + int height; /**< height */ +} AVDeviceRect; + +/** + * Message types used by avdevice_app_to_dev_control_message(). + */ +enum AVAppToDevMessageType { + /** + * Dummy message. + */ + AV_APP_TO_DEV_NONE = MKBETAG('N','O','N','E'), + + /** + * Window size change message. + * + * Message is sent to the device every time the application changes the size + * of the window device renders to. + * Message should also be sent right after window is created. + * + * data: AVDeviceRect: new window size. + */ + AV_APP_TO_DEV_WINDOW_SIZE = MKBETAG('G','E','O','M'), + + /** + * Repaint request message. + * + * Message is sent to the device when window has to be repainted. + * + * data: AVDeviceRect: area required to be repainted. + * NULL: whole area is required to be repainted. + */ + AV_APP_TO_DEV_WINDOW_REPAINT = MKBETAG('R','E','P','A'), + + /** + * Request pause/play. + * + * Application requests pause/unpause playback. + * Mostly usable with devices that have internal buffer. + * By default devices are not paused. + * + * data: NULL + */ + AV_APP_TO_DEV_PAUSE = MKBETAG('P', 'A', 'U', ' '), + AV_APP_TO_DEV_PLAY = MKBETAG('P', 'L', 'A', 'Y'), + AV_APP_TO_DEV_TOGGLE_PAUSE = MKBETAG('P', 'A', 'U', 'T'), + + /** + * Volume control message. + * + * Set volume level. It may be device-dependent if volume + * is changed per stream or system wide. Per stream volume + * change is expected when possible. + * + * data: double: new volume with range of 0.0 - 1.0. + */ + AV_APP_TO_DEV_SET_VOLUME = MKBETAG('S', 'V', 'O', 'L'), + + /** + * Mute control messages. + * + * Change mute state. It may be device-dependent if mute status + * is changed per stream or system wide. Per stream mute status + * change is expected when possible. + * + * data: NULL. + */ + AV_APP_TO_DEV_MUTE = MKBETAG(' ', 'M', 'U', 'T'), + AV_APP_TO_DEV_UNMUTE = MKBETAG('U', 'M', 'U', 'T'), + AV_APP_TO_DEV_TOGGLE_MUTE = MKBETAG('T', 'M', 'U', 'T'), + + /** + * Get volume/mute messages. + * + * Force the device to send AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED or + * AV_DEV_TO_APP_MUTE_STATE_CHANGED command respectively. + * + * data: NULL. + */ + AV_APP_TO_DEV_GET_VOLUME = MKBETAG('G', 'V', 'O', 'L'), + AV_APP_TO_DEV_GET_MUTE = MKBETAG('G', 'M', 'U', 'T'), +}; + +/** + * Message types used by avdevice_dev_to_app_control_message(). + */ +enum AVDevToAppMessageType { + /** + * Dummy message. + */ + AV_DEV_TO_APP_NONE = MKBETAG('N','O','N','E'), + + /** + * Create window buffer message. + * + * Device requests to create a window buffer. Exact meaning is device- + * and application-dependent. Message is sent before rendering first + * frame and all one-shot initializations should be done here. + * Application is allowed to ignore preferred window buffer size. + * + * @note: Application is obligated to inform about window buffer size + * with AV_APP_TO_DEV_WINDOW_SIZE message. + * + * data: AVDeviceRect: preferred size of the window buffer. + * NULL: no preferred size of the window buffer. + */ + AV_DEV_TO_APP_CREATE_WINDOW_BUFFER = MKBETAG('B','C','R','E'), + + /** + * Prepare window buffer message. + * + * Device requests to prepare a window buffer for rendering. + * Exact meaning is device- and application-dependent. + * Message is sent before rendering of each frame. + * + * data: NULL. + */ + AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER = MKBETAG('B','P','R','E'), + + /** + * Display window buffer message. + * + * Device requests to display a window buffer. + * Message is sent when new frame is ready to be displayed. + * Usually buffers need to be swapped in handler of this message. + * + * data: NULL. + */ + AV_DEV_TO_APP_DISPLAY_WINDOW_BUFFER = MKBETAG('B','D','I','S'), + + /** + * Destroy window buffer message. + * + * Device requests to destroy a window buffer. + * Message is sent when device is about to be destroyed and window + * buffer is not required anymore. + * + * data: NULL. + */ + AV_DEV_TO_APP_DESTROY_WINDOW_BUFFER = MKBETAG('B','D','E','S'), + + /** + * Buffer fullness status messages. + * + * Device signals buffer overflow/underflow. + * + * data: NULL. + */ + AV_DEV_TO_APP_BUFFER_OVERFLOW = MKBETAG('B','O','F','L'), + AV_DEV_TO_APP_BUFFER_UNDERFLOW = MKBETAG('B','U','F','L'), + + /** + * Buffer readable/writable. + * + * Device informs that buffer is readable/writable. + * When possible, device informs how many bytes can be read/write. + * + * @warning Device may not inform when number of bytes than can be read/write changes. + * + * data: int64_t: amount of bytes available to read/write. + * NULL: amount of bytes available to read/write is not known. + */ + AV_DEV_TO_APP_BUFFER_READABLE = MKBETAG('B','R','D',' '), + AV_DEV_TO_APP_BUFFER_WRITABLE = MKBETAG('B','W','R',' '), + + /** + * Mute state change message. + * + * Device informs that mute state has changed. + * + * data: int: 0 for not muted state, non-zero for muted state. + */ + AV_DEV_TO_APP_MUTE_STATE_CHANGED = MKBETAG('C','M','U','T'), + + /** + * Volume level change message. + * + * Device informs that volume level has changed. + * + * data: double: new volume with range of 0.0 - 1.0. + */ + AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED = MKBETAG('C','V','O','L'), +}; + +/** + * Send control message from application to device. + * + * @param s device context. + * @param type message type. + * @param data message data. Exact type depends on message type. + * @param data_size size of message data. + * @return >= 0 on success, negative on error. + * AVERROR(ENOSYS) when device doesn't implement handler of the message. + */ +int avdevice_app_to_dev_control_message(struct AVFormatContext *s, + enum AVAppToDevMessageType type, + void *data, size_t data_size); + +/** + * Send control message from device to application. + * + * @param s device context. + * @param type message type. + * @param data message data. Can be NULL. + * @param data_size size of message data. + * @return >= 0 on success, negative on error. + * AVERROR(ENOSYS) when application doesn't implement handler of the message. + */ +int avdevice_dev_to_app_control_message(struct AVFormatContext *s, + enum AVDevToAppMessageType type, + void *data, size_t data_size); + +/** + * Following API allows user to probe device capabilities (supported codecs, + * pixel formats, sample formats, resolutions, channel counts, etc). + * It is build on top op AVOption API. + * Queried capabilities make it possible to set up converters of video or audio + * parameters that fit to the device. + * + * List of capabilities that can be queried: + * - Capabilities valid for both audio and video devices: + * - codec: supported audio/video codecs. + * type: AV_OPT_TYPE_INT (AVCodecID value) + * - Capabilities valid for audio devices: + * - sample_format: supported sample formats. + * type: AV_OPT_TYPE_INT (AVSampleFormat value) + * - sample_rate: supported sample rates. + * type: AV_OPT_TYPE_INT + * - channels: supported number of channels. + * type: AV_OPT_TYPE_INT + * - channel_layout: supported channel layouts. + * type: AV_OPT_TYPE_INT64 + * - Capabilities valid for video devices: + * - pixel_format: supported pixel formats. + * type: AV_OPT_TYPE_INT (AVPixelFormat value) + * - window_size: supported window sizes (describes size of the window size presented to the user). + * type: AV_OPT_TYPE_IMAGE_SIZE + * - frame_size: supported frame sizes (describes size of provided video frames). + * type: AV_OPT_TYPE_IMAGE_SIZE + * - fps: supported fps values + * type: AV_OPT_TYPE_RATIONAL + * + * Value of the capability may be set by user using av_opt_set() function + * and AVDeviceCapabilitiesQuery object. Following queries will + * limit results to the values matching already set capabilities. + * For example, setting a codec may impact number of formats or fps values + * returned during next query. Setting invalid value may limit results to zero. + * + * Example of the usage basing on opengl output device: + * + * @code + * AVFormatContext *oc = NULL; + * AVDeviceCapabilitiesQuery *caps = NULL; + * AVOptionRanges *ranges; + * int ret; + * + * if ((ret = avformat_alloc_output_context2(&oc, NULL, "opengl", NULL)) < 0) + * goto fail; + * if (avdevice_capabilities_create(&caps, oc, NULL) < 0) + * goto fail; + * + * //query codecs + * if (av_opt_query_ranges(&ranges, caps, "codec", AV_OPT_MULTI_COMPONENT_RANGE)) < 0) + * goto fail; + * //pick codec here and set it + * av_opt_set(caps, "codec", AV_CODEC_ID_RAWVIDEO, 0); + * + * //query format + * if (av_opt_query_ranges(&ranges, caps, "pixel_format", AV_OPT_MULTI_COMPONENT_RANGE)) < 0) + * goto fail; + * //pick format here and set it + * av_opt_set(caps, "pixel_format", AV_PIX_FMT_YUV420P, 0); + * + * //query and set more capabilities + * + * fail: + * //clean up code + * avdevice_capabilities_free(&query, oc); + * avformat_free_context(oc); + * @endcode + */ + +/** + * Structure describes device capabilities. + * + * It is used by devices in conjunction with av_device_capabilities AVOption table + * to implement capabilities probing API based on AVOption API. Should not be used directly. + */ +typedef struct AVDeviceCapabilitiesQuery { + const AVClass *av_class; + AVFormatContext *device_context; + enum AVCodecID codec; + enum AVSampleFormat sample_format; + enum AVPixelFormat pixel_format; + int sample_rate; + int channels; + int64_t channel_layout; + int window_width; + int window_height; + int frame_width; + int frame_height; + AVRational fps; +} AVDeviceCapabilitiesQuery; + +/** + * AVOption table used by devices to implement device capabilities API. Should not be used by a user. + */ +extern const AVOption av_device_capabilities[]; + +/** + * Initialize capabilities probing API based on AVOption API. + * + * avdevice_capabilities_free() must be called when query capabilities API is + * not used anymore. + * + * @param[out] caps Device capabilities data. Pointer to a NULL pointer must be passed. + * @param s Context of the device. + * @param device_options An AVDictionary filled with device-private options. + * On return this parameter will be destroyed and replaced with a dict + * containing options that were not found. May be NULL. + * The same options must be passed later to avformat_write_header() for output + * devices or avformat_open_input() for input devices, or at any other place + * that affects device-private options. + * + * @return >= 0 on success, negative otherwise. + */ +int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s, + AVDictionary **device_options); + +/** + * Free resources created by avdevice_capabilities_create() + * + * @param caps Device capabilities data to be freed. + * @param s Context of the device. + */ +void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s); + +/** + * Structure describes basic parameters of the device. + */ +typedef struct AVDeviceInfo { + char *device_name; /**< device name, format depends on device */ + char *device_description; /**< human friendly name */ +} AVDeviceInfo; + +/** + * List of devices. + */ +typedef struct AVDeviceInfoList { + AVDeviceInfo **devices; /**< list of autodetected devices */ + int nb_devices; /**< number of autodetected devices */ + int default_device; /**< index of default device or -1 if no default */ +} AVDeviceInfoList; + +/** + * List devices. + * + * Returns available device names and their parameters. + * + * @note: Some devices may accept system-dependent device names that cannot be + * autodetected. The list returned by this function cannot be assumed to + * be always completed. + * + * @param s device context. + * @param[out] device_list list of autodetected devices. + * @return count of autodetected devices, negative on error. + */ +int avdevice_list_devices(struct AVFormatContext *s, AVDeviceInfoList **device_list); + +/** + * Convenient function to free result of avdevice_list_devices(). + * + * @param devices device list to be freed. + */ +void avdevice_free_list_devices(AVDeviceInfoList **device_list); + +/** + * List devices. + * + * Returns available device names and their parameters. + * These are convinient wrappers for avdevice_list_devices(). + * Device context is allocated and deallocated internally. + * + * @param device device format. May be NULL if device name is set. + * @param device_name device name. May be NULL if device format is set. + * @param device_options An AVDictionary filled with device-private options. May be NULL. + * The same options must be passed later to avformat_write_header() for output + * devices or avformat_open_input() for input devices, or at any other place + * that affects device-private options. + * @param[out] device_list list of autodetected devices + * @return count of autodetected devices, negative on error. + * @note device argument takes precedence over device_name when both are set. + */ +int avdevice_list_input_sources(struct AVInputFormat *device, const char *device_name, + AVDictionary *device_options, AVDeviceInfoList **device_list); +int avdevice_list_output_sinks(struct AVOutputFormat *device, const char *device_name, + AVDictionary *device_options, AVDeviceInfoList **device_list); + +/** + * @} + */ + +#endif /* AVDEVICE_AVDEVICE_H */ diff --git a/ffmpeg/inc/libavdevice/version.h b/ffmpeg/inc/libavdevice/version.h new file mode 100644 index 0000000..9ee3d3d --- /dev/null +++ b/ffmpeg/inc/libavdevice/version.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVDEVICE_VERSION_H +#define AVDEVICE_VERSION_H + +/** + * @file + * @ingroup lavd + * Libavdevice version macros + */ + +#include "libavutil/version.h" + +#define LIBAVDEVICE_VERSION_MAJOR 58 +#define LIBAVDEVICE_VERSION_MINOR 10 +#define LIBAVDEVICE_VERSION_MICRO 100 + +#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ + LIBAVDEVICE_VERSION_MINOR, \ + LIBAVDEVICE_VERSION_MICRO) +#define LIBAVDEVICE_VERSION AV_VERSION(LIBAVDEVICE_VERSION_MAJOR, \ + LIBAVDEVICE_VERSION_MINOR, \ + LIBAVDEVICE_VERSION_MICRO) +#define LIBAVDEVICE_BUILD LIBAVDEVICE_VERSION_INT + +#define LIBAVDEVICE_IDENT "Lavd" AV_STRINGIFY(LIBAVDEVICE_VERSION) + +/** + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + */ + +#endif /* AVDEVICE_VERSION_H */ diff --git a/ffmpeg/inc/libavfilter/avfilter.h b/ffmpeg/inc/libavfilter/avfilter.h new file mode 100644 index 0000000..49b4f7a --- /dev/null +++ b/ffmpeg/inc/libavfilter/avfilter.h @@ -0,0 +1,1168 @@ +/* + * filter layer + * Copyright (c) 2007 Bobby Bingham + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_AVFILTER_H +#define AVFILTER_AVFILTER_H + +/** + * @file + * @ingroup lavfi + * Main libavfilter public API header + */ + +/** + * @defgroup lavfi libavfilter + * Graph-based frame editing library. + * + * @{ + */ + +#include + +#include "libavutil/attributes.h" +#include "libavutil/avutil.h" +#include "libavutil/buffer.h" +#include "libavutil/dict.h" +#include "libavutil/frame.h" +#include "libavutil/log.h" +#include "libavutil/samplefmt.h" +#include "libavutil/pixfmt.h" +#include "libavutil/rational.h" + +#include "libavfilter/version.h" + +/** + * Return the LIBAVFILTER_VERSION_INT constant. + */ +unsigned avfilter_version(void); + +/** + * Return the libavfilter build-time configuration. + */ +const char *avfilter_configuration(void); + +/** + * Return the libavfilter license. + */ +const char *avfilter_license(void); + +typedef struct AVFilterContext AVFilterContext; +typedef struct AVFilterLink AVFilterLink; +typedef struct AVFilterPad AVFilterPad; +typedef struct AVFilterFormats AVFilterFormats; + +/** + * Get the number of elements in a NULL-terminated array of AVFilterPads (e.g. + * AVFilter.inputs/outputs). + */ +int avfilter_pad_count(const AVFilterPad *pads); + +/** + * Get the name of an AVFilterPad. + * + * @param pads an array of AVFilterPads + * @param pad_idx index of the pad in the array; it is the caller's + * responsibility to ensure the index is valid + * + * @return name of the pad_idx'th pad in pads + */ +const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx); + +/** + * Get the type of an AVFilterPad. + * + * @param pads an array of AVFilterPads + * @param pad_idx index of the pad in the array; it is the caller's + * responsibility to ensure the index is valid + * + * @return type of the pad_idx'th pad in pads + */ +enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx); + +/** + * The number of the filter inputs is not determined just by AVFilter.inputs. + * The filter might add additional inputs during initialization depending on the + * options supplied to it. + */ +#define AVFILTER_FLAG_DYNAMIC_INPUTS (1 << 0) +/** + * The number of the filter outputs is not determined just by AVFilter.outputs. + * The filter might add additional outputs during initialization depending on + * the options supplied to it. + */ +#define AVFILTER_FLAG_DYNAMIC_OUTPUTS (1 << 1) +/** + * The filter supports multithreading by splitting frames into multiple parts + * and processing them concurrently. + */ +#define AVFILTER_FLAG_SLICE_THREADS (1 << 2) +/** + * Some filters support a generic "enable" expression option that can be used + * to enable or disable a filter in the timeline. Filters supporting this + * option have this flag set. When the enable expression is false, the default + * no-op filter_frame() function is called in place of the filter_frame() + * callback defined on each input pad, thus the frame is passed unchanged to + * the next filters. + */ +#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC (1 << 16) +/** + * Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will + * have its filter_frame() callback(s) called as usual even when the enable + * expression is false. The filter will disable filtering within the + * filter_frame() callback(s) itself, for example executing code depending on + * the AVFilterContext->is_disabled value. + */ +#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL (1 << 17) +/** + * Handy mask to test whether the filter supports or no the timeline feature + * (internally or generically). + */ +#define AVFILTER_FLAG_SUPPORT_TIMELINE (AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL) + +/** + * Filter definition. This defines the pads a filter contains, and all the + * callback functions used to interact with the filter. + */ +typedef struct AVFilter { + /** + * Filter name. Must be non-NULL and unique among filters. + */ + const char *name; + + /** + * A description of the filter. May be NULL. + * + * You should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *description; + + /** + * List of inputs, terminated by a zeroed element. + * + * NULL if there are no (static) inputs. Instances of filters with + * AVFILTER_FLAG_DYNAMIC_INPUTS set may have more inputs than present in + * this list. + */ + const AVFilterPad *inputs; + /** + * List of outputs, terminated by a zeroed element. + * + * NULL if there are no (static) outputs. Instances of filters with + * AVFILTER_FLAG_DYNAMIC_OUTPUTS set may have more outputs than present in + * this list. + */ + const AVFilterPad *outputs; + + /** + * A class for the private data, used to declare filter private AVOptions. + * This field is NULL for filters that do not declare any options. + * + * If this field is non-NULL, the first member of the filter private data + * must be a pointer to AVClass, which will be set by libavfilter generic + * code to this class. + */ + const AVClass *priv_class; + + /** + * A combination of AVFILTER_FLAG_* + */ + int flags; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavfilter and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + + /** + * Filter pre-initialization function + * + * This callback will be called immediately after the filter context is + * allocated, to allow allocating and initing sub-objects. + * + * If this callback is not NULL, the uninit callback will be called on + * allocation failure. + * + * @return 0 on success, + * AVERROR code on failure (but the code will be + * dropped and treated as ENOMEM by the calling code) + */ + int (*preinit)(AVFilterContext *ctx); + + /** + * Filter initialization function. + * + * This callback will be called only once during the filter lifetime, after + * all the options have been set, but before links between filters are + * established and format negotiation is done. + * + * Basic filter initialization should be done here. Filters with dynamic + * inputs and/or outputs should create those inputs/outputs here based on + * provided options. No more changes to this filter's inputs/outputs can be + * done after this callback. + * + * This callback must not assume that the filter links exist or frame + * parameters are known. + * + * @ref AVFilter.uninit "uninit" is guaranteed to be called even if + * initialization fails, so this callback does not have to clean up on + * failure. + * + * @return 0 on success, a negative AVERROR on failure + */ + int (*init)(AVFilterContext *ctx); + + /** + * Should be set instead of @ref AVFilter.init "init" by the filters that + * want to pass a dictionary of AVOptions to nested contexts that are + * allocated during init. + * + * On return, the options dict should be freed and replaced with one that + * contains all the options which could not be processed by this filter (or + * with NULL if all the options were processed). + * + * Otherwise the semantics is the same as for @ref AVFilter.init "init". + */ + int (*init_dict)(AVFilterContext *ctx, AVDictionary **options); + + /** + * Filter uninitialization function. + * + * Called only once right before the filter is freed. Should deallocate any + * memory held by the filter, release any buffer references, etc. It does + * not need to deallocate the AVFilterContext.priv memory itself. + * + * This callback may be called even if @ref AVFilter.init "init" was not + * called or failed, so it must be prepared to handle such a situation. + */ + void (*uninit)(AVFilterContext *ctx); + + /** + * Query formats supported by the filter on its inputs and outputs. + * + * This callback is called after the filter is initialized (so the inputs + * and outputs are fixed), shortly before the format negotiation. This + * callback may be called more than once. + * + * This callback must set AVFilterLink.out_formats on every input link and + * AVFilterLink.in_formats on every output link to a list of pixel/sample + * formats that the filter supports on that link. For audio links, this + * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" / + * @ref AVFilterLink.out_samplerates "out_samplerates" and + * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" / + * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously. + * + * This callback may be NULL for filters with one input, in which case + * libavfilter assumes that it supports all input formats and preserves + * them on output. + * + * @return zero on success, a negative value corresponding to an + * AVERROR code otherwise + */ + int (*query_formats)(AVFilterContext *); + + int priv_size; ///< size of private data to allocate for the filter + + int flags_internal; ///< Additional flags for avfilter internal use only. + + /** + * Used by the filter registration system. Must not be touched by any other + * code. + */ + struct AVFilter *next; + + /** + * Make the filter instance process a command. + * + * @param cmd the command to process, for handling simplicity all commands must be alphanumeric only + * @param arg the argument for the command + * @param res a buffer with size res_size where the filter(s) can return a response. This must not change when the command is not supported. + * @param flags if AVFILTER_CMD_FLAG_FAST is set and the command would be + * time consuming then a filter should treat it like an unsupported command + * + * @returns >=0 on success otherwise an error code. + * AVERROR(ENOSYS) on unsupported commands + */ + int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags); + + /** + * Filter initialization function, alternative to the init() + * callback. Args contains the user-supplied parameters, opaque is + * used for providing binary data. + */ + int (*init_opaque)(AVFilterContext *ctx, void *opaque); + + /** + * Filter activation function. + * + * Called when any processing is needed from the filter, instead of any + * filter_frame and request_frame on pads. + * + * The function must examine inlinks and outlinks and perform a single + * step of processing. If there is nothing to do, the function must do + * nothing and not return an error. If more steps are or may be + * possible, it must use ff_filter_set_ready() to schedule another + * activation. + */ + int (*activate)(AVFilterContext *ctx); +} AVFilter; + +/** + * Process multiple parts of the frame concurrently. + */ +#define AVFILTER_THREAD_SLICE (1 << 0) + +typedef struct AVFilterInternal AVFilterInternal; + +/** An instance of a filter */ +struct AVFilterContext { + const AVClass *av_class; ///< needed for av_log() and filters common options + + const AVFilter *filter; ///< the AVFilter of which this is an instance + + char *name; ///< name of this filter instance + + AVFilterPad *input_pads; ///< array of input pads + AVFilterLink **inputs; ///< array of pointers to input links + unsigned nb_inputs; ///< number of input pads + + AVFilterPad *output_pads; ///< array of output pads + AVFilterLink **outputs; ///< array of pointers to output links + unsigned nb_outputs; ///< number of output pads + + void *priv; ///< private data for use by the filter + + struct AVFilterGraph *graph; ///< filtergraph this filter belongs to + + /** + * Type of multithreading being allowed/used. A combination of + * AVFILTER_THREAD_* flags. + * + * May be set by the caller before initializing the filter to forbid some + * or all kinds of multithreading for this filter. The default is allowing + * everything. + * + * When the filter is initialized, this field is combined using bit AND with + * AVFilterGraph.thread_type to get the final mask used for determining + * allowed threading types. I.e. a threading type needs to be set in both + * to be allowed. + * + * After the filter is initialized, libavfilter sets this field to the + * threading type that is actually used (0 for no multithreading). + */ + int thread_type; + + /** + * An opaque struct for libavfilter internal use. + */ + AVFilterInternal *internal; + + struct AVFilterCommand *command_queue; + + char *enable_str; ///< enable expression string + void *enable; ///< parsed expression (AVExpr*) + double *var_values; ///< variable values for the enable expression + int is_disabled; ///< the enabled state from the last expression evaluation + + /** + * For filters which will create hardware frames, sets the device the + * filter should create them in. All other filters will ignore this field: + * in particular, a filter which consumes or processes hardware frames will + * instead use the hw_frames_ctx field in AVFilterLink to carry the + * hardware context information. + */ + AVBufferRef *hw_device_ctx; + + /** + * Max number of threads allowed in this filter instance. + * If <= 0, its value is ignored. + * Overrides global number of threads set per filter graph. + */ + int nb_threads; + + /** + * Ready status of the filter. + * A non-0 value means that the filter needs activating; + * a higher value suggests a more urgent activation. + */ + unsigned ready; + + /** + * Sets the number of extra hardware frames which the filter will + * allocate on its output links for use in following filters or by + * the caller. + * + * Some hardware filters require all frames that they will use for + * output to be defined in advance before filtering starts. For such + * filters, any hardware frame pools used for output must therefore be + * of fixed size. The extra frames set here are on top of any number + * that the filter needs internally in order to operate normally. + * + * This field must be set before the graph containing this filter is + * configured. + */ + int extra_hw_frames; +}; + +/** + * A link between two filters. This contains pointers to the source and + * destination filters between which this link exists, and the indexes of + * the pads involved. In addition, this link also contains the parameters + * which have been negotiated and agreed upon between the filter, such as + * image dimensions, format, etc. + * + * Applications must not normally access the link structure directly. + * Use the buffersrc and buffersink API instead. + * In the future, access to the header may be reserved for filters + * implementation. + */ +struct AVFilterLink { + AVFilterContext *src; ///< source filter + AVFilterPad *srcpad; ///< output pad on the source filter + + AVFilterContext *dst; ///< dest filter + AVFilterPad *dstpad; ///< input pad on the dest filter + + enum AVMediaType type; ///< filter media type + + /* These parameters apply only to video */ + int w; ///< agreed upon image width + int h; ///< agreed upon image height + AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio + /* These parameters apply only to audio */ + uint64_t channel_layout; ///< channel layout of current buffer (see libavutil/channel_layout.h) + int sample_rate; ///< samples per second + + int format; ///< agreed upon media format + + /** + * Define the time base used by the PTS of the frames/samples + * which will pass through this link. + * During the configuration stage, each filter is supposed to + * change only the output timebase, while the timebase of the + * input link is assumed to be an unchangeable property. + */ + AVRational time_base; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavfilter and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + /** + * Lists of formats and channel layouts supported by the input and output + * filters respectively. These lists are used for negotiating the format + * to actually be used, which will be loaded into the format and + * channel_layout members, above, when chosen. + * + */ + AVFilterFormats *in_formats; + AVFilterFormats *out_formats; + + /** + * Lists of channel layouts and sample rates used for automatic + * negotiation. + */ + AVFilterFormats *in_samplerates; + AVFilterFormats *out_samplerates; + struct AVFilterChannelLayouts *in_channel_layouts; + struct AVFilterChannelLayouts *out_channel_layouts; + + /** + * Audio only, the destination filter sets this to a non-zero value to + * request that buffers with the given number of samples should be sent to + * it. AVFilterPad.needs_fifo must also be set on the corresponding input + * pad. + * Last buffer before EOF will be padded with silence. + */ + int request_samples; + + /** stage of the initialization of the link properties (dimensions, etc) */ + enum { + AVLINK_UNINIT = 0, ///< not started + AVLINK_STARTINIT, ///< started, but incomplete + AVLINK_INIT ///< complete + } init_state; + + /** + * Graph the filter belongs to. + */ + struct AVFilterGraph *graph; + + /** + * Current timestamp of the link, as defined by the most recent + * frame(s), in link time_base units. + */ + int64_t current_pts; + + /** + * Current timestamp of the link, as defined by the most recent + * frame(s), in AV_TIME_BASE units. + */ + int64_t current_pts_us; + + /** + * Index in the age array. + */ + int age_index; + + /** + * Frame rate of the stream on the link, or 1/0 if unknown or variable; + * if left to 0/0, will be automatically copied from the first input + * of the source filter if it exists. + * + * Sources should set it to the best estimation of the real frame rate. + * If the source frame rate is unknown or variable, set this to 1/0. + * Filters should update it if necessary depending on their function. + * Sinks can use it to set a default output frame rate. + * It is similar to the r_frame_rate field in AVStream. + */ + AVRational frame_rate; + + /** + * Buffer partially filled with samples to achieve a fixed/minimum size. + */ + AVFrame *partial_buf; + + /** + * Size of the partial buffer to allocate. + * Must be between min_samples and max_samples. + */ + int partial_buf_size; + + /** + * Minimum number of samples to filter at once. If filter_frame() is + * called with fewer samples, it will accumulate them in partial_buf. + * This field and the related ones must not be changed after filtering + * has started. + * If 0, all related fields are ignored. + */ + int min_samples; + + /** + * Maximum number of samples to filter at once. If filter_frame() is + * called with more samples, it will split them. + */ + int max_samples; + + /** + * Number of channels. + */ + int channels; + + /** + * Link processing flags. + */ + unsigned flags; + + /** + * Number of past frames sent through the link. + */ + int64_t frame_count_in, frame_count_out; + + /** + * A pointer to a FFFramePool struct. + */ + void *frame_pool; + + /** + * True if a frame is currently wanted on the output of this filter. + * Set when ff_request_frame() is called by the output, + * cleared when a frame is filtered. + */ + int frame_wanted_out; + + /** + * For hwaccel pixel formats, this should be a reference to the + * AVHWFramesContext describing the frames. + */ + AVBufferRef *hw_frames_ctx; + +#ifndef FF_INTERNAL_FIELDS + + /** + * Internal structure members. + * The fields below this limit are internal for libavfilter's use + * and must in no way be accessed by applications. + */ + char reserved[0xF000]; + +#else /* FF_INTERNAL_FIELDS */ + + /** + * Queue of frames waiting to be filtered. + */ + FFFrameQueue fifo; + + /** + * If set, the source filter can not generate a frame as is. + * The goal is to avoid repeatedly calling the request_frame() method on + * the same link. + */ + int frame_blocked_in; + + /** + * Link input status. + * If not zero, all attempts of filter_frame will fail with the + * corresponding code. + */ + int status_in; + + /** + * Timestamp of the input status change. + */ + int64_t status_in_pts; + + /** + * Link output status. + * If not zero, all attempts of request_frame will fail with the + * corresponding code. + */ + int status_out; + +#endif /* FF_INTERNAL_FIELDS */ + +}; + +/** + * Link two filters together. + * + * @param src the source filter + * @param srcpad index of the output pad on the source filter + * @param dst the destination filter + * @param dstpad index of the input pad on the destination filter + * @return zero on success + */ +int avfilter_link(AVFilterContext *src, unsigned srcpad, + AVFilterContext *dst, unsigned dstpad); + +/** + * Free the link in *link, and set its pointer to NULL. + */ +void avfilter_link_free(AVFilterLink **link); + +#if FF_API_FILTER_GET_SET +/** + * Get the number of channels of a link. + * @deprecated Use av_buffersink_get_channels() + */ +attribute_deprecated +int avfilter_link_get_channels(AVFilterLink *link); +#endif + +/** + * Set the closed field of a link. + * @deprecated applications are not supposed to mess with links, they should + * close the sinks. + */ +attribute_deprecated +void avfilter_link_set_closed(AVFilterLink *link, int closed); + +/** + * Negotiate the media format, dimensions, etc of all inputs to a filter. + * + * @param filter the filter to negotiate the properties for its inputs + * @return zero on successful negotiation + */ +int avfilter_config_links(AVFilterContext *filter); + +#define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically +#define AVFILTER_CMD_FLAG_FAST 2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw) + +/** + * Make the filter instance process a command. + * It is recommended to use avfilter_graph_send_command(). + */ +int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags); + +/** + * Iterate over all registered filters. + * + * @param opaque a pointer where libavfilter will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered filter or NULL when the iteration is + * finished + */ +const AVFilter *av_filter_iterate(void **opaque); + +#if FF_API_NEXT +/** Initialize the filter system. Register all builtin filters. */ +attribute_deprecated +void avfilter_register_all(void); + +/** + * Register a filter. This is only needed if you plan to use + * avfilter_get_by_name later to lookup the AVFilter structure by name. A + * filter can still by instantiated with avfilter_graph_alloc_filter even if it + * is not registered. + * + * @param filter the filter to register + * @return 0 if the registration was successful, a negative value + * otherwise + */ +attribute_deprecated +int avfilter_register(AVFilter *filter); + +/** + * Iterate over all registered filters. + * @return If prev is non-NULL, next registered filter after prev or NULL if + * prev is the last filter. If prev is NULL, return the first registered filter. + */ +attribute_deprecated +const AVFilter *avfilter_next(const AVFilter *prev); +#endif + +/** + * Get a filter definition matching the given name. + * + * @param name the filter name to find + * @return the filter definition, if any matching one is registered. + * NULL if none found. + */ +const AVFilter *avfilter_get_by_name(const char *name); + + +/** + * Initialize a filter with the supplied parameters. + * + * @param ctx uninitialized filter context to initialize + * @param args Options to initialize the filter with. This must be a + * ':'-separated list of options in the 'key=value' form. + * May be NULL if the options have been set directly using the + * AVOptions API or there are no options that need to be set. + * @return 0 on success, a negative AVERROR on failure + */ +int avfilter_init_str(AVFilterContext *ctx, const char *args); + +/** + * Initialize a filter with the supplied dictionary of options. + * + * @param ctx uninitialized filter context to initialize + * @param options An AVDictionary filled with options for this filter. On + * return this parameter will be destroyed and replaced with + * a dict containing options that were not found. This dictionary + * must be freed by the caller. + * May be NULL, then this function is equivalent to + * avfilter_init_str() with the second parameter set to NULL. + * @return 0 on success, a negative AVERROR on failure + * + * @note This function and avfilter_init_str() do essentially the same thing, + * the difference is in manner in which the options are passed. It is up to the + * calling code to choose whichever is more preferable. The two functions also + * behave differently when some of the provided options are not declared as + * supported by the filter. In such a case, avfilter_init_str() will fail, but + * this function will leave those extra options in the options AVDictionary and + * continue as usual. + */ +int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options); + +/** + * Free a filter context. This will also remove the filter from its + * filtergraph's list of filters. + * + * @param filter the filter to free + */ +void avfilter_free(AVFilterContext *filter); + +/** + * Insert a filter in the middle of an existing link. + * + * @param link the link into which the filter should be inserted + * @param filt the filter to be inserted + * @param filt_srcpad_idx the input pad on the filter to connect + * @param filt_dstpad_idx the output pad on the filter to connect + * @return zero on success + */ +int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, + unsigned filt_srcpad_idx, unsigned filt_dstpad_idx); + +/** + * @return AVClass for AVFilterContext. + * + * @see av_opt_find(). + */ +const AVClass *avfilter_get_class(void); + +typedef struct AVFilterGraphInternal AVFilterGraphInternal; + +/** + * A function pointer passed to the @ref AVFilterGraph.execute callback to be + * executed multiple times, possibly in parallel. + * + * @param ctx the filter context the job belongs to + * @param arg an opaque parameter passed through from @ref + * AVFilterGraph.execute + * @param jobnr the index of the job being executed + * @param nb_jobs the total number of jobs + * + * @return 0 on success, a negative AVERROR on error + */ +typedef int (avfilter_action_func)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); + +/** + * A function executing multiple jobs, possibly in parallel. + * + * @param ctx the filter context to which the jobs belong + * @param func the function to be called multiple times + * @param arg the argument to be passed to func + * @param ret a nb_jobs-sized array to be filled with return values from each + * invocation of func + * @param nb_jobs the number of jobs to execute + * + * @return 0 on success, a negative AVERROR on error + */ +typedef int (avfilter_execute_func)(AVFilterContext *ctx, avfilter_action_func *func, + void *arg, int *ret, int nb_jobs); + +typedef struct AVFilterGraph { + const AVClass *av_class; + AVFilterContext **filters; + unsigned nb_filters; + + char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters +#if FF_API_LAVR_OPTS + attribute_deprecated char *resample_lavr_opts; ///< libavresample options to use for the auto-inserted resample filters +#endif + + /** + * Type of multithreading allowed for filters in this graph. A combination + * of AVFILTER_THREAD_* flags. + * + * May be set by the caller at any point, the setting will apply to all + * filters initialized after that. The default is allowing everything. + * + * When a filter in this graph is initialized, this field is combined using + * bit AND with AVFilterContext.thread_type to get the final mask used for + * determining allowed threading types. I.e. a threading type needs to be + * set in both to be allowed. + */ + int thread_type; + + /** + * Maximum number of threads used by filters in this graph. May be set by + * the caller before adding any filters to the filtergraph. Zero (the + * default) means that the number of threads is determined automatically. + */ + int nb_threads; + + /** + * Opaque object for libavfilter internal use. + */ + AVFilterGraphInternal *internal; + + /** + * Opaque user data. May be set by the caller to an arbitrary value, e.g. to + * be used from callbacks like @ref AVFilterGraph.execute. + * Libavfilter will not touch this field in any way. + */ + void *opaque; + + /** + * This callback may be set by the caller immediately after allocating the + * graph and before adding any filters to it, to provide a custom + * multithreading implementation. + * + * If set, filters with slice threading capability will call this callback + * to execute multiple jobs in parallel. + * + * If this field is left unset, libavfilter will use its internal + * implementation, which may or may not be multithreaded depending on the + * platform and build options. + */ + avfilter_execute_func *execute; + + char *aresample_swr_opts; ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions + + /** + * Private fields + * + * The following fields are for internal use only. + * Their type, offset, number and semantic can change without notice. + */ + + AVFilterLink **sink_links; + int sink_links_count; + + unsigned disable_auto_convert; +} AVFilterGraph; + +/** + * Allocate a filter graph. + * + * @return the allocated filter graph on success or NULL. + */ +AVFilterGraph *avfilter_graph_alloc(void); + +/** + * Create a new filter instance in a filter graph. + * + * @param graph graph in which the new filter will be used + * @param filter the filter to create an instance of + * @param name Name to give to the new instance (will be copied to + * AVFilterContext.name). This may be used by the caller to identify + * different filters, libavfilter itself assigns no semantics to + * this parameter. May be NULL. + * + * @return the context of the newly created filter instance (note that it is + * also retrievable directly through AVFilterGraph.filters or with + * avfilter_graph_get_filter()) on success or NULL on failure. + */ +AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph, + const AVFilter *filter, + const char *name); + +/** + * Get a filter instance identified by instance name from graph. + * + * @param graph filter graph to search through. + * @param name filter instance name (should be unique in the graph). + * @return the pointer to the found filter instance or NULL if it + * cannot be found. + */ +AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name); + +/** + * Create and add a filter instance into an existing graph. + * The filter instance is created from the filter filt and inited + * with the parameter args. opaque is currently ignored. + * + * In case of success put in *filt_ctx the pointer to the created + * filter instance, otherwise set *filt_ctx to NULL. + * + * @param name the instance name to give to the created filter instance + * @param graph_ctx the filter graph + * @return a negative AVERROR error code in case of failure, a non + * negative value otherwise + */ +int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, + const char *name, const char *args, void *opaque, + AVFilterGraph *graph_ctx); + +/** + * Enable or disable automatic format conversion inside the graph. + * + * Note that format conversion can still happen inside explicitly inserted + * scale and aresample filters. + * + * @param flags any of the AVFILTER_AUTO_CONVERT_* constants + */ +void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags); + +enum { + AVFILTER_AUTO_CONVERT_ALL = 0, /**< all automatic conversions enabled */ + AVFILTER_AUTO_CONVERT_NONE = -1, /**< all automatic conversions disabled */ +}; + +/** + * Check validity and configure all the links and formats in the graph. + * + * @param graphctx the filter graph + * @param log_ctx context used for logging + * @return >= 0 in case of success, a negative AVERROR code otherwise + */ +int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx); + +/** + * Free a graph, destroy its links, and set *graph to NULL. + * If *graph is NULL, do nothing. + */ +void avfilter_graph_free(AVFilterGraph **graph); + +/** + * A linked-list of the inputs/outputs of the filter chain. + * + * This is mainly useful for avfilter_graph_parse() / avfilter_graph_parse2(), + * where it is used to communicate open (unlinked) inputs and outputs from and + * to the caller. + * This struct specifies, per each not connected pad contained in the graph, the + * filter context and the pad index required for establishing a link. + */ +typedef struct AVFilterInOut { + /** unique name for this input/output in the list */ + char *name; + + /** filter context associated to this input/output */ + AVFilterContext *filter_ctx; + + /** index of the filt_ctx pad to use for linking */ + int pad_idx; + + /** next input/input in the list, NULL if this is the last */ + struct AVFilterInOut *next; +} AVFilterInOut; + +/** + * Allocate a single AVFilterInOut entry. + * Must be freed with avfilter_inout_free(). + * @return allocated AVFilterInOut on success, NULL on failure. + */ +AVFilterInOut *avfilter_inout_alloc(void); + +/** + * Free the supplied list of AVFilterInOut and set *inout to NULL. + * If *inout is NULL, do nothing. + */ +void avfilter_inout_free(AVFilterInOut **inout); + +/** + * Add a graph described by a string to a graph. + * + * @note The caller must provide the lists of inputs and outputs, + * which therefore must be known before calling the function. + * + * @note The inputs parameter describes inputs of the already existing + * part of the graph; i.e. from the point of view of the newly created + * part, they are outputs. Similarly the outputs parameter describes + * outputs of the already existing filters, which are provided as + * inputs to the parsed filters. + * + * @param graph the filter graph where to link the parsed graph context + * @param filters string to be parsed + * @param inputs linked list to the inputs of the graph + * @param outputs linked list to the outputs of the graph + * @return zero on success, a negative AVERROR code on error + */ +int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, + AVFilterInOut *inputs, AVFilterInOut *outputs, + void *log_ctx); + +/** + * Add a graph described by a string to a graph. + * + * In the graph filters description, if the input label of the first + * filter is not specified, "in" is assumed; if the output label of + * the last filter is not specified, "out" is assumed. + * + * @param graph the filter graph where to link the parsed graph context + * @param filters string to be parsed + * @param inputs pointer to a linked list to the inputs of the graph, may be NULL. + * If non-NULL, *inputs is updated to contain the list of open inputs + * after the parsing, should be freed with avfilter_inout_free(). + * @param outputs pointer to a linked list to the outputs of the graph, may be NULL. + * If non-NULL, *outputs is updated to contain the list of open outputs + * after the parsing, should be freed with avfilter_inout_free(). + * @return non negative on success, a negative AVERROR code on error + */ +int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, + AVFilterInOut **inputs, AVFilterInOut **outputs, + void *log_ctx); + +/** + * Add a graph described by a string to a graph. + * + * @param[in] graph the filter graph where to link the parsed graph context + * @param[in] filters string to be parsed + * @param[out] inputs a linked list of all free (unlinked) inputs of the + * parsed graph will be returned here. It is to be freed + * by the caller using avfilter_inout_free(). + * @param[out] outputs a linked list of all free (unlinked) outputs of the + * parsed graph will be returned here. It is to be freed by the + * caller using avfilter_inout_free(). + * @return zero on success, a negative AVERROR code on error + * + * @note This function returns the inputs and outputs that are left + * unlinked after parsing the graph and the caller then deals with + * them. + * @note This function makes no reference whatsoever to already + * existing parts of the graph and the inputs parameter will on return + * contain inputs of the newly parsed part of the graph. Analogously + * the outputs parameter will contain outputs of the newly created + * filters. + */ +int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, + AVFilterInOut **inputs, + AVFilterInOut **outputs); + +/** + * Send a command to one or more filter instances. + * + * @param graph the filter graph + * @param target the filter(s) to which the command should be sent + * "all" sends to all filters + * otherwise it can be a filter or filter instance name + * which will send the command to all matching filters. + * @param cmd the command to send, for handling simplicity all commands must be alphanumeric only + * @param arg the argument for the command + * @param res a buffer with size res_size where the filter(s) can return a response. + * + * @returns >=0 on success otherwise an error code. + * AVERROR(ENOSYS) on unsupported commands + */ +int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags); + +/** + * Queue a command for one or more filter instances. + * + * @param graph the filter graph + * @param target the filter(s) to which the command should be sent + * "all" sends to all filters + * otherwise it can be a filter or filter instance name + * which will send the command to all matching filters. + * @param cmd the command to sent, for handling simplicity all commands must be alphanumeric only + * @param arg the argument for the command + * @param ts time at which the command should be sent to the filter + * + * @note As this executes commands after this function returns, no return code + * from the filter is provided, also AVFILTER_CMD_FLAG_ONE is not supported. + */ +int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts); + + +/** + * Dump a graph into a human-readable string representation. + * + * @param graph the graph to dump + * @param options formatting options; currently ignored + * @return a string, or NULL in case of memory allocation failure; + * the string must be freed using av_free + */ +char *avfilter_graph_dump(AVFilterGraph *graph, const char *options); + +/** + * Request a frame on the oldest sink link. + * + * If the request returns AVERROR_EOF, try the next. + * + * Note that this function is not meant to be the sole scheduling mechanism + * of a filtergraph, only a convenience function to help drain a filtergraph + * in a balanced way under normal circumstances. + * + * Also note that AVERROR_EOF does not mean that frames did not arrive on + * some of the sinks during the process. + * When there are multiple sink links, in case the requested link + * returns an EOF, this may cause a filter to flush pending frames + * which are sent to another sink link, although unrequested. + * + * @return the return value of ff_request_frame(), + * or AVERROR_EOF if all links returned AVERROR_EOF + */ +int avfilter_graph_request_oldest(AVFilterGraph *graph); + +/** + * @} + */ + +#endif /* AVFILTER_AVFILTER_H */ diff --git a/ffmpeg/inc/libavfilter/buffersink.h b/ffmpeg/inc/libavfilter/buffersink.h new file mode 100644 index 0000000..2ec821c --- /dev/null +++ b/ffmpeg/inc/libavfilter/buffersink.h @@ -0,0 +1,169 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_BUFFERSINK_H +#define AVFILTER_BUFFERSINK_H + +/** + * @file + * @ingroup lavfi_buffersink + * memory buffer sink API for audio and video + */ + +#include "avfilter.h" + +/** + * @defgroup lavfi_buffersink Buffer sink API + * @ingroup lavfi + * @{ + */ + +/** + * Get a frame with filtered data from sink and put it in frame. + * + * @param ctx pointer to a buffersink or abuffersink filter context. + * @param frame pointer to an allocated frame that will be filled with data. + * The data must be freed using av_frame_unref() / av_frame_free() + * @param flags a combination of AV_BUFFERSINK_FLAG_* flags + * + * @return >= 0 in for success, a negative AVERROR code for failure. + */ +int av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags); + +/** + * Tell av_buffersink_get_buffer_ref() to read video/samples buffer + * reference, but not remove it from the buffer. This is useful if you + * need only to read a video/samples buffer, without to fetch it. + */ +#define AV_BUFFERSINK_FLAG_PEEK 1 + +/** + * Tell av_buffersink_get_buffer_ref() not to request a frame from its input. + * If a frame is already buffered, it is read (and removed from the buffer), + * but if no frame is present, return AVERROR(EAGAIN). + */ +#define AV_BUFFERSINK_FLAG_NO_REQUEST 2 + +#if FF_API_NEXT +/** + * Struct to use for initializing a buffersink context. + */ +typedef struct AVBufferSinkParams { + const enum AVPixelFormat *pixel_fmts; ///< list of allowed pixel formats, terminated by AV_PIX_FMT_NONE +} AVBufferSinkParams; + +/** + * Create an AVBufferSinkParams structure. + * + * Must be freed with av_free(). + */ +attribute_deprecated +AVBufferSinkParams *av_buffersink_params_alloc(void); + +/** + * Struct to use for initializing an abuffersink context. + */ +typedef struct AVABufferSinkParams { + const enum AVSampleFormat *sample_fmts; ///< list of allowed sample formats, terminated by AV_SAMPLE_FMT_NONE + const int64_t *channel_layouts; ///< list of allowed channel layouts, terminated by -1 + const int *channel_counts; ///< list of allowed channel counts, terminated by -1 + int all_channel_counts; ///< if not 0, accept any channel count or layout + int *sample_rates; ///< list of allowed sample rates, terminated by -1 +} AVABufferSinkParams; + +/** + * Create an AVABufferSinkParams structure. + * + * Must be freed with av_free(). + */ +attribute_deprecated +AVABufferSinkParams *av_abuffersink_params_alloc(void); +#endif + +/** + * Set the frame size for an audio buffer sink. + * + * All calls to av_buffersink_get_buffer_ref will return a buffer with + * exactly the specified number of samples, or AVERROR(EAGAIN) if there is + * not enough. The last buffer at EOF will be padded with 0. + */ +void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size); + +/** + * @defgroup lavfi_buffersink_accessors Buffer sink accessors + * Get the properties of the stream + * @{ + */ + +enum AVMediaType av_buffersink_get_type (const AVFilterContext *ctx); +AVRational av_buffersink_get_time_base (const AVFilterContext *ctx); +int av_buffersink_get_format (const AVFilterContext *ctx); + +AVRational av_buffersink_get_frame_rate (const AVFilterContext *ctx); +int av_buffersink_get_w (const AVFilterContext *ctx); +int av_buffersink_get_h (const AVFilterContext *ctx); +AVRational av_buffersink_get_sample_aspect_ratio (const AVFilterContext *ctx); + +int av_buffersink_get_channels (const AVFilterContext *ctx); +uint64_t av_buffersink_get_channel_layout (const AVFilterContext *ctx); +int av_buffersink_get_sample_rate (const AVFilterContext *ctx); + +AVBufferRef * av_buffersink_get_hw_frames_ctx (const AVFilterContext *ctx); + +/** @} */ + +/** + * Get a frame with filtered data from sink and put it in frame. + * + * @param ctx pointer to a context of a buffersink or abuffersink AVFilter. + * @param frame pointer to an allocated frame that will be filled with data. + * The data must be freed using av_frame_unref() / av_frame_free() + * + * @return + * - >= 0 if a frame was successfully returned. + * - AVERROR(EAGAIN) if no frames are available at this point; more + * input frames must be added to the filtergraph to get more output. + * - AVERROR_EOF if there will be no more output frames on this sink. + * - A different negative AVERROR code in other failure cases. + */ +int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame); + +/** + * Same as av_buffersink_get_frame(), but with the ability to specify the number + * of samples read. This function is less efficient than + * av_buffersink_get_frame(), because it copies the data around. + * + * @param ctx pointer to a context of the abuffersink AVFilter. + * @param frame pointer to an allocated frame that will be filled with data. + * The data must be freed using av_frame_unref() / av_frame_free() + * frame will contain exactly nb_samples audio samples, except at + * the end of stream, when it can contain less than nb_samples. + * + * @return The return codes have the same meaning as for + * av_buffersink_get_frame(). + * + * @warning do not mix this function with av_buffersink_get_frame(). Use only one or + * the other with a single sink, not both. + */ +int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples); + +/** + * @} + */ + +#endif /* AVFILTER_BUFFERSINK_H */ diff --git a/ffmpeg/inc/libavfilter/buffersrc.h b/ffmpeg/inc/libavfilter/buffersrc.h new file mode 100644 index 0000000..08fbd18 --- /dev/null +++ b/ffmpeg/inc/libavfilter/buffersrc.h @@ -0,0 +1,209 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_BUFFERSRC_H +#define AVFILTER_BUFFERSRC_H + +/** + * @file + * @ingroup lavfi_buffersrc + * Memory buffer source API. + */ + +#include "avfilter.h" + +/** + * @defgroup lavfi_buffersrc Buffer source API + * @ingroup lavfi + * @{ + */ + +enum { + + /** + * Do not check for format changes. + */ + AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT = 1, + + /** + * Immediately push the frame to the output. + */ + AV_BUFFERSRC_FLAG_PUSH = 4, + + /** + * Keep a reference to the frame. + * If the frame if reference-counted, create a new reference; otherwise + * copy the frame data. + */ + AV_BUFFERSRC_FLAG_KEEP_REF = 8, + +}; + +/** + * Get the number of failed requests. + * + * A failed request is when the request_frame method is called while no + * frame is present in the buffer. + * The number is reset when a frame is added. + */ +unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src); + +/** + * This structure contains the parameters describing the frames that will be + * passed to this filter. + * + * It should be allocated with av_buffersrc_parameters_alloc() and freed with + * av_free(). All the allocated fields in it remain owned by the caller. + */ +typedef struct AVBufferSrcParameters { + /** + * video: the pixel format, value corresponds to enum AVPixelFormat + * audio: the sample format, value corresponds to enum AVSampleFormat + */ + int format; + /** + * The timebase to be used for the timestamps on the input frames. + */ + AVRational time_base; + + /** + * Video only, the display dimensions of the input frames. + */ + int width, height; + + /** + * Video only, the sample (pixel) aspect ratio. + */ + AVRational sample_aspect_ratio; + + /** + * Video only, the frame rate of the input video. This field must only be + * set to a non-zero value if input stream has a known constant framerate + * and should be left at its initial value if the framerate is variable or + * unknown. + */ + AVRational frame_rate; + + /** + * Video with a hwaccel pixel format only. This should be a reference to an + * AVHWFramesContext instance describing the input frames. + */ + AVBufferRef *hw_frames_ctx; + + /** + * Audio only, the audio sampling rate in samples per second. + */ + int sample_rate; + + /** + * Audio only, the audio channel layout + */ + uint64_t channel_layout; +} AVBufferSrcParameters; + +/** + * Allocate a new AVBufferSrcParameters instance. It should be freed by the + * caller with av_free(). + */ +AVBufferSrcParameters *av_buffersrc_parameters_alloc(void); + +/** + * Initialize the buffersrc or abuffersrc filter with the provided parameters. + * This function may be called multiple times, the later calls override the + * previous ones. Some of the parameters may also be set through AVOptions, then + * whatever method is used last takes precedence. + * + * @param ctx an instance of the buffersrc or abuffersrc filter + * @param param the stream parameters. The frames later passed to this filter + * must conform to those parameters. All the allocated fields in + * param remain owned by the caller, libavfilter will make internal + * copies or references when necessary. + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *param); + +/** + * Add a frame to the buffer source. + * + * @param ctx an instance of the buffersrc filter + * @param frame frame to be added. If the frame is reference counted, this + * function will make a new reference to it. Otherwise the frame data will be + * copied. + * + * @return 0 on success, a negative AVERROR on error + * + * This function is equivalent to av_buffersrc_add_frame_flags() with the + * AV_BUFFERSRC_FLAG_KEEP_REF flag. + */ +av_warn_unused_result +int av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame); + +/** + * Add a frame to the buffer source. + * + * @param ctx an instance of the buffersrc filter + * @param frame frame to be added. If the frame is reference counted, this + * function will take ownership of the reference(s) and reset the frame. + * Otherwise the frame data will be copied. If this function returns an error, + * the input frame is not touched. + * + * @return 0 on success, a negative AVERROR on error. + * + * @note the difference between this function and av_buffersrc_write_frame() is + * that av_buffersrc_write_frame() creates a new reference to the input frame, + * while this function takes ownership of the reference passed to it. + * + * This function is equivalent to av_buffersrc_add_frame_flags() without the + * AV_BUFFERSRC_FLAG_KEEP_REF flag. + */ +av_warn_unused_result +int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame); + +/** + * Add a frame to the buffer source. + * + * By default, if the frame is reference-counted, this function will take + * ownership of the reference(s) and reset the frame. This can be controlled + * using the flags. + * + * If this function returns an error, the input frame is not touched. + * + * @param buffer_src pointer to a buffer source context + * @param frame a frame, or NULL to mark EOF + * @param flags a combination of AV_BUFFERSRC_FLAG_* + * @return >= 0 in case of success, a negative AVERROR code + * in case of failure + */ +av_warn_unused_result +int av_buffersrc_add_frame_flags(AVFilterContext *buffer_src, + AVFrame *frame, int flags); + +/** + * Close the buffer source after EOF. + * + * This is similar to passing NULL to av_buffersrc_add_frame_flags() + * except it takes the timestamp of the EOF, i.e. the timestamp of the end + * of the last frame. + */ +int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags); + +/** + * @} + */ + +#endif /* AVFILTER_BUFFERSRC_H */ diff --git a/ffmpeg/inc/libavfilter/version.h b/ffmpeg/inc/libavfilter/version.h new file mode 100644 index 0000000..96b14d6 --- /dev/null +++ b/ffmpeg/inc/libavfilter/version.h @@ -0,0 +1,69 @@ +/* + * Version macros. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_VERSION_H +#define AVFILTER_VERSION_H + +/** + * @file + * @ingroup lavfi + * Libavfilter version macros + */ + +#include "libavutil/version.h" + +#define LIBAVFILTER_VERSION_MAJOR 7 +#define LIBAVFILTER_VERSION_MINOR 85 +#define LIBAVFILTER_VERSION_MICRO 100 + + +#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ + LIBAVFILTER_VERSION_MINOR, \ + LIBAVFILTER_VERSION_MICRO) +#define LIBAVFILTER_VERSION AV_VERSION(LIBAVFILTER_VERSION_MAJOR, \ + LIBAVFILTER_VERSION_MINOR, \ + LIBAVFILTER_VERSION_MICRO) +#define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT + +#define LIBAVFILTER_IDENT "Lavfi" AV_STRINGIFY(LIBAVFILTER_VERSION) + +/** + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + */ + +#ifndef FF_API_OLD_FILTER_OPTS_ERROR +#define FF_API_OLD_FILTER_OPTS_ERROR (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_LAVR_OPTS +#define FF_API_LAVR_OPTS (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_FILTER_GET_SET +#define FF_API_FILTER_GET_SET (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_SWS_PARAM_OPTION +#define FF_API_SWS_PARAM_OPTION (LIBAVFILTER_VERSION_MAJOR < 8) +#endif +#ifndef FF_API_NEXT +#define FF_API_NEXT (LIBAVFILTER_VERSION_MAJOR < 8) +#endif + +#endif /* AVFILTER_VERSION_H */ diff --git a/ffmpeg/inc/libavformat/avformat.h b/ffmpeg/inc/libavformat/avformat.h new file mode 100644 index 0000000..21c282a --- /dev/null +++ b/ffmpeg/inc/libavformat/avformat.h @@ -0,0 +1,3093 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_AVFORMAT_H +#define AVFORMAT_AVFORMAT_H + +/** + * @file + * @ingroup libavf + * Main libavformat public API header + */ + +/** + * @defgroup libavf libavformat + * I/O and Muxing/Demuxing Library + * + * Libavformat (lavf) is a library for dealing with various media container + * formats. Its main two purposes are demuxing - i.e. splitting a media file + * into component streams, and the reverse process of muxing - writing supplied + * data in a specified container format. It also has an @ref lavf_io + * "I/O module" which supports a number of protocols for accessing the data (e.g. + * file, tcp, http and others). + * Unless you are absolutely sure you won't use libavformat's network + * capabilities, you should also call avformat_network_init(). + * + * A supported input format is described by an AVInputFormat struct, conversely + * an output format is described by AVOutputFormat. You can iterate over all + * input/output formats using the av_demuxer_iterate / av_muxer_iterate() functions. + * The protocols layer is not part of the public API, so you can only get the names + * of supported protocols with the avio_enum_protocols() function. + * + * Main lavf structure used for both muxing and demuxing is AVFormatContext, + * which exports all information about the file being read or written. As with + * most Libavformat structures, its size is not part of public ABI, so it cannot be + * allocated on stack or directly with av_malloc(). To create an + * AVFormatContext, use avformat_alloc_context() (some functions, like + * avformat_open_input() might do that for you). + * + * Most importantly an AVFormatContext contains: + * @li the @ref AVFormatContext.iformat "input" or @ref AVFormatContext.oformat + * "output" format. It is either autodetected or set by user for input; + * always set by user for output. + * @li an @ref AVFormatContext.streams "array" of AVStreams, which describe all + * elementary streams stored in the file. AVStreams are typically referred to + * using their index in this array. + * @li an @ref AVFormatContext.pb "I/O context". It is either opened by lavf or + * set by user for input, always set by user for output (unless you are dealing + * with an AVFMT_NOFILE format). + * + * @section lavf_options Passing options to (de)muxers + * It is possible to configure lavf muxers and demuxers using the @ref avoptions + * mechanism. Generic (format-independent) libavformat options are provided by + * AVFormatContext, they can be examined from a user program by calling + * av_opt_next() / av_opt_find() on an allocated AVFormatContext (or its AVClass + * from avformat_get_class()). Private (format-specific) options are provided by + * AVFormatContext.priv_data if and only if AVInputFormat.priv_class / + * AVOutputFormat.priv_class of the corresponding format struct is non-NULL. + * Further options may be provided by the @ref AVFormatContext.pb "I/O context", + * if its AVClass is non-NULL, and the protocols layer. See the discussion on + * nesting in @ref avoptions documentation to learn how to access those. + * + * @section urls + * URL strings in libavformat are made of a scheme/protocol, a ':', and a + * scheme specific string. URLs without a scheme and ':' used for local files + * are supported but deprecated. "file:" should be used for local files. + * + * It is important that the scheme string is not taken from untrusted + * sources without checks. + * + * Note that some schemes/protocols are quite powerful, allowing access to + * both local and remote files, parts of them, concatenations of them, local + * audio and video devices and so on. + * + * @{ + * + * @defgroup lavf_decoding Demuxing + * @{ + * Demuxers read a media file and split it into chunks of data (@em packets). A + * @ref AVPacket "packet" contains one or more encoded frames which belongs to a + * single elementary stream. In the lavf API this process is represented by the + * avformat_open_input() function for opening a file, av_read_frame() for + * reading a single packet and finally avformat_close_input(), which does the + * cleanup. + * + * @section lavf_decoding_open Opening a media file + * The minimum information required to open a file is its URL, which + * is passed to avformat_open_input(), as in the following code: + * @code + * const char *url = "file:in.mp3"; + * AVFormatContext *s = NULL; + * int ret = avformat_open_input(&s, url, NULL, NULL); + * if (ret < 0) + * abort(); + * @endcode + * The above code attempts to allocate an AVFormatContext, open the + * specified file (autodetecting the format) and read the header, exporting the + * information stored there into s. Some formats do not have a header or do not + * store enough information there, so it is recommended that you call the + * avformat_find_stream_info() function which tries to read and decode a few + * frames to find missing information. + * + * In some cases you might want to preallocate an AVFormatContext yourself with + * avformat_alloc_context() and do some tweaking on it before passing it to + * avformat_open_input(). One such case is when you want to use custom functions + * for reading input data instead of lavf internal I/O layer. + * To do that, create your own AVIOContext with avio_alloc_context(), passing + * your reading callbacks to it. Then set the @em pb field of your + * AVFormatContext to newly created AVIOContext. + * + * Since the format of the opened file is in general not known until after + * avformat_open_input() has returned, it is not possible to set demuxer private + * options on a preallocated context. Instead, the options should be passed to + * avformat_open_input() wrapped in an AVDictionary: + * @code + * AVDictionary *options = NULL; + * av_dict_set(&options, "video_size", "640x480", 0); + * av_dict_set(&options, "pixel_format", "rgb24", 0); + * + * if (avformat_open_input(&s, url, NULL, &options) < 0) + * abort(); + * av_dict_free(&options); + * @endcode + * This code passes the private options 'video_size' and 'pixel_format' to the + * demuxer. They would be necessary for e.g. the rawvideo demuxer, since it + * cannot know how to interpret raw video data otherwise. If the format turns + * out to be something different than raw video, those options will not be + * recognized by the demuxer and therefore will not be applied. Such unrecognized + * options are then returned in the options dictionary (recognized options are + * consumed). The calling program can handle such unrecognized options as it + * wishes, e.g. + * @code + * AVDictionaryEntry *e; + * if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX)) { + * fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key); + * abort(); + * } + * @endcode + * + * After you have finished reading the file, you must close it with + * avformat_close_input(). It will free everything associated with the file. + * + * @section lavf_decoding_read Reading from an opened file + * Reading data from an opened AVFormatContext is done by repeatedly calling + * av_read_frame() on it. Each call, if successful, will return an AVPacket + * containing encoded data for one AVStream, identified by + * AVPacket.stream_index. This packet may be passed straight into the libavcodec + * decoding functions avcodec_send_packet() or avcodec_decode_subtitle2() if the + * caller wishes to decode the data. + * + * AVPacket.pts, AVPacket.dts and AVPacket.duration timing information will be + * set if known. They may also be unset (i.e. AV_NOPTS_VALUE for + * pts/dts, 0 for duration) if the stream does not provide them. The timing + * information will be in AVStream.time_base units, i.e. it has to be + * multiplied by the timebase to convert them to seconds. + * + * A packet returned by av_read_frame() is always reference-counted, + * i.e. AVPacket.buf is set and the user may keep it indefinitely. + * The packet must be freed with av_packet_unref() when it is no + * longer needed. + * + * @section lavf_decoding_seek Seeking + * @} + * + * @defgroup lavf_encoding Muxing + * @{ + * Muxers take encoded data in the form of @ref AVPacket "AVPackets" and write + * it into files or other output bytestreams in the specified container format. + * + * The main API functions for muxing are avformat_write_header() for writing the + * file header, av_write_frame() / av_interleaved_write_frame() for writing the + * packets and av_write_trailer() for finalizing the file. + * + * At the beginning of the muxing process, the caller must first call + * avformat_alloc_context() to create a muxing context. The caller then sets up + * the muxer by filling the various fields in this context: + * + * - The @ref AVFormatContext.oformat "oformat" field must be set to select the + * muxer that will be used. + * - Unless the format is of the AVFMT_NOFILE type, the @ref AVFormatContext.pb + * "pb" field must be set to an opened IO context, either returned from + * avio_open2() or a custom one. + * - Unless the format is of the AVFMT_NOSTREAMS type, at least one stream must + * be created with the avformat_new_stream() function. The caller should fill + * the @ref AVStream.codecpar "stream codec parameters" information, such as the + * codec @ref AVCodecParameters.codec_type "type", @ref AVCodecParameters.codec_id + * "id" and other parameters (e.g. width / height, the pixel or sample format, + * etc.) as known. The @ref AVStream.time_base "stream timebase" should + * be set to the timebase that the caller desires to use for this stream (note + * that the timebase actually used by the muxer can be different, as will be + * described later). + * - It is advised to manually initialize only the relevant fields in + * AVCodecParameters, rather than using @ref avcodec_parameters_copy() during + * remuxing: there is no guarantee that the codec context values remain valid + * for both input and output format contexts. + * - The caller may fill in additional information, such as @ref + * AVFormatContext.metadata "global" or @ref AVStream.metadata "per-stream" + * metadata, @ref AVFormatContext.chapters "chapters", @ref + * AVFormatContext.programs "programs", etc. as described in the + * AVFormatContext documentation. Whether such information will actually be + * stored in the output depends on what the container format and the muxer + * support. + * + * When the muxing context is fully set up, the caller must call + * avformat_write_header() to initialize the muxer internals and write the file + * header. Whether anything actually is written to the IO context at this step + * depends on the muxer, but this function must always be called. Any muxer + * private options must be passed in the options parameter to this function. + * + * The data is then sent to the muxer by repeatedly calling av_write_frame() or + * av_interleaved_write_frame() (consult those functions' documentation for + * discussion on the difference between them; only one of them may be used with + * a single muxing context, they should not be mixed). Do note that the timing + * information on the packets sent to the muxer must be in the corresponding + * AVStream's timebase. That timebase is set by the muxer (in the + * avformat_write_header() step) and may be different from the timebase + * requested by the caller. + * + * Once all the data has been written, the caller must call av_write_trailer() + * to flush any buffered packets and finalize the output file, then close the IO + * context (if any) and finally free the muxing context with + * avformat_free_context(). + * @} + * + * @defgroup lavf_io I/O Read/Write + * @{ + * @section lavf_io_dirlist Directory listing + * The directory listing API makes it possible to list files on remote servers. + * + * Some of possible use cases: + * - an "open file" dialog to choose files from a remote location, + * - a recursive media finder providing a player with an ability to play all + * files from a given directory. + * + * @subsection lavf_io_dirlist_open Opening a directory + * At first, a directory needs to be opened by calling avio_open_dir() + * supplied with a URL and, optionally, ::AVDictionary containing + * protocol-specific parameters. The function returns zero or positive + * integer and allocates AVIODirContext on success. + * + * @code + * AVIODirContext *ctx = NULL; + * if (avio_open_dir(&ctx, "smb://example.com/some_dir", NULL) < 0) { + * fprintf(stderr, "Cannot open directory.\n"); + * abort(); + * } + * @endcode + * + * This code tries to open a sample directory using smb protocol without + * any additional parameters. + * + * @subsection lavf_io_dirlist_read Reading entries + * Each directory's entry (i.e. file, another directory, anything else + * within ::AVIODirEntryType) is represented by AVIODirEntry. + * Reading consecutive entries from an opened AVIODirContext is done by + * repeatedly calling avio_read_dir() on it. Each call returns zero or + * positive integer if successful. Reading can be stopped right after the + * NULL entry has been read -- it means there are no entries left to be + * read. The following code reads all entries from a directory associated + * with ctx and prints their names to standard output. + * @code + * AVIODirEntry *entry = NULL; + * for (;;) { + * if (avio_read_dir(ctx, &entry) < 0) { + * fprintf(stderr, "Cannot list directory.\n"); + * abort(); + * } + * if (!entry) + * break; + * printf("%s\n", entry->name); + * avio_free_directory_entry(&entry); + * } + * @endcode + * @} + * + * @defgroup lavf_codec Demuxers + * @{ + * @defgroup lavf_codec_native Native Demuxers + * @{ + * @} + * @defgroup lavf_codec_wrappers External library wrappers + * @{ + * @} + * @} + * @defgroup lavf_protos I/O Protocols + * @{ + * @} + * @defgroup lavf_internal Internal + * @{ + * @} + * @} + */ + +#include +#include /* FILE */ +#include "libavcodec/avcodec.h" +#include "libavutil/dict.h" +#include "libavutil/log.h" + +#include "avio.h" +#include "libavformat/version.h" + +struct AVFormatContext; + +struct AVDeviceInfoList; +struct AVDeviceCapabilitiesQuery; + +/** + * @defgroup metadata_api Public Metadata API + * @{ + * @ingroup libavf + * The metadata API allows libavformat to export metadata tags to a client + * application when demuxing. Conversely it allows a client application to + * set metadata when muxing. + * + * Metadata is exported or set as pairs of key/value strings in the 'metadata' + * fields of the AVFormatContext, AVStream, AVChapter and AVProgram structs + * using the @ref lavu_dict "AVDictionary" API. Like all strings in FFmpeg, + * metadata is assumed to be UTF-8 encoded Unicode. Note that metadata + * exported by demuxers isn't checked to be valid UTF-8 in most cases. + * + * Important concepts to keep in mind: + * - Keys are unique; there can never be 2 tags with the same key. This is + * also meant semantically, i.e., a demuxer should not knowingly produce + * several keys that are literally different but semantically identical. + * E.g., key=Author5, key=Author6. In this example, all authors must be + * placed in the same tag. + * - Metadata is flat, not hierarchical; there are no subtags. If you + * want to store, e.g., the email address of the child of producer Alice + * and actor Bob, that could have key=alice_and_bobs_childs_email_address. + * - Several modifiers can be applied to the tag name. This is done by + * appending a dash character ('-') and the modifier name in the order + * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng. + * - language -- a tag whose value is localized for a particular language + * is appended with the ISO 639-2/B 3-letter language code. + * For example: Author-ger=Michael, Author-eng=Mike + * The original/default language is in the unqualified "Author" tag. + * A demuxer should set a default if it sets any translated tag. + * - sorting -- a modified version of a tag that should be used for + * sorting will have '-sort' appended. E.g. artist="The Beatles", + * artist-sort="Beatles, The". + * - Some protocols and demuxers support metadata updates. After a successful + * call to av_read_packet(), AVFormatContext.event_flags or AVStream.event_flags + * will be updated to indicate if metadata changed. In order to detect metadata + * changes on a stream, you need to loop through all streams in the AVFormatContext + * and check their individual event_flags. + * + * - Demuxers attempt to export metadata in a generic format, however tags + * with no generic equivalents are left as they are stored in the container. + * Follows a list of generic tag names: + * + @verbatim + album -- name of the set this work belongs to + album_artist -- main creator of the set/album, if different from artist. + e.g. "Various Artists" for compilation albums. + artist -- main creator of the work + comment -- any additional description of the file. + composer -- who composed the work, if different from artist. + copyright -- name of copyright holder. + creation_time-- date when the file was created, preferably in ISO 8601. + date -- date when the work was created, preferably in ISO 8601. + disc -- number of a subset, e.g. disc in a multi-disc collection. + encoder -- name/settings of the software/hardware that produced the file. + encoded_by -- person/group who created the file. + filename -- original name of the file. + genre -- . + language -- main language in which the work is performed, preferably + in ISO 639-2 format. Multiple languages can be specified by + separating them with commas. + performer -- artist who performed the work, if different from artist. + E.g for "Also sprach Zarathustra", artist would be "Richard + Strauss" and performer "London Philharmonic Orchestra". + publisher -- name of the label/publisher. + service_name -- name of the service in broadcasting (channel name). + service_provider -- name of the service provider in broadcasting. + title -- name of the work. + track -- number of this work in the set, can be in form current/total. + variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of + @endverbatim + * + * Look in the examples section for an application example how to use the Metadata API. + * + * @} + */ + +/* packet functions */ + + +/** + * Allocate and read the payload of a packet and initialize its + * fields with default values. + * + * @param s associated IO context + * @param pkt packet + * @param size desired payload size + * @return >0 (read size) if OK, AVERROR_xxx otherwise + */ +int av_get_packet(AVIOContext *s, AVPacket *pkt, int size); + + +/** + * Read data and append it to the current content of the AVPacket. + * If pkt->size is 0 this is identical to av_get_packet. + * Note that this uses av_grow_packet and thus involves a realloc + * which is inefficient. Thus this function should only be used + * when there is no reasonable way to know (an upper bound of) + * the final size. + * + * @param s associated IO context + * @param pkt packet + * @param size amount of data to read + * @return >0 (read size) if OK, AVERROR_xxx otherwise, previous data + * will not be lost even if an error occurs. + */ +int av_append_packet(AVIOContext *s, AVPacket *pkt, int size); + +/*************************************************/ +/* input/output formats */ + +struct AVCodecTag; + +/** + * This structure contains the data a format has to probe a file. + */ +typedef struct AVProbeData { + const char *filename; + unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */ + int buf_size; /**< Size of buf except extra allocated bytes */ + const char *mime_type; /**< mime_type, when known. */ +} AVProbeData; + +#define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4) +#define AVPROBE_SCORE_STREAM_RETRY (AVPROBE_SCORE_MAX/4-1) + +#define AVPROBE_SCORE_EXTENSION 50 ///< score for file extension +#define AVPROBE_SCORE_MIME 75 ///< score for file mime type +#define AVPROBE_SCORE_MAX 100 ///< maximum score + +#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer + +/// Demuxer will use avio_open, no opened file should be provided by the caller. +#define AVFMT_NOFILE 0x0001 +#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ +#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ +#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ +#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ +#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ +#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. Note, muxers always require valid (monotone) timestamps */ +#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */ +#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */ +#define AVFMT_NOSTREAMS 0x1000 /**< Format does not require any streams */ +#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fall back on binary search via read_timestamp */ +#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fall back on generic search */ +#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */ +#define AVFMT_ALLOW_FLUSH 0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */ +#define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly + increasing timestamps, but they must + still be monotonic */ +#define AVFMT_TS_NEGATIVE 0x40000 /**< Format allows muxing negative + timestamps. If not set the timestamp + will be shifted in av_write_frame and + av_interleaved_write_frame so they + start from 0. + The user or muxer can override this through + AVFormatContext.avoid_negative_ts + */ + +#define AVFMT_SEEK_TO_PTS 0x4000000 /**< Seeking is based on PTS */ + +/** + * @addtogroup lavf_encoding + * @{ + */ +typedef struct AVOutputFormat { + const char *name; + /** + * Descriptive name for the format, meant to be more human-readable + * than name. You should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + const char *mime_type; + const char *extensions; /**< comma-separated filename extensions */ + /* output support */ + enum AVCodecID audio_codec; /**< default audio codec */ + enum AVCodecID video_codec; /**< default video codec */ + enum AVCodecID subtitle_codec; /**< default subtitle codec */ + /** + * can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, + * AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS, + * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH, + * AVFMT_TS_NONSTRICT, AVFMT_TS_NEGATIVE + */ + int flags; + + /** + * List of supported codec_id-codec_tag pairs, ordered by "better + * choice first". The arrays are all terminated by AV_CODEC_ID_NONE. + */ + const struct AVCodecTag * const *codec_tag; + + + const AVClass *priv_class; ///< AVClass for the private context + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + /** + * The ff_const59 define is not part of the public API and will + * be removed without further warning. + */ +#if FF_API_AVIOFORMAT +#define ff_const59 +#else +#define ff_const59 const +#endif + ff_const59 struct AVOutputFormat *next; + /** + * size of private data so that it can be allocated in the wrapper + */ + int priv_data_size; + + int (*write_header)(struct AVFormatContext *); + /** + * Write a packet. If AVFMT_ALLOW_FLUSH is set in flags, + * pkt can be NULL in order to flush data buffered in the muxer. + * When flushing, return 0 if there still is more data to flush, + * or 1 if everything was flushed and there is no more buffered + * data. + */ + int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); + int (*write_trailer)(struct AVFormatContext *); + /** + * A format-specific function for interleavement. + * If unset, packets will be interleaved by dts. + */ + int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, + AVPacket *in, int flush); + /** + * Test if the given codec can be stored in this container. + * + * @return 1 if the codec is supported, 0 if it is not. + * A negative number if unknown. + * MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC + */ + int (*query_codec)(enum AVCodecID id, int std_compliance); + + void (*get_output_timestamp)(struct AVFormatContext *s, int stream, + int64_t *dts, int64_t *wall); + /** + * Allows sending messages from application to device. + */ + int (*control_message)(struct AVFormatContext *s, int type, + void *data, size_t data_size); + + /** + * Write an uncoded AVFrame. + * + * See av_write_uncoded_frame() for details. + * + * The library will free *frame afterwards, but the muxer can prevent it + * by setting the pointer to NULL. + */ + int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index, + AVFrame **frame, unsigned flags); + /** + * Returns device list with it properties. + * @see avdevice_list_devices() for more details. + */ + int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list); + /** + * Initialize device capabilities submodule. + * @see avdevice_capabilities_create() for more details. + */ + int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps); + /** + * Free device capabilities submodule. + * @see avdevice_capabilities_free() for more details. + */ + int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps); + enum AVCodecID data_codec; /**< default data codec */ + /** + * Initialize format. May allocate data here, and set any AVFormatContext or + * AVStream parameters that need to be set before packets are sent. + * This method must not write output. + * + * Return 0 if streams were fully configured, 1 if not, negative AVERROR on failure + * + * Any allocations made here must be freed in deinit(). + */ + int (*init)(struct AVFormatContext *); + /** + * Deinitialize format. If present, this is called whenever the muxer is being + * destroyed, regardless of whether or not the header has been written. + * + * If a trailer is being written, this is called after write_trailer(). + * + * This is called if init() fails as well. + */ + void (*deinit)(struct AVFormatContext *); + /** + * Set up any necessary bitstream filtering and extract any extra data needed + * for the global header. + * Return 0 if more packets from this stream must be checked; 1 if not. + */ + int (*check_bitstream)(struct AVFormatContext *, const AVPacket *pkt); +} AVOutputFormat; +/** + * @} + */ + +/** + * @addtogroup lavf_decoding + * @{ + */ +typedef struct AVInputFormat { + /** + * A comma separated list of short names for the format. New names + * may be appended with a minor bump. + */ + const char *name; + + /** + * Descriptive name for the format, meant to be more human-readable + * than name. You should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + + /** + * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, + * AVFMT_NOTIMESTAMPS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH, + * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS. + */ + int flags; + + /** + * If extensions are defined, then no probe is done. You should + * usually not use extension format guessing because it is not + * reliable enough + */ + const char *extensions; + + const struct AVCodecTag * const *codec_tag; + + const AVClass *priv_class; ///< AVClass for the private context + + /** + * Comma-separated list of mime types. + * It is used check for matching mime types while probing. + * @see av_probe_input_format2 + */ + const char *mime_type; + + /***************************************************************** + * No fields below this line are part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + ff_const59 struct AVInputFormat *next; + + /** + * Raw demuxers store their codec ID here. + */ + int raw_codec_id; + + /** + * Size of private data so that it can be allocated in the wrapper. + */ + int priv_data_size; + + /** + * Tell if a given file has a chance of being parsed as this format. + * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes + * big so you do not have to check for that unless you need more. + */ + int (*read_probe)(const AVProbeData *); + + /** + * Read the format header and initialize the AVFormatContext + * structure. Return 0 if OK. 'avformat_new_stream' should be + * called to create new streams. + */ + int (*read_header)(struct AVFormatContext *); + + /** + * Read one packet and put it in 'pkt'. pts and flags are also + * set. 'avformat_new_stream' can be called only if the flag + * AVFMTCTX_NOHEADER is used and only in the calling thread (not in a + * background thread). + * @return 0 on success, < 0 on error. + * Upon returning an error, pkt must be unreferenced by the caller. + */ + int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); + + /** + * Close the stream. The AVFormatContext and AVStreams are not + * freed by this function + */ + int (*read_close)(struct AVFormatContext *); + + /** + * Seek to a given timestamp relative to the frames in + * stream component stream_index. + * @param stream_index Must not be -1. + * @param flags Selects which direction should be preferred if no exact + * match is available. + * @return >= 0 on success (but not necessarily the new offset) + */ + int (*read_seek)(struct AVFormatContext *, + int stream_index, int64_t timestamp, int flags); + + /** + * Get the next timestamp in stream[stream_index].time_base units. + * @return the timestamp or AV_NOPTS_VALUE if an error occurred + */ + int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, + int64_t *pos, int64_t pos_limit); + + /** + * Start/resume playing - only meaningful if using a network-based format + * (RTSP). + */ + int (*read_play)(struct AVFormatContext *); + + /** + * Pause playing - only meaningful if using a network-based format + * (RTSP). + */ + int (*read_pause)(struct AVFormatContext *); + + /** + * Seek to timestamp ts. + * Seeking will be done so that the point from which all active streams + * can be presented successfully will be closest to ts and within min/max_ts. + * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. + */ + int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + + /** + * Returns device list with it properties. + * @see avdevice_list_devices() for more details. + */ + int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list); + + /** + * Initialize device capabilities submodule. + * @see avdevice_capabilities_create() for more details. + */ + int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps); + + /** + * Free device capabilities submodule. + * @see avdevice_capabilities_free() for more details. + */ + int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps); +} AVInputFormat; +/** + * @} + */ + +enum AVStreamParseType { + AVSTREAM_PARSE_NONE, + AVSTREAM_PARSE_FULL, /**< full parsing and repack */ + AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ + AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ + AVSTREAM_PARSE_FULL_ONCE, /**< full parsing and repack of the first frame only, only implemented for H.264 currently */ + AVSTREAM_PARSE_FULL_RAW, /**< full parsing and repack with timestamp and position generation by parser for raw + this assumes that each packet in the file contains no demuxer level headers and + just codec level data, otherwise position generation would fail */ +}; + +typedef struct AVIndexEntry { + int64_t pos; + int64_t timestamp; /**< + * Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are available + * when seeking to this entry. That means preferable PTS on keyframe based formats. + * But demuxers can choose to store a different timestamp, if it is more convenient for the implementation or nothing better + * is known + */ +#define AVINDEX_KEYFRAME 0x0001 +#define AVINDEX_DISCARD_FRAME 0x0002 /** + * Flag is used to indicate which frame should be discarded after decoding. + */ + int flags:2; + int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment). + int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ +} AVIndexEntry; + +#define AV_DISPOSITION_DEFAULT 0x0001 +#define AV_DISPOSITION_DUB 0x0002 +#define AV_DISPOSITION_ORIGINAL 0x0004 +#define AV_DISPOSITION_COMMENT 0x0008 +#define AV_DISPOSITION_LYRICS 0x0010 +#define AV_DISPOSITION_KARAOKE 0x0020 + +/** + * Track should be used during playback by default. + * Useful for subtitle track that should be displayed + * even when user did not explicitly ask for subtitles. + */ +#define AV_DISPOSITION_FORCED 0x0040 +#define AV_DISPOSITION_HEARING_IMPAIRED 0x0080 /**< stream for hearing impaired audiences */ +#define AV_DISPOSITION_VISUAL_IMPAIRED 0x0100 /**< stream for visual impaired audiences */ +#define AV_DISPOSITION_CLEAN_EFFECTS 0x0200 /**< stream without voice */ +/** + * The stream is stored in the file as an attached picture/"cover art" (e.g. + * APIC frame in ID3v2). The first (usually only) packet associated with it + * will be returned among the first few packets read from the file unless + * seeking takes place. It can also be accessed at any time in + * AVStream.attached_pic. + */ +#define AV_DISPOSITION_ATTACHED_PIC 0x0400 +/** + * The stream is sparse, and contains thumbnail images, often corresponding + * to chapter markers. Only ever used with AV_DISPOSITION_ATTACHED_PIC. + */ +#define AV_DISPOSITION_TIMED_THUMBNAILS 0x0800 + +typedef struct AVStreamInternal AVStreamInternal; + +/** + * To specify text track kind (different from subtitles default). + */ +#define AV_DISPOSITION_CAPTIONS 0x10000 +#define AV_DISPOSITION_DESCRIPTIONS 0x20000 +#define AV_DISPOSITION_METADATA 0x40000 +#define AV_DISPOSITION_DEPENDENT 0x80000 ///< dependent audio stream (mix_type=0 in mpegts) +#define AV_DISPOSITION_STILL_IMAGE 0x100000 ///< still images in video stream (still_picture_flag=1 in mpegts) + +/** + * Options for behavior on timestamp wrap detection. + */ +#define AV_PTS_WRAP_IGNORE 0 ///< ignore the wrap +#define AV_PTS_WRAP_ADD_OFFSET 1 ///< add the format specific offset on wrap detection +#define AV_PTS_WRAP_SUB_OFFSET -1 ///< subtract the format specific offset on wrap detection + +/** + * Stream structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVStream) must not be used outside libav*. + */ +typedef struct AVStream { + int index; /**< stream index in AVFormatContext */ + /** + * Format-specific stream ID. + * decoding: set by libavformat + * encoding: set by the user, replaced by libavformat if left unset + */ + int id; +#if FF_API_LAVF_AVCTX + /** + * @deprecated use the codecpar struct instead + */ + attribute_deprecated + AVCodecContext *codec; +#endif + void *priv_data; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. + * + * decoding: set by libavformat + * encoding: May be set by the caller before avformat_write_header() to + * provide a hint to the muxer about the desired timebase. In + * avformat_write_header(), the muxer will overwrite this field + * with the timebase that will actually be used for the timestamps + * written into the file (which may or may not be related to the + * user-provided one, depending on the format). + */ + AVRational time_base; + + /** + * Decoding: pts of the first frame of the stream in presentation order, in stream time base. + * Only set this if you are absolutely 100% sure that the value you set + * it to really is the pts of the first frame. + * This may be undefined (AV_NOPTS_VALUE). + * @note The ASF header does NOT contain a correct start_time the ASF + * demuxer must NOT set this. + */ + int64_t start_time; + + /** + * Decoding: duration of the stream, in stream time base. + * If a source file does not specify a duration, but does specify + * a bitrate, this value will be estimated from bitrate and file size. + * + * Encoding: May be set by the caller before avformat_write_header() to + * provide a hint to the muxer about the estimated duration. + */ + int64_t duration; + + int64_t nb_frames; ///< number of frames in this stream if known or 0 + + int disposition; /**< AV_DISPOSITION_* bit field */ + + enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed. + + /** + * sample aspect ratio (0 if unknown) + * - encoding: Set by user. + * - decoding: Set by libavformat. + */ + AVRational sample_aspect_ratio; + + AVDictionary *metadata; + + /** + * Average framerate + * + * - demuxing: May be set by libavformat when creating the stream or in + * avformat_find_stream_info(). + * - muxing: May be set by the caller before avformat_write_header(). + */ + AVRational avg_frame_rate; + + /** + * For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet + * will contain the attached picture. + * + * decoding: set by libavformat, must not be modified by the caller. + * encoding: unused + */ + AVPacket attached_pic; + + /** + * An array of side data that applies to the whole stream (i.e. the + * container does not allow it to change between packets). + * + * There may be no overlap between the side data in this array and side data + * in the packets. I.e. a given side data is either exported by the muxer + * (demuxing) / set by the caller (muxing) in this array, then it never + * appears in the packets, or the side data is exported / sent through + * the packets (always in the first packet where the value becomes known or + * changes), then it does not appear in this array. + * + * - demuxing: Set by libavformat when the stream is created. + * - muxing: May be set by the caller before avformat_write_header(). + * + * Freed by libavformat in avformat_free_context(). + * + * @see av_format_inject_global_side_data() + */ + AVPacketSideData *side_data; + /** + * The number of elements in the AVStream.side_data array. + */ + int nb_side_data; + + /** + * Flags for the user to detect events happening on the stream. Flags must + * be cleared by the user once the event has been handled. + * A combination of AVSTREAM_EVENT_FLAG_*. + */ + int event_flags; +#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata. + + /** + * Real base framerate of the stream. + * This is the lowest framerate with which all timestamps can be + * represented accurately (it is the least common multiple of all + * framerates in the stream). Note, this value is just a guess! + * For example, if the time base is 1/90000 and all frames have either + * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. + */ + AVRational r_frame_rate; + +#if FF_API_LAVF_FFSERVER + /** + * String containing pairs of key and values describing recommended encoder configuration. + * Pairs are separated by ','. + * Keys are separated from values by '='. + * + * @deprecated unused + */ + attribute_deprecated + char *recommended_encoder_configuration; +#endif + + /** + * Codec parameters associated with this stream. Allocated and freed by + * libavformat in avformat_new_stream() and avformat_free_context() + * respectively. + * + * - demuxing: filled by libavformat on stream creation or in + * avformat_find_stream_info() + * - muxing: filled by the caller before avformat_write_header() + */ + AVCodecParameters *codecpar; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * Internal note: be aware that physically removing these fields + * will break ABI. Replace removed fields with dummy fields, and + * add new fields to AVStreamInternal. + ***************************************************************** + */ + +#define MAX_STD_TIMEBASES (30*12+30+3+6) + /** + * Stream information used internally by avformat_find_stream_info() + */ + struct { + int64_t last_dts; + int64_t duration_gcd; + int duration_count; + int64_t rfps_duration_sum; + double (*duration_error)[2][MAX_STD_TIMEBASES]; + int64_t codec_info_duration; + int64_t codec_info_duration_fields; + int frame_delay_evidence; + + /** + * 0 -> decoder has not been searched for yet. + * >0 -> decoder found + * <0 -> decoder with codec_id == -found_decoder has not been found + */ + int found_decoder; + + int64_t last_duration; + + /** + * Those are used for average framerate estimation. + */ + int64_t fps_first_dts; + int fps_first_dts_idx; + int64_t fps_last_dts; + int fps_last_dts_idx; + + } *info; + + int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ + + // Timestamp generation support: + /** + * Timestamp corresponding to the last dts sync point. + * + * Initialized when AVCodecParserContext.dts_sync_point >= 0 and + * a DTS is received from the underlying container. Otherwise set to + * AV_NOPTS_VALUE by default. + */ + int64_t first_dts; + int64_t cur_dts; + int64_t last_IP_pts; + int last_IP_duration; + + /** + * Number of packets to buffer for codec probing + */ + int probe_packets; + + /** + * Number of frames that have been demuxed during avformat_find_stream_info() + */ + int codec_info_nb_frames; + + /* av_read_frame() support */ + enum AVStreamParseType need_parsing; + struct AVCodecParserContext *parser; + + /** + * last packet in packet_buffer for this stream when muxing. + */ + struct AVPacketList *last_in_packet_buffer; + AVProbeData probe_data; +#define MAX_REORDER_DELAY 16 + int64_t pts_buffer[MAX_REORDER_DELAY+1]; + + AVIndexEntry *index_entries; /**< Only used if the format does not + support seeking natively. */ + int nb_index_entries; + unsigned int index_entries_allocated_size; + + /** + * Stream Identifier + * This is the MPEG-TS stream identifier +1 + * 0 means unknown + */ + int stream_identifier; + + /** + * Details of the MPEG-TS program which created this stream. + */ + int program_num; + int pmt_version; + int pmt_stream_idx; + + int64_t interleaver_chunk_size; + int64_t interleaver_chunk_duration; + + /** + * stream probing state + * -1 -> probing finished + * 0 -> no probing requested + * rest -> perform probing with request_probe being the minimum score to accept. + */ + int request_probe; + /** + * Indicates that everything up to the next keyframe + * should be discarded. + */ + int skip_to_keyframe; + + /** + * Number of samples to skip at the start of the frame decoded from the next packet. + */ + int skip_samples; + + /** + * If not 0, the number of samples that should be skipped from the start of + * the stream (the samples are removed from packets with pts==0, which also + * assumes negative timestamps do not happen). + * Intended for use with formats such as mp3 with ad-hoc gapless audio + * support. + */ + int64_t start_skip_samples; + + /** + * If not 0, the first audio sample that should be discarded from the stream. + * This is broken by design (needs global sample count), but can't be + * avoided for broken by design formats such as mp3 with ad-hoc gapless + * audio support. + */ + int64_t first_discard_sample; + + /** + * The sample after last sample that is intended to be discarded after + * first_discard_sample. Works on frame boundaries only. Used to prevent + * early EOF if the gapless info is broken (considered concatenated mp3s). + */ + int64_t last_discard_sample; + + /** + * Number of internally decoded frames, used internally in libavformat, do not access + * its lifetime differs from info which is why it is not in that structure. + */ + int nb_decoded_frames; + + /** + * Timestamp offset added to timestamps before muxing + */ + int64_t mux_ts_offset; + + /** + * Internal data to check for wrapping of the time stamp + */ + int64_t pts_wrap_reference; + + /** + * Options for behavior, when a wrap is detected. + * + * Defined by AV_PTS_WRAP_ values. + * + * If correction is enabled, there are two possibilities: + * If the first time stamp is near the wrap point, the wrap offset + * will be subtracted, which will create negative time stamps. + * Otherwise the offset will be added. + */ + int pts_wrap_behavior; + + /** + * Internal data to prevent doing update_initial_durations() twice + */ + int update_initial_durations_done; + + /** + * Internal data to generate dts from pts + */ + int64_t pts_reorder_error[MAX_REORDER_DELAY+1]; + uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1]; + + /** + * Internal data to analyze DTS and detect faulty mpeg streams + */ + int64_t last_dts_for_order_check; + uint8_t dts_ordered; + uint8_t dts_misordered; + + /** + * Internal data to inject global side data + */ + int inject_global_side_data; + + /** + * display aspect ratio (0 if unknown) + * - encoding: unused + * - decoding: Set by libavformat to calculate sample_aspect_ratio internally + */ + AVRational display_aspect_ratio; + + /** + * An opaque field for libavformat internal usage. + * Must not be accessed in any way by callers. + */ + AVStreamInternal *internal; +} AVStream; + +#if FF_API_FORMAT_GET_SET +/** + * Accessors for some AVStream fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated +AVRational av_stream_get_r_frame_rate(const AVStream *s); +attribute_deprecated +void av_stream_set_r_frame_rate(AVStream *s, AVRational r); +#if FF_API_LAVF_FFSERVER +attribute_deprecated +char* av_stream_get_recommended_encoder_configuration(const AVStream *s); +attribute_deprecated +void av_stream_set_recommended_encoder_configuration(AVStream *s, char *configuration); +#endif +#endif + +struct AVCodecParserContext *av_stream_get_parser(const AVStream *s); + +/** + * Returns the pts of the last muxed packet + its duration + * + * the retuned value is undefined when used with a demuxer. + */ +int64_t av_stream_get_end_pts(const AVStream *st); + +#define AV_PROGRAM_RUNNING 1 + +/** + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVProgram) must not be used outside libav*. + */ +typedef struct AVProgram { + int id; + int flags; + enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller + unsigned int *stream_index; + unsigned int nb_stream_indexes; + AVDictionary *metadata; + + int program_num; + int pmt_pid; + int pcr_pid; + int pmt_version; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + int64_t start_time; + int64_t end_time; + + int64_t pts_wrap_reference; ///< reference dts for wrap detection + int pts_wrap_behavior; ///< behavior on wrap detection +} AVProgram; + +#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present + (streams are added dynamically) */ +#define AVFMTCTX_UNSEEKABLE 0x0002 /**< signal that the stream is definitely + not seekable, and attempts to call the + seek function will fail. For some + network protocols (e.g. HLS), this can + change dynamically at runtime. */ + +typedef struct AVChapter { + int id; ///< unique ID to identify the chapter + AVRational time_base; ///< time base in which the start/end timestamps are specified + int64_t start, end; ///< chapter start/end time in time_base units + AVDictionary *metadata; +} AVChapter; + + +/** + * Callback used by devices to communicate with application. + */ +typedef int (*av_format_control_message)(struct AVFormatContext *s, int type, + void *data, size_t data_size); + +typedef int (*AVOpenCallback)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options); + +/** + * The duration of a video can be estimated through various ways, and this enum can be used + * to know how the duration was estimated. + */ +enum AVDurationEstimationMethod { + AVFMT_DURATION_FROM_PTS, ///< Duration accurately estimated from PTSes + AVFMT_DURATION_FROM_STREAM, ///< Duration estimated from a stream with a known duration + AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate) +}; + +typedef struct AVFormatInternal AVFormatInternal; + +/** + * Format I/O context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVFormatContext) must not be used outside libav*, use + * avformat_alloc_context() to create an AVFormatContext. + * + * Fields can be accessed through AVOptions (av_opt*), + * the name string used matches the associated command line parameter name and + * can be found in libavformat/options_table.h. + * The AVOption/command line parameter names differ in some cases from the C + * structure field names for historic reasons or brevity. + */ +typedef struct AVFormatContext { + /** + * A class for logging and @ref avoptions. Set by avformat_alloc_context(). + * Exports (de)muxer private options if they exist. + */ + const AVClass *av_class; + + /** + * The input container format. + * + * Demuxing only, set by avformat_open_input(). + */ + ff_const59 struct AVInputFormat *iformat; + + /** + * The output container format. + * + * Muxing only, must be set by the caller before avformat_write_header(). + */ + ff_const59 struct AVOutputFormat *oformat; + + /** + * Format private data. This is an AVOptions-enabled struct + * if and only if iformat/oformat.priv_class is not NULL. + * + * - muxing: set by avformat_write_header() + * - demuxing: set by avformat_open_input() + */ + void *priv_data; + + /** + * I/O context. + * + * - demuxing: either set by the user before avformat_open_input() (then + * the user must close it manually) or set by avformat_open_input(). + * - muxing: set by the user before avformat_write_header(). The caller must + * take care of closing / freeing the IO context. + * + * Do NOT set this field if AVFMT_NOFILE flag is set in + * iformat/oformat.flags. In such a case, the (de)muxer will handle + * I/O in some other way and this field will be NULL. + */ + AVIOContext *pb; + + /* stream info */ + /** + * Flags signalling stream properties. A combination of AVFMTCTX_*. + * Set by libavformat. + */ + int ctx_flags; + + /** + * Number of elements in AVFormatContext.streams. + * + * Set by avformat_new_stream(), must not be modified by any other code. + */ + unsigned int nb_streams; + /** + * A list of all streams in the file. New streams are created with + * avformat_new_stream(). + * + * - demuxing: streams are created by libavformat in avformat_open_input(). + * If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also + * appear in av_read_frame(). + * - muxing: streams are created by the user before avformat_write_header(). + * + * Freed by libavformat in avformat_free_context(). + */ + AVStream **streams; + +#if FF_API_FORMAT_FILENAME + /** + * input or output filename + * + * - demuxing: set by avformat_open_input() + * - muxing: may be set by the caller before avformat_write_header() + * + * @deprecated Use url instead. + */ + attribute_deprecated + char filename[1024]; +#endif + + /** + * input or output URL. Unlike the old filename field, this field has no + * length restriction. + * + * - demuxing: set by avformat_open_input(), initialized to an empty + * string if url parameter was NULL in avformat_open_input(). + * - muxing: may be set by the caller before calling avformat_write_header() + * (or avformat_init_output() if that is called first) to a string + * which is freeable by av_free(). Set to an empty string if it + * was NULL in avformat_init_output(). + * + * Freed by libavformat in avformat_free_context(). + */ + char *url; + + /** + * Position of the first frame of the component, in + * AV_TIME_BASE fractional seconds. NEVER set this value directly: + * It is deduced from the AVStream values. + * + * Demuxing only, set by libavformat. + */ + int64_t start_time; + + /** + * Duration of the stream, in AV_TIME_BASE fractional + * seconds. Only set this value if you know none of the individual stream + * durations and also do not set any of them. This is deduced from the + * AVStream values if not set. + * + * Demuxing only, set by libavformat. + */ + int64_t duration; + + /** + * Total stream bitrate in bit/s, 0 if not + * available. Never set it directly if the file_size and the + * duration are known as FFmpeg can compute it automatically. + */ + int64_t bit_rate; + + unsigned int packet_size; + int max_delay; + + /** + * Flags modifying the (de)muxer behaviour. A combination of AVFMT_FLAG_*. + * Set by the user before avformat_open_input() / avformat_write_header(). + */ + int flags; +#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames. +#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. +#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. +#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS +#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container +#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled +#define AVFMT_FLAG_NOBUFFER 0x0040 ///< Do not buffer frames when possible +#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it. +#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted +#define AVFMT_FLAG_FLUSH_PACKETS 0x0200 ///< Flush the AVIOContext every packet. +/** + * When muxing, try to avoid writing any random/volatile data to the output. + * This includes any random IDs, real-time timestamps/dates, muxer version, etc. + * + * This flag is mainly intended for testing. + */ +#define AVFMT_FLAG_BITEXACT 0x0400 +#if FF_API_LAVF_MP4A_LATM +#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Deprecated, does nothing. +#endif +#define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) +#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted) +#if FF_API_LAVF_KEEPSIDE_FLAG +#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Deprecated, does nothing. +#endif +#define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats +#define AVFMT_FLAG_SHORTEST 0x100000 ///< Stop muxing when the shortest stream stops. +#define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Add bitstream filters as requested by the muxer + + /** + * Maximum size of the data read from input for determining + * the input container format. + * Demuxing only, set by the caller before avformat_open_input(). + */ + int64_t probesize; + + /** + * Maximum duration (in AV_TIME_BASE units) of the data read + * from input in avformat_find_stream_info(). + * Demuxing only, set by the caller before avformat_find_stream_info(). + * Can be set to 0 to let avformat choose using a heuristic. + */ + int64_t max_analyze_duration; + + const uint8_t *key; + int keylen; + + unsigned int nb_programs; + AVProgram **programs; + + /** + * Forced video codec_id. + * Demuxing: Set by user. + */ + enum AVCodecID video_codec_id; + + /** + * Forced audio codec_id. + * Demuxing: Set by user. + */ + enum AVCodecID audio_codec_id; + + /** + * Forced subtitle codec_id. + * Demuxing: Set by user. + */ + enum AVCodecID subtitle_codec_id; + + /** + * Maximum amount of memory in bytes to use for the index of each stream. + * If the index exceeds this size, entries will be discarded as + * needed to maintain a smaller size. This can lead to slower or less + * accurate seeking (depends on demuxer). + * Demuxers for which a full in-memory index is mandatory will ignore + * this. + * - muxing: unused + * - demuxing: set by user + */ + unsigned int max_index_size; + + /** + * Maximum amount of memory in bytes to use for buffering frames + * obtained from realtime capture devices. + */ + unsigned int max_picture_buffer; + + /** + * Number of chapters in AVChapter array. + * When muxing, chapters are normally written in the file header, + * so nb_chapters should normally be initialized before write_header + * is called. Some muxers (e.g. mov and mkv) can also write chapters + * in the trailer. To write chapters in the trailer, nb_chapters + * must be zero when write_header is called and non-zero when + * write_trailer is called. + * - muxing: set by user + * - demuxing: set by libavformat + */ + unsigned int nb_chapters; + AVChapter **chapters; + + /** + * Metadata that applies to the whole file. + * + * - demuxing: set by libavformat in avformat_open_input() + * - muxing: may be set by the caller before avformat_write_header() + * + * Freed by libavformat in avformat_free_context(). + */ + AVDictionary *metadata; + + /** + * Start time of the stream in real world time, in microseconds + * since the Unix epoch (00:00 1st January 1970). That is, pts=0 in the + * stream was captured at this real world time. + * - muxing: Set by the caller before avformat_write_header(). If set to + * either 0 or AV_NOPTS_VALUE, then the current wall-time will + * be used. + * - demuxing: Set by libavformat. AV_NOPTS_VALUE if unknown. Note that + * the value may become known after some number of frames + * have been received. + */ + int64_t start_time_realtime; + + /** + * The number of frames used for determining the framerate in + * avformat_find_stream_info(). + * Demuxing only, set by the caller before avformat_find_stream_info(). + */ + int fps_probe_size; + + /** + * Error recognition; higher values will detect more errors but may + * misdetect some more or less valid parts as errors. + * Demuxing only, set by the caller before avformat_open_input(). + */ + int error_recognition; + + /** + * Custom interrupt callbacks for the I/O layer. + * + * demuxing: set by the user before avformat_open_input(). + * muxing: set by the user before avformat_write_header() + * (mainly useful for AVFMT_NOFILE formats). The callback + * should also be passed to avio_open2() if it's used to + * open the file. + */ + AVIOInterruptCB interrupt_callback; + + /** + * Flags to enable debugging. + */ + int debug; +#define FF_FDEBUG_TS 0x0001 + + /** + * Maximum buffering duration for interleaving. + * + * To ensure all the streams are interleaved correctly, + * av_interleaved_write_frame() will wait until it has at least one packet + * for each stream before actually writing any packets to the output file. + * When some streams are "sparse" (i.e. there are large gaps between + * successive packets), this can result in excessive buffering. + * + * This field specifies the maximum difference between the timestamps of the + * first and the last packet in the muxing queue, above which libavformat + * will output a packet regardless of whether it has queued a packet for all + * the streams. + * + * Muxing only, set by the caller before avformat_write_header(). + */ + int64_t max_interleave_delta; + + /** + * Allow non-standard and experimental extension + * @see AVCodecContext.strict_std_compliance + */ + int strict_std_compliance; + + /** + * Flags for the user to detect events happening on the file. Flags must + * be cleared by the user once the event has been handled. + * A combination of AVFMT_EVENT_FLAG_*. + */ + int event_flags; +#define AVFMT_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata. + + /** + * Maximum number of packets to read while waiting for the first timestamp. + * Decoding only. + */ + int max_ts_probe; + + /** + * Avoid negative timestamps during muxing. + * Any value of the AVFMT_AVOID_NEG_TS_* constants. + * Note, this only works when using av_interleaved_write_frame. (interleave_packet_per_dts is in use) + * - muxing: Set by user + * - demuxing: unused + */ + int avoid_negative_ts; +#define AVFMT_AVOID_NEG_TS_AUTO -1 ///< Enabled when required by target format +#define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they are non negative +#define AVFMT_AVOID_NEG_TS_MAKE_ZERO 2 ///< Shift timestamps so that they start at 0 + + /** + * Transport stream id. + * This will be moved into demuxer private options. Thus no API/ABI compatibility + */ + int ts_id; + + /** + * Audio preload in microseconds. + * Note, not all formats support this and unpredictable things may happen if it is used when not supported. + * - encoding: Set by user + * - decoding: unused + */ + int audio_preload; + + /** + * Max chunk time in microseconds. + * Note, not all formats support this and unpredictable things may happen if it is used when not supported. + * - encoding: Set by user + * - decoding: unused + */ + int max_chunk_duration; + + /** + * Max chunk size in bytes + * Note, not all formats support this and unpredictable things may happen if it is used when not supported. + * - encoding: Set by user + * - decoding: unused + */ + int max_chunk_size; + + /** + * forces the use of wallclock timestamps as pts/dts of packets + * This has undefined results in the presence of B frames. + * - encoding: unused + * - decoding: Set by user + */ + int use_wallclock_as_timestamps; + + /** + * avio flags, used to force AVIO_FLAG_DIRECT. + * - encoding: unused + * - decoding: Set by user + */ + int avio_flags; + + /** + * The duration field can be estimated through various ways, and this field can be used + * to know how the duration was estimated. + * - encoding: unused + * - decoding: Read by user + */ + enum AVDurationEstimationMethod duration_estimation_method; + + /** + * Skip initial bytes when opening stream + * - encoding: unused + * - decoding: Set by user + */ + int64_t skip_initial_bytes; + + /** + * Correct single timestamp overflows + * - encoding: unused + * - decoding: Set by user + */ + unsigned int correct_ts_overflow; + + /** + * Force seeking to any (also non key) frames. + * - encoding: unused + * - decoding: Set by user + */ + int seek2any; + + /** + * Flush the I/O context after each packet. + * - encoding: Set by user + * - decoding: unused + */ + int flush_packets; + + /** + * format probing score. + * The maximal score is AVPROBE_SCORE_MAX, its set when the demuxer probes + * the format. + * - encoding: unused + * - decoding: set by avformat, read by user + */ + int probe_score; + + /** + * number of bytes to read maximally to identify format. + * - encoding: unused + * - decoding: set by user + */ + int format_probesize; + + /** + * ',' separated list of allowed decoders. + * If NULL then all are allowed + * - encoding: unused + * - decoding: set by user + */ + char *codec_whitelist; + + /** + * ',' separated list of allowed demuxers. + * If NULL then all are allowed + * - encoding: unused + * - decoding: set by user + */ + char *format_whitelist; + + /** + * An opaque field for libavformat internal usage. + * Must not be accessed in any way by callers. + */ + AVFormatInternal *internal; + + /** + * IO repositioned flag. + * This is set by avformat when the underlaying IO context read pointer + * is repositioned, for example when doing byte based seeking. + * Demuxers can use the flag to detect such changes. + */ + int io_repositioned; + + /** + * Forced video codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user + */ + AVCodec *video_codec; + + /** + * Forced audio codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user + */ + AVCodec *audio_codec; + + /** + * Forced subtitle codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user + */ + AVCodec *subtitle_codec; + + /** + * Forced data codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user + */ + AVCodec *data_codec; + + /** + * Number of bytes to be written as padding in a metadata header. + * Demuxing: Unused. + * Muxing: Set by user via av_format_set_metadata_header_padding. + */ + int metadata_header_padding; + + /** + * User data. + * This is a place for some private data of the user. + */ + void *opaque; + + /** + * Callback used by devices to communicate with application. + */ + av_format_control_message control_message_cb; + + /** + * Output timestamp offset, in microseconds. + * Muxing: set by user + */ + int64_t output_ts_offset; + + /** + * dump format separator. + * can be ", " or "\n " or anything else + * - muxing: Set by user. + * - demuxing: Set by user. + */ + uint8_t *dump_separator; + + /** + * Forced Data codec_id. + * Demuxing: Set by user. + */ + enum AVCodecID data_codec_id; + +#if FF_API_OLD_OPEN_CALLBACKS + /** + * Called to open further IO contexts when needed for demuxing. + * + * This can be set by the user application to perform security checks on + * the URLs before opening them. + * The function should behave like avio_open2(), AVFormatContext is provided + * as contextual information and to reach AVFormatContext.opaque. + * + * If NULL then some simple checks are used together with avio_open2(). + * + * Must not be accessed directly from outside avformat. + * @See av_format_set_open_cb() + * + * Demuxing: Set by user. + * + * @deprecated Use io_open and io_close. + */ + attribute_deprecated + int (*open_cb)(struct AVFormatContext *s, AVIOContext **p, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); +#endif + + /** + * ',' separated list of allowed protocols. + * - encoding: unused + * - decoding: set by user + */ + char *protocol_whitelist; + + /** + * A callback for opening new IO streams. + * + * Whenever a muxer or a demuxer needs to open an IO stream (typically from + * avformat_open_input() for demuxers, but for certain formats can happen at + * other times as well), it will call this callback to obtain an IO context. + * + * @param s the format context + * @param pb on success, the newly opened IO context should be returned here + * @param url the url to open + * @param flags a combination of AVIO_FLAG_* + * @param options a dictionary of additional options, with the same + * semantics as in avio_open2() + * @return 0 on success, a negative AVERROR code on failure + * + * @note Certain muxers and demuxers do nesting, i.e. they open one or more + * additional internal format contexts. Thus the AVFormatContext pointer + * passed to this callback may be different from the one facing the caller. + * It will, however, have the same 'opaque' field. + */ + int (*io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, + int flags, AVDictionary **options); + + /** + * A callback for closing the streams opened with AVFormatContext.io_open(). + */ + void (*io_close)(struct AVFormatContext *s, AVIOContext *pb); + + /** + * ',' separated list of disallowed protocols. + * - encoding: unused + * - decoding: set by user + */ + char *protocol_blacklist; + + /** + * The maximum number of streams. + * - encoding: unused + * - decoding: set by user + */ + int max_streams; + + /** + * Skip duration calcuation in estimate_timings_from_pts. + * - encoding: unused + * - decoding: set by user + */ + int skip_estimate_duration_from_pts; + + /** + * Maximum number of packets that can be probed + * - encoding: unused + * - decoding: set by user + */ + int max_probe_packets; +} AVFormatContext; + +#if FF_API_FORMAT_GET_SET +/** + * Accessors for some AVFormatContext fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated +int av_format_get_probe_score(const AVFormatContext *s); +attribute_deprecated +AVCodec * av_format_get_video_codec(const AVFormatContext *s); +attribute_deprecated +void av_format_set_video_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated +AVCodec * av_format_get_audio_codec(const AVFormatContext *s); +attribute_deprecated +void av_format_set_audio_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated +AVCodec * av_format_get_subtitle_codec(const AVFormatContext *s); +attribute_deprecated +void av_format_set_subtitle_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated +AVCodec * av_format_get_data_codec(const AVFormatContext *s); +attribute_deprecated +void av_format_set_data_codec(AVFormatContext *s, AVCodec *c); +attribute_deprecated +int av_format_get_metadata_header_padding(const AVFormatContext *s); +attribute_deprecated +void av_format_set_metadata_header_padding(AVFormatContext *s, int c); +attribute_deprecated +void * av_format_get_opaque(const AVFormatContext *s); +attribute_deprecated +void av_format_set_opaque(AVFormatContext *s, void *opaque); +attribute_deprecated +av_format_control_message av_format_get_control_message_cb(const AVFormatContext *s); +attribute_deprecated +void av_format_set_control_message_cb(AVFormatContext *s, av_format_control_message callback); +#if FF_API_OLD_OPEN_CALLBACKS +attribute_deprecated AVOpenCallback av_format_get_open_cb(const AVFormatContext *s); +attribute_deprecated void av_format_set_open_cb(AVFormatContext *s, AVOpenCallback callback); +#endif +#endif + +/** + * This function will cause global side data to be injected in the next packet + * of each stream as well as after any subsequent seek. + */ +void av_format_inject_global_side_data(AVFormatContext *s); + +/** + * Returns the method used to set ctx->duration. + * + * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE. + */ +enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx); + +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; + + +/** + * @defgroup lavf_core Core functions + * @ingroup libavf + * + * Functions for querying libavformat capabilities, allocating core structures, + * etc. + * @{ + */ + +/** + * Return the LIBAVFORMAT_VERSION_INT constant. + */ +unsigned avformat_version(void); + +/** + * Return the libavformat build-time configuration. + */ +const char *avformat_configuration(void); + +/** + * Return the libavformat license. + */ +const char *avformat_license(void); + +#if FF_API_NEXT +/** + * Initialize libavformat and register all the muxers, demuxers and + * protocols. If you do not call this function, then you can select + * exactly which formats you want to support. + * + * @see av_register_input_format() + * @see av_register_output_format() + */ +attribute_deprecated +void av_register_all(void); + +attribute_deprecated +void av_register_input_format(AVInputFormat *format); +attribute_deprecated +void av_register_output_format(AVOutputFormat *format); +#endif + +/** + * Do global initialization of network libraries. This is optional, + * and not recommended anymore. + * + * This functions only exists to work around thread-safety issues + * with older GnuTLS or OpenSSL libraries. If libavformat is linked + * to newer versions of those libraries, or if you do not use them, + * calling this function is unnecessary. Otherwise, you need to call + * this function before any other threads using them are started. + * + * This function will be deprecated once support for older GnuTLS and + * OpenSSL libraries is removed, and this function has no purpose + * anymore. + */ +int avformat_network_init(void); + +/** + * Undo the initialization done by avformat_network_init. Call it only + * once for each time you called avformat_network_init. + */ +int avformat_network_deinit(void); + +#if FF_API_NEXT +/** + * If f is NULL, returns the first registered input format, + * if f is non-NULL, returns the next registered input format after f + * or NULL if f is the last one. + */ +attribute_deprecated +AVInputFormat *av_iformat_next(const AVInputFormat *f); + +/** + * If f is NULL, returns the first registered output format, + * if f is non-NULL, returns the next registered output format after f + * or NULL if f is the last one. + */ +attribute_deprecated +AVOutputFormat *av_oformat_next(const AVOutputFormat *f); +#endif + +/** + * Iterate over all registered muxers. + * + * @param opaque a pointer where libavformat will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered muxer or NULL when the iteration is + * finished + */ +const AVOutputFormat *av_muxer_iterate(void **opaque); + +/** + * Iterate over all registered demuxers. + * + * @param opaque a pointer where libavformat will store the iteration state. Must + * point to NULL to start the iteration. + * + * @return the next registered demuxer or NULL when the iteration is + * finished + */ +const AVInputFormat *av_demuxer_iterate(void **opaque); + +/** + * Allocate an AVFormatContext. + * avformat_free_context() can be used to free the context and everything + * allocated by the framework within it. + */ +AVFormatContext *avformat_alloc_context(void); + +/** + * Free an AVFormatContext and all its streams. + * @param s context to free + */ +void avformat_free_context(AVFormatContext *s); + +/** + * Get the AVClass for AVFormatContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avformat_get_class(void); + +/** + * Add a new stream to a media file. + * + * When demuxing, it is called by the demuxer in read_header(). If the + * flag AVFMTCTX_NOHEADER is set in s.ctx_flags, then it may also + * be called in read_packet(). + * + * When muxing, should be called by the user before avformat_write_header(). + * + * User is required to call avcodec_close() and avformat_free_context() to + * clean up the allocation by avformat_new_stream(). + * + * @param s media file handle + * @param c If non-NULL, the AVCodecContext corresponding to the new stream + * will be initialized to use this codec. This is needed for e.g. codec-specific + * defaults to be set, so codec should be provided if it is known. + * + * @return newly created stream or NULL on error. + */ +AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c); + +/** + * Wrap an existing array as stream side data. + * + * @param st stream + * @param type side information type + * @param data the side data array. It must be allocated with the av_malloc() + * family of functions. The ownership of the data is transferred to + * st. + * @param size side information size + * @return zero on success, a negative AVERROR code on failure. On failure, + * the stream is unchanged and the data remains owned by the caller. + */ +int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type, + uint8_t *data, size_t size); + +/** + * Allocate new information from stream. + * + * @param stream stream + * @param type desired side information type + * @param size side information size + * @return pointer to fresh allocated data or NULL otherwise + */ +uint8_t *av_stream_new_side_data(AVStream *stream, + enum AVPacketSideDataType type, int size); +/** + * Get side information from stream. + * + * @param stream stream + * @param type desired side information type + * @param size pointer for side information size to store (optional) + * @return pointer to data if present or NULL otherwise + */ +uint8_t *av_stream_get_side_data(const AVStream *stream, + enum AVPacketSideDataType type, int *size); + +AVProgram *av_new_program(AVFormatContext *s, int id); + +/** + * @} + */ + + +/** + * Allocate an AVFormatContext for an output format. + * avformat_free_context() can be used to free the context and + * everything allocated by the framework within it. + * + * @param *ctx is set to the created format context, or to NULL in + * case of failure + * @param oformat format to use for allocating the context, if NULL + * format_name and filename are used instead + * @param format_name the name of output format to use for allocating the + * context, if NULL filename is used instead + * @param filename the name of the filename to use for allocating the + * context, may be NULL + * @return >= 0 in case of success, a negative AVERROR code in case of + * failure + */ +int avformat_alloc_output_context2(AVFormatContext **ctx, ff_const59 AVOutputFormat *oformat, + const char *format_name, const char *filename); + +/** + * @addtogroup lavf_decoding + * @{ + */ + +/** + * Find AVInputFormat based on the short name of the input format. + */ +ff_const59 AVInputFormat *av_find_input_format(const char *short_name); + +/** + * Guess the file format. + * + * @param pd data to be probed + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + */ +ff_const59 AVInputFormat *av_probe_input_format(ff_const59 AVProbeData *pd, int is_opened); + +/** + * Guess the file format. + * + * @param pd data to be probed + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + * @param score_max A probe score larger that this is required to accept a + * detection, the variable is set to the actual detection + * score afterwards. + * If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended + * to retry with a larger probe buffer. + */ +ff_const59 AVInputFormat *av_probe_input_format2(ff_const59 AVProbeData *pd, int is_opened, int *score_max); + +/** + * Guess the file format. + * + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + * @param score_ret The score of the best detection. + */ +ff_const59 AVInputFormat *av_probe_input_format3(ff_const59 AVProbeData *pd, int is_opened, int *score_ret); + +/** + * Probe a bytestream to determine the input format. Each time a probe returns + * with a score that is too low, the probe buffer size is increased and another + * attempt is made. When the maximum probe size is reached, the input format + * with the highest score is returned. + * + * @param pb the bytestream to probe + * @param fmt the input format is put here + * @param url the url of the stream + * @param logctx the log context + * @param offset the offset within the bytestream to probe from + * @param max_probe_size the maximum probe buffer size (zero for default) + * @return the score in case of success, a negative value corresponding to an + * the maximal score is AVPROBE_SCORE_MAX + * AVERROR code otherwise + */ +int av_probe_input_buffer2(AVIOContext *pb, ff_const59 AVInputFormat **fmt, + const char *url, void *logctx, + unsigned int offset, unsigned int max_probe_size); + +/** + * Like av_probe_input_buffer2() but returns 0 on success + */ +int av_probe_input_buffer(AVIOContext *pb, ff_const59 AVInputFormat **fmt, + const char *url, void *logctx, + unsigned int offset, unsigned int max_probe_size); + +/** + * Open an input stream and read the header. The codecs are not opened. + * The stream must be closed with avformat_close_input(). + * + * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context). + * May be a pointer to NULL, in which case an AVFormatContext is allocated by this + * function and written into ps. + * Note that a user-supplied AVFormatContext will be freed on failure. + * @param url URL of the stream to open. + * @param fmt If non-NULL, this parameter forces a specific input format. + * Otherwise the format is autodetected. + * @param options A dictionary filled with AVFormatContext and demuxer-private options. + * On return this parameter will be destroyed and replaced with a dict containing + * options that were not found. May be NULL. + * + * @return 0 on success, a negative AVERROR on failure. + * + * @note If you want to use custom IO, preallocate the format context and set its pb field. + */ +int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options); + +attribute_deprecated +int av_demuxer_open(AVFormatContext *ic); + +/** + * Read packets of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also computes the real framerate in case of MPEG-2 repeat + * frame mode. + * The logical file position is not changed by this function; + * examined packets may be buffered for later processing. + * + * @param ic media file handle + * @param options If non-NULL, an ic.nb_streams long array of pointers to + * dictionaries, where i-th member contains options for + * codec corresponding to i-th stream. + * On return each dictionary will be filled with options that were not found. + * @return >=0 if OK, AVERROR_xxx on error + * + * @note this function isn't guaranteed to open all the codecs, so + * options being non-empty at return is a perfectly normal behavior. + * + * @todo Let the user decide somehow what information is needed so that + * we do not waste time getting stuff the user does not need. + */ +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options); + +/** + * Find the programs which belong to a given stream. + * + * @param ic media file handle + * @param last the last found program, the search will start after this + * program, or from the beginning if it is NULL + * @param s stream index + * @return the next program which belongs to s, NULL if no program is found or + * the last program is not among the programs of ic. + */ +AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s); + +void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx); + +/** + * Find the "best" stream in the file. + * The best stream is determined according to various heuristics as the most + * likely to be what the user expects. + * If the decoder parameter is non-NULL, av_find_best_stream will find the + * default decoder for the stream's codec; streams for which no decoder can + * be found are ignored. + * + * @param ic media file handle + * @param type stream type: video, audio, subtitles, etc. + * @param wanted_stream_nb user-requested stream number, + * or -1 for automatic selection + * @param related_stream try to find a stream related (eg. in the same + * program) to this one, or -1 if none + * @param decoder_ret if non-NULL, returns the decoder for the + * selected stream + * @param flags flags; none are currently defined + * @return the non-negative stream number in case of success, + * AVERROR_STREAM_NOT_FOUND if no stream with the requested type + * could be found, + * AVERROR_DECODER_NOT_FOUND if streams were found but no decoder + * @note If av_find_best_stream returns successfully and decoder_ret is not + * NULL, then *decoder_ret is guaranteed to be set to a valid AVCodec. + */ +int av_find_best_stream(AVFormatContext *ic, + enum AVMediaType type, + int wanted_stream_nb, + int related_stream, + AVCodec **decoder_ret, + int flags); + +/** + * Return the next frame of a stream. + * This function returns what is stored in the file, and does not validate + * that what is there are valid frames for the decoder. It will split what is + * stored in the file into frames and return one for each call. It will not + * omit invalid data between valid frames so as to give the decoder the maximum + * information possible for decoding. + * + * On success, the returned packet is reference-counted (pkt->buf is set) and + * valid indefinitely. The packet must be freed with av_packet_unref() when + * it is no longer needed. For video, the packet contains exactly one frame. + * For audio, it contains an integer number of frames if each frame has + * a known fixed size (e.g. PCM or ADPCM data). If the audio frames have + * a variable size (e.g. MPEG audio), then it contains one frame. + * + * pkt->pts, pkt->dts and pkt->duration are always set to correct + * values in AVStream.time_base units (and guessed if the format cannot + * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format + * has B-frames, so it is better to rely on pkt->dts if you do not + * decompress the payload. + * + * @return 0 if OK, < 0 on error or end of file. On error, pkt will be blank + * (as if it came from av_packet_alloc()). + * + * @note pkt will be initialized, so it may be uninitialized, but it must not + * contain data that needs to be freed. + */ +int av_read_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Seek to the keyframe at timestamp. + * 'timestamp' in 'stream_index'. + * + * @param s media file handle + * @param stream_index If stream_index is (-1), a default + * stream is selected, and timestamp is automatically converted + * from AV_TIME_BASE units to the stream specific time_base. + * @param timestamp Timestamp in AVStream.time_base units + * or, if no stream is specified, in AV_TIME_BASE units. + * @param flags flags which select direction and seeking mode + * @return >= 0 on success + */ +int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, + int flags); + +/** + * Seek to timestamp ts. + * Seeking will be done so that the point from which all active streams + * can be presented successfully will be closest to ts and within min/max_ts. + * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. + * + * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and + * are the file position (this may not be supported by all demuxers). + * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames + * in the stream with stream_index (this may not be supported by all demuxers). + * Otherwise all timestamps are in units of the stream selected by stream_index + * or if stream_index is -1, in AV_TIME_BASE units. + * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as + * keyframes (this may not be supported by all demuxers). + * If flags contain AVSEEK_FLAG_BACKWARD, it is ignored. + * + * @param s media file handle + * @param stream_index index of the stream which is used as time base reference + * @param min_ts smallest acceptable timestamp + * @param ts target timestamp + * @param max_ts largest acceptable timestamp + * @param flags flags + * @return >=0 on success, error code otherwise + * + * @note This is part of the new seek API which is still under construction. + */ +int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + +/** + * Discard all internally buffered data. This can be useful when dealing with + * discontinuities in the byte stream. Generally works only with formats that + * can resync. This includes headerless formats like MPEG-TS/TS but should also + * work with NUT, Ogg and in a limited way AVI for example. + * + * The set of streams, the detected duration, stream parameters and codecs do + * not change when calling this function. If you want a complete reset, it's + * better to open a new AVFormatContext. + * + * This does not flush the AVIOContext (s->pb). If necessary, call + * avio_flush(s->pb) before calling this function. + * + * @param s media file handle + * @return >=0 on success, error code otherwise + */ +int avformat_flush(AVFormatContext *s); + +/** + * Start playing a network-based stream (e.g. RTSP stream) at the + * current position. + */ +int av_read_play(AVFormatContext *s); + +/** + * Pause a network-based stream (e.g. RTSP stream). + * + * Use av_read_play() to resume it. + */ +int av_read_pause(AVFormatContext *s); + +/** + * Close an opened input AVFormatContext. Free it and all its contents + * and set *s to NULL. + */ +void avformat_close_input(AVFormatContext **s); +/** + * @} + */ + +#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward +#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes +#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes +#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number + +/** + * @addtogroup lavf_encoding + * @{ + */ + +#define AVSTREAM_INIT_IN_WRITE_HEADER 0 ///< stream parameters initialized in avformat_write_header +#define AVSTREAM_INIT_IN_INIT_OUTPUT 1 ///< stream parameters initialized in avformat_init_output + +/** + * Allocate the stream private data and write the stream header to + * an output media file. + * + * @param s Media file handle, must be allocated with avformat_alloc_context(). + * Its oformat field must be set to the desired output format; + * Its pb field must be set to an already opened AVIOContext. + * @param options An AVDictionary filled with AVFormatContext and muxer-private options. + * On return this parameter will be destroyed and replaced with a dict containing + * options that were not found. May be NULL. + * + * @return AVSTREAM_INIT_IN_WRITE_HEADER on success if the codec had not already been fully initialized in avformat_init, + * AVSTREAM_INIT_IN_INIT_OUTPUT on success if the codec had already been fully initialized in avformat_init, + * negative AVERROR on failure. + * + * @see av_opt_find, av_dict_set, avio_open, av_oformat_next, avformat_init_output. + */ +av_warn_unused_result +int avformat_write_header(AVFormatContext *s, AVDictionary **options); + +/** + * Allocate the stream private data and initialize the codec, but do not write the header. + * May optionally be used before avformat_write_header to initialize stream parameters + * before actually writing the header. + * If using this function, do not pass the same options to avformat_write_header. + * + * @param s Media file handle, must be allocated with avformat_alloc_context(). + * Its oformat field must be set to the desired output format; + * Its pb field must be set to an already opened AVIOContext. + * @param options An AVDictionary filled with AVFormatContext and muxer-private options. + * On return this parameter will be destroyed and replaced with a dict containing + * options that were not found. May be NULL. + * + * @return AVSTREAM_INIT_IN_WRITE_HEADER on success if the codec requires avformat_write_header to fully initialize, + * AVSTREAM_INIT_IN_INIT_OUTPUT on success if the codec has been fully initialized, + * negative AVERROR on failure. + * + * @see av_opt_find, av_dict_set, avio_open, av_oformat_next, avformat_write_header. + */ +av_warn_unused_result +int avformat_init_output(AVFormatContext *s, AVDictionary **options); + +/** + * Write a packet to an output media file. + * + * This function passes the packet directly to the muxer, without any buffering + * or reordering. The caller is responsible for correctly interleaving the + * packets if the format requires it. Callers that want libavformat to handle + * the interleaving should call av_interleaved_write_frame() instead of this + * function. + * + * @param s media file handle + * @param pkt The packet containing the data to be written. Note that unlike + * av_interleaved_write_frame(), this function does not take + * ownership of the packet passed to it (though some muxers may make + * an internal reference to the input packet). + *
+ * This parameter can be NULL (at any time, not just at the end), in + * order to immediately flush data buffered within the muxer, for + * muxers that buffer up data internally before writing it to the + * output. + *
+ * Packet's @ref AVPacket.stream_index "stream_index" field must be + * set to the index of the corresponding stream in @ref + * AVFormatContext.streams "s->streams". + *
+ * The timestamps (@ref AVPacket.pts "pts", @ref AVPacket.dts "dts") + * must be set to correct values in the stream's timebase (unless the + * output format is flagged with the AVFMT_NOTIMESTAMPS flag, then + * they can be set to AV_NOPTS_VALUE). + * The dts for subsequent packets passed to this function must be strictly + * increasing when compared in their respective timebases (unless the + * output format is flagged with the AVFMT_TS_NONSTRICT, then they + * merely have to be nondecreasing). @ref AVPacket.duration + * "duration") should also be set if known. + * @return < 0 on error, = 0 if OK, 1 if flushed and there is no more data to flush + * + * @see av_interleaved_write_frame() + */ +int av_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Write a packet to an output media file ensuring correct interleaving. + * + * This function will buffer the packets internally as needed to make sure the + * packets in the output file are properly interleaved in the order of + * increasing dts. Callers doing their own interleaving should call + * av_write_frame() instead of this function. + * + * Using this function instead of av_write_frame() can give muxers advance + * knowledge of future packets, improving e.g. the behaviour of the mp4 + * muxer for VFR content in fragmenting mode. + * + * @param s media file handle + * @param pkt The packet containing the data to be written. + *
+ * If the packet is reference-counted, this function will take + * ownership of this reference and unreference it later when it sees + * fit. + * The caller must not access the data through this reference after + * this function returns. If the packet is not reference-counted, + * libavformat will make a copy. + *
+ * This parameter can be NULL (at any time, not just at the end), to + * flush the interleaving queues. + *
+ * Packet's @ref AVPacket.stream_index "stream_index" field must be + * set to the index of the corresponding stream in @ref + * AVFormatContext.streams "s->streams". + *
+ * The timestamps (@ref AVPacket.pts "pts", @ref AVPacket.dts "dts") + * must be set to correct values in the stream's timebase (unless the + * output format is flagged with the AVFMT_NOTIMESTAMPS flag, then + * they can be set to AV_NOPTS_VALUE). + * The dts for subsequent packets in one stream must be strictly + * increasing (unless the output format is flagged with the + * AVFMT_TS_NONSTRICT, then they merely have to be nondecreasing). + * @ref AVPacket.duration "duration") should also be set if known. + * + * @return 0 on success, a negative AVERROR on error. Libavformat will always + * take care of freeing the packet, even if this function fails. + * + * @see av_write_frame(), AVFormatContext.max_interleave_delta + */ +int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Write an uncoded frame to an output media file. + * + * The frame must be correctly interleaved according to the container + * specification; if not, av_interleaved_write_uncoded_frame() must be used. + * + * See av_interleaved_write_uncoded_frame() for details. + */ +int av_write_uncoded_frame(AVFormatContext *s, int stream_index, + AVFrame *frame); + +/** + * Write an uncoded frame to an output media file. + * + * If the muxer supports it, this function makes it possible to write an AVFrame + * structure directly, without encoding it into a packet. + * It is mostly useful for devices and similar special muxers that use raw + * video or PCM data and will not serialize it into a byte stream. + * + * To test whether it is possible to use it with a given muxer and stream, + * use av_write_uncoded_frame_query(). + * + * The caller gives up ownership of the frame and must not access it + * afterwards. + * + * @return >=0 for success, a negative code on error + */ +int av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index, + AVFrame *frame); + +/** + * Test whether a muxer supports uncoded frame. + * + * @return >=0 if an uncoded frame can be written to that muxer and stream, + * <0 if not + */ +int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index); + +/** + * Write the stream trailer to an output media file and free the + * file private data. + * + * May only be called after a successful call to avformat_write_header. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_trailer(AVFormatContext *s); + +/** + * Return the output format in the list of registered output formats + * which best matches the provided parameters, or return NULL if + * there is no match. + * + * @param short_name if non-NULL checks if short_name matches with the + * names of the registered formats + * @param filename if non-NULL checks if filename terminates with the + * extensions of the registered formats + * @param mime_type if non-NULL checks if mime_type matches with the + * MIME type of the registered formats + */ +ff_const59 AVOutputFormat *av_guess_format(const char *short_name, + const char *filename, + const char *mime_type); + +/** + * Guess the codec ID based upon muxer and filename. + */ +enum AVCodecID av_guess_codec(ff_const59 AVOutputFormat *fmt, const char *short_name, + const char *filename, const char *mime_type, + enum AVMediaType type); + +/** + * Get timing information for the data currently output. + * The exact meaning of "currently output" depends on the format. + * It is mostly relevant for devices that have an internal buffer and/or + * work in real time. + * @param s media file handle + * @param stream stream in the media file + * @param[out] dts DTS of the last packet output for the stream, in stream + * time_base units + * @param[out] wall absolute time when that packet whas output, + * in microsecond + * @return 0 if OK, AVERROR(ENOSYS) if the format does not support it + * Note: some formats or devices may not allow to measure dts and wall + * atomically. + */ +int av_get_output_timestamp(struct AVFormatContext *s, int stream, + int64_t *dts, int64_t *wall); + + +/** + * @} + */ + + +/** + * @defgroup lavf_misc Utility functions + * @ingroup libavf + * @{ + * + * Miscellaneous utility functions related to both muxing and demuxing + * (or neither). + */ + +/** + * Send a nice hexadecimal dump of a buffer to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump_log, av_pkt_dump2, av_pkt_dump_log2 + */ +void av_hex_dump(FILE *f, const uint8_t *buf, int size); + +/** + * Send a nice hexadecimal dump of a buffer to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump, av_pkt_dump2, av_pkt_dump_log2 + */ +void av_hex_dump_log(void *avcl, int level, const uint8_t *buf, int size); + +/** + * Send a nice dump of a packet to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + * @param st AVStream that the packet belongs to + */ +void av_pkt_dump2(FILE *f, const AVPacket *pkt, int dump_payload, const AVStream *st); + + +/** + * Send a nice dump of a packet to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + * @param st AVStream that the packet belongs to + */ +void av_pkt_dump_log2(void *avcl, int level, const AVPacket *pkt, int dump_payload, + const AVStream *st); + +/** + * Get the AVCodecID for the given codec tag tag. + * If no codec id is found returns AV_CODEC_ID_NONE. + * + * @param tags list of supported codec_id-codec_tag pairs, as stored + * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + * @param tag codec tag to match to a codec ID + */ +enum AVCodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); + +/** + * Get the codec tag for the given codec id id. + * If no codec tag is found returns 0. + * + * @param tags list of supported codec_id-codec_tag pairs, as stored + * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + * @param id codec ID to match to a codec tag + */ +unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum AVCodecID id); + +/** + * Get the codec tag for the given codec id. + * + * @param tags list of supported codec_id - codec_tag pairs, as stored + * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + * @param id codec id that should be searched for in the list + * @param tag A pointer to the found tag + * @return 0 if id was not found in tags, > 0 if it was found + */ +int av_codec_get_tag2(const struct AVCodecTag * const *tags, enum AVCodecID id, + unsigned int *tag); + +int av_find_default_stream_index(AVFormatContext *s); + +/** + * Get the index for a specific timestamp. + * + * @param st stream that the timestamp belongs to + * @param timestamp timestamp to retrieve the index for + * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond + * to the timestamp which is <= the requested one, if backward + * is 0, then it will be >= + * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise + * @return < 0 if no such timestamp could be found + */ +int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); + +/** + * Add an index entry into a sorted list. Update the entry if the list + * already contains it. + * + * @param timestamp timestamp in the time base of the given stream + */ +int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, + int size, int distance, int flags); + + +/** + * Split a URL string into components. + * + * The pointers to buffers for storing individual components may be null, + * in order to ignore that component. Buffers for components not found are + * set to empty strings. If the port is not found, it is set to a negative + * value. + * + * @param proto the buffer for the protocol + * @param proto_size the size of the proto buffer + * @param authorization the buffer for the authorization + * @param authorization_size the size of the authorization buffer + * @param hostname the buffer for the host name + * @param hostname_size the size of the hostname buffer + * @param port_ptr a pointer to store the port number in + * @param path the buffer for the path + * @param path_size the size of the path buffer + * @param url the URL to split + */ +void av_url_split(char *proto, int proto_size, + char *authorization, int authorization_size, + char *hostname, int hostname_size, + int *port_ptr, + char *path, int path_size, + const char *url); + + +/** + * Print detailed information about the input or output format, such as + * duration, bitrate, streams, container, programs, metadata, side data, + * codec and time base. + * + * @param ic the context to analyze + * @param index index of the stream to dump information about + * @param url the URL to print, such as source or destination file + * @param is_output Select whether the specified context is an input(0) or output(1) + */ +void av_dump_format(AVFormatContext *ic, + int index, + const char *url, + int is_output); + + +#define AV_FRAME_FILENAME_FLAGS_MULTIPLE 1 ///< Allow multiple %d + +/** + * Return in 'buf' the path with '%d' replaced by a number. + * + * Also handles the '%0nd' format where 'n' is the total number + * of digits and '%%'. + * + * @param buf destination buffer + * @param buf_size destination buffer size + * @param path numbered sequence string + * @param number frame number + * @param flags AV_FRAME_FILENAME_FLAGS_* + * @return 0 if OK, -1 on format error + */ +int av_get_frame_filename2(char *buf, int buf_size, + const char *path, int number, int flags); + +int av_get_frame_filename(char *buf, int buf_size, + const char *path, int number); + +/** + * Check whether filename actually is a numbered sequence generator. + * + * @param filename possible numbered sequence string + * @return 1 if a valid numbered sequence string, 0 otherwise + */ +int av_filename_number_test(const char *filename); + +/** + * Generate an SDP for an RTP session. + * + * Note, this overwrites the id values of AVStreams in the muxer contexts + * for getting unique dynamic payload types. + * + * @param ac array of AVFormatContexts describing the RTP streams. If the + * array is composed by only one context, such context can contain + * multiple AVStreams (one AVStream per RTP stream). Otherwise, + * all the contexts in the array (an AVCodecContext per RTP stream) + * must contain only one AVStream. + * @param n_files number of AVCodecContexts contained in ac + * @param buf buffer where the SDP will be stored (must be allocated by + * the caller) + * @param size the size of the buffer + * @return 0 if OK, AVERROR_xxx on error + */ +int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size); + +/** + * Return a positive value if the given filename has one of the given + * extensions, 0 otherwise. + * + * @param filename file name to check against the given extensions + * @param extensions a comma-separated list of filename extensions + */ +int av_match_ext(const char *filename, const char *extensions); + +/** + * Test if the given container can store a codec. + * + * @param ofmt container to check for compatibility + * @param codec_id codec to potentially store in container + * @param std_compliance standards compliance level, one of FF_COMPLIANCE_* + * + * @return 1 if codec with ID codec_id can be stored in ofmt, 0 if it cannot. + * A negative number if this information is not available. + */ +int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id, + int std_compliance); + +/** + * @defgroup riff_fourcc RIFF FourCCs + * @{ + * Get the tables mapping RIFF FourCCs to libavcodec AVCodecIDs. The tables are + * meant to be passed to av_codec_get_id()/av_codec_get_tag() as in the + * following code: + * @code + * uint32_t tag = MKTAG('H', '2', '6', '4'); + * const struct AVCodecTag *table[] = { avformat_get_riff_video_tags(), 0 }; + * enum AVCodecID id = av_codec_get_id(table, tag); + * @endcode + */ +/** + * @return the table mapping RIFF FourCCs for video to libavcodec AVCodecID. + */ +const struct AVCodecTag *avformat_get_riff_video_tags(void); +/** + * @return the table mapping RIFF FourCCs for audio to AVCodecID. + */ +const struct AVCodecTag *avformat_get_riff_audio_tags(void); +/** + * @return the table mapping MOV FourCCs for video to libavcodec AVCodecID. + */ +const struct AVCodecTag *avformat_get_mov_video_tags(void); +/** + * @return the table mapping MOV FourCCs for audio to AVCodecID. + */ +const struct AVCodecTag *avformat_get_mov_audio_tags(void); + +/** + * @} + */ + +/** + * Guess the sample aspect ratio of a frame, based on both the stream and the + * frame aspect ratio. + * + * Since the frame aspect ratio is set by the codec but the stream aspect ratio + * is set by the demuxer, these two may not be equal. This function tries to + * return the value that you should use if you would like to display the frame. + * + * Basic logic is to use the stream aspect ratio if it is set to something sane + * otherwise use the frame aspect ratio. This way a container setting, which is + * usually easy to modify can override the coded value in the frames. + * + * @param format the format context which the stream is part of + * @param stream the stream which the frame is part of + * @param frame the frame with the aspect ratio to be determined + * @return the guessed (valid) sample_aspect_ratio, 0/1 if no idea + */ +AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame); + +/** + * Guess the frame rate, based on both the container and codec information. + * + * @param ctx the format context which the stream is part of + * @param stream the stream which the frame is part of + * @param frame the frame for which the frame rate should be determined, may be NULL + * @return the guessed (valid) frame rate, 0/1 if no idea + */ +AVRational av_guess_frame_rate(AVFormatContext *ctx, AVStream *stream, AVFrame *frame); + +/** + * Check if the stream st contained in s is matched by the stream specifier + * spec. + * + * See the "stream specifiers" chapter in the documentation for the syntax + * of spec. + * + * @return >0 if st is matched by spec; + * 0 if st is not matched by spec; + * AVERROR code if spec is invalid + * + * @note A stream specifier can match several streams in the format. + */ +int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, + const char *spec); + +int avformat_queue_attached_pictures(AVFormatContext *s); + +#if FF_API_OLD_BSF +/** + * Apply a list of bitstream filters to a packet. + * + * @param codec AVCodecContext, usually from an AVStream + * @param pkt the packet to apply filters to. If, on success, the returned + * packet has size == 0 and side_data_elems == 0, it indicates that + * the packet should be dropped + * @param bsfc a NULL-terminated list of filters to apply + * @return >=0 on success; + * AVERROR code on failure + */ +attribute_deprecated +int av_apply_bitstream_filters(AVCodecContext *codec, AVPacket *pkt, + AVBitStreamFilterContext *bsfc); +#endif + +enum AVTimebaseSource { + AVFMT_TBCF_AUTO = -1, + AVFMT_TBCF_DECODER, + AVFMT_TBCF_DEMUXER, +#if FF_API_R_FRAME_RATE + AVFMT_TBCF_R_FRAMERATE, +#endif +}; + +/** + * Transfer internal timing information from one stream to another. + * + * This function is useful when doing stream copy. + * + * @param ofmt target output format for ost + * @param ost output stream which needs timings copy and adjustments + * @param ist reference input stream to copy timings from + * @param copy_tb define from where the stream codec timebase needs to be imported + */ +int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt, + AVStream *ost, const AVStream *ist, + enum AVTimebaseSource copy_tb); + +/** + * Get the internal codec timebase from a stream. + * + * @param st input stream to extract the timebase from + */ +AVRational av_stream_get_codec_timebase(const AVStream *st); + +/** + * @} + */ + +#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/ffmpeg/inc/libavformat/avio.h b/ffmpeg/inc/libavformat/avio.h new file mode 100644 index 0000000..d022820 --- /dev/null +++ b/ffmpeg/inc/libavformat/avio.h @@ -0,0 +1,888 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVFORMAT_AVIO_H +#define AVFORMAT_AVIO_H + +/** + * @file + * @ingroup lavf_io + * Buffered I/O operations + */ + +#include + +#include "libavutil/common.h" +#include "libavutil/dict.h" +#include "libavutil/log.h" + +#include "libavformat/version.h" + +/** + * Seeking works like for a local file. + */ +#define AVIO_SEEKABLE_NORMAL (1 << 0) + +/** + * Seeking by timestamp with avio_seek_time() is possible. + */ +#define AVIO_SEEKABLE_TIME (1 << 1) + +/** + * Callback for checking whether to abort blocking functions. + * AVERROR_EXIT is returned in this case by the interrupted + * function. During blocking operations, callback is called with + * opaque as parameter. If the callback returns 1, the + * blocking operation will be aborted. + * + * No members can be added to this struct without a major bump, if + * new elements have been added after this struct in AVFormatContext + * or AVIOContext. + */ +typedef struct AVIOInterruptCB { + int (*callback)(void*); + void *opaque; +} AVIOInterruptCB; + +/** + * Directory entry types. + */ +enum AVIODirEntryType { + AVIO_ENTRY_UNKNOWN, + AVIO_ENTRY_BLOCK_DEVICE, + AVIO_ENTRY_CHARACTER_DEVICE, + AVIO_ENTRY_DIRECTORY, + AVIO_ENTRY_NAMED_PIPE, + AVIO_ENTRY_SYMBOLIC_LINK, + AVIO_ENTRY_SOCKET, + AVIO_ENTRY_FILE, + AVIO_ENTRY_SERVER, + AVIO_ENTRY_SHARE, + AVIO_ENTRY_WORKGROUP, +}; + +/** + * Describes single entry of the directory. + * + * Only name and type fields are guaranteed be set. + * Rest of fields are protocol or/and platform dependent and might be unknown. + */ +typedef struct AVIODirEntry { + char *name; /**< Filename */ + int type; /**< Type of the entry */ + int utf8; /**< Set to 1 when name is encoded with UTF-8, 0 otherwise. + Name can be encoded with UTF-8 even though 0 is set. */ + int64_t size; /**< File size in bytes, -1 if unknown. */ + int64_t modification_timestamp; /**< Time of last modification in microseconds since unix + epoch, -1 if unknown. */ + int64_t access_timestamp; /**< Time of last access in microseconds since unix epoch, + -1 if unknown. */ + int64_t status_change_timestamp; /**< Time of last status change in microseconds since unix + epoch, -1 if unknown. */ + int64_t user_id; /**< User ID of owner, -1 if unknown. */ + int64_t group_id; /**< Group ID of owner, -1 if unknown. */ + int64_t filemode; /**< Unix file mode, -1 if unknown. */ +} AVIODirEntry; + +typedef struct AVIODirContext { + struct URLContext *url_context; +} AVIODirContext; + +/** + * Different data types that can be returned via the AVIO + * write_data_type callback. + */ +enum AVIODataMarkerType { + /** + * Header data; this needs to be present for the stream to be decodeable. + */ + AVIO_DATA_MARKER_HEADER, + /** + * A point in the output bytestream where a decoder can start decoding + * (i.e. a keyframe). A demuxer/decoder given the data flagged with + * AVIO_DATA_MARKER_HEADER, followed by any AVIO_DATA_MARKER_SYNC_POINT, + * should give decodeable results. + */ + AVIO_DATA_MARKER_SYNC_POINT, + /** + * A point in the output bytestream where a demuxer can start parsing + * (for non self synchronizing bytestream formats). That is, any + * non-keyframe packet start point. + */ + AVIO_DATA_MARKER_BOUNDARY_POINT, + /** + * This is any, unlabelled data. It can either be a muxer not marking + * any positions at all, it can be an actual boundary/sync point + * that the muxer chooses not to mark, or a later part of a packet/fragment + * that is cut into multiple write callbacks due to limited IO buffer size. + */ + AVIO_DATA_MARKER_UNKNOWN, + /** + * Trailer data, which doesn't contain actual content, but only for + * finalizing the output file. + */ + AVIO_DATA_MARKER_TRAILER, + /** + * A point in the output bytestream where the underlying AVIOContext might + * flush the buffer depending on latency or buffering requirements. Typically + * means the end of a packet. + */ + AVIO_DATA_MARKER_FLUSH_POINT, +}; + +/** + * Bytestream IO Context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVIOContext) must not be used outside libav*. + * + * @note None of the function pointers in AVIOContext should be called + * directly, they should only be set by the client application + * when implementing custom I/O. Normally these are set to the + * function pointers specified in avio_alloc_context() + */ +typedef struct AVIOContext { + /** + * A class for private options. + * + * If this AVIOContext is created by avio_open2(), av_class is set and + * passes the options down to protocols. + * + * If this AVIOContext is manually allocated, then av_class may be set by + * the caller. + * + * warning -- this field can be NULL, be sure to not pass this AVIOContext + * to any av_opt_* functions in that case. + */ + const AVClass *av_class; + + /* + * The following shows the relationship between buffer, buf_ptr, + * buf_ptr_max, buf_end, buf_size, and pos, when reading and when writing + * (since AVIOContext is used for both): + * + ********************************************************************************** + * READING + ********************************************************************************** + * + * | buffer_size | + * |---------------------------------------| + * | | + * + * buffer buf_ptr buf_end + * +---------------+-----------------------+ + * |/ / / / / / / /|/ / / / / / /| | + * read buffer: |/ / consumed / | to be read /| | + * |/ / / / / / / /|/ / / / / / /| | + * +---------------+-----------------------+ + * + * pos + * +-------------------------------------------+-----------------+ + * input file: | | | + * +-------------------------------------------+-----------------+ + * + * + ********************************************************************************** + * WRITING + ********************************************************************************** + * + * | buffer_size | + * |--------------------------------------| + * | | + * + * buf_ptr_max + * buffer (buf_ptr) buf_end + * +-----------------------+--------------+ + * |/ / / / / / / / / / / /| | + * write buffer: | / / to be flushed / / | | + * |/ / / / / / / / / / / /| | + * +-----------------------+--------------+ + * buf_ptr can be in this + * due to a backward seek + * + * pos + * +-------------+----------------------------------------------+ + * output file: | | | + * +-------------+----------------------------------------------+ + * + */ + unsigned char *buffer; /**< Start of the buffer. */ + int buffer_size; /**< Maximum buffer size */ + unsigned char *buf_ptr; /**< Current position in the buffer */ + unsigned char *buf_end; /**< End of the data, may be less than + buffer+buffer_size if the read function returned + less data than requested, e.g. for streams where + no more data has been received yet. */ + void *opaque; /**< A private pointer, passed to the read/write/seek/... + functions. */ + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); + int64_t (*seek)(void *opaque, int64_t offset, int whence); + int64_t pos; /**< position in the file of the current buffer */ + int eof_reached; /**< true if was unable to read due to error or eof */ + int write_flag; /**< true if open for writing */ + int max_packet_size; + unsigned long checksum; + unsigned char *checksum_ptr; + unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); + int error; /**< contains the error code or 0 if no error happened */ + /** + * Pause or resume playback for network streaming protocols - e.g. MMS. + */ + int (*read_pause)(void *opaque, int pause); + /** + * Seek to a given timestamp in stream with the specified stream_index. + * Needed for some network streaming protocols which don't support seeking + * to byte position. + */ + int64_t (*read_seek)(void *opaque, int stream_index, + int64_t timestamp, int flags); + /** + * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable. + */ + int seekable; + + /** + * max filesize, used to limit allocations + * This field is internal to libavformat and access from outside is not allowed. + */ + int64_t maxsize; + + /** + * avio_read and avio_write should if possible be satisfied directly + * instead of going through a buffer, and avio_seek will always + * call the underlying seek function directly. + */ + int direct; + + /** + * Bytes read statistic + * This field is internal to libavformat and access from outside is not allowed. + */ + int64_t bytes_read; + + /** + * seek statistic + * This field is internal to libavformat and access from outside is not allowed. + */ + int seek_count; + + /** + * writeout statistic + * This field is internal to libavformat and access from outside is not allowed. + */ + int writeout_count; + + /** + * Original buffer size + * used internally after probing and ensure seekback to reset the buffer size + * This field is internal to libavformat and access from outside is not allowed. + */ + int orig_buffer_size; + + /** + * Threshold to favor readahead over seek. + * This is current internal only, do not use from outside. + */ + int short_seek_threshold; + + /** + * ',' separated list of allowed protocols. + */ + const char *protocol_whitelist; + + /** + * ',' separated list of disallowed protocols. + */ + const char *protocol_blacklist; + + /** + * A callback that is used instead of write_packet. + */ + int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size, + enum AVIODataMarkerType type, int64_t time); + /** + * If set, don't call write_data_type separately for AVIO_DATA_MARKER_BOUNDARY_POINT, + * but ignore them and treat them as AVIO_DATA_MARKER_UNKNOWN (to avoid needlessly + * small chunks of data returned from the callback). + */ + int ignore_boundary_point; + + /** + * Internal, not meant to be used from outside of AVIOContext. + */ + enum AVIODataMarkerType current_type; + int64_t last_time; + + /** + * A callback that is used instead of short_seek_threshold. + * This is current internal only, do not use from outside. + */ + int (*short_seek_get)(void *opaque); + + int64_t written; + + /** + * Maximum reached position before a backward seek in the write buffer, + * used keeping track of already written data for a later flush. + */ + unsigned char *buf_ptr_max; + + /** + * Try to buffer at least this amount of data before flushing it + */ + int min_packet_size; +} AVIOContext; + +/** + * Return the name of the protocol that will handle the passed URL. + * + * NULL is returned if no protocol could be found for the given URL. + * + * @return Name of the protocol or NULL. + */ +const char *avio_find_protocol_name(const char *url); + +/** + * Return AVIO_FLAG_* access flags corresponding to the access permissions + * of the resource in url, or a negative value corresponding to an + * AVERROR code in case of failure. The returned access flags are + * masked by the value in flags. + * + * @note This function is intrinsically unsafe, in the sense that the + * checked resource may change its existence or permission status from + * one call to another. Thus you should not trust the returned value, + * unless you are sure that no other processes are accessing the + * checked resource. + */ +int avio_check(const char *url, int flags); + +/** + * Move or rename a resource. + * + * @note url_src and url_dst should share the same protocol and authority. + * + * @param url_src url to resource to be moved + * @param url_dst new url to resource if the operation succeeded + * @return >=0 on success or negative on error. + */ +int avpriv_io_move(const char *url_src, const char *url_dst); + +/** + * Delete a resource. + * + * @param url resource to be deleted. + * @return >=0 on success or negative on error. + */ +int avpriv_io_delete(const char *url); + +/** + * Open directory for reading. + * + * @param s directory read context. Pointer to a NULL pointer must be passed. + * @param url directory to be listed. + * @param options A dictionary filled with protocol-private options. On return + * this parameter will be destroyed and replaced with a dictionary + * containing options that were not found. May be NULL. + * @return >=0 on success or negative on error. + */ +int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options); + +/** + * Get next directory entry. + * + * Returned entry must be freed with avio_free_directory_entry(). In particular + * it may outlive AVIODirContext. + * + * @param s directory read context. + * @param[out] next next entry or NULL when no more entries. + * @return >=0 on success or negative on error. End of list is not considered an + * error. + */ +int avio_read_dir(AVIODirContext *s, AVIODirEntry **next); + +/** + * Close directory. + * + * @note Entries created using avio_read_dir() are not deleted and must be + * freeded with avio_free_directory_entry(). + * + * @param s directory read context. + * @return >=0 on success or negative on error. + */ +int avio_close_dir(AVIODirContext **s); + +/** + * Free entry allocated by avio_read_dir(). + * + * @param entry entry to be freed. + */ +void avio_free_directory_entry(AVIODirEntry **entry); + +/** + * Allocate and initialize an AVIOContext for buffered I/O. It must be later + * freed with avio_context_free(). + * + * @param buffer Memory block for input/output operations via AVIOContext. + * The buffer must be allocated with av_malloc() and friends. + * It may be freed and replaced with a new buffer by libavformat. + * AVIOContext.buffer holds the buffer currently in use, + * which must be later freed with av_free(). + * @param buffer_size The buffer size is very important for performance. + * For protocols with fixed blocksize it should be set to this blocksize. + * For others a typical size is a cache page, e.g. 4kb. + * @param write_flag Set to 1 if the buffer should be writable, 0 otherwise. + * @param opaque An opaque pointer to user-specific data. + * @param read_packet A function for refilling the buffer, may be NULL. + * For stream protocols, must never return 0 but rather + * a proper AVERROR code. + * @param write_packet A function for writing the buffer contents, may be NULL. + * The function may not change the input buffers content. + * @param seek A function for seeking to specified byte position, may be NULL. + * + * @return Allocated AVIOContext or NULL on failure. + */ +AVIOContext *avio_alloc_context( + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int64_t (*seek)(void *opaque, int64_t offset, int whence)); + +/** + * Free the supplied IO context and everything associated with it. + * + * @param s Double pointer to the IO context. This function will write NULL + * into s. + */ +void avio_context_free(AVIOContext **s); + +void avio_w8(AVIOContext *s, int b); +void avio_write(AVIOContext *s, const unsigned char *buf, int size); +void avio_wl64(AVIOContext *s, uint64_t val); +void avio_wb64(AVIOContext *s, uint64_t val); +void avio_wl32(AVIOContext *s, unsigned int val); +void avio_wb32(AVIOContext *s, unsigned int val); +void avio_wl24(AVIOContext *s, unsigned int val); +void avio_wb24(AVIOContext *s, unsigned int val); +void avio_wl16(AVIOContext *s, unsigned int val); +void avio_wb16(AVIOContext *s, unsigned int val); + +/** + * Write a NULL-terminated string. + * @return number of bytes written. + */ +int avio_put_str(AVIOContext *s, const char *str); + +/** + * Convert an UTF-8 string to UTF-16LE and write it. + * @param s the AVIOContext + * @param str NULL-terminated UTF-8 string + * + * @return number of bytes written. + */ +int avio_put_str16le(AVIOContext *s, const char *str); + +/** + * Convert an UTF-8 string to UTF-16BE and write it. + * @param s the AVIOContext + * @param str NULL-terminated UTF-8 string + * + * @return number of bytes written. + */ +int avio_put_str16be(AVIOContext *s, const char *str); + +/** + * Mark the written bytestream as a specific type. + * + * Zero-length ranges are omitted from the output. + * + * @param time the stream time the current bytestream pos corresponds to + * (in AV_TIME_BASE units), or AV_NOPTS_VALUE if unknown or not + * applicable + * @param type the kind of data written starting at the current pos + */ +void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type); + +/** + * ORing this as the "whence" parameter to a seek function causes it to + * return the filesize without seeking anywhere. Supporting this is optional. + * If it is not supported then the seek function will return <0. + */ +#define AVSEEK_SIZE 0x10000 + +/** + * Passing this flag as the "whence" parameter to a seek function causes it to + * seek by any means (like reopening and linear reading) or other normally unreasonable + * means that can be extremely slow. + * This may be ignored by the seek code. + */ +#define AVSEEK_FORCE 0x20000 + +/** + * fseek() equivalent for AVIOContext. + * @return new position or AVERROR. + */ +int64_t avio_seek(AVIOContext *s, int64_t offset, int whence); + +/** + * Skip given number of bytes forward + * @return new position or AVERROR. + */ +int64_t avio_skip(AVIOContext *s, int64_t offset); + +/** + * ftell() equivalent for AVIOContext. + * @return position or AVERROR. + */ +static av_always_inline int64_t avio_tell(AVIOContext *s) +{ + return avio_seek(s, 0, SEEK_CUR); +} + +/** + * Get the filesize. + * @return filesize or AVERROR + */ +int64_t avio_size(AVIOContext *s); + +/** + * Similar to feof() but also returns nonzero on read errors. + * @return non zero if and only if at end of file or a read error happened when reading. + */ +int avio_feof(AVIOContext *s); + +/** + * Writes a formatted string to the context. + * @return number of bytes written, < 0 on error. + */ +int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3); + +/** + * Write a NULL terminated array of strings to the context. + * Usually you don't need to use this function directly but its macro wrapper, + * avio_print. + */ +void avio_print_string_array(AVIOContext *s, const char *strings[]); + +/** + * Write strings (const char *) to the context. + * This is a convenience macro around avio_print_string_array and it + * automatically creates the string array from the variable argument list. + * For simple string concatenations this function is more performant than using + * avio_printf since it does not need a temporary buffer. + */ +#define avio_print(s, ...) \ + avio_print_string_array(s, (const char*[]){__VA_ARGS__, NULL}) + +/** + * Force flushing of buffered data. + * + * For write streams, force the buffered data to be immediately written to the output, + * without to wait to fill the internal buffer. + * + * For read streams, discard all currently buffered data, and advance the + * reported file position to that of the underlying stream. This does not + * read new data, and does not perform any seeks. + */ +void avio_flush(AVIOContext *s); + +/** + * Read size bytes from AVIOContext into buf. + * @return number of bytes read or AVERROR + */ +int avio_read(AVIOContext *s, unsigned char *buf, int size); + +/** + * Read size bytes from AVIOContext into buf. Unlike avio_read(), this is allowed + * to read fewer bytes than requested. The missing bytes can be read in the next + * call. This always tries to read at least 1 byte. + * Useful to reduce latency in certain cases. + * @return number of bytes read or AVERROR + */ +int avio_read_partial(AVIOContext *s, unsigned char *buf, int size); + +/** + * @name Functions for reading from AVIOContext + * @{ + * + * @note return 0 if EOF, so you cannot use it if EOF handling is + * necessary + */ +int avio_r8 (AVIOContext *s); +unsigned int avio_rl16(AVIOContext *s); +unsigned int avio_rl24(AVIOContext *s); +unsigned int avio_rl32(AVIOContext *s); +uint64_t avio_rl64(AVIOContext *s); +unsigned int avio_rb16(AVIOContext *s); +unsigned int avio_rb24(AVIOContext *s); +unsigned int avio_rb32(AVIOContext *s); +uint64_t avio_rb64(AVIOContext *s); +/** + * @} + */ + +/** + * Read a string from pb into buf. The reading will terminate when either + * a NULL character was encountered, maxlen bytes have been read, or nothing + * more can be read from pb. The result is guaranteed to be NULL-terminated, it + * will be truncated if buf is too small. + * Note that the string is not interpreted or validated in any way, it + * might get truncated in the middle of a sequence for multi-byte encodings. + * + * @return number of bytes read (is always <= maxlen). + * If reading ends on EOF or error, the return value will be one more than + * bytes actually read. + */ +int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen); + +/** + * Read a UTF-16 string from pb and convert it to UTF-8. + * The reading will terminate when either a null or invalid character was + * encountered or maxlen bytes have been read. + * @return number of bytes read (is always <= maxlen) + */ +int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen); +int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen); + + +/** + * @name URL open modes + * The flags argument to avio_open must be one of the following + * constants, optionally ORed with other flags. + * @{ + */ +#define AVIO_FLAG_READ 1 /**< read-only */ +#define AVIO_FLAG_WRITE 2 /**< write-only */ +#define AVIO_FLAG_READ_WRITE (AVIO_FLAG_READ|AVIO_FLAG_WRITE) /**< read-write pseudo flag */ +/** + * @} + */ + +/** + * Use non-blocking mode. + * If this flag is set, operations on the context will return + * AVERROR(EAGAIN) if they can not be performed immediately. + * If this flag is not set, operations on the context will never return + * AVERROR(EAGAIN). + * Note that this flag does not affect the opening/connecting of the + * context. Connecting a protocol will always block if necessary (e.g. on + * network protocols) but never hang (e.g. on busy devices). + * Warning: non-blocking protocols is work-in-progress; this flag may be + * silently ignored. + */ +#define AVIO_FLAG_NONBLOCK 8 + +/** + * Use direct mode. + * avio_read and avio_write should if possible be satisfied directly + * instead of going through a buffer, and avio_seek will always + * call the underlying seek function directly. + */ +#define AVIO_FLAG_DIRECT 0x8000 + +/** + * Create and initialize a AVIOContext for accessing the + * resource indicated by url. + * @note When the resource indicated by url has been opened in + * read+write mode, the AVIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created AVIOContext. + * In case of failure the pointed to value is set to NULL. + * @param url resource to access + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int avio_open(AVIOContext **s, const char *url, int flags); + +/** + * Create and initialize a AVIOContext for accessing the + * resource indicated by url. + * @note When the resource indicated by url has been opened in + * read+write mode, the AVIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created AVIOContext. + * In case of failure the pointed to value is set to NULL. + * @param url resource to access + * @param flags flags which control how the resource indicated by url + * is to be opened + * @param int_cb an interrupt callback to be used at the protocols level + * @param options A dictionary filled with protocol-private options. On return + * this parameter will be destroyed and replaced with a dict containing options + * that were not found. May be NULL. + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int avio_open2(AVIOContext **s, const char *url, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options); + +/** + * Close the resource accessed by the AVIOContext s and free it. + * This function can only be used if s was opened by avio_open(). + * + * The internal buffer is automatically flushed before closing the + * resource. + * + * @return 0 on success, an AVERROR < 0 on error. + * @see avio_closep + */ +int avio_close(AVIOContext *s); + +/** + * Close the resource accessed by the AVIOContext *s, free it + * and set the pointer pointing to it to NULL. + * This function can only be used if s was opened by avio_open(). + * + * The internal buffer is automatically flushed before closing the + * resource. + * + * @return 0 on success, an AVERROR < 0 on error. + * @see avio_close + */ +int avio_closep(AVIOContext **s); + + +/** + * Open a write only memory stream. + * + * @param s new IO context + * @return zero if no error. + */ +int avio_open_dyn_buf(AVIOContext **s); + +/** + * Return the written size and a pointer to the buffer. + * The AVIOContext stream is left intact. + * The buffer must NOT be freed. + * No padding is added to the buffer. + * + * @param s IO context + * @param pbuffer pointer to a byte buffer + * @return the length of the byte buffer + */ +int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer); + +/** + * Return the written size and a pointer to the buffer. The buffer + * must be freed with av_free(). + * Padding of AV_INPUT_BUFFER_PADDING_SIZE is added to the buffer. + * + * @param s IO context + * @param pbuffer pointer to a byte buffer + * @return the length of the byte buffer + */ +int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer); + +/** + * Iterate through names of available protocols. + * + * @param opaque A private pointer representing current protocol. + * It must be a pointer to NULL on first iteration and will + * be updated by successive calls to avio_enum_protocols. + * @param output If set to 1, iterate over output protocols, + * otherwise over input protocols. + * + * @return A static string containing the name of current protocol or NULL + */ +const char *avio_enum_protocols(void **opaque, int output); + +/** + * Get AVClass by names of available protocols. + * + * @return A AVClass of input protocol name or NULL + */ +const AVClass *avio_protocol_get_class(const char *name); + +/** + * Pause and resume playing - only meaningful if using a network streaming + * protocol (e.g. MMS). + * + * @param h IO context from which to call the read_pause function pointer + * @param pause 1 for pause, 0 for resume + */ +int avio_pause(AVIOContext *h, int pause); + +/** + * Seek to a given timestamp relative to some component stream. + * Only meaningful if using a network streaming protocol (e.g. MMS.). + * + * @param h IO context from which to call the seek function pointers + * @param stream_index The stream index that the timestamp is relative to. + * If stream_index is (-1) the timestamp should be in AV_TIME_BASE + * units from the beginning of the presentation. + * If a stream_index >= 0 is used and the protocol does not support + * seeking based on component streams, the call will fail. + * @param timestamp timestamp in AVStream.time_base units + * or if there is no stream specified then in AV_TIME_BASE units. + * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE + * and AVSEEK_FLAG_ANY. The protocol may silently ignore + * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will + * fail if used and not supported. + * @return >= 0 on success + * @see AVInputFormat::read_seek + */ +int64_t avio_seek_time(AVIOContext *h, int stream_index, + int64_t timestamp, int flags); + +/* Avoid a warning. The header can not be included because it breaks c++. */ +struct AVBPrint; + +/** + * Read contents of h into print buffer, up to max_size bytes, or up to EOF. + * + * @return 0 for success (max_size bytes read or EOF reached), negative error + * code otherwise + */ +int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t max_size); + +/** + * Accept and allocate a client context on a server context. + * @param s the server context + * @param c the client context, must be unallocated + * @return >= 0 on success or a negative value corresponding + * to an AVERROR on failure + */ +int avio_accept(AVIOContext *s, AVIOContext **c); + +/** + * Perform one step of the protocol handshake to accept a new client. + * This function must be called on a client returned by avio_accept() before + * using it as a read/write context. + * It is separate from avio_accept() because it may block. + * A step of the handshake is defined by places where the application may + * decide to change the proceedings. + * For example, on a protocol with a request header and a reply header, each + * one can constitute a step because the application may use the parameters + * from the request to change parameters in the reply; or each individual + * chunk of the request can constitute a step. + * If the handshake is already finished, avio_handshake() does nothing and + * returns 0 immediately. + * + * @param c the client context to perform the handshake on + * @return 0 on a complete and successful handshake + * > 0 if the handshake progressed, but is not complete + * < 0 for an AVERROR code + */ +int avio_handshake(AVIOContext *c); +#endif /* AVFORMAT_AVIO_H */ diff --git a/ffmpeg/inc/libavformat/version.h b/ffmpeg/inc/libavformat/version.h new file mode 100644 index 0000000..13c8a61 --- /dev/null +++ b/ffmpeg/inc/libavformat/version.h @@ -0,0 +1,114 @@ +/* + * Version macros. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_VERSION_H +#define AVFORMAT_VERSION_H + +/** + * @file + * @ingroup libavf + * Libavformat version macros + */ + +#include "libavutil/version.h" + +// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) +// Also please add any ticket numbers that you believe might be affected here +#define LIBAVFORMAT_VERSION_MAJOR 58 +#define LIBAVFORMAT_VERSION_MINOR 45 +#define LIBAVFORMAT_VERSION_MICRO 100 + +#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT + +#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) + +/** + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + * + * @note, when bumping the major version it is recommended to manually + * disable each FF_API_* in its own commit instead of disabling them all + * at once through the bump. This improves the git bisect-ability of the change. + * + */ +#ifndef FF_API_COMPUTE_PKT_FIELDS2 +#define FF_API_COMPUTE_PKT_FIELDS2 (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_OPEN_CALLBACKS +#define FF_API_OLD_OPEN_CALLBACKS (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LAVF_AVCTX +#define FF_API_LAVF_AVCTX (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_HTTP_USER_AGENT +#define FF_API_HTTP_USER_AGENT (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_HLS_WRAP +#define FF_API_HLS_WRAP (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_HLS_USE_LOCALTIME +#define FF_API_HLS_USE_LOCALTIME (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LAVF_KEEPSIDE_FLAG +#define FF_API_LAVF_KEEPSIDE_FLAG (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_ROTATE_API +#define FF_API_OLD_ROTATE_API (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_FORMAT_GET_SET +#define FF_API_FORMAT_GET_SET (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_AVIO_EOF_0 +#define FF_API_OLD_AVIO_EOF_0 (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LAVF_FFSERVER +#define FF_API_LAVF_FFSERVER (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_FORMAT_FILENAME +#define FF_API_FORMAT_FILENAME (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_OLD_RTSP_OPTIONS +#define FF_API_OLD_RTSP_OPTIONS (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_NEXT +#define FF_API_NEXT (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_DASH_MIN_SEG_DURATION +#define FF_API_DASH_MIN_SEG_DURATION (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_LAVF_MP4A_LATM +#define FF_API_LAVF_MP4A_LATM (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif +#ifndef FF_API_AVIOFORMAT +#define FF_API_AVIOFORMAT (LIBAVFORMAT_VERSION_MAJOR < 59) +#endif + + +#ifndef FF_API_R_FRAME_RATE +#define FF_API_R_FRAME_RATE 1 +#endif +#endif /* AVFORMAT_VERSION_H */ diff --git a/ffmpeg/inc/libavutil/adler32.h b/ffmpeg/inc/libavutil/adler32.h new file mode 100644 index 0000000..a1f035b --- /dev/null +++ b/ffmpeg/inc/libavutil/adler32.h @@ -0,0 +1,60 @@ +/* + * copyright (c) 2006 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_adler32 + * Public header for Adler-32 hash function implementation. + */ + +#ifndef AVUTIL_ADLER32_H +#define AVUTIL_ADLER32_H + +#include +#include "attributes.h" + +/** + * @defgroup lavu_adler32 Adler-32 + * @ingroup lavu_hash + * Adler-32 hash function implementation. + * + * @{ + */ + +/** + * Calculate the Adler32 checksum of a buffer. + * + * Passing the return value to a subsequent av_adler32_update() call + * allows the checksum of multiple buffers to be calculated as though + * they were concatenated. + * + * @param adler initial checksum value + * @param buf pointer to input buffer + * @param len size of input buffer + * @return updated checksum + */ +unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, + unsigned int len) av_pure; + +/** + * @} + */ + +#endif /* AVUTIL_ADLER32_H */ diff --git a/ffmpeg/inc/libavutil/aes.h b/ffmpeg/inc/libavutil/aes.h new file mode 100644 index 0000000..09efbda --- /dev/null +++ b/ffmpeg/inc/libavutil/aes.h @@ -0,0 +1,65 @@ +/* + * copyright (c) 2007 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_H +#define AVUTIL_AES_H + +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_aes AES + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_aes_size; + +struct AVAES; + +/** + * Allocate an AVAES context. + */ +struct AVAES *av_aes_alloc(void); + +/** + * Initialize an AVAES context. + * @param key_bits 128, 192 or 256 + * @param decrypt 0 for encryption, 1 for decryption + */ +int av_aes_init(struct AVAES *a, const uint8_t *key, int key_bits, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * @param count number of 16 byte blocks + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_aes_crypt(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_AES_H */ diff --git a/ffmpeg/inc/libavutil/aes_ctr.h b/ffmpeg/inc/libavutil/aes_ctr.h new file mode 100644 index 0000000..e4aae12 --- /dev/null +++ b/ffmpeg/inc/libavutil/aes_ctr.h @@ -0,0 +1,88 @@ +/* + * AES-CTR cipher + * Copyright (c) 2015 Eran Kornblau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AES_CTR_H +#define AVUTIL_AES_CTR_H + +#include + +#include "attributes.h" +#include "version.h" + +#define AES_CTR_KEY_SIZE (16) +#define AES_CTR_IV_SIZE (8) + +struct AVAESCTR; + +/** + * Allocate an AVAESCTR context. + */ +struct AVAESCTR *av_aes_ctr_alloc(void); + +/** + * Initialize an AVAESCTR context. + * @param key encryption key, must have a length of AES_CTR_KEY_SIZE + */ +int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key); + +/** + * Release an AVAESCTR context. + */ +void av_aes_ctr_free(struct AVAESCTR *a); + +/** + * Process a buffer using a previously initialized context. + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param size the size of src and dst + */ +void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int size); + +/** + * Get the current iv + */ +const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a); + +/** + * Generate a random iv + */ +void av_aes_ctr_set_random_iv(struct AVAESCTR *a); + +/** + * Forcefully change the 8-byte iv + */ +void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv); + +/** + * Forcefully change the "full" 16-byte iv, including the counter + */ +void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv); + +/** + * Increment the top 64 bit of the iv (performed after each frame) + */ +void av_aes_ctr_increment_iv(struct AVAESCTR *a); + +/** + * @} + */ + +#endif /* AVUTIL_AES_CTR_H */ diff --git a/ffmpeg/inc/libavutil/attributes.h b/ffmpeg/inc/libavutil/attributes.h new file mode 100644 index 0000000..5cb9fe3 --- /dev/null +++ b/ffmpeg/inc/libavutil/attributes.h @@ -0,0 +1,173 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Macro definitions for various function/variable attributes + */ + +#ifndef AVUTIL_ATTRIBUTES_H +#define AVUTIL_ATTRIBUTES_H + +#ifdef __GNUC__ +# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +# define AV_GCC_VERSION_AT_MOST(x,y) (__GNUC__ < (x) || __GNUC__ == (x) && __GNUC_MINOR__ <= (y)) +#else +# define AV_GCC_VERSION_AT_LEAST(x,y) 0 +# define AV_GCC_VERSION_AT_MOST(x,y) 0 +#endif + +#ifdef __has_builtin +# define AV_HAS_BUILTIN(x) __has_builtin(x) +#else +# define AV_HAS_BUILTIN(x) 0 +#endif + +#ifndef av_always_inline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_always_inline __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +# define av_always_inline __forceinline +#else +# define av_always_inline inline +#endif +#endif + +#ifndef av_extern_inline +#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__) +# define av_extern_inline extern inline +#else +# define av_extern_inline inline +#endif +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,4) +# define av_warn_unused_result __attribute__((warn_unused_result)) +#else +# define av_warn_unused_result +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_noinline __attribute__((noinline)) +#elif defined(_MSC_VER) +# define av_noinline __declspec(noinline) +#else +# define av_noinline +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) +# define av_pure __attribute__((pure)) +#else +# define av_pure +#endif + +#if AV_GCC_VERSION_AT_LEAST(2,6) || defined(__clang__) +# define av_const __attribute__((const)) +#else +# define av_const +#endif + +#if AV_GCC_VERSION_AT_LEAST(4,3) || defined(__clang__) +# define av_cold __attribute__((cold)) +#else +# define av_cold +#endif + +#if AV_GCC_VERSION_AT_LEAST(4,1) && !defined(__llvm__) +# define av_flatten __attribute__((flatten)) +#else +# define av_flatten +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_deprecated __attribute__((deprecated)) +#elif defined(_MSC_VER) +# define attribute_deprecated __declspec(deprecated) +#else +# define attribute_deprecated +#endif + +/** + * Disable warnings about deprecated features + * This is useful for sections of code kept for backward compatibility and + * scheduled for removal. + */ +#ifndef AV_NOWARN_DEPRECATED +#if AV_GCC_VERSION_AT_LEAST(4,6) +# define AV_NOWARN_DEPRECATED(code) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ + code \ + _Pragma("GCC diagnostic pop") +#elif defined(_MSC_VER) +# define AV_NOWARN_DEPRECATED(code) \ + __pragma(warning(push)) \ + __pragma(warning(disable : 4996)) \ + code; \ + __pragma(warning(pop)) +#else +# define AV_NOWARN_DEPRECATED(code) code +#endif +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define av_unused __attribute__((unused)) +#else +# define av_unused +#endif + +/** + * Mark a variable as used and prevent the compiler from optimizing it + * away. This is useful for variables accessed only from inline + * assembler without the compiler being aware. + */ +#if AV_GCC_VERSION_AT_LEAST(3,1) || defined(__clang__) +# define av_used __attribute__((used)) +#else +# define av_used +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,3) || defined(__clang__) +# define av_alias __attribute__((may_alias)) +#else +# define av_alias +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__INTEL_COMPILER) +# define av_uninit(x) x=x +#else +# define av_uninit(x) x +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define av_builtin_constant_p __builtin_constant_p +# define av_printf_format(fmtpos, attrpos) __attribute__((__format__(__printf__, fmtpos, attrpos))) +#else +# define av_builtin_constant_p(x) 0 +# define av_printf_format(fmtpos, attrpos) +#endif + +#if AV_GCC_VERSION_AT_LEAST(2,5) || defined(__clang__) +# define av_noreturn __attribute__((noreturn)) +#else +# define av_noreturn +#endif + +#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/ffmpeg/inc/libavutil/audio_fifo.h b/ffmpeg/inc/libavutil/audio_fifo.h new file mode 100644 index 0000000..d8a9194 --- /dev/null +++ b/ffmpeg/inc/libavutil/audio_fifo.h @@ -0,0 +1,187 @@ +/* + * Audio FIFO + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Audio FIFO Buffer + */ + +#ifndef AVUTIL_AUDIO_FIFO_H +#define AVUTIL_AUDIO_FIFO_H + +#include "avutil.h" +#include "fifo.h" +#include "samplefmt.h" + +/** + * @addtogroup lavu_audio + * @{ + * + * @defgroup lavu_audiofifo Audio FIFO Buffer + * @{ + */ + +/** + * Context for an Audio FIFO Buffer. + * + * - Operates at the sample level rather than the byte level. + * - Supports multiple channels with either planar or packed sample format. + * - Automatic reallocation when writing to a full buffer. + */ +typedef struct AVAudioFifo AVAudioFifo; + +/** + * Free an AVAudioFifo. + * + * @param af AVAudioFifo to free + */ +void av_audio_fifo_free(AVAudioFifo *af); + +/** + * Allocate an AVAudioFifo. + * + * @param sample_fmt sample format + * @param channels number of channels + * @param nb_samples initial allocation size, in samples + * @return newly allocated AVAudioFifo, or NULL on error + */ +AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, + int nb_samples); + +/** + * Reallocate an AVAudioFifo. + * + * @param af AVAudioFifo to reallocate + * @param nb_samples new allocation size, in samples + * @return 0 if OK, or negative AVERROR code on failure + */ +av_warn_unused_result +int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples); + +/** + * Write data to an AVAudioFifo. + * + * The AVAudioFifo will be reallocated automatically if the available space + * is less than nb_samples. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to write to + * @param data audio data plane pointers + * @param nb_samples number of samples to write + * @return number of samples actually written, or negative AVERROR + * code on failure. If successful, the number of samples + * actually written will always be nb_samples. + */ +int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Peek data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to peek + * @return number of samples actually peek, or negative AVERROR code + * on failure. The number of samples actually peek will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Peek data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to peek + * @param offset offset from current read position + * @return number of samples actually peek, or negative AVERROR code + * on failure. The number of samples actually peek will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_peek_at(AVAudioFifo *af, void **data, int nb_samples, int offset); + +/** + * Read data from an AVAudioFifo. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param af AVAudioFifo to read from + * @param data audio data plane pointers + * @param nb_samples number of samples to read + * @return number of samples actually read, or negative AVERROR code + * on failure. The number of samples actually read will not + * be greater than nb_samples, and will only be less than + * nb_samples if av_audio_fifo_size is less than nb_samples. + */ +int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples); + +/** + * Drain data from an AVAudioFifo. + * + * Removes the data without reading it. + * + * @param af AVAudioFifo to drain + * @param nb_samples number of samples to drain + * @return 0 if OK, or negative AVERROR code on failure + */ +int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples); + +/** + * Reset the AVAudioFifo buffer. + * + * This empties all data in the buffer. + * + * @param af AVAudioFifo to reset + */ +void av_audio_fifo_reset(AVAudioFifo *af); + +/** + * Get the current number of samples in the AVAudioFifo available for reading. + * + * @param af the AVAudioFifo to query + * @return number of samples available for reading + */ +int av_audio_fifo_size(AVAudioFifo *af); + +/** + * Get the current number of samples in the AVAudioFifo available for writing. + * + * @param af the AVAudioFifo to query + * @return number of samples available for writing + */ +int av_audio_fifo_space(AVAudioFifo *af); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_AUDIO_FIFO_H */ diff --git a/ffmpeg/inc/libavutil/avassert.h b/ffmpeg/inc/libavutil/avassert.h new file mode 100644 index 0000000..9abeade --- /dev/null +++ b/ffmpeg/inc/libavutil/avassert.h @@ -0,0 +1,75 @@ +/* + * copyright (c) 2010 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * simple assert() macros that are a bit more flexible than ISO C assert(). + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_AVASSERT_H +#define AVUTIL_AVASSERT_H + +#include +#include "avutil.h" +#include "log.h" + +/** + * assert() equivalent, that is always enabled. + */ +#define av_assert0(cond) do { \ + if (!(cond)) { \ + av_log(NULL, AV_LOG_PANIC, "Assertion %s failed at %s:%d\n", \ + AV_STRINGIFY(cond), __FILE__, __LINE__); \ + abort(); \ + } \ +} while (0) + + +/** + * assert() equivalent, that does not lie in speed critical code. + * These asserts() thus can be enabled without fearing speed loss. + */ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 0 +#define av_assert1(cond) av_assert0(cond) +#else +#define av_assert1(cond) ((void)0) +#endif + + +/** + * assert() equivalent, that does lie in speed critical code. + */ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 +#define av_assert2(cond) av_assert0(cond) +#define av_assert2_fpu() av_assert0_fpu() +#else +#define av_assert2(cond) ((void)0) +#define av_assert2_fpu() ((void)0) +#endif + +/** + * Assert that floating point operations can be executed. + * + * This will av_assert0() that the cpu is not in MMX state on X86 + */ +void av_assert0_fpu(void); + +#endif /* AVUTIL_AVASSERT_H */ diff --git a/ffmpeg/inc/libavutil/avconfig.h b/ffmpeg/inc/libavutil/avconfig.h new file mode 100644 index 0000000..c289fbb --- /dev/null +++ b/ffmpeg/inc/libavutil/avconfig.h @@ -0,0 +1,6 @@ +/* Generated by ffmpeg configure */ +#ifndef AVUTIL_AVCONFIG_H +#define AVUTIL_AVCONFIG_H +#define AV_HAVE_BIGENDIAN 0 +#define AV_HAVE_FAST_UNALIGNED 1 +#endif /* AVUTIL_AVCONFIG_H */ diff --git a/ffmpeg/inc/libavutil/avstring.h b/ffmpeg/inc/libavutil/avstring.h new file mode 100644 index 0000000..274335c --- /dev/null +++ b/ffmpeg/inc/libavutil/avstring.h @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2007 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVSTRING_H +#define AVUTIL_AVSTRING_H + +#include +#include +#include "attributes.h" + +/** + * @addtogroup lavu_string + * @{ + */ + +/** + * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to + * the address of the first character in str after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_strstart(const char *str, const char *pfx, const char **ptr); + +/** + * Return non-zero if pfx is a prefix of str independent of case. If + * it is, *ptr is set to the address of the first character in str + * after the prefix. + * + * @param str input string + * @param pfx prefix to test + * @param ptr updated if the prefix is matched inside str + * @return non-zero if the prefix matches, zero otherwise + */ +int av_stristart(const char *str, const char *pfx, const char **ptr); + +/** + * Locate the first case-independent occurrence in the string haystack + * of the string needle. A zero-length string needle is considered to + * match at the start of haystack. + * + * This function is a case-insensitive version of the standard strstr(). + * + * @param haystack string to search in + * @param needle string to search for + * @return pointer to the located match within haystack + * or a null pointer if no match + */ +char *av_stristr(const char *haystack, const char *needle); + +/** + * Locate the first occurrence of the string needle in the string haystack + * where not more than hay_length characters are searched. A zero-length + * string needle is considered to match at the start of haystack. + * + * This function is a length-limited version of the standard strstr(). + * + * @param haystack string to search in + * @param needle string to search for + * @param hay_length length of string to search in + * @return pointer to the located match within haystack + * or a null pointer if no match + */ +char *av_strnstr(const char *haystack, const char *needle, size_t hay_length); + +/** + * Copy the string src to dst, but no more than size - 1 bytes, and + * null-terminate dst. + * + * This function is the same as BSD strlcpy(). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the length of src + * + * @warning since the return value is the length of src, src absolutely + * _must_ be a properly 0-terminated string, otherwise this will read beyond + * the end of the buffer and possibly crash. + */ +size_t av_strlcpy(char *dst, const char *src, size_t size); + +/** + * Append the string src to the string dst, but to a total length of + * no more than size - 1 bytes, and null-terminate dst. + * + * This function is similar to BSD strlcat(), but differs when + * size <= strlen(dst). + * + * @param dst destination buffer + * @param src source string + * @param size size of destination buffer + * @return the total length of src and dst + * + * @warning since the return value use the length of src and dst, these + * absolutely _must_ be a properly 0-terminated strings, otherwise this + * will read beyond the end of the buffer and possibly crash. + */ +size_t av_strlcat(char *dst, const char *src, size_t size); + +/** + * Append output to a string, according to a format. Never write out of + * the destination buffer, and always put a terminating 0 within + * the buffer. + * @param dst destination buffer (string to which the output is + * appended) + * @param size total size of the destination buffer + * @param fmt printf-compatible format string, specifying how the + * following parameters are used + * @return the length of the string that would have been generated + * if enough space had been available + */ +size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4); + +/** + * Get the count of continuous non zero chars starting from the beginning. + * + * @param len maximum number of characters to check in the string, that + * is the maximum value which is returned by the function + */ +static inline size_t av_strnlen(const char *s, size_t len) +{ + size_t i; + for (i = 0; i < len && s[i]; i++) + ; + return i; +} + +/** + * Print arguments following specified format into a large enough auto + * allocated buffer. It is similar to GNU asprintf(). + * @param fmt printf-compatible format string, specifying how the + * following parameters are used. + * @return the allocated string + * @note You have to free the string yourself with av_free(). + */ +char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2); + +/** + * Convert a number to an av_malloced string. + */ +char *av_d2str(double d); + +/** + * Unescape the given string until a non escaped terminating char, + * and return the token corresponding to the unescaped string. + * + * The normal \ and ' escaping is supported. Leading and trailing + * whitespaces are removed, unless they are escaped with '\' or are + * enclosed between ''. + * + * @param buf the buffer to parse, buf will be updated to point to the + * terminating char + * @param term a 0-terminated list of terminating chars + * @return the malloced unescaped string, which must be av_freed by + * the user, NULL in case of allocation failure + */ +char *av_get_token(const char **buf, const char *term); + +/** + * Split the string into several tokens which can be accessed by + * successive calls to av_strtok(). + * + * A token is defined as a sequence of characters not belonging to the + * set specified in delim. + * + * On the first call to av_strtok(), s should point to the string to + * parse, and the value of saveptr is ignored. In subsequent calls, s + * should be NULL, and saveptr should be unchanged since the previous + * call. + * + * This function is similar to strtok_r() defined in POSIX.1. + * + * @param s the string to parse, may be NULL + * @param delim 0-terminated list of token delimiters, must be non-NULL + * @param saveptr user-provided pointer which points to stored + * information necessary for av_strtok() to continue scanning the same + * string. saveptr is updated to point to the next character after the + * first delimiter found, or to NULL if the string was terminated + * @return the found token, or NULL when no token is found + */ +char *av_strtok(char *s, const char *delim, char **saveptr); + +/** + * Locale-independent conversion of ASCII isdigit. + */ +static inline av_const int av_isdigit(int c) +{ + return c >= '0' && c <= '9'; +} + +/** + * Locale-independent conversion of ASCII isgraph. + */ +static inline av_const int av_isgraph(int c) +{ + return c > 32 && c < 127; +} + +/** + * Locale-independent conversion of ASCII isspace. + */ +static inline av_const int av_isspace(int c) +{ + return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || + c == '\v'; +} + +/** + * Locale-independent conversion of ASCII characters to uppercase. + */ +static inline av_const int av_toupper(int c) +{ + if (c >= 'a' && c <= 'z') + c ^= 0x20; + return c; +} + +/** + * Locale-independent conversion of ASCII characters to lowercase. + */ +static inline av_const int av_tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + c ^= 0x20; + return c; +} + +/** + * Locale-independent conversion of ASCII isxdigit. + */ +static inline av_const int av_isxdigit(int c) +{ + c = av_tolower(c); + return av_isdigit(c) || (c >= 'a' && c <= 'f'); +} + +/** + * Locale-independent case-insensitive compare. + * @note This means only ASCII-range characters are case-insensitive + */ +int av_strcasecmp(const char *a, const char *b); + +/** + * Locale-independent case-insensitive compare. + * @note This means only ASCII-range characters are case-insensitive + */ +int av_strncasecmp(const char *a, const char *b, size_t n); + +/** + * Locale-independent strings replace. + * @note This means only ASCII-range characters are replace + */ +char *av_strireplace(const char *str, const char *from, const char *to); + +/** + * Thread safe basename. + * @param path the string to parse, on DOS both \ and / are considered separators. + * @return pointer to the basename substring. + * If path does not contain a slash, the function returns a copy of path. + * If path is a NULL pointer or points to an empty string, a pointer + * to a string "." is returned. + */ +const char *av_basename(const char *path); + +/** + * Thread safe dirname. + * @param path the string to parse, on DOS both \ and / are considered separators. + * @return A pointer to a string that's the parent directory of path. + * If path is a NULL pointer or points to an empty string, a pointer + * to a string "." is returned. + * @note the function may modify the contents of the path, so copies should be passed. + */ +const char *av_dirname(char *path); + +/** + * Match instances of a name in a comma-separated list of names. + * List entries are checked from the start to the end of the names list, + * the first match ends further processing. If an entry prefixed with '-' + * matches, then 0 is returned. The "ALL" list entry is considered to + * match all names. + * + * @param name Name to look for. + * @param names List of names. + * @return 1 on match, 0 otherwise. + */ +int av_match_name(const char *name, const char *names); + +/** + * Append path component to the existing path. + * Path separator '/' is placed between when needed. + * Resulting string have to be freed with av_free(). + * @param path base path + * @param component component to be appended + * @return new path or NULL on error. + */ +char *av_append_path_component(const char *path, const char *component); + +enum AVEscapeMode { + AV_ESCAPE_MODE_AUTO, ///< Use auto-selected escaping mode. + AV_ESCAPE_MODE_BACKSLASH, ///< Use backslash escaping. + AV_ESCAPE_MODE_QUOTE, ///< Use single-quote escaping. +}; + +/** + * Consider spaces special and escape them even in the middle of the + * string. + * + * This is equivalent to adding the whitespace characters to the special + * characters lists, except it is guaranteed to use the exact same list + * of whitespace characters as the rest of libavutil. + */ +#define AV_ESCAPE_FLAG_WHITESPACE (1 << 0) + +/** + * Escape only specified special characters. + * Without this flag, escape also any characters that may be considered + * special by av_get_token(), such as the single quote. + */ +#define AV_ESCAPE_FLAG_STRICT (1 << 1) + +/** + * Escape string in src, and put the escaped string in an allocated + * string in *dst, which must be freed with av_free(). + * + * @param dst pointer where an allocated string is put + * @param src string to escape, must be non-NULL + * @param special_chars string containing the special characters which + * need to be escaped, can be NULL + * @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros. + * Any unknown value for mode will be considered equivalent to + * AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without + * notice. + * @param flags flags which control how to escape, see AV_ESCAPE_FLAG_ macros + * @return the length of the allocated string, or a negative error code in case of error + * @see av_bprint_escape() + */ +av_warn_unused_result +int av_escape(char **dst, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags); + +#define AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES 1 ///< accept codepoints over 0x10FFFF +#define AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS 2 ///< accept non-characters - 0xFFFE and 0xFFFF +#define AV_UTF8_FLAG_ACCEPT_SURROGATES 4 ///< accept UTF-16 surrogates codes +#define AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES 8 ///< exclude control codes not accepted by XML + +#define AV_UTF8_FLAG_ACCEPT_ALL \ + AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES|AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS|AV_UTF8_FLAG_ACCEPT_SURROGATES + +/** + * Read and decode a single UTF-8 code point (character) from the + * buffer in *buf, and update *buf to point to the next byte to + * decode. + * + * In case of an invalid byte sequence, the pointer will be updated to + * the next byte after the invalid sequence and the function will + * return an error code. + * + * Depending on the specified flags, the function will also fail in + * case the decoded code point does not belong to a valid range. + * + * @note For speed-relevant code a carefully implemented use of + * GET_UTF8() may be preferred. + * + * @param codep pointer used to return the parsed code in case of success. + * The value in *codep is set even in case the range check fails. + * @param bufp pointer to the address the first byte of the sequence + * to decode, updated by the function to point to the + * byte next after the decoded sequence + * @param buf_end pointer to the end of the buffer, points to the next + * byte past the last in the buffer. This is used to + * avoid buffer overreads (in case of an unfinished + * UTF-8 sequence towards the end of the buffer). + * @param flags a collection of AV_UTF8_FLAG_* flags + * @return >= 0 in case a sequence was successfully read, a negative + * value in case of invalid sequence + */ +av_warn_unused_result +int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, + unsigned int flags); + +/** + * Check if a name is in a list. + * @returns 0 if not found, or the 1 based index where it has been found in the + * list. + */ +int av_match_list(const char *name, const char *list, char separator); + +/** + * See libc sscanf manual for more information. + * Locale-independent sscanf implementation. + */ +int av_sscanf(const char *string, const char *format, ...); + +/** + * @} + */ + +#endif /* AVUTIL_AVSTRING_H */ diff --git a/ffmpeg/inc/libavutil/avutil.h b/ffmpeg/inc/libavutil/avutil.h new file mode 100644 index 0000000..4d63315 --- /dev/null +++ b/ffmpeg/inc/libavutil/avutil.h @@ -0,0 +1,365 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file + * @ingroup lavu + * Convenience header that includes @ref lavu "libavutil"'s core. + */ + +/** + * @mainpage + * + * @section ffmpeg_intro Introduction + * + * This document describes the usage of the different libraries + * provided by FFmpeg. + * + * @li @ref libavc "libavcodec" encoding/decoding library + * @li @ref lavfi "libavfilter" graph-based frame editing library + * @li @ref libavf "libavformat" I/O and muxing/demuxing library + * @li @ref lavd "libavdevice" special devices muxing/demuxing library + * @li @ref lavu "libavutil" common utility library + * @li @ref lswr "libswresample" audio resampling, format conversion and mixing + * @li @ref lpp "libpostproc" post processing library + * @li @ref libsws "libswscale" color conversion and scaling library + * + * @section ffmpeg_versioning Versioning and compatibility + * + * Each of the FFmpeg libraries contains a version.h header, which defines a + * major, minor and micro version number with the + * LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO} macros. The major version + * number is incremented with backward incompatible changes - e.g. removing + * parts of the public API, reordering public struct members, etc. The minor + * version number is incremented for backward compatible API changes or major + * new features - e.g. adding a new public function or a new decoder. The micro + * version number is incremented for smaller changes that a calling program + * might still want to check for - e.g. changing behavior in a previously + * unspecified situation. + * + * FFmpeg guarantees backward API and ABI compatibility for each library as long + * as its major version number is unchanged. This means that no public symbols + * will be removed or renamed. Types and names of the public struct members and + * values of public macros and enums will remain the same (unless they were + * explicitly declared as not part of the public API). Documented behavior will + * not change. + * + * In other words, any correct program that works with a given FFmpeg snapshot + * should work just as well without any changes with any later snapshot with the + * same major versions. This applies to both rebuilding the program against new + * FFmpeg versions or to replacing the dynamic FFmpeg libraries that a program + * links against. + * + * However, new public symbols may be added and new members may be appended to + * public structs whose size is not part of public ABI (most public structs in + * FFmpeg). New macros and enum values may be added. Behavior in undocumented + * situations may change slightly (and be documented). All those are accompanied + * by an entry in doc/APIchanges and incrementing either the minor or micro + * version number. + */ + +/** + * @defgroup lavu libavutil + * Common code shared across all FFmpeg libraries. + * + * @note + * libavutil is designed to be modular. In most cases, in order to use the + * functions provided by one component of libavutil you must explicitly include + * the specific header containing that feature. If you are only using + * media-related components, you could simply include libavutil/avutil.h, which + * brings in most of the "core" components. + * + * @{ + * + * @defgroup lavu_crypto Crypto and Hashing + * + * @{ + * @} + * + * @defgroup lavu_math Mathematics + * @{ + * + * @} + * + * @defgroup lavu_string String Manipulation + * + * @{ + * + * @} + * + * @defgroup lavu_mem Memory Management + * + * @{ + * + * @} + * + * @defgroup lavu_data Data Structures + * @{ + * + * @} + * + * @defgroup lavu_video Video related + * + * @{ + * + * @} + * + * @defgroup lavu_audio Audio related + * + * @{ + * + * @} + * + * @defgroup lavu_error Error Codes + * + * @{ + * + * @} + * + * @defgroup lavu_log Logging Facility + * + * @{ + * + * @} + * + * @defgroup lavu_misc Other + * + * @{ + * + * @defgroup preproc_misc Preprocessor String Macros + * + * @{ + * + * @} + * + * @defgroup version_utils Library Version Macros + * + * @{ + * + * @} + */ + + +/** + * @addtogroup lavu_ver + * @{ + */ + +/** + * Return the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +/** + * Return an informative version string. This usually is the actual release + * version number or a git commit description. This string has no fixed format + * and can change any time. It should never be parsed by code. + */ +const char *av_version_info(void); + +/** + * Return the libavutil build-time configuration. + */ +const char *avutil_configuration(void); + +/** + * Return the libavutil license. + */ +const char *avutil_license(void); + +/** + * @} + */ + +/** + * @addtogroup lavu_media Media Type + * @brief Media Type + */ + +enum AVMediaType { + AVMEDIA_TYPE_UNKNOWN = -1, ///< Usually treated as AVMEDIA_TYPE_DATA + AVMEDIA_TYPE_VIDEO, + AVMEDIA_TYPE_AUDIO, + AVMEDIA_TYPE_DATA, ///< Opaque data information usually continuous + AVMEDIA_TYPE_SUBTITLE, + AVMEDIA_TYPE_ATTACHMENT, ///< Opaque data information usually sparse + AVMEDIA_TYPE_NB +}; + +/** + * Return a string describing the media_type enum, NULL if media_type + * is unknown. + */ +const char *av_get_media_type_string(enum AVMediaType media_type); + +/** + * @defgroup lavu_const Constants + * @{ + * + * @defgroup lavu_enc Encoding specific + * + * @note those definition should move to avcodec + * @{ + */ + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1< + +/** + * @defgroup lavu_base64 Base64 + * @ingroup lavu_crypto + * @{ + */ + +/** + * Decode a base64-encoded string. + * + * @param out buffer for decoded data + * @param in null-terminated input string + * @param out_size size in bytes of the out buffer, must be at + * least 3/4 of the length of in, that is AV_BASE64_DECODE_SIZE(strlen(in)) + * @return number of bytes written, or a negative value in case of + * invalid input + */ +int av_base64_decode(uint8_t *out, const char *in, int out_size); + +/** + * Calculate the output size in bytes needed to decode a base64 string + * with length x to a data buffer. + */ +#define AV_BASE64_DECODE_SIZE(x) ((x) * 3LL / 4) + +/** + * Encode data to base64 and null-terminate. + * + * @param out buffer for encoded data + * @param out_size size in bytes of the out buffer (including the + * null terminator), must be at least AV_BASE64_SIZE(in_size) + * @param in input buffer containing the data to encode + * @param in_size size in bytes of the in buffer + * @return out or NULL in case of error + */ +char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size); + +/** + * Calculate the output size needed to base64-encode x bytes to a + * null-terminated string. + */ +#define AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) + + /** + * @} + */ + +#endif /* AVUTIL_BASE64_H */ diff --git a/ffmpeg/inc/libavutil/blowfish.h b/ffmpeg/inc/libavutil/blowfish.h new file mode 100644 index 0000000..9e289a4 --- /dev/null +++ b/ffmpeg/inc/libavutil/blowfish.h @@ -0,0 +1,82 @@ +/* + * Blowfish algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BLOWFISH_H +#define AVUTIL_BLOWFISH_H + +#include + +/** + * @defgroup lavu_blowfish Blowfish + * @ingroup lavu_crypto + * @{ + */ + +#define AV_BF_ROUNDS 16 + +typedef struct AVBlowfish { + uint32_t p[AV_BF_ROUNDS + 2]; + uint32_t s[4][256]; +} AVBlowfish; + +/** + * Allocate an AVBlowfish context. + */ +AVBlowfish *av_blowfish_alloc(void); + +/** + * Initialize an AVBlowfish context. + * + * @param ctx an AVBlowfish context + * @param key a key + * @param key_len length of the key + */ +void av_blowfish_init(struct AVBlowfish *ctx, const uint8_t *key, int key_len); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVBlowfish context + * @param xl left four bytes halves of input to be encrypted + * @param xr right four bytes halves of input to be encrypted + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_blowfish_crypt_ecb(struct AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, + int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVBlowfish context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_blowfish_crypt(struct AVBlowfish *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_BLOWFISH_H */ diff --git a/ffmpeg/inc/libavutil/bprint.h b/ffmpeg/inc/libavutil/bprint.h new file mode 100644 index 0000000..c09b1ac --- /dev/null +++ b/ffmpeg/inc/libavutil/bprint.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2012 Nicolas George + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_BPRINT_H +#define AVUTIL_BPRINT_H + +#include + +#include "attributes.h" +#include "avstring.h" + +/** + * Define a structure with extra padding to a fixed size + * This helps ensuring binary compatibility with future versions. + */ + +#define FF_PAD_STRUCTURE(name, size, ...) \ +struct ff_pad_helper_##name { __VA_ARGS__ }; \ +typedef struct name { \ + __VA_ARGS__ \ + char reserved_padding[size - sizeof(struct ff_pad_helper_##name)]; \ +} name; + +/** + * Buffer to print data progressively + * + * The string buffer grows as necessary and is always 0-terminated. + * The content of the string is never accessed, and thus is + * encoding-agnostic and can even hold binary data. + * + * Small buffers are kept in the structure itself, and thus require no + * memory allocation at all (unless the contents of the buffer is needed + * after the structure goes out of scope). This is almost as lightweight as + * declaring a local "char buf[512]". + * + * The length of the string can go beyond the allocated size: the buffer is + * then truncated, but the functions still keep account of the actual total + * length. + * + * In other words, buf->len can be greater than buf->size and records the + * total length of what would have been to the buffer if there had been + * enough memory. + * + * Append operations do not need to be tested for failure: if a memory + * allocation fails, data stop being appended to the buffer, but the length + * is still updated. This situation can be tested with + * av_bprint_is_complete(). + * + * The size_max field determines several possible behaviours: + * + * size_max = -1 (= UINT_MAX) or any large value will let the buffer be + * reallocated as necessary, with an amortized linear cost. + * + * size_max = 0 prevents writing anything to the buffer: only the total + * length is computed. The write operations can then possibly be repeated in + * a buffer with exactly the necessary size + * (using size_init = size_max = len + 1). + * + * size_max = 1 is automatically replaced by the exact size available in the + * structure itself, thus ensuring no dynamic memory allocation. The + * internal buffer is large enough to hold a reasonable paragraph of text, + * such as the current paragraph. + */ + +FF_PAD_STRUCTURE(AVBPrint, 1024, + char *str; /**< string so far */ + unsigned len; /**< length so far */ + unsigned size; /**< allocated memory */ + unsigned size_max; /**< maximum allocated memory */ + char reserved_internal_buffer[1]; +) + +/** + * Convenience macros for special values for av_bprint_init() size_max + * parameter. + */ +#define AV_BPRINT_SIZE_UNLIMITED ((unsigned)-1) +#define AV_BPRINT_SIZE_AUTOMATIC 1 +#define AV_BPRINT_SIZE_COUNT_ONLY 0 + +/** + * Init a print buffer. + * + * @param buf buffer to init + * @param size_init initial size (including the final 0) + * @param size_max maximum size; + * 0 means do not write anything, just count the length; + * 1 is replaced by the maximum value for automatic storage; + * any large value means that the internal buffer will be + * reallocated as needed up to that limit; -1 is converted to + * UINT_MAX, the largest limit possible. + * Check also AV_BPRINT_SIZE_* macros. + */ +void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max); + +/** + * Init a print buffer using a pre-existing buffer. + * + * The buffer will not be reallocated. + * + * @param buf buffer structure to init + * @param buffer byte buffer to use for the string data + * @param size size of buffer + */ +void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size); + +/** + * Append a formatted string to a print buffer. + */ +void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3); + +/** + * Append a formatted string to a print buffer. + */ +void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg); + +/** + * Append char c n times to a print buffer. + */ +void av_bprint_chars(AVBPrint *buf, char c, unsigned n); + +/** + * Append data to a print buffer. + * + * param buf bprint buffer to use + * param data pointer to data + * param size size of data + */ +void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size); + +struct tm; +/** + * Append a formatted date and time to a print buffer. + * + * param buf bprint buffer to use + * param fmt date and time format string, see strftime() + * param tm broken-down time structure to translate + * + * @note due to poor design of the standard strftime function, it may + * produce poor results if the format string expands to a very long text and + * the bprint buffer is near the limit stated by the size_max option. + */ +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm); + +/** + * Allocate bytes in the buffer for external use. + * + * @param[in] buf buffer structure + * @param[in] size required size + * @param[out] mem pointer to the memory area + * @param[out] actual_size size of the memory area after allocation; + * can be larger or smaller than size + */ +void av_bprint_get_buffer(AVBPrint *buf, unsigned size, + unsigned char **mem, unsigned *actual_size); + +/** + * Reset the string to "" but keep internal allocated data. + */ +void av_bprint_clear(AVBPrint *buf); + +/** + * Test if the print buffer is complete (not truncated). + * + * It may have been truncated due to a memory allocation failure + * or the size_max limit (compare size and size_max if necessary). + */ +static inline int av_bprint_is_complete(const AVBPrint *buf) +{ + return buf->len < buf->size; +} + +/** + * Finalize a print buffer. + * + * The print buffer can no longer be used afterwards, + * but the len and size fields are still valid. + * + * @arg[out] ret_str if not NULL, used to return a permanent copy of the + * buffer contents, or NULL if memory allocation fails; + * if NULL, the buffer is discarded and freed + * @return 0 for success or error code (probably AVERROR(ENOMEM)) + */ +int av_bprint_finalize(AVBPrint *buf, char **ret_str); + +/** + * Escape the content in src and append it to dstbuf. + * + * @param dstbuf already inited destination bprint buffer + * @param src string containing the text to escape + * @param special_chars string containing the special characters which + * need to be escaped, can be NULL + * @param mode escape mode to employ, see AV_ESCAPE_MODE_* macros. + * Any unknown value for mode will be considered equivalent to + * AV_ESCAPE_MODE_BACKSLASH, but this behaviour can change without + * notice. + * @param flags flags which control how to escape, see AV_ESCAPE_FLAG_* macros + */ +void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars, + enum AVEscapeMode mode, int flags); + +#endif /* AVUTIL_BPRINT_H */ diff --git a/ffmpeg/inc/libavutil/bswap.h b/ffmpeg/inc/libavutil/bswap.h new file mode 100644 index 0000000..91cb795 --- /dev/null +++ b/ffmpeg/inc/libavutil/bswap.h @@ -0,0 +1,109 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * byte swapping routines + */ + +#ifndef AVUTIL_BSWAP_H +#define AVUTIL_BSWAP_H + +#include +#include "libavutil/avconfig.h" +#include "attributes.h" + +#ifdef HAVE_AV_CONFIG_H + +#include "config.h" + +#if ARCH_AARCH64 +# include "aarch64/bswap.h" +#elif ARCH_ARM +# include "arm/bswap.h" +#elif ARCH_AVR32 +# include "avr32/bswap.h" +#elif ARCH_SH4 +# include "sh4/bswap.h" +#elif ARCH_X86 +# include "x86/bswap.h" +#endif + +#endif /* HAVE_AV_CONFIG_H */ + +#define AV_BSWAP16C(x) (((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff)) +#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16)) +#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C((x) >> 32)) + +#define AV_BSWAPC(s, x) AV_BSWAP##s##C(x) + +#ifndef av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + x= (x>>8) | (x<<8); + return x; +} +#endif + +#ifndef av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return AV_BSWAP32C(x); +} +#endif + +#ifndef av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + return (uint64_t)av_bswap32(x) << 32 | av_bswap32(x >> 32); +} +#endif + +// be2ne ... big-endian to native-endian +// le2ne ... little-endian to native-endian + +#if AV_HAVE_BIGENDIAN +#define av_be2ne16(x) (x) +#define av_be2ne32(x) (x) +#define av_be2ne64(x) (x) +#define av_le2ne16(x) av_bswap16(x) +#define av_le2ne32(x) av_bswap32(x) +#define av_le2ne64(x) av_bswap64(x) +#define AV_BE2NEC(s, x) (x) +#define AV_LE2NEC(s, x) AV_BSWAPC(s, x) +#else +#define av_be2ne16(x) av_bswap16(x) +#define av_be2ne32(x) av_bswap32(x) +#define av_be2ne64(x) av_bswap64(x) +#define av_le2ne16(x) (x) +#define av_le2ne32(x) (x) +#define av_le2ne64(x) (x) +#define AV_BE2NEC(s, x) AV_BSWAPC(s, x) +#define AV_LE2NEC(s, x) (x) +#endif + +#define AV_BE2NE16C(x) AV_BE2NEC(16, x) +#define AV_BE2NE32C(x) AV_BE2NEC(32, x) +#define AV_BE2NE64C(x) AV_BE2NEC(64, x) +#define AV_LE2NE16C(x) AV_LE2NEC(16, x) +#define AV_LE2NE32C(x) AV_LE2NEC(32, x) +#define AV_LE2NE64C(x) AV_LE2NEC(64, x) + +#endif /* AVUTIL_BSWAP_H */ diff --git a/ffmpeg/inc/libavutil/buffer.h b/ffmpeg/inc/libavutil/buffer.h new file mode 100644 index 0000000..c0f3f6c --- /dev/null +++ b/ffmpeg/inc/libavutil/buffer.h @@ -0,0 +1,305 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_buffer + * refcounted data buffer API + */ + +#ifndef AVUTIL_BUFFER_H +#define AVUTIL_BUFFER_H + +#include + +/** + * @defgroup lavu_buffer AVBuffer + * @ingroup lavu_data + * + * @{ + * AVBuffer is an API for reference-counted data buffers. + * + * There are two core objects in this API -- AVBuffer and AVBufferRef. AVBuffer + * represents the data buffer itself; it is opaque and not meant to be accessed + * by the caller directly, but only through AVBufferRef. However, the caller may + * e.g. compare two AVBuffer pointers to check whether two different references + * are describing the same data buffer. AVBufferRef represents a single + * reference to an AVBuffer and it is the object that may be manipulated by the + * caller directly. + * + * There are two functions provided for creating a new AVBuffer with a single + * reference -- av_buffer_alloc() to just allocate a new buffer, and + * av_buffer_create() to wrap an existing array in an AVBuffer. From an existing + * reference, additional references may be created with av_buffer_ref(). + * Use av_buffer_unref() to free a reference (this will automatically free the + * data once all the references are freed). + * + * The convention throughout this API and the rest of FFmpeg is such that the + * buffer is considered writable if there exists only one reference to it (and + * it has not been marked as read-only). The av_buffer_is_writable() function is + * provided to check whether this is true and av_buffer_make_writable() will + * automatically create a new writable buffer when necessary. + * Of course nothing prevents the calling code from violating this convention, + * however that is safe only when all the existing references are under its + * control. + * + * @note Referencing and unreferencing the buffers is thread-safe and thus + * may be done from multiple threads simultaneously without any need for + * additional locking. + * + * @note Two different references to the same buffer can point to different + * parts of the buffer (i.e. their AVBufferRef.data will not be equal). + */ + +/** + * A reference counted buffer type. It is opaque and is meant to be used through + * references (AVBufferRef). + */ +typedef struct AVBuffer AVBuffer; + +/** + * A reference to a data buffer. + * + * The size of this struct is not a part of the public ABI and it is not meant + * to be allocated directly. + */ +typedef struct AVBufferRef { + AVBuffer *buffer; + + /** + * The data buffer. It is considered writable if and only if + * this is the only reference to the buffer, in which case + * av_buffer_is_writable() returns 1. + */ + uint8_t *data; + /** + * Size of data in bytes. + */ + int size; +} AVBufferRef; + +/** + * Allocate an AVBuffer of the given size using av_malloc(). + * + * @return an AVBufferRef of given size or NULL when out of memory + */ +AVBufferRef *av_buffer_alloc(int size); + +/** + * Same as av_buffer_alloc(), except the returned buffer will be initialized + * to zero. + */ +AVBufferRef *av_buffer_allocz(int size); + +/** + * Always treat the buffer as read-only, even when it has only one + * reference. + */ +#define AV_BUFFER_FLAG_READONLY (1 << 0) + +/** + * Create an AVBuffer from an existing array. + * + * If this function is successful, data is owned by the AVBuffer. The caller may + * only access data through the returned AVBufferRef and references derived from + * it. + * If this function fails, data is left untouched. + * @param data data array + * @param size size of data in bytes + * @param free a callback for freeing this buffer's data + * @param opaque parameter to be got for processing or passed to free + * @param flags a combination of AV_BUFFER_FLAG_* + * + * @return an AVBufferRef referring to data on success, NULL on failure. + */ +AVBufferRef *av_buffer_create(uint8_t *data, int size, + void (*free)(void *opaque, uint8_t *data), + void *opaque, int flags); + +/** + * Default free callback, which calls av_free() on the buffer data. + * This function is meant to be passed to av_buffer_create(), not called + * directly. + */ +void av_buffer_default_free(void *opaque, uint8_t *data); + +/** + * Create a new reference to an AVBuffer. + * + * @return a new AVBufferRef referring to the same AVBuffer as buf or NULL on + * failure. + */ +AVBufferRef *av_buffer_ref(AVBufferRef *buf); + +/** + * Free a given reference and automatically free the buffer if there are no more + * references to it. + * + * @param buf the reference to be freed. The pointer is set to NULL on return. + */ +void av_buffer_unref(AVBufferRef **buf); + +/** + * @return 1 if the caller may write to the data referred to by buf (which is + * true if and only if buf is the only reference to the underlying AVBuffer). + * Return 0 otherwise. + * A positive answer is valid until av_buffer_ref() is called on buf. + */ +int av_buffer_is_writable(const AVBufferRef *buf); + +/** + * @return the opaque parameter set by av_buffer_create. + */ +void *av_buffer_get_opaque(const AVBufferRef *buf); + +int av_buffer_get_ref_count(const AVBufferRef *buf); + +/** + * Create a writable reference from a given buffer reference, avoiding data copy + * if possible. + * + * @param buf buffer reference to make writable. On success, buf is either left + * untouched, or it is unreferenced and a new writable AVBufferRef is + * written in its place. On failure, buf is left untouched. + * @return 0 on success, a negative AVERROR on failure. + */ +int av_buffer_make_writable(AVBufferRef **buf); + +/** + * Reallocate a given buffer. + * + * @param buf a buffer reference to reallocate. On success, buf will be + * unreferenced and a new reference with the required size will be + * written in its place. On failure buf will be left untouched. *buf + * may be NULL, then a new buffer is allocated. + * @param size required new buffer size. + * @return 0 on success, a negative AVERROR on failure. + * + * @note the buffer is actually reallocated with av_realloc() only if it was + * initially allocated through av_buffer_realloc(NULL) and there is only one + * reference to it (i.e. the one passed to this function). In all other cases + * a new buffer is allocated and the data is copied. + */ +int av_buffer_realloc(AVBufferRef **buf, int size); + +/** + * @} + */ + +/** + * @defgroup lavu_bufferpool AVBufferPool + * @ingroup lavu_data + * + * @{ + * AVBufferPool is an API for a lock-free thread-safe pool of AVBuffers. + * + * Frequently allocating and freeing large buffers may be slow. AVBufferPool is + * meant to solve this in cases when the caller needs a set of buffers of the + * same size (the most obvious use case being buffers for raw video or audio + * frames). + * + * At the beginning, the user must call av_buffer_pool_init() to create the + * buffer pool. Then whenever a buffer is needed, call av_buffer_pool_get() to + * get a reference to a new buffer, similar to av_buffer_alloc(). This new + * reference works in all aspects the same way as the one created by + * av_buffer_alloc(). However, when the last reference to this buffer is + * unreferenced, it is returned to the pool instead of being freed and will be + * reused for subsequent av_buffer_pool_get() calls. + * + * When the caller is done with the pool and no longer needs to allocate any new + * buffers, av_buffer_pool_uninit() must be called to mark the pool as freeable. + * Once all the buffers are released, it will automatically be freed. + * + * Allocating and releasing buffers with this API is thread-safe as long as + * either the default alloc callback is used, or the user-supplied one is + * thread-safe. + */ + +/** + * The buffer pool. This structure is opaque and not meant to be accessed + * directly. It is allocated with av_buffer_pool_init() and freed with + * av_buffer_pool_uninit(). + */ +typedef struct AVBufferPool AVBufferPool; + +/** + * Allocate and initialize a buffer pool. + * + * @param size size of each buffer in this pool + * @param alloc a function that will be used to allocate new buffers when the + * pool is empty. May be NULL, then the default allocator will be used + * (av_buffer_alloc()). + * @return newly created buffer pool on success, NULL on error. + */ +AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)); + +/** + * Allocate and initialize a buffer pool with a more complex allocator. + * + * @param size size of each buffer in this pool + * @param opaque arbitrary user data used by the allocator + * @param alloc a function that will be used to allocate new buffers when the + * pool is empty. May be NULL, then the default allocator will be + * used (av_buffer_alloc()). + * @param pool_free a function that will be called immediately before the pool + * is freed. I.e. after av_buffer_pool_uninit() is called + * by the caller and all the frames are returned to the pool + * and freed. It is intended to uninitialize the user opaque + * data. May be NULL. + * @return newly created buffer pool on success, NULL on error. + */ +AVBufferPool *av_buffer_pool_init2(int size, void *opaque, + AVBufferRef* (*alloc)(void *opaque, int size), + void (*pool_free)(void *opaque)); + +/** + * Mark the pool as being available for freeing. It will actually be freed only + * once all the allocated buffers associated with the pool are released. Thus it + * is safe to call this function while some of the allocated buffers are still + * in use. + * + * @param pool pointer to the pool to be freed. It will be set to NULL. + */ +void av_buffer_pool_uninit(AVBufferPool **pool); + +/** + * Allocate a new AVBuffer, reusing an old buffer from the pool when available. + * This function may be called simultaneously from multiple threads. + * + * @return a reference to the new buffer on success, NULL on error. + */ +AVBufferRef *av_buffer_pool_get(AVBufferPool *pool); + +/** + * Query the original opaque parameter of an allocated buffer in the pool. + * + * @param ref a buffer reference to a buffer returned by av_buffer_pool_get. + * @return the opaque parameter set by the buffer allocator function of the + * buffer pool. + * + * @note the opaque parameter of ref is used by the buffer pool implementation, + * therefore you have to use this function to access the original opaque + * parameter of an allocated buffer. + */ +void *av_buffer_pool_buffer_get_opaque(AVBufferRef *ref); + +/** + * @} + */ + +#endif /* AVUTIL_BUFFER_H */ diff --git a/ffmpeg/inc/libavutil/camellia.h b/ffmpeg/inc/libavutil/camellia.h new file mode 100644 index 0000000..e674c9b --- /dev/null +++ b/ffmpeg/inc/libavutil/camellia.h @@ -0,0 +1,70 @@ +/* + * An implementation of the CAMELLIA algorithm as mentioned in RFC3713 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CAMELLIA_H +#define AVUTIL_CAMELLIA_H + +#include + + +/** + * @file + * @brief Public header for libavutil CAMELLIA algorithm + * @defgroup lavu_camellia CAMELLIA + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_camellia_size; + +struct AVCAMELLIA; + +/** + * Allocate an AVCAMELLIA context + * To free the struct: av_free(ptr) + */ +struct AVCAMELLIA *av_camellia_alloc(void); + +/** + * Initialize an AVCAMELLIA context. + * + * @param ctx an AVCAMELLIA context + * @param key a key of 16, 24, 32 bytes used for encryption/decryption + * @param key_bits number of keybits: possible are 128, 192, 256 + */ +int av_camellia_init(struct AVCAMELLIA *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVCAMELLIA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 16 byte blocks + * @paran iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_camellia_crypt(struct AVCAMELLIA *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t* iv, int decrypt); + +/** + * @} + */ +#endif /* AVUTIL_CAMELLIA_H */ diff --git a/ffmpeg/inc/libavutil/cast5.h b/ffmpeg/inc/libavutil/cast5.h new file mode 100644 index 0000000..ad5b347 --- /dev/null +++ b/ffmpeg/inc/libavutil/cast5.h @@ -0,0 +1,80 @@ +/* + * An implementation of the CAST128 algorithm as mentioned in RFC2144 + * Copyright (c) 2014 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CAST5_H +#define AVUTIL_CAST5_H + +#include + + +/** + * @file + * @brief Public header for libavutil CAST5 algorithm + * @defgroup lavu_cast5 CAST5 + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_cast5_size; + +struct AVCAST5; + +/** + * Allocate an AVCAST5 context + * To free the struct: av_free(ptr) + */ +struct AVCAST5 *av_cast5_alloc(void); +/** + * Initialize an AVCAST5 context. + * + * @param ctx an AVCAST5 context + * @param key a key of 5,6,...16 bytes used for encryption/decryption + * @param key_bits number of keybits: possible are 40,48,...,128 + * @return 0 on success, less than 0 on failure + */ +int av_cast5_init(struct AVCAST5 *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, ECB mode only + * + * @param ctx an AVCAST5 context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_cast5_crypt(struct AVCAST5 *ctx, uint8_t *dst, const uint8_t *src, int count, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVCAST5 context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_cast5_crypt2(struct AVCAST5 *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); +/** + * @} + */ +#endif /* AVUTIL_CAST5_H */ diff --git a/ffmpeg/inc/libavutil/channel_layout.h b/ffmpeg/inc/libavutil/channel_layout.h new file mode 100644 index 0000000..50bb8f0 --- /dev/null +++ b/ffmpeg/inc/libavutil/channel_layout.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2006 Michael Niedermayer + * Copyright (c) 2008 Peter Ross + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CHANNEL_LAYOUT_H +#define AVUTIL_CHANNEL_LAYOUT_H + +#include + +/** + * @file + * audio channel layout utility functions + */ + +/** + * @addtogroup lavu_audio + * @{ + */ + +/** + * @defgroup channel_masks Audio channel masks + * + * A channel layout is a 64-bits integer with a bit set for every channel. + * The number of bits set must be equal to the number of channels. + * The value 0 means that the channel layout is not known. + * @note this data structure is not powerful enough to handle channels + * combinations that have the same channel multiple times, such as + * dual-mono. + * + * @{ + */ +#define AV_CH_FRONT_LEFT 0x00000001 +#define AV_CH_FRONT_RIGHT 0x00000002 +#define AV_CH_FRONT_CENTER 0x00000004 +#define AV_CH_LOW_FREQUENCY 0x00000008 +#define AV_CH_BACK_LEFT 0x00000010 +#define AV_CH_BACK_RIGHT 0x00000020 +#define AV_CH_FRONT_LEFT_OF_CENTER 0x00000040 +#define AV_CH_FRONT_RIGHT_OF_CENTER 0x00000080 +#define AV_CH_BACK_CENTER 0x00000100 +#define AV_CH_SIDE_LEFT 0x00000200 +#define AV_CH_SIDE_RIGHT 0x00000400 +#define AV_CH_TOP_CENTER 0x00000800 +#define AV_CH_TOP_FRONT_LEFT 0x00001000 +#define AV_CH_TOP_FRONT_CENTER 0x00002000 +#define AV_CH_TOP_FRONT_RIGHT 0x00004000 +#define AV_CH_TOP_BACK_LEFT 0x00008000 +#define AV_CH_TOP_BACK_CENTER 0x00010000 +#define AV_CH_TOP_BACK_RIGHT 0x00020000 +#define AV_CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. +#define AV_CH_STEREO_RIGHT 0x40000000 ///< See AV_CH_STEREO_LEFT. +#define AV_CH_WIDE_LEFT 0x0000000080000000ULL +#define AV_CH_WIDE_RIGHT 0x0000000100000000ULL +#define AV_CH_SURROUND_DIRECT_LEFT 0x0000000200000000ULL +#define AV_CH_SURROUND_DIRECT_RIGHT 0x0000000400000000ULL +#define AV_CH_LOW_FREQUENCY_2 0x0000000800000000ULL + +/** Channel mask value used for AVCodecContext.request_channel_layout + to indicate that the user requests the channel order of the decoder output + to be the native codec channel order. */ +#define AV_CH_LAYOUT_NATIVE 0x8000000000000000ULL + +/** + * @} + * @defgroup channel_mask_c Audio channel layouts + * @{ + * */ +#define AV_CH_LAYOUT_MONO (AV_CH_FRONT_CENTER) +#define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT) +#define AV_CH_LAYOUT_2POINT1 (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_2_1 (AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_SURROUND (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) +#define AV_CH_LAYOUT_3POINT1 (AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_4POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_4POINT1 (AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_2_2 (AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) +#define AV_CH_LAYOUT_QUAD (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_5POINT0 (AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) +#define AV_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_5POINT0_BACK (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_5POINT1_BACK (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_6POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT0_FRONT (AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_HEXAGONAL (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER) +#define AV_CH_LAYOUT_6POINT1_FRONT (AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY) +#define AV_CH_LAYOUT_7POINT0 (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_7POINT0_FRONT (AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_7POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_7POINT1_WIDE (AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_7POINT1_WIDE_BACK (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) +#define AV_CH_LAYOUT_OCTAGONAL (AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) +#define AV_CH_LAYOUT_HEXADECAGONAL (AV_CH_LAYOUT_OCTAGONAL|AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT) +#define AV_CH_LAYOUT_STEREO_DOWNMIX (AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) + +enum AVMatrixEncoding { + AV_MATRIX_ENCODING_NONE, + AV_MATRIX_ENCODING_DOLBY, + AV_MATRIX_ENCODING_DPLII, + AV_MATRIX_ENCODING_DPLIIX, + AV_MATRIX_ENCODING_DPLIIZ, + AV_MATRIX_ENCODING_DOLBYEX, + AV_MATRIX_ENCODING_DOLBYHEADPHONE, + AV_MATRIX_ENCODING_NB +}; + +/** + * Return a channel layout id that matches name, or 0 if no match is found. + * + * name can be one or several of the following notations, + * separated by '+' or '|': + * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0, + * 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix); + * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC, + * SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR); + * - a number of channels, in decimal, followed by 'c', yielding + * the default channel layout for that number of channels (@see + * av_get_default_channel_layout); + * - a channel layout mask, in hexadecimal starting with "0x" (see the + * AV_CH_* macros). + * + * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7" + */ +uint64_t av_get_channel_layout(const char *name); + +/** + * Return a channel layout and the number of channels based on the specified name. + * + * This function is similar to (@see av_get_channel_layout), but can also parse + * unknown channel layout specifications. + * + * @param[in] name channel layout specification string + * @param[out] channel_layout parsed channel layout (0 if unknown) + * @param[out] nb_channels number of channels + * + * @return 0 on success, AVERROR(EINVAL) if the parsing fails. + */ +int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels); + +/** + * Return a description of a channel layout. + * If nb_channels is <= 0, it is guessed from the channel_layout. + * + * @param buf put here the string containing the channel layout + * @param buf_size size in bytes of the buffer + */ +void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout); + +struct AVBPrint; +/** + * Append a description of a channel layout to a bprint buffer. + */ +void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout); + +/** + * Return the number of channels in the channel layout. + */ +int av_get_channel_layout_nb_channels(uint64_t channel_layout); + +/** + * Return default channel layout for a given number of channels. + */ +int64_t av_get_default_channel_layout(int nb_channels); + +/** + * Get the index of a channel in channel_layout. + * + * @param channel a channel layout describing exactly one channel which must be + * present in channel_layout. + * + * @return index of channel in channel_layout on success, a negative AVERROR + * on error. + */ +int av_get_channel_layout_channel_index(uint64_t channel_layout, + uint64_t channel); + +/** + * Get the channel with the given index in channel_layout. + */ +uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index); + +/** + * Get the name of a given channel. + * + * @return channel name on success, NULL on error. + */ +const char *av_get_channel_name(uint64_t channel); + +/** + * Get the description of a given channel. + * + * @param channel a channel layout with a single channel + * @return channel description on success, NULL on error + */ +const char *av_get_channel_description(uint64_t channel); + +/** + * Get the value and name of a standard channel layout. + * + * @param[in] index index in an internal list, starting at 0 + * @param[out] layout channel layout mask + * @param[out] name name of the layout + * @return 0 if the layout exists, + * <0 if index is beyond the limits + */ +int av_get_standard_channel_layout(unsigned index, uint64_t *layout, + const char **name); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_CHANNEL_LAYOUT_H */ diff --git a/ffmpeg/inc/libavutil/common.h b/ffmpeg/inc/libavutil/common.h new file mode 100644 index 0000000..92b721a --- /dev/null +++ b/ffmpeg/inc/libavutil/common.h @@ -0,0 +1,608 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C) +#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "attributes.h" +#include "macros.h" +#include "version.h" +#include "libavutil/avconfig.h" + +#if AV_HAVE_BIGENDIAN +# define AV_NE(be, le) (be) +#else +# define AV_NE(be, le) (le) +#endif + +//rounded division & shift +#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) +/* assume b>0 */ +#define ROUNDED_DIV(a,b) (((a)>=0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) +/* Fast a/(1<=0 and b>=0 */ +#define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \ + : ((a) + (1<<(b)) - 1) >> (b)) +/* Backwards compat. */ +#define FF_CEIL_RSHIFT AV_CEIL_RSHIFT + +#define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b)) +#define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b)) + +/** + * Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they + * are not representable as absolute values of their type. This is the same + * as with *abs() + * @see FFNABS() + */ +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +/** + * Negative Absolute value. + * this works for all integers of all types. + * As with many macros, this evaluates its argument twice, it thus must not have + * a sideeffect, that is FFNABS(x++) has undefined behavior. + */ +#define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) + +/** + * Comparator. + * For two numerical expressions x and y, gives 1 if x > y, -1 if x < y, and 0 + * if x == y. This is useful for instance in a qsort comparator callback. + * Furthermore, compilers are able to optimize this to branchless code, and + * there is no risk of overflow with signed types. + * As with many macros, this evaluates its argument multiple times, it thus + * must not have a side-effect. + */ +#define FFDIFFSIGN(x,y) (((x)>(y)) - ((x)<(y))) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +/* misc math functions */ + +#ifdef HAVE_AV_CONFIG_H +# include "config.h" +# include "intmath.h" +#endif + +/* Pull in unguarded fallback defines at the end of this file. */ +#include "common.h" + +#ifndef av_log2 +av_const int av_log2(unsigned v); +#endif + +#ifndef av_log2_16bit +av_const int av_log2_16bit(unsigned v); +#endif + +/** + * Clip a signed integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const int av_clip_c(int a, int amin, int amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a signed 64bit integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, int64_t amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a signed integer value into the 0-255 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const uint8_t av_clip_uint8_c(int a) +{ + if (a&(~0xFF)) return (~a)>>31; + else return a; +} + +/** + * Clip a signed integer value into the -128,127 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int8_t av_clip_int8_c(int a) +{ + if ((a+0x80U) & ~0xFF) return (a>>31) ^ 0x7F; + else return a; +} + +/** + * Clip a signed integer value into the 0-65535 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const uint16_t av_clip_uint16_c(int a) +{ + if (a&(~0xFFFF)) return (~a)>>31; + else return a; +} + +/** + * Clip a signed integer value into the -32768,32767 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int16_t av_clip_int16_c(int a) +{ + if ((a+0x8000U) & ~0xFFFF) return (a>>31) ^ 0x7FFF; + else return a; +} + +/** + * Clip a signed 64-bit integer value into the -2147483648,2147483647 range. + * @param a value to clip + * @return clipped value + */ +static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a) +{ + if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (int32_t)((a>>63) ^ 0x7FFFFFFF); + else return (int32_t)a; +} + +/** + * Clip a signed integer into the -(2^p),(2^p-1) range. + * @param a value to clip + * @param p bit position to clip at + * @return clipped value + */ +static av_always_inline av_const int av_clip_intp2_c(int a, int p) +{ + if (((unsigned)a + (1 << p)) & ~((2 << p) - 1)) + return (a >> 31) ^ ((1 << p) - 1); + else + return a; +} + +/** + * Clip a signed integer to an unsigned power of two range. + * @param a value to clip + * @param p bit position to clip at + * @return clipped value + */ +static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) +{ + if (a & ~((1<> 31 & ((1<= 0 && a >= INT64_MAX - b) + return INT64_MAX; + if (b <= 0 && a <= INT64_MIN - b) + return INT64_MIN; + return a + b; +#endif +} + +/** + * Subtract two signed 64-bit values with saturation. + * + * @param a one value + * @param b another value + * @return difference with signed saturation + */ +static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) { +#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_sub_overflow) + int64_t tmp; + return !__builtin_sub_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); +#else + if (b <= 0 && a >= INT64_MAX + b) + return INT64_MAX; + if (b >= 0 && a <= INT64_MIN + b) + return INT64_MIN; + return a - b; +#endif +} + +/** + * Clip a float value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const float av_clipf_c(float a, float amin, float amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clip a double value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static av_always_inline av_const double av_clipd_c(double a, double amin, double amax) +{ +#if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** Compute ceil(log2(x)). + * @param x value used to compute ceil(log2(x)) + * @return computed ceiling of log2(x) + */ +static av_always_inline av_const int av_ceil_log2_c(int x) +{ + return av_log2((x - 1U) << 1); +} + +/** + * Count number of bits set to one in x + * @param x value to count bits of + * @return the number of bits set to one in x + */ +static av_always_inline av_const int av_popcount_c(uint32_t x) +{ + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + x += x >> 8; + return (x + (x >> 16)) & 0x3F; +} + +/** + * Count number of bits set to one in x + * @param x value to count bits of + * @return the number of bits set to one in x + */ +static av_always_inline av_const int av_popcount64_c(uint64_t x) +{ + return av_popcount((uint32_t)x) + av_popcount((uint32_t)(x >> 32)); +} + +static av_always_inline av_const int av_parity_c(uint32_t v) +{ + return av_popcount(v) & 1; +} + +#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24)) +#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24)) + +/** + * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form. + * + * @param val Output value, must be an lvalue of type uint32_t. + * @param GET_BYTE Expression reading one byte from the input. + * Evaluated up to 7 times (4 for the currently + * assigned Unicode range). With a memory buffer + * input, this could be *ptr++, or if you want to make sure + * that *ptr stops at the end of a NULL terminated string then + * *ptr ? *ptr++ : 0 + * @param ERROR Expression to be evaluated on invalid input, + * typically a goto statement. + * + * @warning ERROR should not contain a loop control statement which + * could interact with the internal while loop, and should force an + * exit from the macro code (e.g. through a goto or a return) in order + * to prevent undefined results. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= (GET_BYTE);\ + {\ + uint32_t top = (val & 128) >> 1;\ + if ((val & 0xc0) == 0x80 || val >= 0xFE)\ + {ERROR}\ + while (val & top) {\ + unsigned int tmp = (GET_BYTE) - 128;\ + if(tmp>>6)\ + {ERROR}\ + val= (val<<6) + tmp;\ + top <<= 5;\ + }\ + val &= (top << 1) - 1;\ + } + +/** + * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form. + * + * @param val Output value, must be an lvalue of type uint32_t. + * @param GET_16BIT Expression returning two bytes of UTF-16 data converted + * to native byte order. Evaluated one or two times. + * @param ERROR Expression to be evaluated on invalid input, + * typically a goto statement. + */ +#define GET_UTF16(val, GET_16BIT, ERROR)\ + val = (GET_16BIT);\ + {\ + unsigned int hi = val - 0xD800;\ + if (hi < 0x800) {\ + val = (GET_16BIT) - 0xDC00;\ + if (val > 0x3FFU || hi > 0x3FFU)\ + {ERROR}\ + val += (hi<<10) + 0x10000;\ + }\ + }\ + +/** + * @def PUT_UTF8(val, tmp, PUT_BYTE) + * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). + * @param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If + * val is given as a function it is executed only once. + * @param tmp is a temporary variable and should be of type uint8_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_BYTE. + * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. + * It could be a function or a statement, and uses tmp as the input byte. + * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be + * executed up to 4 times for values in the valid UTF-8 range and up to + * 7 times in the general case, depending on the length of the converted + * Unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +/** + * @def PUT_UTF16(val, tmp, PUT_16BIT) + * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). + * @param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If + * val is given as a function it is executed only once. + * @param tmp is a temporary variable and should be of type uint16_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_16BIT. + * @param PUT_16BIT writes the converted UTF-16 data to any proper destination + * in desired endianness. It could be a function or a statement, and uses tmp + * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" + * PUT_BYTE will be executed 1 or 2 times depending on input character. + */ +#define PUT_UTF16(val, tmp, PUT_16BIT)\ + {\ + uint32_t in = val;\ + if (in < 0x10000) {\ + tmp = in;\ + PUT_16BIT\ + } else {\ + tmp = 0xD800 | ((in - 0x10000) >> 10);\ + PUT_16BIT\ + tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ + PUT_16BIT\ + }\ + }\ + + + +#include "mem.h" + +#ifdef HAVE_AV_CONFIG_H +# include "internal.h" +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVUTIL_COMMON_H */ + +/* + * The following definitions are outside the multiple inclusion guard + * to ensure they are immediately available in intmath.h. + */ + +#ifndef av_ceil_log2 +# define av_ceil_log2 av_ceil_log2_c +#endif +#ifndef av_clip +# define av_clip av_clip_c +#endif +#ifndef av_clip64 +# define av_clip64 av_clip64_c +#endif +#ifndef av_clip_uint8 +# define av_clip_uint8 av_clip_uint8_c +#endif +#ifndef av_clip_int8 +# define av_clip_int8 av_clip_int8_c +#endif +#ifndef av_clip_uint16 +# define av_clip_uint16 av_clip_uint16_c +#endif +#ifndef av_clip_int16 +# define av_clip_int16 av_clip_int16_c +#endif +#ifndef av_clipl_int32 +# define av_clipl_int32 av_clipl_int32_c +#endif +#ifndef av_clip_intp2 +# define av_clip_intp2 av_clip_intp2_c +#endif +#ifndef av_clip_uintp2 +# define av_clip_uintp2 av_clip_uintp2_c +#endif +#ifndef av_mod_uintp2 +# define av_mod_uintp2 av_mod_uintp2_c +#endif +#ifndef av_sat_add32 +# define av_sat_add32 av_sat_add32_c +#endif +#ifndef av_sat_dadd32 +# define av_sat_dadd32 av_sat_dadd32_c +#endif +#ifndef av_sat_sub32 +# define av_sat_sub32 av_sat_sub32_c +#endif +#ifndef av_sat_dsub32 +# define av_sat_dsub32 av_sat_dsub32_c +#endif +#ifndef av_sat_add64 +# define av_sat_add64 av_sat_add64_c +#endif +#ifndef av_sat_sub64 +# define av_sat_sub64 av_sat_sub64_c +#endif +#ifndef av_clipf +# define av_clipf av_clipf_c +#endif +#ifndef av_clipd +# define av_clipd av_clipd_c +#endif +#ifndef av_popcount +# define av_popcount av_popcount_c +#endif +#ifndef av_popcount64 +# define av_popcount64 av_popcount64_c +#endif +#ifndef av_parity +# define av_parity av_parity_c +#endif diff --git a/ffmpeg/inc/libavutil/cpu.h b/ffmpeg/inc/libavutil/cpu.h new file mode 100644 index 0000000..8bb9eb6 --- /dev/null +++ b/ffmpeg/inc/libavutil/cpu.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_CPU_H +#define AVUTIL_CPU_H + +#include + +#include "attributes.h" + +#define AV_CPU_FLAG_FORCE 0x80000000 /* force usage of selected flags (OR) */ + + /* lower 16 bits - CPU features */ +#define AV_CPU_FLAG_MMX 0x0001 ///< standard MMX +#define AV_CPU_FLAG_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#define AV_CPU_FLAG_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext +#define AV_CPU_FLAG_3DNOW 0x0004 ///< AMD 3DNOW +#define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions +#define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions +#define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) +#define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions +#define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) +#define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define AV_CPU_FLAG_SSSE3SLOW 0x4000000 ///< SSSE3 supported, but usually not faster +#define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower +#define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions +#define AV_CPU_FLAG_SSE42 0x0200 ///< Nehalem SSE4.2 functions +#define AV_CPU_FLAG_AESNI 0x80000 ///< Advanced Encryption Standard functions +#define AV_CPU_FLAG_AVX 0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used +#define AV_CPU_FLAG_AVXSLOW 0x8000000 ///< AVX supported, but slow when using YMM registers (e.g. Bulldozer) +#define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions +#define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions +#define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction +#define AV_CPU_FLAG_AVX2 0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't used +#define AV_CPU_FLAG_FMA3 0x10000 ///< Haswell FMA3 functions +#define AV_CPU_FLAG_BMI1 0x20000 ///< Bit Manipulation Instruction Set 1 +#define AV_CPU_FLAG_BMI2 0x40000 ///< Bit Manipulation Instruction Set 2 +#define AV_CPU_FLAG_AVX512 0x100000 ///< AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used + +#define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard +#define AV_CPU_FLAG_VSX 0x0002 ///< ISA 2.06 +#define AV_CPU_FLAG_POWER8 0x0004 ///< ISA 2.07 + +#define AV_CPU_FLAG_ARMV5TE (1 << 0) +#define AV_CPU_FLAG_ARMV6 (1 << 1) +#define AV_CPU_FLAG_ARMV6T2 (1 << 2) +#define AV_CPU_FLAG_VFP (1 << 3) +#define AV_CPU_FLAG_VFPV3 (1 << 4) +#define AV_CPU_FLAG_NEON (1 << 5) +#define AV_CPU_FLAG_ARMV8 (1 << 6) +#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations +#define AV_CPU_FLAG_SETEND (1 <<16) + +/** + * Return the flags which specify extensions supported by the CPU. + * The returned value is affected by av_force_cpu_flags() if that was used + * before. So av_get_cpu_flags() can easily be used in an application to + * detect the enabled cpu flags. + */ +int av_get_cpu_flags(void); + +/** + * Disables cpu detection and forces the specified flags. + * -1 is a special case that disables forcing of specific flags. + */ +void av_force_cpu_flags(int flags); + +/** + * Set a mask on flags returned by av_get_cpu_flags(). + * This function is mainly useful for testing. + * Please use av_force_cpu_flags() and av_get_cpu_flags() instead which are more flexible + */ +attribute_deprecated void av_set_cpu_flags_mask(int mask); + +/** + * Parse CPU flags from a string. + * + * The returned flags contain the specified flags as well as related unspecified flags. + * + * This function exists only for compatibility with libav. + * Please use av_parse_cpu_caps() when possible. + * @return a combination of AV_CPU_* flags, negative on error. + */ +attribute_deprecated +int av_parse_cpu_flags(const char *s); + +/** + * Parse CPU caps from a string and update the given AV_CPU_* flags based on that. + * + * @return negative on error. + */ +int av_parse_cpu_caps(unsigned *flags, const char *s); + +/** + * @return the number of logical CPU cores present. + */ +int av_cpu_count(void); + +/** + * Get the maximum data alignment that may be required by FFmpeg. + * + * Note that this is affected by the build configuration and the CPU flags mask, + * so e.g. if the CPU supports AVX, but libavutil has been built with + * --disable-avx or the AV_CPU_FLAG_AVX flag has been disabled through + * av_set_cpu_flags_mask(), then this function will behave as if AVX is not + * present. + */ +size_t av_cpu_max_align(void); + +#endif /* AVUTIL_CPU_H */ diff --git a/ffmpeg/inc/libavutil/crc.h b/ffmpeg/inc/libavutil/crc.h new file mode 100644 index 0000000..47e22b4 --- /dev/null +++ b/ffmpeg/inc/libavutil/crc.h @@ -0,0 +1,100 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_crc32 + * Public header for CRC hash function implementation. + */ + +#ifndef AVUTIL_CRC_H +#define AVUTIL_CRC_H + +#include +#include +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_crc32 CRC + * @ingroup lavu_hash + * CRC (Cyclic Redundancy Check) hash function implementation. + * + * This module supports numerous CRC polynomials, in addition to the most + * widely used CRC-32-IEEE. See @ref AVCRCId for a list of available + * polynomials. + * + * @{ + */ + +typedef uint32_t AVCRC; + +typedef enum { + AV_CRC_8_ATM, + AV_CRC_16_ANSI, + AV_CRC_16_CCITT, + AV_CRC_32_IEEE, + AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */ + AV_CRC_16_ANSI_LE, /*< reversed bitorder version of AV_CRC_16_ANSI */ + AV_CRC_24_IEEE, + AV_CRC_8_EBU, + AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */ +}AVCRCId; + +/** + * Initialize a CRC table. + * @param ctx must be an array of size sizeof(AVCRC)*257 or sizeof(AVCRC)*1024 + * @param le If 1, the lowest bit represents the coefficient for the highest + * exponent of the corresponding polynomial (both for poly and + * actual CRC). + * If 0, you must swap the CRC parameter and the result of av_crc + * if you need the standard representation (can be simplified in + * most cases to e.g. bswap16): + * av_bswap32(crc << (32-bits)) + * @param bits number of bits for the CRC + * @param poly generator polynomial without the x**bits coefficient, in the + * representation as specified by le + * @param ctx_size size of ctx in bytes + * @return <0 on failure + */ +int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size); + +/** + * Get an initialized standard CRC table. + * @param crc_id ID of a standard CRC + * @return a pointer to the CRC table or NULL on failure + */ +const AVCRC *av_crc_get_table(AVCRCId crc_id); + +/** + * Calculate the CRC of a block. + * @param crc CRC of previous blocks if any or initial value for CRC + * @return CRC updated with the data from the given block + * + * @see av_crc_init() "le" parameter + */ +uint32_t av_crc(const AVCRC *ctx, uint32_t crc, + const uint8_t *buffer, size_t length) av_pure; + +/** + * @} + */ + +#endif /* AVUTIL_CRC_H */ diff --git a/ffmpeg/inc/libavutil/des.h b/ffmpeg/inc/libavutil/des.h new file mode 100644 index 0000000..4cf11f5 --- /dev/null +++ b/ffmpeg/inc/libavutil/des.h @@ -0,0 +1,77 @@ +/* + * DES encryption/decryption + * Copyright (c) 2007 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DES_H +#define AVUTIL_DES_H + +#include + +/** + * @defgroup lavu_des DES + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVDES { + uint64_t round_keys[3][16]; + int triple_des; +} AVDES; + +/** + * Allocate an AVDES context. + */ +AVDES *av_des_alloc(void); + +/** + * @brief Initializes an AVDES context. + * + * @param key_bits must be 64 or 192 + * @param decrypt 0 for encryption/CBC-MAC, 1 for decryption + * @return zero on success, negative value otherwise + */ +int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt); + +/** + * @brief Encrypts / decrypts using the DES algorithm. + * + * @param count number of 8 byte blocks + * @param dst destination array, can be equal to src, must be 8-byte aligned + * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL + * @param iv initialization vector for CBC mode, if NULL then ECB will be used, + * must be 8-byte aligned + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_des_crypt(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @brief Calculates CBC-MAC using the DES algorithm. + * + * @param count number of 8 byte blocks + * @param dst destination array, can be equal to src, must be 8-byte aligned + * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL + */ +void av_des_mac(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count); + +/** + * @} + */ + +#endif /* AVUTIL_DES_H */ diff --git a/ffmpeg/inc/libavutil/dict.h b/ffmpeg/inc/libavutil/dict.h new file mode 100644 index 0000000..118f1f0 --- /dev/null +++ b/ffmpeg/inc/libavutil/dict.h @@ -0,0 +1,200 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Public dictionary API. + * @deprecated + * AVDictionary is provided for compatibility with libav. It is both in + * implementation as well as API inefficient. It does not scale and is + * extremely slow with large dictionaries. + * It is recommended that new code uses our tree container from tree.c/h + * where applicable, which uses AVL trees to achieve O(log n) performance. + */ + +#ifndef AVUTIL_DICT_H +#define AVUTIL_DICT_H + +#include + +#include "version.h" + +/** + * @addtogroup lavu_dict AVDictionary + * @ingroup lavu_data + * + * @brief Simple key:value store + * + * @{ + * Dictionaries are used for storing key:value pairs. To create + * an AVDictionary, simply pass an address of a NULL pointer to + * av_dict_set(). NULL can be used as an empty dictionary wherever + * a pointer to an AVDictionary is required. + * Use av_dict_get() to retrieve an entry or iterate over all + * entries and finally av_dict_free() to free the dictionary + * and all its contents. + * + @code + AVDictionary *d = NULL; // "create" an empty dictionary + AVDictionaryEntry *t = NULL; + + av_dict_set(&d, "foo", "bar", 0); // add an entry + + char *k = av_strdup("key"); // if your strings are already allocated, + char *v = av_strdup("value"); // you can avoid copying them like this + av_dict_set(&d, k, v, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); + + while (t = av_dict_get(d, "", t, AV_DICT_IGNORE_SUFFIX)) { + <....> // iterate over all entries in d + } + av_dict_free(&d); + @endcode + */ + +#define AV_DICT_MATCH_CASE 1 /**< Only get an entry with exact-case key match. Only relevant in av_dict_get(). */ +#define AV_DICT_IGNORE_SUFFIX 2 /**< Return first entry in a dictionary whose first part corresponds to the search key, + ignoring the suffix of the found key string. Only relevant in av_dict_get(). */ +#define AV_DICT_DONT_STRDUP_KEY 4 /**< Take ownership of a key that's been + allocated with av_malloc() or another memory allocation function. */ +#define AV_DICT_DONT_STRDUP_VAL 8 /**< Take ownership of a value that's been + allocated with av_malloc() or another memory allocation function. */ +#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries. +#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no + delimiter is added, the strings are simply concatenated. */ +#define AV_DICT_MULTIKEY 64 /**< Allow to store several equal keys in the dictionary */ + +typedef struct AVDictionaryEntry { + char *key; + char *value; +} AVDictionaryEntry; + +typedef struct AVDictionary AVDictionary; + +/** + * Get a dictionary entry with matching key. + * + * The returned entry key or value must not be changed, or it will + * cause undefined behavior. + * + * To iterate through all the dictionary entries, you can set the matching key + * to the null string "" and set the AV_DICT_IGNORE_SUFFIX flag. + * + * @param prev Set to the previous matching element to find the next. + * If set to NULL the first matching element is returned. + * @param key matching key + * @param flags a collection of AV_DICT_* flags controlling how the entry is retrieved + * @return found entry or NULL in case no matching entry was found in the dictionary + */ +AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key, + const AVDictionaryEntry *prev, int flags); + +/** + * Get number of entries in dictionary. + * + * @param m dictionary + * @return number of entries in dictionary + */ +int av_dict_count(const AVDictionary *m); + +/** + * Set the given entry in *pm, overwriting an existing entry. + * + * Note: If AV_DICT_DONT_STRDUP_KEY or AV_DICT_DONT_STRDUP_VAL is set, + * these arguments will be freed on error. + * + * Warning: Adding a new entry to a dictionary invalidates all existing entries + * previously returned with av_dict_get. + * + * @param pm pointer to a pointer to a dictionary struct. If *pm is NULL + * a dictionary struct is allocated and put in *pm. + * @param key entry key to add to *pm (will either be av_strduped or added as a new key depending on flags) + * @param value entry value to add to *pm (will be av_strduped or added as a new key depending on flags). + * Passing a NULL value will cause an existing entry to be deleted. + * @return >= 0 on success otherwise an error code <0 + */ +int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags); + +/** + * Convenience wrapper for av_dict_set that converts the value to a string + * and stores it. + * + * Note: If AV_DICT_DONT_STRDUP_KEY is set, key will be freed on error. + */ +int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags); + +/** + * Parse the key/value pairs list and add the parsed entries to a dictionary. + * + * In case of failure, all the successfully set entries are stored in + * *pm. You may need to manually free the created dictionary. + * + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other + * @param flags flags to use when adding to dictionary. + * AV_DICT_DONT_STRDUP_KEY and AV_DICT_DONT_STRDUP_VAL + * are ignored since the key/value tokens will always + * be duplicated. + * @return 0 on success, negative AVERROR code on failure + */ +int av_dict_parse_string(AVDictionary **pm, const char *str, + const char *key_val_sep, const char *pairs_sep, + int flags); + +/** + * Copy entries from one AVDictionary struct into another. + * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL, + * this function will allocate a struct for you and put it in *dst + * @param src pointer to source AVDictionary struct + * @param flags flags to use when setting entries in *dst + * @note metadata is read using the AV_DICT_IGNORE_SUFFIX flag + * @return 0 on success, negative AVERROR code on failure. If dst was allocated + * by this function, callers should free the associated memory. + */ +int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags); + +/** + * Free all the memory allocated for an AVDictionary struct + * and all keys and values. + */ +void av_dict_free(AVDictionary **m); + +/** + * Get dictionary entries as a string. + * + * Create a string containing dictionary's entries. + * Such string may be passed back to av_dict_parse_string(). + * @note String is escaped with backslashes ('\'). + * + * @param[in] m dictionary + * @param[out] buffer Pointer to buffer that will be allocated with string containg entries. + * Buffer must be freed by the caller when is no longer needed. + * @param[in] key_val_sep character used to separate key from value + * @param[in] pairs_sep character used to separate two pairs from each other + * @return >= 0 on success, negative on error + * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same. + */ +int av_dict_get_string(const AVDictionary *m, char **buffer, + const char key_val_sep, const char pairs_sep); + +/** + * @} + */ + +#endif /* AVUTIL_DICT_H */ diff --git a/ffmpeg/inc/libavutil/display.h b/ffmpeg/inc/libavutil/display.h new file mode 100644 index 0000000..515adad --- /dev/null +++ b/ffmpeg/inc/libavutil/display.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Display matrix + */ + +#ifndef AVUTIL_DISPLAY_H +#define AVUTIL_DISPLAY_H + +#include +#include "common.h" + +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_display Display transformation matrix functions + * @{ + */ + +/** + * @addtogroup lavu_video_display + * The display transformation matrix specifies an affine transformation that + * should be applied to video frames for correct presentation. It is compatible + * with the matrices stored in the ISO/IEC 14496-12 container format. + * + * The data is a 3x3 matrix represented as a 9-element array: + * + * @code{.unparsed} + * | a b u | + * (a, b, u, c, d, v, x, y, w) -> | c d v | + * | x y w | + * @endcode + * + * All numbers are stored in native endianness, as 16.16 fixed-point values, + * except for u, v and w, which are stored as 2.30 fixed-point values. + * + * The transformation maps a point (p, q) in the source (pre-transformation) + * frame to the point (p', q') in the destination (post-transformation) frame as + * follows: + * + * @code{.unparsed} + * | a b u | + * (p, q, 1) . | c d v | = z * (p', q', 1) + * | x y w | + * @endcode + * + * The transformation can also be more explicitly written in components as + * follows: + * + * @code{.unparsed} + * p' = (a * p + c * q + x) / z; + * q' = (b * p + d * q + y) / z; + * z = u * p + v * q + w + * @endcode + */ + +/** + * Extract the rotation component of the transformation matrix. + * + * @param matrix the transformation matrix + * @return the angle (in degrees) by which the transformation rotates the frame + * counterclockwise. The angle will be in range [-180.0, 180.0], + * or NaN if the matrix is singular. + * + * @note floating point numbers are inherently inexact, so callers are + * recommended to round the return value to nearest integer before use. + */ +double av_display_rotation_get(const int32_t matrix[9]); + +/** + * Initialize a transformation matrix describing a pure counterclockwise + * rotation by the specified angle (in degrees). + * + * @param matrix an allocated transformation matrix (will be fully overwritten + * by this function) + * @param angle rotation angle in degrees. + */ +void av_display_rotation_set(int32_t matrix[9], double angle); + +/** + * Flip the input matrix horizontally and/or vertically. + * + * @param matrix an allocated transformation matrix + * @param hflip whether the matrix should be flipped horizontally + * @param vflip whether the matrix should be flipped vertically + */ +void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_DISPLAY_H */ diff --git a/ffmpeg/inc/libavutil/dovi_meta.h b/ffmpeg/inc/libavutil/dovi_meta.h new file mode 100644 index 0000000..299911d --- /dev/null +++ b/ffmpeg/inc/libavutil/dovi_meta.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020 Vacing Fang + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * DOVI configuration + */ + + +#ifndef AVUTIL_DOVI_META_H +#define AVUTIL_DOVI_META_H + +#include +#include + +/* + * DOVI configuration + * ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.1.2 + dolby-vision-bitstreams-in-mpeg-2-transport-stream-multiplex-v1.2 + * @code + * uint8_t dv_version_major, the major version number that the stream complies with + * uint8_t dv_version_minor, the minor version number that the stream complies with + * uint8_t dv_profile, the Dolby Vision profile + * uint8_t dv_level, the Dolby Vision level + * uint8_t rpu_present_flag + * uint8_t el_present_flag + * uint8_t bl_present_flag + * uint8_t dv_bl_signal_compatibility_id + * @endcode + * + * @note The struct must be allocated with av_dovi_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVDOVIDecoderConfigurationRecord { + uint8_t dv_version_major; + uint8_t dv_version_minor; + uint8_t dv_profile; + uint8_t dv_level; + uint8_t rpu_present_flag; + uint8_t el_present_flag; + uint8_t bl_present_flag; + uint8_t dv_bl_signal_compatibility_id; +} AVDOVIDecoderConfigurationRecord; + +/** + * Allocate a AVDOVIDecoderConfigurationRecord structure and initialize its + * fields to default values. + * + * @return the newly allocated struct or NULL on failure + */ +AVDOVIDecoderConfigurationRecord *av_dovi_alloc(size_t *size); + +#endif /* AVUTIL_DOVI_META_H */ diff --git a/ffmpeg/inc/libavutil/downmix_info.h b/ffmpeg/inc/libavutil/downmix_info.h new file mode 100644 index 0000000..221cf5b --- /dev/null +++ b/ffmpeg/inc/libavutil/downmix_info.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 Tim Walker + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_DOWNMIX_INFO_H +#define AVUTIL_DOWNMIX_INFO_H + +#include "frame.h" + +/** + * @file + * audio downmix medatata + */ + +/** + * @addtogroup lavu_audio + * @{ + */ + +/** + * @defgroup downmix_info Audio downmix metadata + * @{ + */ + +/** + * Possible downmix types. + */ +enum AVDownmixType { + AV_DOWNMIX_TYPE_UNKNOWN, /**< Not indicated. */ + AV_DOWNMIX_TYPE_LORO, /**< Lo/Ro 2-channel downmix (Stereo). */ + AV_DOWNMIX_TYPE_LTRT, /**< Lt/Rt 2-channel downmix, Dolby Surround compatible. */ + AV_DOWNMIX_TYPE_DPLII, /**< Lt/Rt 2-channel downmix, Dolby Pro Logic II compatible. */ + AV_DOWNMIX_TYPE_NB /**< Number of downmix types. Not part of ABI. */ +}; + +/** + * This structure describes optional metadata relevant to a downmix procedure. + * + * All fields are set by the decoder to the value indicated in the audio + * bitstream (if present), or to a "sane" default otherwise. + */ +typedef struct AVDownmixInfo { + /** + * Type of downmix preferred by the mastering engineer. + */ + enum AVDownmixType preferred_downmix_type; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during a regular downmix. + */ + double center_mix_level; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during an Lt/Rt compatible downmix. + */ + double center_mix_level_ltrt; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during a regular downmix. + */ + double surround_mix_level; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during an Lt/Rt compatible downmix. + */ + double surround_mix_level_ltrt; + + /** + * Absolute scale factor representing the level at which the LFE data is + * mixed into L/R channels during downmixing. + */ + double lfe_mix_level; +} AVDownmixInfo; + +/** + * Get a frame's AV_FRAME_DATA_DOWNMIX_INFO side data for editing. + * + * If the side data is absent, it is created and added to the frame. + * + * @param frame the frame for which the side data is to be obtained or created + * + * @return the AVDownmixInfo structure to be edited by the caller, or NULL if + * the structure cannot be allocated. + */ +AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame); + +/** + * @} + */ + +/** + * @} + */ + +#endif /* AVUTIL_DOWNMIX_INFO_H */ diff --git a/ffmpeg/inc/libavutil/encryption_info.h b/ffmpeg/inc/libavutil/encryption_info.h new file mode 100644 index 0000000..8fe7ebf --- /dev/null +++ b/ffmpeg/inc/libavutil/encryption_info.h @@ -0,0 +1,205 @@ +/** + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_ENCRYPTION_INFO_H +#define AVUTIL_ENCRYPTION_INFO_H + +#include +#include + +typedef struct AVSubsampleEncryptionInfo { + /** The number of bytes that are clear. */ + unsigned int bytes_of_clear_data; + + /** + * The number of bytes that are protected. If using pattern encryption, + * the pattern applies to only the protected bytes; if not using pattern + * encryption, all these bytes are encrypted. + */ + unsigned int bytes_of_protected_data; +} AVSubsampleEncryptionInfo; + +/** + * This describes encryption info for a packet. This contains frame-specific + * info for how to decrypt the packet before passing it to the decoder. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInfo { + /** The fourcc encryption scheme, in big-endian byte order. */ + uint32_t scheme; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are encrypted. + */ + uint32_t crypt_byte_block; + + /** + * Only used for pattern encryption. This is the number of 16-byte blocks + * that are clear. + */ + uint32_t skip_byte_block; + + /** + * The ID of the key used to encrypt the packet. This should always be + * 16 bytes long, but may be changed in the future. + */ + uint8_t *key_id; + uint32_t key_id_size; + + /** + * The initialization vector. This may have been zero-filled to be the + * correct block size. This should always be 16 bytes long, but may be + * changed in the future. + */ + uint8_t *iv; + uint32_t iv_size; + + /** + * An array of subsample encryption info specifying how parts of the sample + * are encrypted. If there are no subsamples, then the whole sample is + * encrypted. + */ + AVSubsampleEncryptionInfo *subsamples; + uint32_t subsample_count; +} AVEncryptionInfo; + +/** + * This describes info used to initialize an encryption key system. + * + * The size of this struct is not part of the public ABI. + */ +typedef struct AVEncryptionInitInfo { + /** + * A unique identifier for the key system this is for, can be NULL if it + * is not known. This should always be 16 bytes, but may change in the + * future. + */ + uint8_t* system_id; + uint32_t system_id_size; + + /** + * An array of key IDs this initialization data is for. All IDs are the + * same length. Can be NULL if there are no known key IDs. + */ + uint8_t** key_ids; + /** The number of key IDs. */ + uint32_t num_key_ids; + /** + * The number of bytes in each key ID. This should always be 16, but may + * change in the future. + */ + uint32_t key_id_size; + + /** + * Key-system specific initialization data. This data is copied directly + * from the file and the format depends on the specific key system. This + * can be NULL if there is no initialization data; in that case, there + * will be at least one key ID. + */ + uint8_t* data; + uint32_t data_size; + + /** + * An optional pointer to the next initialization info in the list. + */ + struct AVEncryptionInitInfo *next; +} AVEncryptionInitInfo; + +/** + * Allocates an AVEncryptionInfo structure and sub-pointers to hold the given + * number of subsamples. This will allocate pointers for the key ID, IV, + * and subsample entries, set the size members, and zero-initialize the rest. + * + * @param subsample_count The number of subsamples. + * @param key_id_size The number of bytes in the key ID, should be 16. + * @param iv_size The number of bytes in the IV, should be 16. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size); + +/** + * Allocates an AVEncryptionInfo structure with a copy of the given data. + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info); + +/** + * Frees the given encryption info object. This MUST NOT be used to free the + * side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_info_free(AVEncryptionInfo *info); + +/** + * Creates a copy of the AVEncryptionInfo that is contained in the given side + * data. The resulting object should be passed to av_encryption_info_free() + * when done. + * + * @return The new AVEncryptionInfo structure, or NULL on error. + */ +AVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t *side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * info. The resulting pointer should be either freed using av_free or given + * to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_info_add_side_data( + const AVEncryptionInfo *info, size_t *side_data_size); + + +/** + * Allocates an AVEncryptionInitInfo structure and sub-pointers to hold the + * given sizes. This will allocate pointers and set all the fields. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_alloc( + uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size); + +/** + * Frees the given encryption init info object. This MUST NOT be used to free + * the side-data data pointer, that should use normal side-data methods. + */ +void av_encryption_init_info_free(AVEncryptionInitInfo* info); + +/** + * Creates a copy of the AVEncryptionInitInfo that is contained in the given + * side data. The resulting object should be passed to + * av_encryption_init_info_free() when done. + * + * @return The new AVEncryptionInitInfo structure, or NULL on error. + */ +AVEncryptionInitInfo *av_encryption_init_info_get_side_data( + const uint8_t* side_data, size_t side_data_size); + +/** + * Allocates and initializes side data that holds a copy of the given encryption + * init info. The resulting pointer should be either freed using av_free or + * given to av_packet_add_side_data(). + * + * @return The new side-data pointer, or NULL. + */ +uint8_t *av_encryption_init_info_add_side_data( + const AVEncryptionInitInfo *info, size_t *side_data_size); + +#endif /* AVUTIL_ENCRYPTION_INFO_H */ diff --git a/ffmpeg/inc/libavutil/error.h b/ffmpeg/inc/libavutil/error.h new file mode 100644 index 0000000..71df4da --- /dev/null +++ b/ffmpeg/inc/libavutil/error.h @@ -0,0 +1,126 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * error code definitions + */ + +#ifndef AVUTIL_ERROR_H +#define AVUTIL_ERROR_H + +#include +#include + +/** + * @addtogroup lavu_error + * + * @{ + */ + + +/* error handling */ +#if EDOM > 0 +#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. +#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. +#else +/* Some platforms have E* and errno already negated. */ +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif + +#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d)) + +#define AVERROR_BSF_NOT_FOUND FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found +#define AVERROR_BUG FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2 +#define AVERROR_BUFFER_TOO_SMALL FFERRTAG( 'B','U','F','S') ///< Buffer too small +#define AVERROR_DECODER_NOT_FOUND FFERRTAG(0xF8,'D','E','C') ///< Decoder not found +#define AVERROR_DEMUXER_NOT_FOUND FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found +#define AVERROR_ENCODER_NOT_FOUND FFERRTAG(0xF8,'E','N','C') ///< Encoder not found +#define AVERROR_EOF FFERRTAG( 'E','O','F',' ') ///< End of file +#define AVERROR_EXIT FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted +#define AVERROR_EXTERNAL FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library +#define AVERROR_FILTER_NOT_FOUND FFERRTAG(0xF8,'F','I','L') ///< Filter not found +#define AVERROR_INVALIDDATA FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input +#define AVERROR_MUXER_NOT_FOUND FFERRTAG(0xF8,'M','U','X') ///< Muxer not found +#define AVERROR_OPTION_NOT_FOUND FFERRTAG(0xF8,'O','P','T') ///< Option not found +#define AVERROR_PATCHWELCOME FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome +#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found + +#define AVERROR_STREAM_NOT_FOUND FFERRTAG(0xF8,'S','T','R') ///< Stream not found +/** + * This is semantically identical to AVERROR_BUG + * it has been introduced in Libav after our AVERROR_BUG and with a modified value. + */ +#define AVERROR_BUG2 FFERRTAG( 'B','U','G',' ') +#define AVERROR_UNKNOWN FFERRTAG( 'U','N','K','N') ///< Unknown error, typically from an external library +#define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it. +#define AVERROR_INPUT_CHANGED (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED) +#define AVERROR_OUTPUT_CHANGED (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED) +/* HTTP & RTSP errors */ +#define AVERROR_HTTP_BAD_REQUEST FFERRTAG(0xF8,'4','0','0') +#define AVERROR_HTTP_UNAUTHORIZED FFERRTAG(0xF8,'4','0','1') +#define AVERROR_HTTP_FORBIDDEN FFERRTAG(0xF8,'4','0','3') +#define AVERROR_HTTP_NOT_FOUND FFERRTAG(0xF8,'4','0','4') +#define AVERROR_HTTP_OTHER_4XX FFERRTAG(0xF8,'4','X','X') +#define AVERROR_HTTP_SERVER_ERROR FFERRTAG(0xF8,'5','X','X') + +#define AV_ERROR_MAX_STRING_SIZE 64 + +/** + * Put a description of the AVERROR code errnum in errbuf. + * In case of failure the global variable errno is set to indicate the + * error. Even in case of failure av_strerror() will print a generic + * error message indicating the errnum provided to errbuf. + * + * @param errnum error code to describe + * @param errbuf buffer to which description is written + * @param errbuf_size the size in bytes of errbuf + * @return 0 on success, a negative value if a description for errnum + * cannot be found + */ +int av_strerror(int errnum, char *errbuf, size_t errbuf_size); + +/** + * Fill the provided buffer with a string containing an error string + * corresponding to the AVERROR code errnum. + * + * @param errbuf a buffer + * @param errbuf_size size in bytes of errbuf + * @param errnum error code to describe + * @return the buffer in input, filled with the error description + * @see av_strerror() + */ +static inline char *av_make_error_string(char *errbuf, size_t errbuf_size, int errnum) +{ + av_strerror(errnum, errbuf, errbuf_size); + return errbuf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_err2str(errnum) \ + av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum) + +/** + * @} + */ + +#endif /* AVUTIL_ERROR_H */ diff --git a/ffmpeg/inc/libavutil/eval.h b/ffmpeg/inc/libavutil/eval.h new file mode 100644 index 0000000..068c62c --- /dev/null +++ b/ffmpeg/inc/libavutil/eval.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2002 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * simple arithmetic expression evaluator + */ + +#ifndef AVUTIL_EVAL_H +#define AVUTIL_EVAL_H + +#include "avutil.h" + +typedef struct AVExpr AVExpr; + +/** + * Parse and evaluate an expression. + * Note, this is significantly slower than av_expr_eval(). + * + * @param res a pointer to a double where is put the result value of + * the expression, or NAN in case of error + * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)" + * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0} + * @param const_values a zero terminated array of values for the identifiers from const_names + * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers + * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers + * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments + * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2 + * @param log_ctx parent logging context + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_expr_parse_and_eval(double *res, const char *s, + const char * const *const_names, const double *const_values, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + void *opaque, int log_offset, void *log_ctx); + +/** + * Parse an expression. + * + * @param expr a pointer where is put an AVExpr containing the parsed + * value in case of successful parsing, or NULL otherwise. + * The pointed to AVExpr must be freed with av_expr_free() by the user + * when it is not needed anymore. + * @param s expression as a zero terminated string, for example "1+2^3+5*5+sin(2/3)" + * @param const_names NULL terminated array of zero terminated strings of constant identifiers, for example {"PI", "E", 0} + * @param func1_names NULL terminated array of zero terminated strings of funcs1 identifiers + * @param funcs1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2_names NULL terminated array of zero terminated strings of funcs2 identifiers + * @param funcs2 NULL terminated array of function pointers for functions which take 2 arguments + * @param log_ctx parent logging context + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_expr_parse(AVExpr **expr, const char *s, + const char * const *const_names, + const char * const *func1_names, double (* const *funcs1)(void *, double), + const char * const *func2_names, double (* const *funcs2)(void *, double, double), + int log_offset, void *log_ctx); + +/** + * Evaluate a previously parsed expression. + * + * @param const_values a zero terminated array of values for the identifiers from av_expr_parse() const_names + * @param opaque a pointer which will be passed to all functions from funcs1 and funcs2 + * @return the value of the expression + */ +double av_expr_eval(AVExpr *e, const double *const_values, void *opaque); + +/** + * Track the presence of variables and their number of occurrences in a parsed expression + * + * @param counter a zero-initialized array where the count of each variable will be stored + * @param size size of array + * @return 0 on success, a negative value indicates that no expression or array was passed + * or size was zero + */ +int av_expr_count_vars(AVExpr *e, unsigned *counter, int size); + +/** + * Track the presence of user provided functions and their number of occurrences + * in a parsed expression. + * + * @param counter a zero-initialized array where the count of each function will be stored + * if you passed 5 functions with 2 arguments to av_expr_parse() + * then for arg=2 this will use upto 5 entries. + * @param size size of array + * @param arg number of arguments the counted functions have + * @return 0 on success, a negative value indicates that no expression or array was passed + * or size was zero + */ +int av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg); + +/** + * Free a parsed expression previously created with av_expr_parse(). + */ +void av_expr_free(AVExpr *e); + +/** + * Parse the string in numstr and return its value as a double. If + * the string is empty, contains only whitespaces, or does not contain + * an initial substring that has the expected syntax for a + * floating-point number, no conversion is performed. In this case, + * returns a value of zero and the value returned in tail is the value + * of numstr. + * + * @param numstr a string representing a number, may contain one of + * the International System number postfixes, for example 'K', 'M', + * 'G'. If 'i' is appended after the postfix, powers of 2 are used + * instead of powers of 10. The 'B' postfix multiplies the value by + * 8, and can be appended after another postfix or used alone. This + * allows using for example 'KB', 'MiB', 'G' and 'B' as postfix. + * @param tail if non-NULL puts here the pointer to the char next + * after the last parsed character + */ +double av_strtod(const char *numstr, char **tail); + +#endif /* AVUTIL_EVAL_H */ diff --git a/ffmpeg/inc/libavutil/ffversion.h b/ffmpeg/inc/libavutil/ffversion.h new file mode 100644 index 0000000..fc30482 --- /dev/null +++ b/ffmpeg/inc/libavutil/ffversion.h @@ -0,0 +1,5 @@ +/* Automatically generated by version.sh, do not manually edit! */ +#ifndef AVUTIL_FFVERSION_H +#define AVUTIL_FFVERSION_H +#define FFMPEG_VERSION "4.3.1" +#endif /* AVUTIL_FFVERSION_H */ diff --git a/ffmpeg/inc/libavutil/fifo.h b/ffmpeg/inc/libavutil/fifo.h new file mode 100644 index 0000000..dc7bc6f --- /dev/null +++ b/ffmpeg/inc/libavutil/fifo.h @@ -0,0 +1,179 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * a very simple circular buffer FIFO implementation + */ + +#ifndef AVUTIL_FIFO_H +#define AVUTIL_FIFO_H + +#include +#include "avutil.h" +#include "attributes.h" + +typedef struct AVFifoBuffer { + uint8_t *buffer; + uint8_t *rptr, *wptr, *end; + uint32_t rndx, wndx; +} AVFifoBuffer; + +/** + * Initialize an AVFifoBuffer. + * @param size of FIFO + * @return AVFifoBuffer or NULL in case of memory allocation failure + */ +AVFifoBuffer *av_fifo_alloc(unsigned int size); + +/** + * Initialize an AVFifoBuffer. + * @param nmemb number of elements + * @param size size of the single element + * @return AVFifoBuffer or NULL in case of memory allocation failure + */ +AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size); + +/** + * Free an AVFifoBuffer. + * @param f AVFifoBuffer to free + */ +void av_fifo_free(AVFifoBuffer *f); + +/** + * Free an AVFifoBuffer and reset pointer to NULL. + * @param f AVFifoBuffer to free + */ +void av_fifo_freep(AVFifoBuffer **f); + +/** + * Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied. + * @param f AVFifoBuffer to reset + */ +void av_fifo_reset(AVFifoBuffer *f); + +/** + * Return the amount of data in bytes in the AVFifoBuffer, that is the + * amount of data you can read from it. + * @param f AVFifoBuffer to read from + * @return size + */ +int av_fifo_size(const AVFifoBuffer *f); + +/** + * Return the amount of space in bytes in the AVFifoBuffer, that is the + * amount of data you can write into it. + * @param f AVFifoBuffer to write into + * @return size + */ +int av_fifo_space(const AVFifoBuffer *f); + +/** + * Feed data at specific position from an AVFifoBuffer to a user-supplied callback. + * Similar as av_fifo_gereric_read but without discarding data. + * @param f AVFifoBuffer to read from + * @param offset offset from current read position + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + */ +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from an AVFifoBuffer to a user-supplied callback. + * Similar as av_fifo_gereric_read but without discarding data. + * @param f AVFifoBuffer to read from + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + */ +int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from an AVFifoBuffer to a user-supplied callback. + * @param f AVFifoBuffer to read from + * @param buf_size number of bytes to read + * @param func generic read function + * @param dest data destination + */ +int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); + +/** + * Feed data from a user-supplied callback to an AVFifoBuffer. + * @param f AVFifoBuffer to write to + * @param src data source; non-const since it may be used as a + * modifiable context by the function defined in func + * @param size number of bytes to write + * @param func generic write function; the first parameter is src, + * the second is dest_buf, the third is dest_buf_size. + * func must return the number of bytes written to dest_buf, or <= 0 to + * indicate no more data available to write. + * If func is NULL, src is interpreted as a simple byte array for source data. + * @return the number of bytes written to the FIFO + */ +int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)); + +/** + * Resize an AVFifoBuffer. + * In case of reallocation failure, the old FIFO is kept unchanged. + * + * @param f AVFifoBuffer to resize + * @param size new AVFifoBuffer size in bytes + * @return <0 for failure, >=0 otherwise + */ +int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size); + +/** + * Enlarge an AVFifoBuffer. + * In case of reallocation failure, the old FIFO is kept unchanged. + * The new fifo size may be larger than the requested size. + * + * @param f AVFifoBuffer to resize + * @param additional_space the amount of space in bytes to allocate in addition to av_fifo_size() + * @return <0 for failure, >=0 otherwise + */ +int av_fifo_grow(AVFifoBuffer *f, unsigned int additional_space); + +/** + * Read and discard the specified amount of data from an AVFifoBuffer. + * @param f AVFifoBuffer to read from + * @param size amount of data to read in bytes + */ +void av_fifo_drain(AVFifoBuffer *f, int size); + +/** + * Return a pointer to the data stored in a FIFO buffer at a certain offset. + * The FIFO buffer is not modified. + * + * @param f AVFifoBuffer to peek at, f must be non-NULL + * @param offs an offset in bytes, its absolute value must be less + * than the used buffer size or the returned pointer will + * point outside to the buffer data. + * The used buffer size can be checked with av_fifo_size(). + */ +static inline uint8_t *av_fifo_peek2(const AVFifoBuffer *f, int offs) +{ + uint8_t *ptr = f->rptr + offs; + if (ptr >= f->end) + ptr = f->buffer + (ptr - f->end); + else if (ptr < f->buffer) + ptr = f->end - (f->buffer - ptr); + return ptr; +} + +#endif /* AVUTIL_FIFO_H */ diff --git a/ffmpeg/inc/libavutil/file.h b/ffmpeg/inc/libavutil/file.h new file mode 100644 index 0000000..3ef4a60 --- /dev/null +++ b/ffmpeg/inc/libavutil/file.h @@ -0,0 +1,71 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_FILE_H +#define AVUTIL_FILE_H + +#include + +#include "avutil.h" + +/** + * @file + * Misc file utilities. + */ + +/** + * Read the file with name filename, and put its content in a newly + * allocated buffer or map it with mmap() when available. + * In case of success set *bufptr to the read or mmapped buffer, and + * *size to the size in bytes of the buffer in *bufptr. + * Unlike mmap this function succeeds with zero sized files, in this + * case *bufptr will be set to NULL and *size will be set to 0. + * The returned buffer must be released with av_file_unmap(). + * + * @param log_offset loglevel offset used for logging + * @param log_ctx context used for logging + * @return a non negative number in case of success, a negative value + * corresponding to an AVERROR error code in case of failure + */ +av_warn_unused_result +int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, + int log_offset, void *log_ctx); + +/** + * Unmap or free the buffer bufptr created by av_file_map(). + * + * @param size size in bytes of bufptr, must be the same as returned + * by av_file_map() + */ +void av_file_unmap(uint8_t *bufptr, size_t size); + +/** + * Wrapper to work around the lack of mkstemp() on mingw. + * Also, tries to create file in /tmp first, if possible. + * *prefix can be a character constant; *filename will be allocated internally. + * @return file descriptor of opened file (or negative value corresponding to an + * AVERROR code on error) + * and opened file name in **filename. + * @note On very old libcs it is necessary to set a secure umask before + * calling this, av_tempfile() can't call umask itself as it is used in + * libraries and could interfere with the calling application. + * @deprecated as fd numbers cannot be passed saftely between libs on some platforms + */ +int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx); + +#endif /* AVUTIL_FILE_H */ diff --git a/ffmpeg/inc/libavutil/frame.h b/ffmpeg/inc/libavutil/frame.h new file mode 100644 index 0000000..fc67db0 --- /dev/null +++ b/ffmpeg/inc/libavutil/frame.h @@ -0,0 +1,975 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_frame + * reference-counted frame API + */ + +#ifndef AVUTIL_FRAME_H +#define AVUTIL_FRAME_H + +#include +#include + +#include "avutil.h" +#include "buffer.h" +#include "dict.h" +#include "rational.h" +#include "samplefmt.h" +#include "pixfmt.h" +#include "version.h" + + +/** + * @defgroup lavu_frame AVFrame + * @ingroup lavu_data + * + * @{ + * AVFrame is an abstraction for reference-counted raw multimedia data. + */ + +enum AVFrameSideDataType { + /** + * The data is the AVPanScan struct defined in libavcodec. + */ + AV_FRAME_DATA_PANSCAN, + /** + * ATSC A53 Part 4 Closed Captions. + * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data. + * The number of bytes of CC data is AVFrameSideData.size. + */ + AV_FRAME_DATA_A53_CC, + /** + * Stereoscopic 3d metadata. + * The data is the AVStereo3D struct defined in libavutil/stereo3d.h. + */ + AV_FRAME_DATA_STEREO3D, + /** + * The data is the AVMatrixEncoding enum defined in libavutil/channel_layout.h. + */ + AV_FRAME_DATA_MATRIXENCODING, + /** + * Metadata relevant to a downmix procedure. + * The data is the AVDownmixInfo struct defined in libavutil/downmix_info.h. + */ + AV_FRAME_DATA_DOWNMIX_INFO, + /** + * ReplayGain information in the form of the AVReplayGain struct. + */ + AV_FRAME_DATA_REPLAYGAIN, + /** + * This side data contains a 3x3 transformation matrix describing an affine + * transformation that needs to be applied to the frame for correct + * presentation. + * + * See libavutil/display.h for a detailed description of the data. + */ + AV_FRAME_DATA_DISPLAYMATRIX, + /** + * Active Format Description data consisting of a single byte as specified + * in ETSI TS 101 154 using AVActiveFormatDescription enum. + */ + AV_FRAME_DATA_AFD, + /** + * Motion vectors exported by some codecs (on demand through the export_mvs + * flag set in the libavcodec AVCodecContext flags2 option). + * The data is the AVMotionVector struct defined in + * libavutil/motion_vector.h. + */ + AV_FRAME_DATA_MOTION_VECTORS, + /** + * Recommmends skipping the specified number of samples. This is exported + * only if the "skip_manual" AVOption is set in libavcodec. + * This has the same format as AV_PKT_DATA_SKIP_SAMPLES. + * @code + * u32le number of samples to skip from start of this packet + * u32le number of samples to skip from end of this packet + * u8 reason for start skip + * u8 reason for end skip (0=padding silence, 1=convergence) + * @endcode + */ + AV_FRAME_DATA_SKIP_SAMPLES, + /** + * This side data must be associated with an audio frame and corresponds to + * enum AVAudioServiceType defined in avcodec.h. + */ + AV_FRAME_DATA_AUDIO_SERVICE_TYPE, + /** + * Mastering display metadata associated with a video frame. The payload is + * an AVMasteringDisplayMetadata type and contains information about the + * mastering display color volume. + */ + AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, + /** + * The GOP timecode in 25 bit timecode format. Data format is 64-bit integer. + * This is set on the first frame of a GOP that has a temporal reference of 0. + */ + AV_FRAME_DATA_GOP_TIMECODE, + + /** + * The data represents the AVSphericalMapping structure defined in + * libavutil/spherical.h. + */ + AV_FRAME_DATA_SPHERICAL, + + /** + * Content light level (based on CTA-861.3). This payload contains data in + * the form of the AVContentLightMetadata struct. + */ + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + + /** + * The data contains an ICC profile as an opaque octet buffer following the + * format described by ISO 15076-1 with an optional name defined in the + * metadata key entry "name". + */ + AV_FRAME_DATA_ICC_PROFILE, + +#if FF_API_FRAME_QP + /** + * Implementation-specific description of the format of AV_FRAME_QP_TABLE_DATA. + * The contents of this side data are undocumented and internal; use + * av_frame_set_qp_table() and av_frame_get_qp_table() to access this in a + * meaningful way instead. + */ + AV_FRAME_DATA_QP_TABLE_PROPERTIES, + + /** + * Raw QP table data. Its format is described by + * AV_FRAME_DATA_QP_TABLE_PROPERTIES. Use av_frame_set_qp_table() and + * av_frame_get_qp_table() to access this instead. + */ + AV_FRAME_DATA_QP_TABLE_DATA, +#endif + + /** + * Timecode which conforms to SMPTE ST 12-1. The data is an array of 4 uint32_t + * where the first uint32_t describes how many (1-3) of the other timecodes are used. + * The timecode format is described in the av_timecode_get_smpte_from_framenum() + * function in libavutil/timecode.c. + */ + AV_FRAME_DATA_S12M_TIMECODE, + + /** + * HDR dynamic metadata associated with a video frame. The payload is + * an AVDynamicHDRPlus type and contains information for color + * volume transform - application 4 of SMPTE 2094-40:2016 standard. + */ + AV_FRAME_DATA_DYNAMIC_HDR_PLUS, + + /** + * Regions Of Interest, the data is an array of AVRegionOfInterest type, the number of + * array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size. + */ + AV_FRAME_DATA_REGIONS_OF_INTEREST, + + /** + * Encoding parameters for a video frame, as described by AVVideoEncParams. + */ + AV_FRAME_DATA_VIDEO_ENC_PARAMS, +}; + +enum AVActiveFormatDescription { + AV_AFD_SAME = 8, + AV_AFD_4_3 = 9, + AV_AFD_16_9 = 10, + AV_AFD_14_9 = 11, + AV_AFD_4_3_SP_14_9 = 13, + AV_AFD_16_9_SP_14_9 = 14, + AV_AFD_SP_4_3 = 15, +}; + + +/** + * Structure to hold side data for an AVFrame. + * + * sizeof(AVFrameSideData) is not a part of the public ABI, so new fields may be added + * to the end with a minor bump. + */ +typedef struct AVFrameSideData { + enum AVFrameSideDataType type; + uint8_t *data; + int size; + AVDictionary *metadata; + AVBufferRef *buf; +} AVFrameSideData; + +/** + * Structure describing a single Region Of Interest. + * + * When multiple regions are defined in a single side-data block, they + * should be ordered from most to least important - some encoders are only + * capable of supporting a limited number of distinct regions, so will have + * to truncate the list. + * + * When overlapping regions are defined, the first region containing a given + * area of the frame applies. + */ +typedef struct AVRegionOfInterest { + /** + * Must be set to the size of this data structure (that is, + * sizeof(AVRegionOfInterest)). + */ + uint32_t self_size; + /** + * Distance in pixels from the top edge of the frame to the top and + * bottom edges and from the left edge of the frame to the left and + * right edges of the rectangle defining this region of interest. + * + * The constraints on a region are encoder dependent, so the region + * actually affected may be slightly larger for alignment or other + * reasons. + */ + int top; + int bottom; + int left; + int right; + /** + * Quantisation offset. + * + * Must be in the range -1 to +1. A value of zero indicates no quality + * change. A negative value asks for better quality (less quantisation), + * while a positive value asks for worse quality (greater quantisation). + * + * The range is calibrated so that the extreme values indicate the + * largest possible offset - if the rest of the frame is encoded with the + * worst possible quality, an offset of -1 indicates that this region + * should be encoded with the best possible quality anyway. Intermediate + * values are then interpolated in some codec-dependent way. + * + * For example, in 10-bit H.264 the quantisation parameter varies between + * -12 and 51. A typical qoffset value of -1/10 therefore indicates that + * this region should be encoded with a QP around one-tenth of the full + * range better than the rest of the frame. So, if most of the frame + * were to be encoded with a QP of around 30, this region would get a QP + * of around 24 (an offset of approximately -1/10 * (51 - -12) = -6.3). + * An extreme value of -1 would indicate that this region should be + * encoded with the best possible quality regardless of the treatment of + * the rest of the frame - that is, should be encoded at a QP of -12. + */ + AVRational qoffset; +} AVRegionOfInterest; + +/** + * This structure describes decoded (raw) audio or video data. + * + * AVFrame must be allocated using av_frame_alloc(). Note that this only + * allocates the AVFrame itself, the buffers for the data must be managed + * through other means (see below). + * AVFrame must be freed with av_frame_free(). + * + * AVFrame is typically allocated once and then reused multiple times to hold + * different data (e.g. a single AVFrame to hold frames received from a + * decoder). In such a case, av_frame_unref() will free any references held by + * the frame and reset it to its original clean state before it + * is reused again. + * + * The data described by an AVFrame is usually reference counted through the + * AVBuffer API. The underlying buffer references are stored in AVFrame.buf / + * AVFrame.extended_buf. An AVFrame is considered to be reference counted if at + * least one reference is set, i.e. if AVFrame.buf[0] != NULL. In such a case, + * every single data plane must be contained in one of the buffers in + * AVFrame.buf or AVFrame.extended_buf. + * There may be a single buffer for all the data, or one separate buffer for + * each plane, or anything in between. + * + * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added + * to the end with a minor bump. + * + * Fields can be accessed through AVOptions, the name string used, matches the + * C structure field name for fields accessible through AVOptions. The AVClass + * for AVFrame can be obtained from avcodec_get_frame_class() + */ +typedef struct AVFrame { +#define AV_NUM_DATA_POINTERS 8 + /** + * pointer to the picture/channel planes. + * This might be different from the first allocated byte + * + * Some decoders access areas outside 0,0 - width,height, please + * see avcodec_align_dimensions2(). Some filters and swscale can read + * up to 16 bytes beyond the planes, if these filters are to be used, + * then 16 extra bytes must be allocated. + * + * NOTE: Except for hwaccel formats, pointers not needed by the format + * MUST be set to NULL. + */ + uint8_t *data[AV_NUM_DATA_POINTERS]; + + /** + * For video, size in bytes of each picture line. + * For audio, size in bytes of each plane. + * + * For audio, only linesize[0] may be set. For planar audio, each channel + * plane must be the same size. + * + * For video the linesizes should be multiples of the CPUs alignment + * preference, this is 16 or 32 for modern desktop CPUs. + * Some code requires such alignment other code can be slower without + * correct alignment, for yet other it makes no difference. + * + * @note The linesize may be larger than the size of usable data -- there + * may be extra padding present for performance reasons. + */ + int linesize[AV_NUM_DATA_POINTERS]; + + /** + * pointers to the data planes/channels. + * + * For video, this should simply point to data[]. + * + * For planar audio, each channel has a separate data pointer, and + * linesize[0] contains the size of each channel buffer. + * For packed audio, there is just one data pointer, and linesize[0] + * contains the total size of the buffer for all channels. + * + * Note: Both data and extended_data should always be set in a valid frame, + * but for planar audio with more channels that can fit in data, + * extended_data must be used in order to access all channels. + */ + uint8_t **extended_data; + + /** + * @name Video dimensions + * Video frames only. The coded dimensions (in pixels) of the video frame, + * i.e. the size of the rectangle that contains some well-defined values. + * + * @note The part of the frame intended for display/presentation is further + * restricted by the @ref cropping "Cropping rectangle". + * @{ + */ + int width, height; + /** + * @} + */ + + /** + * number of audio samples (per channel) described by this frame + */ + int nb_samples; + + /** + * format of the frame, -1 if unknown or unset + * Values correspond to enum AVPixelFormat for video frames, + * enum AVSampleFormat for audio) + */ + int format; + + /** + * 1 -> keyframe, 0-> not + */ + int key_frame; + + /** + * Picture type of the frame. + */ + enum AVPictureType pict_type; + + /** + * Sample aspect ratio for the video frame, 0/1 if unknown/unspecified. + */ + AVRational sample_aspect_ratio; + + /** + * Presentation timestamp in time_base units (time when frame should be shown to user). + */ + int64_t pts; + +#if FF_API_PKT_PTS + /** + * PTS copied from the AVPacket that was decoded to produce this frame. + * @deprecated use the pts field instead + */ + attribute_deprecated + int64_t pkt_pts; +#endif + + /** + * DTS copied from the AVPacket that triggered returning this frame. (if frame threading isn't used) + * This is also the Presentation time of this AVFrame calculated from + * only AVPacket.dts values without pts values. + */ + int64_t pkt_dts; + + /** + * picture number in bitstream order + */ + int coded_picture_number; + /** + * picture number in display order + */ + int display_picture_number; + + /** + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) + */ + int quality; + + /** + * for some private data of the user + */ + void *opaque; + +#if FF_API_ERROR_FRAME + /** + * @deprecated unused + */ + attribute_deprecated + uint64_t error[AV_NUM_DATA_POINTERS]; +#endif + + /** + * When decoding, this signals how much the picture must be delayed. + * extra_delay = repeat_pict / (2*fps) + */ + int repeat_pict; + + /** + * The content of the picture is interlaced. + */ + int interlaced_frame; + + /** + * If the content is interlaced, is top field displayed first. + */ + int top_field_first; + + /** + * Tell user application that palette has changed from previous frame. + */ + int palette_has_changed; + + /** + * reordered opaque 64 bits (generally an integer or a double precision float + * PTS but can be anything). + * The user sets AVCodecContext.reordered_opaque to represent the input at + * that time, + * the decoder reorders values as needed and sets AVFrame.reordered_opaque + * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque + */ + int64_t reordered_opaque; + + /** + * Sample rate of the audio data. + */ + int sample_rate; + + /** + * Channel layout of the audio data. + */ + uint64_t channel_layout; + + /** + * AVBuffer references backing the data for this frame. If all elements of + * this array are NULL, then this frame is not reference counted. This array + * must be filled contiguously -- if buf[i] is non-NULL then buf[j] must + * also be non-NULL for all j < i. + * + * There may be at most one AVBuffer per data plane, so for video this array + * always contains all the references. For planar audio with more than + * AV_NUM_DATA_POINTERS channels, there may be more buffers than can fit in + * this array. Then the extra AVBufferRef pointers are stored in the + * extended_buf array. + */ + AVBufferRef *buf[AV_NUM_DATA_POINTERS]; + + /** + * For planar audio which requires more than AV_NUM_DATA_POINTERS + * AVBufferRef pointers, this array will hold all the references which + * cannot fit into AVFrame.buf. + * + * Note that this is different from AVFrame.extended_data, which always + * contains all the pointers. This array only contains the extra pointers, + * which cannot fit into AVFrame.buf. + * + * This array is always allocated using av_malloc() by whoever constructs + * the frame. It is freed in av_frame_unref(). + */ + AVBufferRef **extended_buf; + /** + * Number of elements in extended_buf. + */ + int nb_extended_buf; + + AVFrameSideData **side_data; + int nb_side_data; + +/** + * @defgroup lavu_frame_flags AV_FRAME_FLAGS + * @ingroup lavu_frame + * Flags describing additional frame properties. + * + * @{ + */ + +/** + * The frame data may be corrupted, e.g. due to decoding errors. + */ +#define AV_FRAME_FLAG_CORRUPT (1 << 0) +/** + * A flag to mark the frames which need to be decoded, but shouldn't be output. + */ +#define AV_FRAME_FLAG_DISCARD (1 << 2) +/** + * @} + */ + + /** + * Frame flags, a combination of @ref lavu_frame_flags + */ + int flags; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + enum AVColorPrimaries color_primaries; + + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + enum AVChromaLocation chroma_location; + + /** + * frame timestamp estimated using various heuristics, in stream time base + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int64_t best_effort_timestamp; + + /** + * reordered pos from the last AVPacket that has been input into the decoder + * - encoding: unused + * - decoding: Read by user. + */ + int64_t pkt_pos; + + /** + * duration of the corresponding packet, expressed in + * AVStream->time_base units, 0 if unknown. + * - encoding: unused + * - decoding: Read by user. + */ + int64_t pkt_duration; + + /** + * metadata. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVDictionary *metadata; + + /** + * decode error flags of the frame, set to a combination of + * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there + * were errors during the decoding. + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int decode_error_flags; +#define FF_DECODE_ERROR_INVALID_BITSTREAM 1 +#define FF_DECODE_ERROR_MISSING_REFERENCE 2 +#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4 +#define FF_DECODE_ERROR_DECODE_SLICES 8 + + /** + * number of audio channels, only used for audio. + * - encoding: unused + * - decoding: Read by user. + */ + int channels; + + /** + * size of the corresponding packet containing the compressed + * frame. + * It is set to a negative value if unknown. + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int pkt_size; + +#if FF_API_FRAME_QP + /** + * QP table + */ + attribute_deprecated + int8_t *qscale_table; + /** + * QP store stride + */ + attribute_deprecated + int qstride; + + attribute_deprecated + int qscale_type; + + attribute_deprecated + AVBufferRef *qp_table_buf; +#endif + /** + * For hwaccel-format frames, this should be a reference to the + * AVHWFramesContext describing the frame. + */ + AVBufferRef *hw_frames_ctx; + + /** + * AVBufferRef for free use by the API user. FFmpeg will never check the + * contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when + * the frame is unreferenced. av_frame_copy_props() calls create a new + * reference with av_buffer_ref() for the target frame's opaque_ref field. + * + * This is unrelated to the opaque field, although it serves a similar + * purpose. + */ + AVBufferRef *opaque_ref; + + /** + * @anchor cropping + * @name Cropping + * Video frames only. The number of pixels to discard from the the + * top/bottom/left/right border of the frame to obtain the sub-rectangle of + * the frame intended for presentation. + * @{ + */ + size_t crop_top; + size_t crop_bottom; + size_t crop_left; + size_t crop_right; + /** + * @} + */ + + /** + * AVBufferRef for internal use by a single libav* library. + * Must not be used to transfer data between libraries. + * Has to be NULL when ownership of the frame leaves the respective library. + * + * Code outside the FFmpeg libs should never check or change the contents of the buffer ref. + * + * FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. + * av_frame_copy_props() calls create a new reference with av_buffer_ref() + * for the target frame's private_ref field. + */ + AVBufferRef *private_ref; +} AVFrame; + +#if FF_API_FRAME_GET_SET +/** + * Accessors for some AVFrame fields. These used to be provided for ABI + * compatibility, and do not need to be used anymore. + */ +attribute_deprecated +int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame); +attribute_deprecated +void av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val); +attribute_deprecated +int64_t av_frame_get_pkt_duration (const AVFrame *frame); +attribute_deprecated +void av_frame_set_pkt_duration (AVFrame *frame, int64_t val); +attribute_deprecated +int64_t av_frame_get_pkt_pos (const AVFrame *frame); +attribute_deprecated +void av_frame_set_pkt_pos (AVFrame *frame, int64_t val); +attribute_deprecated +int64_t av_frame_get_channel_layout (const AVFrame *frame); +attribute_deprecated +void av_frame_set_channel_layout (AVFrame *frame, int64_t val); +attribute_deprecated +int av_frame_get_channels (const AVFrame *frame); +attribute_deprecated +void av_frame_set_channels (AVFrame *frame, int val); +attribute_deprecated +int av_frame_get_sample_rate (const AVFrame *frame); +attribute_deprecated +void av_frame_set_sample_rate (AVFrame *frame, int val); +attribute_deprecated +AVDictionary *av_frame_get_metadata (const AVFrame *frame); +attribute_deprecated +void av_frame_set_metadata (AVFrame *frame, AVDictionary *val); +attribute_deprecated +int av_frame_get_decode_error_flags (const AVFrame *frame); +attribute_deprecated +void av_frame_set_decode_error_flags (AVFrame *frame, int val); +attribute_deprecated +int av_frame_get_pkt_size(const AVFrame *frame); +attribute_deprecated +void av_frame_set_pkt_size(AVFrame *frame, int val); +#if FF_API_FRAME_QP +attribute_deprecated +int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type); +attribute_deprecated +int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int type); +#endif +attribute_deprecated +enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame); +attribute_deprecated +void av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val); +attribute_deprecated +enum AVColorRange av_frame_get_color_range(const AVFrame *frame); +attribute_deprecated +void av_frame_set_color_range(AVFrame *frame, enum AVColorRange val); +#endif + +/** + * Get the name of a colorspace. + * @return a static string identifying the colorspace; can be NULL. + */ +const char *av_get_colorspace_name(enum AVColorSpace val); + +/** + * Allocate an AVFrame and set its fields to default values. The resulting + * struct must be freed using av_frame_free(). + * + * @return An AVFrame filled with default values or NULL on failure. + * + * @note this only allocates the AVFrame itself, not the data buffers. Those + * must be allocated through other means, e.g. with av_frame_get_buffer() or + * manually. + */ +AVFrame *av_frame_alloc(void); + +/** + * Free the frame and any dynamically allocated objects in it, + * e.g. extended_data. If the frame is reference counted, it will be + * unreferenced first. + * + * @param frame frame to be freed. The pointer will be set to NULL. + */ +void av_frame_free(AVFrame **frame); + +/** + * Set up a new reference to the data described by the source frame. + * + * Copy frame properties from src to dst and create a new reference for each + * AVBufferRef from src. + * + * If src is not reference counted, new buffers are allocated and the data is + * copied. + * + * @warning: dst MUST have been either unreferenced with av_frame_unref(dst), + * or newly allocated with av_frame_alloc() before calling this + * function, or undefined behavior will occur. + * + * @return 0 on success, a negative AVERROR on error + */ +int av_frame_ref(AVFrame *dst, const AVFrame *src); + +/** + * Create a new frame that references the same data as src. + * + * This is a shortcut for av_frame_alloc()+av_frame_ref(). + * + * @return newly created AVFrame on success, NULL on error. + */ +AVFrame *av_frame_clone(const AVFrame *src); + +/** + * Unreference all the buffers referenced by frame and reset the frame fields. + */ +void av_frame_unref(AVFrame *frame); + +/** + * Move everything contained in src to dst and reset src. + * + * @warning: dst is not unreferenced, but directly overwritten without reading + * or deallocating its contents. Call av_frame_unref(dst) manually + * before calling this function to ensure that no memory is leaked. + */ +void av_frame_move_ref(AVFrame *dst, AVFrame *src); + +/** + * Allocate new buffer(s) for audio or video data. + * + * The following fields must be set on frame before calling this function: + * - format (pixel format for video, sample format for audio) + * - width and height for video + * - nb_samples and channel_layout for audio + * + * This function will fill AVFrame.data and AVFrame.buf arrays and, if + * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf. + * For planar formats, one buffer will be allocated for each plane. + * + * @warning: if frame already has been allocated, calling this function will + * leak memory. In addition, undefined behavior can occur in certain + * cases. + * + * @param frame frame in which to store the new buffers. + * @param align Required buffer size alignment. If equal to 0, alignment will be + * chosen automatically for the current CPU. It is highly + * recommended to pass 0 here unless you know what you are doing. + * + * @return 0 on success, a negative AVERROR on error. + */ +int av_frame_get_buffer(AVFrame *frame, int align); + +/** + * Check if the frame data is writable. + * + * @return A positive value if the frame data is writable (which is true if and + * only if each of the underlying buffers has only one reference, namely the one + * stored in this frame). Return 0 otherwise. + * + * If 1 is returned the answer is valid until av_buffer_ref() is called on any + * of the underlying AVBufferRefs (e.g. through av_frame_ref() or directly). + * + * @see av_frame_make_writable(), av_buffer_is_writable() + */ +int av_frame_is_writable(AVFrame *frame); + +/** + * Ensure that the frame data is writable, avoiding data copy if possible. + * + * Do nothing if the frame is writable, allocate new buffers and copy the data + * if it is not. + * + * @return 0 on success, a negative AVERROR on error. + * + * @see av_frame_is_writable(), av_buffer_is_writable(), + * av_buffer_make_writable() + */ +int av_frame_make_writable(AVFrame *frame); + +/** + * Copy the frame data from src to dst. + * + * This function does not allocate anything, dst must be already initialized and + * allocated with the same parameters as src. + * + * This function only copies the frame data (i.e. the contents of the data / + * extended data arrays), not any other properties. + * + * @return >= 0 on success, a negative AVERROR on error. + */ +int av_frame_copy(AVFrame *dst, const AVFrame *src); + +/** + * Copy only "metadata" fields from src to dst. + * + * Metadata for the purpose of this function are those fields that do not affect + * the data layout in the buffers. E.g. pts, sample rate (for audio) or sample + * aspect ratio (for video), but not width/height or channel layout. + * Side data is also copied. + */ +int av_frame_copy_props(AVFrame *dst, const AVFrame *src); + +/** + * Get the buffer reference a given data plane is stored in. + * + * @param plane index of the data plane of interest in frame->extended_data. + * + * @return the buffer reference that contains the plane or NULL if the input + * frame is not valid. + */ +AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane); + +/** + * Add a new side data to a frame. + * + * @param frame a frame to which the side data should be added + * @param type type of the added side data + * @param size size of the side data + * + * @return newly added side data on success, NULL on error + */ +AVFrameSideData *av_frame_new_side_data(AVFrame *frame, + enum AVFrameSideDataType type, + int size); + +/** + * Add a new side data to a frame from an existing AVBufferRef + * + * @param frame a frame to which the side data should be added + * @param type the type of the added side data + * @param buf an AVBufferRef to add as side data. The ownership of + * the reference is transferred to the frame. + * + * @return newly added side data on success, NULL on error. On failure + * the frame is unchanged and the AVBufferRef remains owned by + * the caller. + */ +AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf); + +/** + * @return a pointer to the side data of a given type on success, NULL if there + * is no side data with such type in this frame. + */ +AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, + enum AVFrameSideDataType type); + +/** + * Remove and free all side data instances of the given type. + */ +void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type); + + +/** + * Flags for frame cropping. + */ +enum { + /** + * Apply the maximum possible cropping, even if it requires setting the + * AVFrame.data[] entries to unaligned pointers. Passing unaligned data + * to FFmpeg API is generally not allowed, and causes undefined behavior + * (such as crashes). You can pass unaligned data only to FFmpeg APIs that + * are explicitly documented to accept it. Use this flag only if you + * absolutely know what you are doing. + */ + AV_FRAME_CROP_UNALIGNED = 1 << 0, +}; + +/** + * Crop the given video AVFrame according to its crop_left/crop_top/crop_right/ + * crop_bottom fields. If cropping is successful, the function will adjust the + * data pointers and the width/height fields, and set the crop fields to 0. + * + * In all cases, the cropping boundaries will be rounded to the inherent + * alignment of the pixel format. In some cases, such as for opaque hwaccel + * formats, the left/top cropping is ignored. The crop fields are set to 0 even + * if the cropping was rounded or ignored. + * + * @param frame the frame which should be cropped + * @param flags Some combination of AV_FRAME_CROP_* flags, or 0. + * + * @return >= 0 on success, a negative AVERROR on error. If the cropping fields + * were invalid, AVERROR(ERANGE) is returned, and nothing is changed. + */ +int av_frame_apply_cropping(AVFrame *frame, int flags); + +/** + * @return a string identifying the side data type + */ +const char *av_frame_side_data_name(enum AVFrameSideDataType type); + +/** + * @} + */ + +#endif /* AVUTIL_FRAME_H */ diff --git a/ffmpeg/inc/libavutil/hash.h b/ffmpeg/inc/libavutil/hash.h new file mode 100644 index 0000000..7693e6b --- /dev/null +++ b/ffmpeg/inc/libavutil/hash.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_hash_generic + * Generic hashing API + */ + +#ifndef AVUTIL_HASH_H +#define AVUTIL_HASH_H + +#include + +#include "version.h" + +/** + * @defgroup lavu_hash Hash Functions + * @ingroup lavu_crypto + * Hash functions useful in multimedia. + * + * Hash functions are widely used in multimedia, from error checking and + * concealment to internal regression testing. libavutil has efficient + * implementations of a variety of hash functions that may be useful for + * FFmpeg and other multimedia applications. + * + * @{ + * + * @defgroup lavu_hash_generic Generic Hashing API + * An abstraction layer for all hash functions supported by libavutil. + * + * If your application needs to support a wide range of different hash + * functions, then the Generic Hashing API is for you. It provides a generic, + * reusable API for @ref lavu_hash "all hash functions" implemented in libavutil. + * If you just need to use one particular hash function, use the @ref lavu_hash + * "individual hash" directly. + * + * @section Sample Code + * + * A basic template for using the Generic Hashing API follows: + * + * @code + * struct AVHashContext *ctx = NULL; + * const char *hash_name = NULL; + * uint8_t *output_buf = NULL; + * + * // Select from a string returned by av_hash_names() + * hash_name = ...; + * + * // Allocate a hash context + * ret = av_hash_alloc(&ctx, hash_name); + * if (ret < 0) + * return ret; + * + * // Initialize the hash context + * av_hash_init(ctx); + * + * // Update the hash context with data + * while (data_left) { + * av_hash_update(ctx, data, size); + * } + * + * // Now we have no more data, so it is time to finalize the hash and get the + * // output. But we need to first allocate an output buffer. Note that you can + * // use any memory allocation function, including malloc(), not just + * // av_malloc(). + * output_buf = av_malloc(av_hash_get_size(ctx)); + * if (!output_buf) + * return AVERROR(ENOMEM); + * + * // Finalize the hash context. + * // You can use any of the av_hash_final*() functions provided, for other + * // output formats. If you do so, be sure to adjust the memory allocation + * // above. See the function documentation below for the exact amount of extra + * // memory needed. + * av_hash_final(ctx, output_buffer); + * + * // Free the context + * av_hash_freep(&ctx); + * @endcode + * + * @section Hash Function-Specific Information + * If the CRC32 hash is selected, the #AV_CRC_32_IEEE polynomial will be + * used. + * + * If the Murmur3 hash is selected, the default seed will be used. See @ref + * lavu_murmur3_seedinfo "Murmur3" for more information. + * + * @{ + */ + +/** + * @example ffhash.c + * This example is a simple command line application that takes one or more + * arguments. It demonstrates a typical use of the hashing API with allocation, + * initialization, updating, and finalizing. + */ + +struct AVHashContext; + +/** + * Allocate a hash context for the algorithm specified by name. + * + * @return >= 0 for success, a negative error code for failure + * + * @note The context is not initialized after a call to this function; you must + * call av_hash_init() to do so. + */ +int av_hash_alloc(struct AVHashContext **ctx, const char *name); + +/** + * Get the names of available hash algorithms. + * + * This function can be used to enumerate the algorithms. + * + * @param[in] i Index of the hash algorithm, starting from 0 + * @return Pointer to a static string or `NULL` if `i` is out of range + */ +const char *av_hash_names(int i); + +/** + * Get the name of the algorithm corresponding to the given hash context. + */ +const char *av_hash_get_name(const struct AVHashContext *ctx); + +/** + * Maximum value that av_hash_get_size() will currently return. + * + * You can use this if you absolutely want or need to use static allocation for + * the output buffer and are fine with not supporting hashes newly added to + * libavutil without recompilation. + * + * @warning + * Adding new hashes with larger sizes, and increasing the macro while doing + * so, will not be considered an ABI change. To prevent your code from + * overflowing a buffer, either dynamically allocate the output buffer with + * av_hash_get_size(), or limit your use of the Hashing API to hashes that are + * already in FFmpeg during the time of compilation. + */ +#define AV_HASH_MAX_SIZE 64 + +/** + * Get the size of the resulting hash value in bytes. + * + * The maximum value this function will currently return is available as macro + * #AV_HASH_MAX_SIZE. + * + * @param[in] ctx Hash context + * @return Size of the hash value in bytes + */ +int av_hash_get_size(const struct AVHashContext *ctx); + +/** + * Initialize or reset a hash context. + * + * @param[in,out] ctx Hash context + */ +void av_hash_init(struct AVHashContext *ctx); + +/** + * Update a hash context with additional data. + * + * @param[in,out] ctx Hash context + * @param[in] src Data to be added to the hash context + * @param[in] len Size of the additional data + */ +#if FF_API_CRYPTO_SIZE_T +void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, int len); +#else +void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, size_t len); +#endif + +/** + * Finalize a hash context and compute the actual hash value. + * + * The minimum size of `dst` buffer is given by av_hash_get_size() or + * #AV_HASH_MAX_SIZE. The use of the latter macro is discouraged. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * + * @see av_hash_final_bin() provides an alternative API + */ +void av_hash_final(struct AVHashContext *ctx, uint8_t *dst); + +/** + * Finalize a hash context and store the actual hash value in a buffer. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * If `size` is smaller than the hash size (given by av_hash_get_size()), the + * hash is truncated; if size is larger, the buffer is padded with 0. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * @param[in] size Number of bytes to write to `dst` + */ +void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Finalize a hash context and store the hexadecimal representation of the + * actual hash value as a string. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * The string is always 0-terminated. + * + * If `size` is smaller than `2 * hash_size + 1`, where `hash_size` is the + * value returned by av_hash_get_size(), the string will be truncated. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the string will be stored + * @param[in] size Maximum number of bytes to write to `dst` + */ +void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Finalize a hash context and store the Base64 representation of the + * actual hash value as a string. + * + * It is not safe to update or finalize a hash context again, if it has already + * been finalized. + * + * The string is always 0-terminated. + * + * If `size` is smaller than AV_BASE64_SIZE(hash_size), where `hash_size` is + * the value returned by av_hash_get_size(), the string will be truncated. + * + * @param[in,out] ctx Hash context + * @param[out] dst Where the final hash value will be stored + * @param[in] size Maximum number of bytes to write to `dst` + */ +void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size); + +/** + * Free hash context and set hash context pointer to `NULL`. + * + * @param[in,out] ctx Pointer to hash context + */ +void av_hash_freep(struct AVHashContext **ctx); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_HASH_H */ diff --git a/ffmpeg/inc/libavutil/hdr_dynamic_metadata.h b/ffmpeg/inc/libavutil/hdr_dynamic_metadata.h new file mode 100644 index 0000000..2d72de5 --- /dev/null +++ b/ffmpeg/inc/libavutil/hdr_dynamic_metadata.h @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2018 Mohammad Izadi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HDR_DYNAMIC_METADATA_H +#define AVUTIL_HDR_DYNAMIC_METADATA_H + +#include "frame.h" +#include "rational.h" + +/** + * Option for overlapping elliptical pixel selectors in an image. + */ +enum AVHDRPlusOverlapProcessOption { + AV_HDR_PLUS_OVERLAP_PROCESS_WEIGHTED_AVERAGING = 0, + AV_HDR_PLUS_OVERLAP_PROCESS_LAYERING = 1, +}; + +/** + * Represents the percentile at a specific percentage in + * a distribution. + */ +typedef struct AVHDRPlusPercentile { + /** + * The percentage value corresponding to a specific percentile linearized + * RGB value in the processing window in the scene. The value shall be in + * the range of 0 to100, inclusive. + */ + uint8_t percentage; + + /** + * The linearized maxRGB value at a specific percentile in the processing + * window in the scene. The value shall be in the range of 0 to 1, inclusive + * and in multiples of 0.00001. + */ + AVRational percentile; +} AVHDRPlusPercentile; + +/** + * Color transform parameters at a processing window in a dynamic metadata for + * SMPTE 2094-40. + */ +typedef struct AVHDRPlusColorTransformParams { + /** + * The relative x coordinate of the top left pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(width of Picture - 1). The value 1 corresponds + * to the absolute coordinate of width of Picture - 1. The value for + * first processing window shall be 0. + */ + AVRational window_upper_left_corner_x; + + /** + * The relative y coordinate of the top left pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(height of Picture - 1). The value 1 corresponds + * to the absolute coordinate of height of Picture - 1. The value for + * first processing window shall be 0. + */ + AVRational window_upper_left_corner_y; + + /** + * The relative x coordinate of the bottom right pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(width of Picture - 1). The value 1 corresponds + * to the absolute coordinate of width of Picture - 1. The value for + * first processing window shall be 1. + */ + AVRational window_lower_right_corner_x; + + /** + * The relative y coordinate of the bottom right pixel of the processing + * window. The value shall be in the range of 0 and 1, inclusive and + * in multiples of 1/(height of Picture - 1). The value 1 corresponds + * to the absolute coordinate of height of Picture - 1. The value for + * first processing window shall be 1. + */ + AVRational window_lower_right_corner_y; + + /** + * The x coordinate of the center position of the concentric internal and + * external ellipses of the elliptical pixel selector in the processing + * window. The value shall be in the range of 0 to (width of Picture - 1), + * inclusive and in multiples of 1 pixel. + */ + uint16_t center_of_ellipse_x; + + /** + * The y coordinate of the center position of the concentric internal and + * external ellipses of the elliptical pixel selector in the processing + * window. The value shall be in the range of 0 to (height of Picture - 1), + * inclusive and in multiples of 1 pixel. + */ + uint16_t center_of_ellipse_y; + + /** + * The clockwise rotation angle in degree of arc with respect to the + * positive direction of the x-axis of the concentric internal and external + * ellipses of the elliptical pixel selector in the processing window. The + * value shall be in the range of 0 to 180, inclusive and in multiples of 1. + */ + uint8_t rotation_angle; + + /** + * The semi-major axis value of the internal ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value shall be + * in the range of 1 to 65535, inclusive and in multiples of 1 pixel. + */ + uint16_t semimajor_axis_internal_ellipse; + + /** + * The semi-major axis value of the external ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value + * shall not be less than semimajor_axis_internal_ellipse of the current + * processing window. The value shall be in the range of 1 to 65535, + * inclusive and in multiples of 1 pixel. + */ + uint16_t semimajor_axis_external_ellipse; + + /** + * The semi-minor axis value of the external ellipse of the elliptical pixel + * selector in amount of pixels in the processing window. The value shall be + * in the range of 1 to 65535, inclusive and in multiples of 1 pixel. + */ + uint16_t semiminor_axis_external_ellipse; + + /** + * Overlap process option indicates one of the two methods of combining + * rendered pixels in the processing window in an image with at least one + * elliptical pixel selector. For overlapping elliptical pixel selectors + * in an image, overlap_process_option shall have the same value. + */ + enum AVHDRPlusOverlapProcessOption overlap_process_option; + + /** + * The maximum of the color components of linearized RGB values in the + * processing window in the scene. The values should be in the range of 0 to + * 1, inclusive and in multiples of 0.00001. maxscl[ 0 ], maxscl[ 1 ], and + * maxscl[ 2 ] are corresponding to R, G, B color components respectively. + */ + AVRational maxscl[3]; + + /** + * The average of linearized maxRGB values in the processing window in the + * scene. The value should be in the range of 0 to 1, inclusive and in + * multiples of 0.00001. + */ + AVRational average_maxrgb; + + /** + * The number of linearized maxRGB values at given percentiles in the + * processing window in the scene. The maximum value shall be 15. + */ + uint8_t num_distribution_maxrgb_percentiles; + + /** + * The linearized maxRGB values at given percentiles in the + * processing window in the scene. + */ + AVHDRPlusPercentile distribution_maxrgb[15]; + + /** + * The fraction of selected pixels in the image that contains the brightest + * pixel in the scene. The value shall be in the range of 0 to 1, inclusive + * and in multiples of 0.001. + */ + AVRational fraction_bright_pixels; + + /** + * This flag indicates that the metadata for the tone mapping function in + * the processing window is present (for value of 1). + */ + uint8_t tone_mapping_flag; + + /** + * The x coordinate of the separation point between the linear part and the + * curved part of the tone mapping function. The value shall be in the range + * of 0 to 1, excluding 0 and in multiples of 1/4095. + */ + AVRational knee_point_x; + + /** + * The y coordinate of the separation point between the linear part and the + * curved part of the tone mapping function. The value shall be in the range + * of 0 to 1, excluding 0 and in multiples of 1/4095. + */ + AVRational knee_point_y; + + /** + * The number of the intermediate anchor parameters of the tone mapping + * function in the processing window. The maximum value shall be 15. + */ + uint8_t num_bezier_curve_anchors; + + /** + * The intermediate anchor parameters of the tone mapping function in the + * processing window in the scene. The values should be in the range of 0 + * to 1, inclusive and in multiples of 1/1023. + */ + AVRational bezier_curve_anchors[15]; + + /** + * This flag shall be equal to 0 in bitstreams conforming to this version of + * this Specification. Other values are reserved for future use. + */ + uint8_t color_saturation_mapping_flag; + + /** + * The color saturation gain in the processing window in the scene. The + * value shall be in the range of 0 to 63/8, inclusive and in multiples of + * 1/8. The default value shall be 1. + */ + AVRational color_saturation_weight; +} AVHDRPlusColorTransformParams; + +/** + * This struct represents dynamic metadata for color volume transform - + * application 4 of SMPTE 2094-40:2016 standard. + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with + * av_dynamic_hdr_plus_alloc() and its size is not a part of + * the public ABI. + */ +typedef struct AVDynamicHDRPlus { + /** + * Country code by Rec. ITU-T T.35 Annex A. The value shall be 0xB5. + */ + uint8_t itu_t_t35_country_code; + + /** + * Application version in the application defining document in ST-2094 + * suite. The value shall be set to 0. + */ + uint8_t application_version; + + /** + * The number of processing windows. The value shall be in the range + * of 1 to 3, inclusive. + */ + uint8_t num_windows; + + /** + * The color transform parameters for every processing window. + */ + AVHDRPlusColorTransformParams params[3]; + + /** + * The nominal maximum display luminance of the targeted system display, + * in units of 0.0001 candelas per square metre. The value shall be in + * the range of 0 to 10000, inclusive. + */ + AVRational targeted_system_display_maximum_luminance; + + /** + * This flag shall be equal to 0 in bit streams conforming to this version + * of this Specification. The value 1 is reserved for future use. + */ + uint8_t targeted_system_display_actual_peak_luminance_flag; + + /** + * The number of rows in the targeted system_display_actual_peak_luminance + * array. The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_rows_targeted_system_display_actual_peak_luminance; + + /** + * The number of columns in the + * targeted_system_display_actual_peak_luminance array. The value shall be + * in the range of 2 to 25, inclusive. + */ + uint8_t num_cols_targeted_system_display_actual_peak_luminance; + + /** + * The normalized actual peak luminance of the targeted system display. The + * values should be in the range of 0 to 1, inclusive and in multiples of + * 1/15. + */ + AVRational targeted_system_display_actual_peak_luminance[25][25]; + + /** + * This flag shall be equal to 0 in bitstreams conforming to this version of + * this Specification. The value 1 is reserved for future use. + */ + uint8_t mastering_display_actual_peak_luminance_flag; + + /** + * The number of rows in the mastering_display_actual_peak_luminance array. + * The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_rows_mastering_display_actual_peak_luminance; + + /** + * The number of columns in the mastering_display_actual_peak_luminance + * array. The value shall be in the range of 2 to 25, inclusive. + */ + uint8_t num_cols_mastering_display_actual_peak_luminance; + + /** + * The normalized actual peak luminance of the mastering display used for + * mastering the image essence. The values should be in the range of 0 to 1, + * inclusive and in multiples of 1/15. + */ + AVRational mastering_display_actual_peak_luminance[25][25]; +} AVDynamicHDRPlus; + +/** + * Allocate an AVDynamicHDRPlus structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVDynamicHDRPlus filled with default values or NULL + * on failure. + */ +AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size); + +/** + * Allocate a complete AVDynamicHDRPlus and add it to the frame. + * @param frame The frame which side data is added to. + * + * @return The AVDynamicHDRPlus structure to be filled by caller or NULL + * on failure. + */ +AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */ diff --git a/ffmpeg/inc/libavutil/hmac.h b/ffmpeg/inc/libavutil/hmac.h new file mode 100644 index 0000000..412e950 --- /dev/null +++ b/ffmpeg/inc/libavutil/hmac.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HMAC_H +#define AVUTIL_HMAC_H + +#include + +#include "version.h" +/** + * @defgroup lavu_hmac HMAC + * @ingroup lavu_crypto + * @{ + */ + +enum AVHMACType { + AV_HMAC_MD5, + AV_HMAC_SHA1, + AV_HMAC_SHA224, + AV_HMAC_SHA256, + AV_HMAC_SHA384, + AV_HMAC_SHA512, +}; + +typedef struct AVHMAC AVHMAC; + +/** + * Allocate an AVHMAC context. + * @param type The hash function used for the HMAC. + */ +AVHMAC *av_hmac_alloc(enum AVHMACType type); + +/** + * Free an AVHMAC context. + * @param ctx The context to free, may be NULL + */ +void av_hmac_free(AVHMAC *ctx); + +/** + * Initialize an AVHMAC context with an authentication key. + * @param ctx The HMAC context + * @param key The authentication key + * @param keylen The length of the key, in bytes + */ +void av_hmac_init(AVHMAC *ctx, const uint8_t *key, unsigned int keylen); + +/** + * Hash data with the HMAC. + * @param ctx The HMAC context + * @param data The data to hash + * @param len The length of the data, in bytes + */ +void av_hmac_update(AVHMAC *ctx, const uint8_t *data, unsigned int len); + +/** + * Finish hashing and output the HMAC digest. + * @param ctx The HMAC context + * @param out The output buffer to write the digest into + * @param outlen The length of the out buffer, in bytes + * @return The number of bytes written to out, or a negative error code. + */ +int av_hmac_final(AVHMAC *ctx, uint8_t *out, unsigned int outlen); + +/** + * Hash an array of data with a key. + * @param ctx The HMAC context + * @param data The data to hash + * @param len The length of the data, in bytes + * @param key The authentication key + * @param keylen The length of the key, in bytes + * @param out The output buffer to write the digest into + * @param outlen The length of the out buffer, in bytes + * @return The number of bytes written to out, or a negative error code. + */ +int av_hmac_calc(AVHMAC *ctx, const uint8_t *data, unsigned int len, + const uint8_t *key, unsigned int keylen, + uint8_t *out, unsigned int outlen); + +/** + * @} + */ + +#endif /* AVUTIL_HMAC_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext.h b/ffmpeg/inc/libavutil/hwcontext.h new file mode 100644 index 0000000..04d19d8 --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext.h @@ -0,0 +1,605 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_H +#define AVUTIL_HWCONTEXT_H + +#include "buffer.h" +#include "frame.h" +#include "log.h" +#include "pixfmt.h" + +enum AVHWDeviceType { + AV_HWDEVICE_TYPE_NONE, + AV_HWDEVICE_TYPE_VDPAU, + AV_HWDEVICE_TYPE_CUDA, + AV_HWDEVICE_TYPE_VAAPI, + AV_HWDEVICE_TYPE_DXVA2, + AV_HWDEVICE_TYPE_QSV, + AV_HWDEVICE_TYPE_VIDEOTOOLBOX, + AV_HWDEVICE_TYPE_D3D11VA, + AV_HWDEVICE_TYPE_DRM, + AV_HWDEVICE_TYPE_OPENCL, + AV_HWDEVICE_TYPE_MEDIACODEC, + AV_HWDEVICE_TYPE_VULKAN, +}; + +typedef struct AVHWDeviceInternal AVHWDeviceInternal; + +/** + * This struct aggregates all the (hardware/vendor-specific) "high-level" state, + * i.e. state that is not tied to a concrete processing configuration. + * E.g., in an API that supports hardware-accelerated encoding and decoding, + * this struct will (if possible) wrap the state that is common to both encoding + * and decoding and from which specific instances of encoders or decoders can be + * derived. + * + * This struct is reference-counted with the AVBuffer mechanism. The + * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field + * points to the actual AVHWDeviceContext. Further objects derived from + * AVHWDeviceContext (such as AVHWFramesContext, describing a frame pool with + * specific properties) will hold an internal reference to it. After all the + * references are released, the AVHWDeviceContext itself will be freed, + * optionally invoking a user-specified callback for uninitializing the hardware + * state. + */ +typedef struct AVHWDeviceContext { + /** + * A class for logging. Set by av_hwdevice_ctx_alloc(). + */ + const AVClass *av_class; + + /** + * Private data used internally by libavutil. Must not be accessed in any + * way by the caller. + */ + AVHWDeviceInternal *internal; + + /** + * This field identifies the underlying API used for hardware access. + * + * This field is set when this struct is allocated and never changed + * afterwards. + */ + enum AVHWDeviceType type; + + /** + * The format-specific data, allocated and freed by libavutil along with + * this context. + * + * Should be cast by the user to the format-specific context defined in the + * corresponding header (hwcontext_*.h) and filled as described in the + * documentation before calling av_hwdevice_ctx_init(). + * + * After calling av_hwdevice_ctx_init() this struct should not be modified + * by the caller. + */ + void *hwctx; + + /** + * This field may be set by the caller before calling av_hwdevice_ctx_init(). + * + * If non-NULL, this callback will be called when the last reference to + * this context is unreferenced, immediately before it is freed. + * + * @note when other objects (e.g an AVHWFramesContext) are derived from this + * struct, this callback will be invoked after all such child objects + * are fully uninitialized and their respective destructors invoked. + */ + void (*free)(struct AVHWDeviceContext *ctx); + + /** + * Arbitrary user data, to be used e.g. by the free() callback. + */ + void *user_opaque; +} AVHWDeviceContext; + +typedef struct AVHWFramesInternal AVHWFramesInternal; + +/** + * This struct describes a set or pool of "hardware" frames (i.e. those with + * data not located in normal system memory). All the frames in the pool are + * assumed to be allocated in the same way and interchangeable. + * + * This struct is reference-counted with the AVBuffer mechanism and tied to a + * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor + * yields a reference, whose data field points to the actual AVHWFramesContext + * struct. + */ +typedef struct AVHWFramesContext { + /** + * A class for logging. + */ + const AVClass *av_class; + + /** + * Private data used internally by libavutil. Must not be accessed in any + * way by the caller. + */ + AVHWFramesInternal *internal; + + /** + * A reference to the parent AVHWDeviceContext. This reference is owned and + * managed by the enclosing AVHWFramesContext, but the caller may derive + * additional references from it. + */ + AVBufferRef *device_ref; + + /** + * The parent AVHWDeviceContext. This is simply a pointer to + * device_ref->data provided for convenience. + * + * Set by libavutil in av_hwframe_ctx_init(). + */ + AVHWDeviceContext *device_ctx; + + /** + * The format-specific data, allocated and freed automatically along with + * this context. + * + * Should be cast by the user to the format-specific context defined in the + * corresponding header (hwframe_*.h) and filled as described in the + * documentation before calling av_hwframe_ctx_init(). + * + * After any frames using this context are created, the contents of this + * struct should not be modified by the caller. + */ + void *hwctx; + + /** + * This field may be set by the caller before calling av_hwframe_ctx_init(). + * + * If non-NULL, this callback will be called when the last reference to + * this context is unreferenced, immediately before it is freed. + */ + void (*free)(struct AVHWFramesContext *ctx); + + /** + * Arbitrary user data, to be used e.g. by the free() callback. + */ + void *user_opaque; + + /** + * A pool from which the frames are allocated by av_hwframe_get_buffer(). + * This field may be set by the caller before calling av_hwframe_ctx_init(). + * The buffers returned by calling av_buffer_pool_get() on this pool must + * have the properties described in the documentation in the corresponding hw + * type's header (hwcontext_*.h). The pool will be freed strictly before + * this struct's free() callback is invoked. + * + * This field may be NULL, then libavutil will attempt to allocate a pool + * internally. Note that certain device types enforce pools allocated at + * fixed size (frame count), which cannot be extended dynamically. In such a + * case, initial_pool_size must be set appropriately. + */ + AVBufferPool *pool; + + /** + * Initial size of the frame pool. If a device type does not support + * dynamically resizing the pool, then this is also the maximum pool size. + * + * May be set by the caller before calling av_hwframe_ctx_init(). Must be + * set if pool is NULL and the device type does not support dynamic pools. + */ + int initial_pool_size; + + /** + * The pixel format identifying the underlying HW surface type. + * + * Must be a hwaccel format, i.e. the corresponding descriptor must have the + * AV_PIX_FMT_FLAG_HWACCEL flag set. + * + * Must be set by the user before calling av_hwframe_ctx_init(). + */ + enum AVPixelFormat format; + + /** + * The pixel format identifying the actual data layout of the hardware + * frames. + * + * Must be set by the caller before calling av_hwframe_ctx_init(). + * + * @note when the underlying API does not provide the exact data layout, but + * only the colorspace/bit depth, this field should be set to the fully + * planar version of that format (e.g. for 8-bit 420 YUV it should be + * AV_PIX_FMT_YUV420P, not AV_PIX_FMT_NV12 or anything else). + */ + enum AVPixelFormat sw_format; + + /** + * The allocated dimensions of the frames in this pool. + * + * Must be set by the user before calling av_hwframe_ctx_init(). + */ + int width, height; +} AVHWFramesContext; + +/** + * Look up an AVHWDeviceType by name. + * + * @param name String name of the device type (case-insensitive). + * @return The type from enum AVHWDeviceType, or AV_HWDEVICE_TYPE_NONE if + * not found. + */ +enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name); + +/** Get the string name of an AVHWDeviceType. + * + * @param type Type from enum AVHWDeviceType. + * @return Pointer to a static string containing the name, or NULL if the type + * is not valid. + */ +const char *av_hwdevice_get_type_name(enum AVHWDeviceType type); + +/** + * Iterate over supported device types. + * + * @param type AV_HWDEVICE_TYPE_NONE initially, then the previous type + * returned by this function in subsequent iterations. + * @return The next usable device type from enum AVHWDeviceType, or + * AV_HWDEVICE_TYPE_NONE if there are no more. + */ +enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev); + +/** + * Allocate an AVHWDeviceContext for a given hardware type. + * + * @param type the type of the hardware device to allocate. + * @return a reference to the newly created AVHWDeviceContext on success or NULL + * on failure. + */ +AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type); + +/** + * Finalize the device context before use. This function must be called after + * the context is filled with all the required information and before it is + * used in any way. + * + * @param ref a reference to the AVHWDeviceContext + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwdevice_ctx_init(AVBufferRef *ref); + +/** + * Open a device of the specified type and create an AVHWDeviceContext for it. + * + * This is a convenience function intended to cover the simple cases. Callers + * who need to fine-tune device creation/management should open the device + * manually and then wrap it in an AVHWDeviceContext using + * av_hwdevice_ctx_alloc()/av_hwdevice_ctx_init(). + * + * The returned context is already initialized and ready for use, the caller + * should not call av_hwdevice_ctx_init() on it. The user_opaque/free fields of + * the created AVHWDeviceContext are set by this function and should not be + * touched by the caller. + * + * @param device_ctx On success, a reference to the newly-created device context + * will be written here. The reference is owned by the caller + * and must be released with av_buffer_unref() when no longer + * needed. On failure, NULL will be written to this pointer. + * @param type The type of the device to create. + * @param device A type-specific string identifying the device to open. + * @param opts A dictionary of additional (type-specific) options to use in + * opening the device. The dictionary remains owned by the caller. + * @param flags currently unused + * + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags); + +/** + * Create a new device of the specified type from an existing device. + * + * If the source device is a device of the target type or was originally + * derived from such a device (possibly through one or more intermediate + * devices of other types), then this will return a reference to the + * existing device of the same type as is requested. + * + * Otherwise, it will attempt to derive a new device from the given source + * device. If direct derivation to the new type is not implemented, it will + * attempt the same derivation from each ancestor of the source device in + * turn looking for an implemented derivation method. + * + * @param dst_ctx On success, a reference to the newly-created + * AVHWDeviceContext. + * @param type The type of the new device to create. + * @param src_ctx A reference to an existing AVHWDeviceContext which will be + * used to create the new device. + * @param flags Currently unused; should be set to zero. + * @return Zero on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ctx, + enum AVHWDeviceType type, + AVBufferRef *src_ctx, int flags); + +/** + * Create a new device of the specified type from an existing device. + * + * This function performs the same action as av_hwdevice_ctx_create_derived, + * however, it is able to set options for the new device to be derived. + * + * @param dst_ctx On success, a reference to the newly-created + * AVHWDeviceContext. + * @param type The type of the new device to create. + * @param src_ctx A reference to an existing AVHWDeviceContext which will be + * used to create the new device. + * @param options Options for the new device to create, same format as in + * av_hwdevice_ctx_create. + * @param flags Currently unused; should be set to zero. + * @return Zero on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ctx, + enum AVHWDeviceType type, + AVBufferRef *src_ctx, + AVDictionary *options, int flags); + +/** + * Allocate an AVHWFramesContext tied to a given device context. + * + * @param device_ctx a reference to a AVHWDeviceContext. This function will make + * a new reference for internal use, the one passed to the + * function remains owned by the caller. + * @return a reference to the newly created AVHWFramesContext on success or NULL + * on failure. + */ +AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ctx); + +/** + * Finalize the context before use. This function must be called after the + * context is filled with all the required information and before it is attached + * to any frames. + * + * @param ref a reference to the AVHWFramesContext + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwframe_ctx_init(AVBufferRef *ref); + +/** + * Allocate a new frame attached to the given AVHWFramesContext. + * + * @param hwframe_ctx a reference to an AVHWFramesContext + * @param frame an empty (freshly allocated or unreffed) frame to be filled with + * newly allocated buffers. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR code on failure + */ +int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags); + +/** + * Copy data to or from a hw surface. At least one of dst/src must have an + * AVHWFramesContext attached. + * + * If src has an AVHWFramesContext attached, then the format of dst (if set) + * must use one of the formats returned by av_hwframe_transfer_get_formats(src, + * AV_HWFRAME_TRANSFER_DIRECTION_FROM). + * If dst has an AVHWFramesContext attached, then the format of src must use one + * of the formats returned by av_hwframe_transfer_get_formats(dst, + * AV_HWFRAME_TRANSFER_DIRECTION_TO) + * + * dst may be "clean" (i.e. with data/buf pointers unset), in which case the + * data buffers will be allocated by this function using av_frame_get_buffer(). + * If dst->format is set, then this format will be used, otherwise (when + * dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen. + * + * The two frames must have matching allocated dimensions (i.e. equal to + * AVHWFramesContext.width/height), since not all device types support + * transferring a sub-rectangle of the whole surface. The display dimensions + * (i.e. AVFrame.width/height) may be smaller than the allocated dimensions, but + * also have to be equal for both frames. When the display dimensions are + * smaller than the allocated dimensions, the content of the padding in the + * destination frame is unspecified. + * + * @param dst the destination frame. dst is not touched on failure. + * @param src the source frame. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR error code on failure. + */ +int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags); + +enum AVHWFrameTransferDirection { + /** + * Transfer the data from the queried hw frame. + */ + AV_HWFRAME_TRANSFER_DIRECTION_FROM, + + /** + * Transfer the data to the queried hw frame. + */ + AV_HWFRAME_TRANSFER_DIRECTION_TO, +}; + +/** + * Get a list of possible source or target formats usable in + * av_hwframe_transfer_data(). + * + * @param hwframe_ctx the frame context to obtain the information for + * @param dir the direction of the transfer + * @param formats the pointer to the output format list will be written here. + * The list is terminated with AV_PIX_FMT_NONE and must be freed + * by the caller when no longer needed using av_free(). + * If this function returns successfully, the format list will + * have at least one item (not counting the terminator). + * On failure, the contents of this pointer are unspecified. + * @param flags currently unused, should be set to zero + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats, int flags); + + +/** + * This struct describes the constraints on hardware frames attached to + * a given device with a hardware-specific configuration. This is returned + * by av_hwdevice_get_hwframe_constraints() and must be freed by + * av_hwframe_constraints_free() after use. + */ +typedef struct AVHWFramesConstraints { + /** + * A list of possible values for format in the hw_frames_ctx, + * terminated by AV_PIX_FMT_NONE. This member will always be filled. + */ + enum AVPixelFormat *valid_hw_formats; + + /** + * A list of possible values for sw_format in the hw_frames_ctx, + * terminated by AV_PIX_FMT_NONE. Can be NULL if this information is + * not known. + */ + enum AVPixelFormat *valid_sw_formats; + + /** + * The minimum size of frames in this hw_frames_ctx. + * (Zero if not known.) + */ + int min_width; + int min_height; + + /** + * The maximum size of frames in this hw_frames_ctx. + * (INT_MAX if not known / no limit.) + */ + int max_width; + int max_height; +} AVHWFramesConstraints; + +/** + * Allocate a HW-specific configuration structure for a given HW device. + * After use, the user must free all members as required by the specific + * hardware structure being used, then free the structure itself with + * av_free(). + * + * @param device_ctx a reference to the associated AVHWDeviceContext. + * @return The newly created HW-specific configuration structure on + * success or NULL on failure. + */ +void *av_hwdevice_hwconfig_alloc(AVBufferRef *device_ctx); + +/** + * Get the constraints on HW frames given a device and the HW-specific + * configuration to be used with that device. If no HW-specific + * configuration is provided, returns the maximum possible capabilities + * of the device. + * + * @param ref a reference to the associated AVHWDeviceContext. + * @param hwconfig a filled HW-specific configuration structure, or NULL + * to return the maximum possible capabilities of the device. + * @return AVHWFramesConstraints structure describing the constraints + * on the device, or NULL if not available. + */ +AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, + const void *hwconfig); + +/** + * Free an AVHWFrameConstraints structure. + * + * @param constraints The (filled or unfilled) AVHWFrameConstraints structure. + */ +void av_hwframe_constraints_free(AVHWFramesConstraints **constraints); + + +/** + * Flags to apply to frame mappings. + */ +enum { + /** + * The mapping must be readable. + */ + AV_HWFRAME_MAP_READ = 1 << 0, + /** + * The mapping must be writeable. + */ + AV_HWFRAME_MAP_WRITE = 1 << 1, + /** + * The mapped frame will be overwritten completely in subsequent + * operations, so the current frame data need not be loaded. Any values + * which are not overwritten are unspecified. + */ + AV_HWFRAME_MAP_OVERWRITE = 1 << 2, + /** + * The mapping must be direct. That is, there must not be any copying in + * the map or unmap steps. Note that performance of direct mappings may + * be much lower than normal memory. + */ + AV_HWFRAME_MAP_DIRECT = 1 << 3, +}; + +/** + * Map a hardware frame. + * + * This has a number of different possible effects, depending on the format + * and origin of the src and dst frames. On input, src should be a usable + * frame with valid buffers and dst should be blank (typically as just created + * by av_frame_alloc()). src should have an associated hwframe context, and + * dst may optionally have a format and associated hwframe context. + * + * If src was created by mapping a frame from the hwframe context of dst, + * then this function undoes the mapping - dst is replaced by a reference to + * the frame that src was originally mapped from. + * + * If both src and dst have an associated hwframe context, then this function + * attempts to map the src frame from its hardware context to that of dst and + * then fill dst with appropriate data to be usable there. This will only be + * possible if the hwframe contexts and associated devices are compatible - + * given compatible devices, av_hwframe_ctx_create_derived() can be used to + * create a hwframe context for dst in which mapping should be possible. + * + * If src has a hwframe context but dst does not, then the src frame is + * mapped to normal memory and should thereafter be usable as a normal frame. + * If the format is set on dst, then the mapping will attempt to create dst + * with that format and fail if it is not possible. If format is unset (is + * AV_PIX_FMT_NONE) then dst will be mapped with whatever the most appropriate + * format to use is (probably the sw_format of the src hwframe context). + * + * A return value of AVERROR(ENOSYS) indicates that the mapping is not + * possible with the given arguments and hwframe setup, while other return + * values indicate that it failed somehow. + * + * @param dst Destination frame, to contain the mapping. + * @param src Source frame, to be mapped. + * @param flags Some combination of AV_HWFRAME_MAP_* flags. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags); + + +/** + * Create and initialise an AVHWFramesContext as a mapping of another existing + * AVHWFramesContext on a different device. + * + * av_hwframe_ctx_init() should not be called after this. + * + * @param derived_frame_ctx On success, a reference to the newly created + * AVHWFramesContext. + * @param derived_device_ctx A reference to the device to create the new + * AVHWFramesContext on. + * @param source_frame_ctx A reference to an existing AVHWFramesContext + * which will be mapped to the derived context. + * @param flags Some combination of AV_HWFRAME_MAP_* flags, defining the + * mapping parameters to apply to frames which are allocated + * in the derived device. + * @return Zero on success, negative AVERROR code on failure. + */ +int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx, + enum AVPixelFormat format, + AVBufferRef *derived_device_ctx, + AVBufferRef *source_frame_ctx, + int flags); + +#endif /* AVUTIL_HWCONTEXT_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_cuda.h b/ffmpeg/inc/libavutil/hwcontext_cuda.h new file mode 100644 index 0000000..cefbe0c --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_cuda.h @@ -0,0 +1,69 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_CUDA_H +#define AVUTIL_HWCONTEXT_CUDA_H + +#ifndef CUDA_VERSION +#include +#endif + +#include "pixfmt.h" + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_CUDA. + * + * This API supports dynamic frame pools. AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a CUdeviceptr. + */ + +typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal; + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVCUDADeviceContext { + CUcontext cuda_ctx; + CUstream stream; + AVCUDADeviceContextInternal *internal; +} AVCUDADeviceContext; + +/** + * AVHWFramesContext.hwctx is currently not used + */ + +/** + * @defgroup hwcontext_cuda Device context creation flags + * + * Flags for av_hwdevice_ctx_create. + * + * @{ + */ + +/** + * Use primary device context instead of creating a new one. + */ +#define AV_CUDA_USE_PRIMARY_CONTEXT (1 << 0) + +/** + * @} + */ + +#endif /* AVUTIL_HWCONTEXT_CUDA_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_d3d11va.h b/ffmpeg/inc/libavutil/hwcontext_d3d11va.h new file mode 100644 index 0000000..9f91e9b --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_d3d11va.h @@ -0,0 +1,169 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_D3D11VA_H +#define AVUTIL_HWCONTEXT_D3D11VA_H + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_D3D11VA. + * + * The default pool implementation will be fixed-size if initial_pool_size is + * set (and allocate elements from an array texture). Otherwise it will allocate + * individual textures. Be aware that decoding requires a single array texture. + * + * Using sw_format==AV_PIX_FMT_YUV420P has special semantics, and maps to + * DXGI_FORMAT_420_OPAQUE. av_hwframe_transfer_data() is not supported for + * this format. Refer to MSDN for details. + * + * av_hwdevice_ctx_create() for this device type supports a key named "debug" + * for the AVDictionary entry. If this is set to any value, the device creation + * code will try to load various supported D3D debugging layers. + */ + +#include +#include + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVD3D11VADeviceContext { + /** + * Device used for texture creation and access. This can also be used to + * set the libavcodec decoding device. + * + * Must be set by the user. This is the only mandatory field - the other + * device context fields are set from this and are available for convenience. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11Device *device; + + /** + * If unset, this will be set from the device field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11DeviceContext *device_context; + + /** + * If unset, this will be set from the device field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11VideoDevice *video_device; + + /** + * If unset, this will be set from the device_context field on init. + * + * Deallocating the AVHWDeviceContext will always release this interface, + * and it does not matter whether it was user-allocated. + */ + ID3D11VideoContext *video_context; + + /** + * Callbacks for locking. They protect accesses to device_context and + * video_context calls. They also protect access to the internal staging + * texture (for av_hwframe_transfer_data() calls). They do NOT protect + * access to hwcontext or decoder state in general. + * + * If unset on init, the hwcontext implementation will set them to use an + * internal mutex. + * + * The underlying lock must be recursive. lock_ctx is for free use by the + * locking implementation. + */ + void (*lock)(void *lock_ctx); + void (*unlock)(void *lock_ctx); + void *lock_ctx; +} AVD3D11VADeviceContext; + +/** + * D3D11 frame descriptor for pool allocation. + * + * In user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer pointing at an object of this type describing the + * planes of the frame. + * + * This has no use outside of custom allocation, and AVFrame AVBufferRef do not + * necessarily point to an instance of this struct. + */ +typedef struct AVD3D11FrameDescriptor { + /** + * The texture in which the frame is located. The reference count is + * managed by the AVBufferRef, and destroying the reference will release + * the interface. + * + * Normally stored in AVFrame.data[0]. + */ + ID3D11Texture2D *texture; + + /** + * The index into the array texture element representing the frame, or 0 + * if the texture is not an array texture. + * + * Normally stored in AVFrame.data[1] (cast from intptr_t). + */ + intptr_t index; +} AVD3D11FrameDescriptor; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVD3D11VAFramesContext { + /** + * The canonical texture used for pool allocation. If this is set to NULL + * on init, the hwframes implementation will allocate and set an array + * texture if initial_pool_size > 0. + * + * The only situation when the API user should set this is: + * - the user wants to do manual pool allocation (setting + * AVHWFramesContext.pool), instead of letting AVHWFramesContext + * allocate the pool + * - of an array texture + * - and wants it to use it for decoding + * - this has to be done before calling av_hwframe_ctx_init() + * + * Deallocating the AVHWFramesContext will always release this interface, + * and it does not matter whether it was user-allocated. + * + * This is in particular used by the libavcodec D3D11VA hwaccel, which + * requires a single array texture. It will create ID3D11VideoDecoderOutputView + * objects for each array texture element on decoder initialization. + */ + ID3D11Texture2D *texture; + + /** + * D3D11_TEXTURE2D_DESC.BindFlags used for texture creation. The user must + * at least set D3D11_BIND_DECODER if the frames context is to be used for + * video decoding. + * This field is ignored/invalid if a user-allocated texture is provided. + */ + UINT BindFlags; + + /** + * D3D11_TEXTURE2D_DESC.MiscFlags used for texture creation. + * This field is ignored/invalid if a user-allocated texture is provided. + */ + UINT MiscFlags; +} AVD3D11VAFramesContext; + +#endif /* AVUTIL_HWCONTEXT_D3D11VA_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_drm.h b/ffmpeg/inc/libavutil/hwcontext_drm.h new file mode 100644 index 0000000..42709f2 --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_drm.h @@ -0,0 +1,169 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_DRM_H +#define AVUTIL_HWCONTEXT_DRM_H + +#include +#include + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_DRM. + * + * Internal frame allocation is not currently supported - all frames + * must be allocated by the user. Thus AVHWFramesContext is always + * NULL, though this may change if support for frame allocation is + * added in future. + */ + +enum { + /** + * The maximum number of layers/planes in a DRM frame. + */ + AV_DRM_MAX_PLANES = 4 +}; + +/** + * DRM object descriptor. + * + * Describes a single DRM object, addressing it as a PRIME file + * descriptor. + */ +typedef struct AVDRMObjectDescriptor { + /** + * DRM PRIME fd for the object. + */ + int fd; + /** + * Total size of the object. + * + * (This includes any parts not which do not contain image data.) + */ + size_t size; + /** + * Format modifier applied to the object (DRM_FORMAT_MOD_*). + * + * If the format modifier is unknown then this should be set to + * DRM_FORMAT_MOD_INVALID. + */ + uint64_t format_modifier; +} AVDRMObjectDescriptor; + +/** + * DRM plane descriptor. + * + * Describes a single plane of a layer, which is contained within + * a single object. + */ +typedef struct AVDRMPlaneDescriptor { + /** + * Index of the object containing this plane in the objects + * array of the enclosing frame descriptor. + */ + int object_index; + /** + * Offset within that object of this plane. + */ + ptrdiff_t offset; + /** + * Pitch (linesize) of this plane. + */ + ptrdiff_t pitch; +} AVDRMPlaneDescriptor; + +/** + * DRM layer descriptor. + * + * Describes a single layer within a frame. This has the structure + * defined by its format, and will contain one or more planes. + */ +typedef struct AVDRMLayerDescriptor { + /** + * Format of the layer (DRM_FORMAT_*). + */ + uint32_t format; + /** + * Number of planes in the layer. + * + * This must match the number of planes required by format. + */ + int nb_planes; + /** + * Array of planes in this layer. + */ + AVDRMPlaneDescriptor planes[AV_DRM_MAX_PLANES]; +} AVDRMLayerDescriptor; + +/** + * DRM frame descriptor. + * + * This is used as the data pointer for AV_PIX_FMT_DRM_PRIME frames. + * It is also used by user-allocated frame pools - allocating in + * AVHWFramesContext.pool must return AVBufferRefs which contain + * an object of this type. + * + * The fields of this structure should be set such it can be + * imported directly by EGL using the EGL_EXT_image_dma_buf_import + * and EGL_EXT_image_dma_buf_import_modifiers extensions. + * (Note that the exact layout of a particular format may vary between + * platforms - we only specify that the same platform should be able + * to import it.) + * + * The total number of planes must not exceed AV_DRM_MAX_PLANES, and + * the order of the planes by increasing layer index followed by + * increasing plane index must be the same as the order which would + * be used for the data pointers in the equivalent software format. + */ +typedef struct AVDRMFrameDescriptor { + /** + * Number of DRM objects making up this frame. + */ + int nb_objects; + /** + * Array of objects making up the frame. + */ + AVDRMObjectDescriptor objects[AV_DRM_MAX_PLANES]; + /** + * Number of layers in the frame. + */ + int nb_layers; + /** + * Array of layers in the frame. + */ + AVDRMLayerDescriptor layers[AV_DRM_MAX_PLANES]; +} AVDRMFrameDescriptor; + +/** + * DRM device. + * + * Allocated as AVHWDeviceContext.hwctx. + */ +typedef struct AVDRMDeviceContext { + /** + * File descriptor of DRM device. + * + * This is used as the device to create frames on, and may also be + * used in some derivation and mapping operations. + * + * If no device is required, set to -1. + */ + int fd; +} AVDRMDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_DRM_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_dxva2.h b/ffmpeg/inc/libavutil/hwcontext_dxva2.h new file mode 100644 index 0000000..e1b79bc --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_dxva2.h @@ -0,0 +1,75 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef AVUTIL_HWCONTEXT_DXVA2_H +#define AVUTIL_HWCONTEXT_DXVA2_H + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_DXVA2. + * + * Only fixed-size pools are supported. + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to a pointer to IDirect3DSurface9. + */ + +#include +#include + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVDXVA2DeviceContext { + IDirect3DDeviceManager9 *devmgr; +} AVDXVA2DeviceContext; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVDXVA2FramesContext { + /** + * The surface type (e.g. DXVA2_VideoProcessorRenderTarget or + * DXVA2_VideoDecoderRenderTarget). Must be set by the caller. + */ + DWORD surface_type; + + /** + * The surface pool. When an external pool is not provided by the caller, + * this will be managed (allocated and filled on init, freed on uninit) by + * libavutil. + */ + IDirect3DSurface9 **surfaces; + int nb_surfaces; + + /** + * Certain drivers require the decoder to be destroyed before the surfaces. + * To allow internally managed pools to work properly in such cases, this + * field is provided. + * + * If it is non-NULL, libavutil will call IDirectXVideoDecoder_Release() on + * it just before the internal surface pool is freed. + * + * This is for convenience only. Some code uses other methods to manage the + * decoder reference. + */ + IDirectXVideoDecoder *decoder_to_release; +} AVDXVA2FramesContext; + +#endif /* AVUTIL_HWCONTEXT_DXVA2_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_mediacodec.h b/ffmpeg/inc/libavutil/hwcontext_mediacodec.h new file mode 100644 index 0000000..101a980 --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_mediacodec.h @@ -0,0 +1,36 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_MEDIACODEC_H +#define AVUTIL_HWCONTEXT_MEDIACODEC_H + +/** + * MediaCodec details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVMediaCodecDeviceContext { + /** + * android/view/Surface handle, to be filled by the user. + * + * This is the default surface used by decoders on this device. + */ + void *surface; +} AVMediaCodecDeviceContext; + +#endif /* AVUTIL_HWCONTEXT_MEDIACODEC_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_opencl.h b/ffmpeg/inc/libavutil/hwcontext_opencl.h new file mode 100644 index 0000000..ef54486 --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_opencl.h @@ -0,0 +1,100 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_OPENCL_H +#define AVUTIL_HWCONTEXT_OPENCL_H + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "frame.h" + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_OPENCL. + * + * Pools allocated internally are always dynamic, and are primarily intended + * to be used in OpenCL-only cases. If interoperation is required, it is + * typically required to allocate frames in the other API and then map the + * frames context to OpenCL with av_hwframe_ctx_create_derived(). + */ + +/** + * OpenCL frame descriptor for pool allocation. + * + * In user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer pointing at an object of this type describing the + * planes of the frame. + */ +typedef struct AVOpenCLFrameDescriptor { + /** + * Number of planes in the frame. + */ + int nb_planes; + /** + * OpenCL image2d objects for each plane of the frame. + */ + cl_mem planes[AV_NUM_DATA_POINTERS]; +} AVOpenCLFrameDescriptor; + +/** + * OpenCL device details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVOpenCLDeviceContext { + /** + * The primary device ID of the device. If multiple OpenCL devices + * are associated with the context then this is the one which will + * be used for all operations internal to FFmpeg. + */ + cl_device_id device_id; + /** + * The OpenCL context which will contain all operations and frames on + * this device. + */ + cl_context context; + /** + * The default command queue for this device, which will be used by all + * frames contexts which do not have their own command queue. If not + * intialised by the user, a default queue will be created on the + * primary device. + */ + cl_command_queue command_queue; +} AVOpenCLDeviceContext; + +/** + * OpenCL-specific data associated with a frame pool. + * + * Allocated as AVHWFramesContext.hwctx. + */ +typedef struct AVOpenCLFramesContext { + /** + * The command queue used for internal asynchronous operations on this + * device (av_hwframe_transfer_data(), av_hwframe_map()). + * + * If this is not set, the command queue from the associated device is + * used instead. + */ + cl_command_queue command_queue; +} AVOpenCLFramesContext; + +#endif /* AVUTIL_HWCONTEXT_OPENCL_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_qsv.h b/ffmpeg/inc/libavutil/hwcontext_qsv.h new file mode 100644 index 0000000..b98d611 --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_qsv.h @@ -0,0 +1,53 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_QSV_H +#define AVUTIL_HWCONTEXT_QSV_H + +#include + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_QSV. + * + * This API does not support dynamic frame pools. AVHWFramesContext.pool must + * contain AVBufferRefs whose data pointer points to an mfxFrameSurface1 struct. + */ + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVQSVDeviceContext { + mfxSession session; +} AVQSVDeviceContext; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + */ +typedef struct AVQSVFramesContext { + mfxFrameSurface1 *surfaces; + int nb_surfaces; + + /** + * A combination of MFX_MEMTYPE_* describing the frame pool. + */ + int frame_type; +} AVQSVFramesContext; + +#endif /* AVUTIL_HWCONTEXT_QSV_H */ + diff --git a/ffmpeg/inc/libavutil/hwcontext_vaapi.h b/ffmpeg/inc/libavutil/hwcontext_vaapi.h new file mode 100644 index 0000000..0b2e071 --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_vaapi.h @@ -0,0 +1,117 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VAAPI_H +#define AVUTIL_HWCONTEXT_VAAPI_H + +#include + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_VAAPI. + * + * Dynamic frame pools are supported, but note that any pool used as a render + * target is required to be of fixed size in order to be be usable as an + * argument to vaCreateContext(). + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to a VASurfaceID. + */ + +enum { + /** + * The quirks field has been set by the user and should not be detected + * automatically by av_hwdevice_ctx_init(). + */ + AV_VAAPI_DRIVER_QUIRK_USER_SET = (1 << 0), + /** + * The driver does not destroy parameter buffers when they are used by + * vaRenderPicture(). Additional code will be required to destroy them + * separately afterwards. + */ + AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS = (1 << 1), + + /** + * The driver does not support the VASurfaceAttribMemoryType attribute, + * so the surface allocation code will not try to use it. + */ + AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2), + + /** + * The driver does not support surface attributes at all. + * The surface allocation code will never pass them to surface allocation, + * and the results of the vaQuerySurfaceAttributes() call will be faked. + */ + AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES = (1 << 3), +}; + +/** + * VAAPI connection details. + * + * Allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVVAAPIDeviceContext { + /** + * The VADisplay handle, to be filled by the user. + */ + VADisplay display; + /** + * Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), + * with reference to a table of known drivers, unless the + * AV_VAAPI_DRIVER_QUIRK_USER_SET bit is already present. The user + * may need to refer to this field when performing any later + * operations using VAAPI with the same VADisplay. + */ + unsigned int driver_quirks; +} AVVAAPIDeviceContext; + +/** + * VAAPI-specific data associated with a frame pool. + * + * Allocated as AVHWFramesContext.hwctx. + */ +typedef struct AVVAAPIFramesContext { + /** + * Set by the user to apply surface attributes to all surfaces in + * the frame pool. If null, default settings are used. + */ + VASurfaceAttrib *attributes; + int nb_attributes; + /** + * The surfaces IDs of all surfaces in the pool after creation. + * Only valid if AVHWFramesContext.initial_pool_size was positive. + * These are intended to be used as the render_targets arguments to + * vaCreateContext(). + */ + VASurfaceID *surface_ids; + int nb_surfaces; +} AVVAAPIFramesContext; + +/** + * VAAPI hardware pipeline configuration details. + * + * Allocated with av_hwdevice_hwconfig_alloc(). + */ +typedef struct AVVAAPIHWConfig { + /** + * ID of a VAAPI pipeline configuration. + */ + VAConfigID config_id; +} AVVAAPIHWConfig; + +#endif /* AVUTIL_HWCONTEXT_VAAPI_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_vdpau.h b/ffmpeg/inc/libavutil/hwcontext_vdpau.h new file mode 100644 index 0000000..1b7ea1e --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_vdpau.h @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VDPAU_H +#define AVUTIL_HWCONTEXT_VDPAU_H + +#include + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_VDPAU. + * + * This API supports dynamic frame pools. AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a VdpVideoSurface. + */ + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + */ +typedef struct AVVDPAUDeviceContext { + VdpDevice device; + VdpGetProcAddress *get_proc_address; +} AVVDPAUDeviceContext; + +/** + * AVHWFramesContext.hwctx is currently not used + */ + +#endif /* AVUTIL_HWCONTEXT_VDPAU_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_videotoolbox.h b/ffmpeg/inc/libavutil/hwcontext_videotoolbox.h new file mode 100644 index 0000000..5074d79 --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_videotoolbox.h @@ -0,0 +1,60 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H +#define AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H + +#include + +#include + +#include "pixfmt.h" + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_VIDEOTOOLBOX. + * + * This API currently does not support frame allocation, as the raw VideoToolbox + * API does allocation, and FFmpeg itself never has the need to allocate frames. + * + * If the API user sets a custom pool, AVHWFramesContext.pool must return + * AVBufferRefs whose data pointer is a CVImageBufferRef or CVPixelBufferRef. + * + * Currently AVHWDeviceContext.hwctx and AVHWFramesContext.hwctx are always + * NULL. + */ + +/** + * Convert a VideoToolbox (actually CoreVideo) format to AVPixelFormat. + * Returns AV_PIX_FMT_NONE if no known equivalent was found. + */ +enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt); + +/** + * Convert an AVPixelFormat to a VideoToolbox (actually CoreVideo) format. + * Returns 0 if no known equivalent was found. + */ +uint32_t av_map_videotoolbox_format_from_pixfmt(enum AVPixelFormat pix_fmt); + +/** + * Same as av_map_videotoolbox_format_from_pixfmt function, but can map and + * return full range pixel formats via a flag. + */ +uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range); + +#endif /* AVUTIL_HWCONTEXT_VIDEOTOOLBOX_H */ diff --git a/ffmpeg/inc/libavutil/hwcontext_vulkan.h b/ffmpeg/inc/libavutil/hwcontext_vulkan.h new file mode 100644 index 0000000..5cbeb8e --- /dev/null +++ b/ffmpeg/inc/libavutil/hwcontext_vulkan.h @@ -0,0 +1,204 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HWCONTEXT_VULKAN_H +#define AVUTIL_HWCONTEXT_VULKAN_H + +#include + +#include "pixfmt.h" +#include "frame.h" + +/** + * @file + * API-specific header for AV_HWDEVICE_TYPE_VULKAN. + * + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs + * with the data pointer set to an AVVkFrame. + */ + +/** + * Main Vulkan context, allocated as AVHWDeviceContext.hwctx. + * All of these can be set before init to change what the context uses + */ +typedef struct AVVulkanDeviceContext { + /** + * Custom memory allocator, else NULL + */ + const VkAllocationCallbacks *alloc; + /** + * Vulkan instance. Must be at least version 1.1. + */ + VkInstance inst; + /** + * Physical device + */ + VkPhysicalDevice phys_dev; + /** + * Active device + */ + VkDevice act_dev; + /** + * Queue family index for graphics + * @note av_hwdevice_create() will set all 3 queue indices if unset + * If there is no dedicated queue for compute or transfer operations, + * they will be set to the graphics queue index which can handle both. + * nb_graphics_queues indicates how many queues were enabled for the + * graphics queue (must be at least 1) + */ + int queue_family_index; + int nb_graphics_queues; + /** + * Queue family index to use for transfer operations, and the amount of queues + * enabled. In case there is no dedicated transfer queue, nb_tx_queues + * must be 0 and queue_family_tx_index must be the same as either the graphics + * queue or the compute queue, if available. + */ + int queue_family_tx_index; + int nb_tx_queues; + /** + * Queue family index for compute ops, and the amount of queues enabled. + * In case there are no dedicated compute queues, nb_comp_queues must be + * 0 and its queue family index must be set to the graphics queue. + */ + int queue_family_comp_index; + int nb_comp_queues; + /** + * Enabled instance extensions. + * If supplying your own device context, set this to an array of strings, with + * each entry containing the specified Vulkan extension string to enable. + * Duplicates are possible and accepted. + * If no extensions are enabled, set these fields to NULL, and 0 respectively. + */ + const char * const *enabled_inst_extensions; + int nb_enabled_inst_extensions; + /** + * Enabled device extensions. By default, VK_KHR_external_memory_fd, + * VK_EXT_external_memory_dma_buf, VK_EXT_image_drm_format_modifier, + * VK_KHR_external_semaphore_fd and VK_EXT_external_memory_host are enabled if found. + * If supplying your own device context, these fields takes the same format as + * the above fields, with the same conditions that duplicates are possible + * and accepted, and that NULL and 0 respectively means no extensions are enabled. + */ + const char * const *enabled_dev_extensions; + int nb_enabled_dev_extensions; + /** + * This structure should be set to the set of features that present and enabled + * during device creation. When a device is created by FFmpeg, it will default to + * enabling all that are present of the shaderImageGatherExtended, + * fragmentStoresAndAtomics, shaderInt64 and vertexPipelineStoresAndAtomics features. + */ + VkPhysicalDeviceFeatures2 device_features; +} AVVulkanDeviceContext; + +/** + * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options + */ +typedef struct AVVulkanFramesContext { + /** + * Controls the tiling of allocated frames. + */ + VkImageTiling tiling; + /** + * Defines extra usage of output frames. If left as 0, the following bits + * are set: TRANSFER_SRC, TRANSFER_DST. SAMPLED and STORAGE. + */ + VkImageUsageFlagBits usage; + /** + * Extension data for image creation. + */ + void *create_pnext; + /** + * Extension data for memory allocation. Must have as many entries as + * the number of planes of the sw_format. + * This will be chained to VkExportMemoryAllocateInfo, which is used + * to make all pool images exportable to other APIs if the necessary + * extensions are present in enabled_dev_extensions. + */ + void *alloc_pnext[AV_NUM_DATA_POINTERS]; +} AVVulkanFramesContext; + +/* + * Frame structure, the VkFormat of the image will always match + * the pool's sw_format. + * All frames, imported or allocated, will be created with the + * VK_IMAGE_CREATE_ALIAS_BIT flag set, so the memory may be aliased if needed. + * + * If all three queue family indices in the device context are the same, + * images will be created with the EXCLUSIVE sharing mode. Otherwise, all images + * will be created using the CONCURRENT sharing mode. + * + * @note the size of this structure is not part of the ABI, to allocate + * you must use @av_vk_frame_alloc(). + */ +typedef struct AVVkFrame { + /** + * Vulkan images to which the memory is bound to. + */ + VkImage img[AV_NUM_DATA_POINTERS]; + + /** + * The same tiling must be used for all images in the frame. + */ + VkImageTiling tiling; + + /** + * Memory backing the images. Could be less than the amount of images + * if importing from a DRM or VAAPI frame. + */ + VkDeviceMemory mem[AV_NUM_DATA_POINTERS]; + size_t size[AV_NUM_DATA_POINTERS]; + + /** + * OR'd flags for all memory allocated + */ + VkMemoryPropertyFlagBits flags; + + /** + * Updated after every barrier + */ + VkAccessFlagBits access[AV_NUM_DATA_POINTERS]; + VkImageLayout layout[AV_NUM_DATA_POINTERS]; + + /** + * Synchronization semaphores. Must not be freed manually. Must be waited on + * and signalled at every queue submission. + * Could be less than the amount of images: either one per VkDeviceMemory + * or one for the entire frame. All others will be set to VK_NULL_HANDLE. + */ + VkSemaphore sem[AV_NUM_DATA_POINTERS]; + + /** + * Internal data. + */ + struct AVVkFrameInternal *internal; +} AVVkFrame; + +/** + * Allocates a single AVVkFrame and initializes everything as 0. + * @note Must be freed via av_free() + */ +AVVkFrame *av_vk_frame_alloc(void); + +/** + * Returns the format of each image up to the number of planes for a given sw_format. + * Returns NULL on unsupported formats. + */ +const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p); + +#endif /* AVUTIL_HWCONTEXT_VULKAN_H */ diff --git a/ffmpeg/inc/libavutil/imgutils.h b/ffmpeg/inc/libavutil/imgutils.h new file mode 100644 index 0000000..5b790ec --- /dev/null +++ b/ffmpeg/inc/libavutil/imgutils.h @@ -0,0 +1,277 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_IMGUTILS_H +#define AVUTIL_IMGUTILS_H + +/** + * @file + * misc image utilities + * + * @addtogroup lavu_picture + * @{ + */ + +#include "avutil.h" +#include "pixdesc.h" +#include "rational.h" + +/** + * Compute the max pixel step for each plane of an image with a + * format described by pixdesc. + * + * The pixel step is the distance in bytes between the first byte of + * the group of bytes which describe a pixel component and the first + * byte of the successive group in the same plane for the same + * component. + * + * @param max_pixsteps an array which is filled with the max pixel step + * for each plane. Since a plane may contain different pixel + * components, the computed max_pixsteps[plane] is relative to the + * component in the plane with the max pixel step. + * @param max_pixstep_comps an array which is filled with the component + * for each plane which has the max pixel step. May be NULL. + */ +void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], + const AVPixFmtDescriptor *pixdesc); + +/** + * Compute the size of an image line with format pix_fmt and width + * width for the plane plane. + * + * @return the computed size in bytes + */ +int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane); + +/** + * Fill plane linesizes for an image with pixel format pix_fmt and + * width width. + * + * @param linesizes array to be filled with the linesize for each plane + * @return >= 0 in case of success, a negative error code otherwise + */ +int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width); + +/** + * Fill plane data pointers for an image with pixel format pix_fmt and + * height height. + * + * @param data pointers array to be filled with the pointer for each image plane + * @param ptr the pointer to a buffer which will contain the image + * @param linesizes the array containing the linesize for each + * plane, should be filled by av_image_fill_linesizes() + * @return the size in bytes required for the image buffer, a negative + * error code in case of failure + */ +int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, + uint8_t *ptr, const int linesizes[4]); + +/** + * Allocate an image with size w and h and pixel format pix_fmt, and + * fill pointers and linesizes accordingly. + * The allocated image buffer has to be freed by using + * av_freep(&pointers[0]). + * + * @param align the value to use for buffer size alignment + * @return the size in bytes required for the image buffer, a negative + * error code in case of failure + */ +int av_image_alloc(uint8_t *pointers[4], int linesizes[4], + int w, int h, enum AVPixelFormat pix_fmt, int align); + +/** + * Copy image plane from src to dst. + * That is, copy "height" number of lines of "bytewidth" bytes each. + * The first byte of each successive line is separated by *_linesize + * bytes. + * + * bytewidth must be contained by both absolute values of dst_linesize + * and src_linesize, otherwise the function behavior is undefined. + * + * @param dst_linesize linesize for the image plane in dst + * @param src_linesize linesize for the image plane in src + */ +void av_image_copy_plane(uint8_t *dst, int dst_linesize, + const uint8_t *src, int src_linesize, + int bytewidth, int height); + +/** + * Copy image in src_data to dst_data. + * + * @param dst_linesizes linesizes for the image in dst_data + * @param src_linesizes linesizes for the image in src_data + */ +void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], + const uint8_t *src_data[4], const int src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * Copy image data located in uncacheable (e.g. GPU mapped) memory. Where + * available, this function will use special functionality for reading from such + * memory, which may result in greatly improved performance compared to plain + * av_image_copy(). + * + * The data pointers and the linesizes must be aligned to the maximum required + * by the CPU architecture. + * + * @note The linesize parameters have the type ptrdiff_t here, while they are + * int for av_image_copy(). + * @note On x86, the linesizes currently need to be aligned to the cacheline + * size (i.e. 64) to get improved performance. + */ +void av_image_copy_uc_from(uint8_t *dst_data[4], const ptrdiff_t dst_linesizes[4], + const uint8_t *src_data[4], const ptrdiff_t src_linesizes[4], + enum AVPixelFormat pix_fmt, int width, int height); + +/** + * Setup the data pointers and linesizes based on the specified image + * parameters and the provided array. + * + * The fields of the given image are filled in by using the src + * address which points to the image data buffer. Depending on the + * specified pixel format, one or multiple image data pointers and + * line sizes will be set. If a planar format is specified, several + * pointers will be set pointing to the different picture planes and + * the line sizes of the different planes will be stored in the + * lines_sizes array. Call with src == NULL to get the required + * size for the src buffer. + * + * To allocate the buffer and fill in the dst_data and dst_linesize in + * one call, use av_image_alloc(). + * + * @param dst_data data pointers to be filled in + * @param dst_linesize linesizes for the image in dst_data to be filled in + * @param src buffer which will contain or contains the actual image data, can be NULL + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param align the value used in src for linesize alignment + * @return the size in bytes required for src, a negative error code + * in case of failure + */ +int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], + const uint8_t *src, + enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Return the size in bytes of the amount of data required to store an + * image with the given parameters. + * + * @param pix_fmt the pixel format of the image + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param align the assumed linesize alignment + * @return the buffer size in bytes, a negative error code in case of failure + */ +int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Copy image data from an image into a buffer. + * + * av_image_get_buffer_size() can be used to compute the required size + * for the buffer to fill. + * + * @param dst a buffer into which picture data will be copied + * @param dst_size the size in bytes of dst + * @param src_data pointers containing the source image data + * @param src_linesize linesizes for the image in src_data + * @param pix_fmt the pixel format of the source image + * @param width the width of the source image in pixels + * @param height the height of the source image in pixels + * @param align the assumed linesize alignment for dst + * @return the number of bytes written to dst, or a negative value + * (error code) on error + */ +int av_image_copy_to_buffer(uint8_t *dst, int dst_size, + const uint8_t * const src_data[4], const int src_linesize[4], + enum AVPixelFormat pix_fmt, int width, int height, int align); + +/** + * Check if the given dimension of an image is valid, meaning that all + * bytes of the image can be addressed with a signed int. + * + * @param w the width of the picture + * @param h the height of the picture + * @param log_offset the offset to sum to the log level for logging with log_ctx + * @param log_ctx the parent logging context, it may be NULL + * @return >= 0 if valid, a negative error code otherwise + */ +int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx); + +/** + * Check if the given dimension of an image is valid, meaning that all + * bytes of a plane of an image with the specified pix_fmt can be addressed + * with a signed int. + * + * @param w the width of the picture + * @param h the height of the picture + * @param max_pixels the maximum number of pixels the user wants to accept + * @param pix_fmt the pixel format, can be AV_PIX_FMT_NONE if unknown. + * @param log_offset the offset to sum to the log level for logging with log_ctx + * @param log_ctx the parent logging context, it may be NULL + * @return >= 0 if valid, a negative error code otherwise + */ +int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx); + +/** + * Check if the given sample aspect ratio of an image is valid. + * + * It is considered invalid if the denominator is 0 or if applying the ratio + * to the image size would make the smaller dimension less than 1. If the + * sar numerator is 0, it is considered unknown and will return as valid. + * + * @param w width of the image + * @param h height of the image + * @param sar sample aspect ratio of the image + * @return 0 if valid, a negative AVERROR code otherwise + */ +int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar); + +/** + * Overwrite the image data with black. This is suitable for filling a + * sub-rectangle of an image, meaning the padding between the right most pixel + * and the left most pixel on the next line will not be overwritten. For some + * formats, the image size might be rounded up due to inherent alignment. + * + * If the pixel format has alpha, the alpha is cleared to opaque. + * + * This can return an error if the pixel format is not supported. Normally, all + * non-hwaccel pixel formats should be supported. + * + * Passing NULL for dst_data is allowed. Then the function returns whether the + * operation would have succeeded. (It can return an error if the pix_fmt is + * not supported.) + * + * @param dst_data data pointers to destination image + * @param dst_linesize linesizes for the destination image + * @param pix_fmt the pixel format of the image + * @param range the color range of the image (important for colorspaces such as YUV) + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return 0 if the image data was cleared, a negative AVERROR code otherwise + */ +int av_image_fill_black(uint8_t *dst_data[4], const ptrdiff_t dst_linesize[4], + enum AVPixelFormat pix_fmt, enum AVColorRange range, + int width, int height); + +/** + * @} + */ + + +#endif /* AVUTIL_IMGUTILS_H */ diff --git a/ffmpeg/inc/libavutil/intfloat.h b/ffmpeg/inc/libavutil/intfloat.h new file mode 100644 index 0000000..fe3d7ec --- /dev/null +++ b/ffmpeg/inc/libavutil/intfloat.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Mans Rullgard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTFLOAT_H +#define AVUTIL_INTFLOAT_H + +#include +#include "attributes.h" + +union av_intfloat32 { + uint32_t i; + float f; +}; + +union av_intfloat64 { + uint64_t i; + double f; +}; + +/** + * Reinterpret a 32-bit integer as a float. + */ +static av_always_inline float av_int2float(uint32_t i) +{ + union av_intfloat32 v; + v.i = i; + return v.f; +} + +/** + * Reinterpret a float as a 32-bit integer. + */ +static av_always_inline uint32_t av_float2int(float f) +{ + union av_intfloat32 v; + v.f = f; + return v.i; +} + +/** + * Reinterpret a 64-bit integer as a double. + */ +static av_always_inline double av_int2double(uint64_t i) +{ + union av_intfloat64 v; + v.i = i; + return v.f; +} + +/** + * Reinterpret a double as a 64-bit integer. + */ +static av_always_inline uint64_t av_double2int(double f) +{ + union av_intfloat64 v; + v.f = f; + return v.i; +} + +#endif /* AVUTIL_INTFLOAT_H */ diff --git a/ffmpeg/inc/libavutil/intreadwrite.h b/ffmpeg/inc/libavutil/intreadwrite.h new file mode 100644 index 0000000..4c8413a --- /dev/null +++ b/ffmpeg/inc/libavutil/intreadwrite.h @@ -0,0 +1,644 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTREADWRITE_H +#define AVUTIL_INTREADWRITE_H + +#include +#include "libavutil/avconfig.h" +#include "attributes.h" +#include "bswap.h" + +typedef union { + uint64_t u64; + uint32_t u32[2]; + uint16_t u16[4]; + uint8_t u8 [8]; + double f64; + float f32[2]; +} av_alias av_alias64; + +typedef union { + uint32_t u32; + uint16_t u16[2]; + uint8_t u8 [4]; + float f32; +} av_alias av_alias32; + +typedef union { + uint16_t u16; + uint8_t u8 [2]; +} av_alias av_alias16; + +/* + * Arch-specific headers can provide any combination of + * AV_[RW][BLN](16|24|32|48|64) and AV_(COPY|SWAP|ZERO)(64|128) macros. + * Preprocessor symbols must be defined, even if these are implemented + * as inline functions. + * + * R/W means read/write, B/L/N means big/little/native endianness. + * The following macros require aligned access, compared to their + * unaligned variants: AV_(COPY|SWAP|ZERO)(64|128), AV_[RW]N[8-64]A. + * Incorrect usage may range from abysmal performance to crash + * depending on the platform. + * + * The unaligned variants are AV_[RW][BLN][8-64] and AV_COPY*U. + */ + +#ifdef HAVE_AV_CONFIG_H + +#include "config.h" + +#if ARCH_ARM +# include "arm/intreadwrite.h" +#elif ARCH_AVR32 +# include "avr32/intreadwrite.h" +#elif ARCH_MIPS +# include "mips/intreadwrite.h" +#elif ARCH_PPC +# include "ppc/intreadwrite.h" +#elif ARCH_TOMI +# include "tomi/intreadwrite.h" +#elif ARCH_X86 +# include "x86/intreadwrite.h" +#endif + +#endif /* HAVE_AV_CONFIG_H */ + +/* + * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers. + */ + +#if AV_HAVE_BIGENDIAN + +# if defined(AV_RN16) && !defined(AV_RB16) +# define AV_RB16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RB16) +# define AV_RN16(p) AV_RB16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WB16) +# define AV_WB16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WB16) +# define AV_WN16(p, v) AV_WB16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RB24) +# define AV_RB24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RB24) +# define AV_RN24(p) AV_RB24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WB24) +# define AV_WB24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WB24) +# define AV_WN24(p, v) AV_WB24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RB32) +# define AV_RB32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RB32) +# define AV_RN32(p) AV_RB32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WB32) +# define AV_WB32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WB32) +# define AV_WN32(p, v) AV_WB32(p, v) +# endif + +# if defined(AV_RN48) && !defined(AV_RB48) +# define AV_RB48(p) AV_RN48(p) +# elif !defined(AV_RN48) && defined(AV_RB48) +# define AV_RN48(p) AV_RB48(p) +# endif + +# if defined(AV_WN48) && !defined(AV_WB48) +# define AV_WB48(p, v) AV_WN48(p, v) +# elif !defined(AV_WN48) && defined(AV_WB48) +# define AV_WN48(p, v) AV_WB48(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RB64) +# define AV_RB64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RB64) +# define AV_RN64(p) AV_RB64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WB64) +# define AV_WB64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WB64) +# define AV_WN64(p, v) AV_WB64(p, v) +# endif + +#else /* AV_HAVE_BIGENDIAN */ + +# if defined(AV_RN16) && !defined(AV_RL16) +# define AV_RL16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RL16) +# define AV_RN16(p) AV_RL16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WL16) +# define AV_WL16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WL16) +# define AV_WN16(p, v) AV_WL16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RL24) +# define AV_RL24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RL24) +# define AV_RN24(p) AV_RL24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WL24) +# define AV_WL24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WL24) +# define AV_WN24(p, v) AV_WL24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RL32) +# define AV_RL32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RL32) +# define AV_RN32(p) AV_RL32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WL32) +# define AV_WL32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WL32) +# define AV_WN32(p, v) AV_WL32(p, v) +# endif + +# if defined(AV_RN48) && !defined(AV_RL48) +# define AV_RL48(p) AV_RN48(p) +# elif !defined(AV_RN48) && defined(AV_RL48) +# define AV_RN48(p) AV_RL48(p) +# endif + +# if defined(AV_WN48) && !defined(AV_WL48) +# define AV_WL48(p, v) AV_WN48(p, v) +# elif !defined(AV_WN48) && defined(AV_WL48) +# define AV_WN48(p, v) AV_WL48(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RL64) +# define AV_RL64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RL64) +# define AV_RN64(p) AV_RL64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WL64) +# define AV_WL64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WL64) +# define AV_WN64(p, v) AV_WL64(p, v) +# endif + +#endif /* !AV_HAVE_BIGENDIAN */ + +/* + * Define AV_[RW]N helper macros to simplify definitions not provided + * by per-arch headers. + */ + +#if defined(__GNUC__) + +union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; +union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; +union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; + +# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) +# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) + +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_X64) || defined(_M_ARM64)) && AV_HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) +# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) + +#elif AV_HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s) +# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#else + +#ifndef AV_RB16 +# define AV_RB16(x) \ + ((((const uint8_t*)(x))[0] << 8) | \ + ((const uint8_t*)(x))[1]) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, val) do { \ + uint16_t d = (val); \ + ((uint8_t*)(p))[1] = (d); \ + ((uint8_t*)(p))[0] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RL16 +# define AV_RL16(x) \ + ((((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, val) do { \ + uint16_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RB32 +# define AV_RB32(x) \ + (((uint32_t)((const uint8_t*)(x))[0] << 24) | \ + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) +#endif +#ifndef AV_WB32 +# define AV_WB32(p, val) do { \ + uint32_t d = (val); \ + ((uint8_t*)(p))[3] = (d); \ + ((uint8_t*)(p))[2] = (d)>>8; \ + ((uint8_t*)(p))[1] = (d)>>16; \ + ((uint8_t*)(p))[0] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RL32 +# define AV_RL32(x) \ + (((uint32_t)((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, val) do { \ + uint32_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RB64 +# define AV_RB64(x) \ + (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 8) | \ + (uint64_t)((const uint8_t*)(x))[7]) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, val) do { \ + uint64_t d = (val); \ + ((uint8_t*)(p))[7] = (d); \ + ((uint8_t*)(p))[6] = (d)>>8; \ + ((uint8_t*)(p))[5] = (d)>>16; \ + ((uint8_t*)(p))[4] = (d)>>24; \ + ((uint8_t*)(p))[3] = (d)>>32; \ + ((uint8_t*)(p))[2] = (d)>>40; \ + ((uint8_t*)(p))[1] = (d)>>48; \ + ((uint8_t*)(p))[0] = (d)>>56; \ + } while(0) +#endif + +#ifndef AV_RL64 +# define AV_RL64(x) \ + (((uint64_t)((const uint8_t*)(x))[7] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, val) do { \ + uint64_t d = (val); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + ((uint8_t*)(p))[6] = (d)>>48; \ + ((uint8_t*)(p))[7] = (d)>>56; \ + } while(0) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RN(s, p) AV_RB##s(p) +# define AV_WN(s, p, v) AV_WB##s(p, v) +#else +# define AV_RN(s, p) AV_RL##s(p) +# define AV_WN(s, p, v) AV_WL##s(p, v) +#endif + +#endif /* HAVE_FAST_UNALIGNED */ + +#ifndef AV_RN16 +# define AV_RN16(p) AV_RN(16, p) +#endif + +#ifndef AV_RN32 +# define AV_RN32(p) AV_RN(32, p) +#endif + +#ifndef AV_RN64 +# define AV_RN64(p) AV_RN(64, p) +#endif + +#ifndef AV_WN16 +# define AV_WN16(p, v) AV_WN(16, p, v) +#endif + +#ifndef AV_WN32 +# define AV_WN32(p, v) AV_WN(32, p, v) +#endif + +#ifndef AV_WN64 +# define AV_WN64(p, v) AV_WN(64, p, v) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RB(s, p) AV_RN##s(p) +# define AV_WB(s, p, v) AV_WN##s(p, v) +# define AV_RL(s, p) av_bswap##s(AV_RN##s(p)) +# define AV_WL(s, p, v) AV_WN##s(p, av_bswap##s(v)) +#else +# define AV_RB(s, p) av_bswap##s(AV_RN##s(p)) +# define AV_WB(s, p, v) AV_WN##s(p, av_bswap##s(v)) +# define AV_RL(s, p) AV_RN##s(p) +# define AV_WL(s, p, v) AV_WN##s(p, v) +#endif + +#define AV_RB8(x) (((const uint8_t*)(x))[0]) +#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0) + +#define AV_RL8(x) AV_RB8(x) +#define AV_WL8(p, d) AV_WB8(p, d) + +#ifndef AV_RB16 +# define AV_RB16(p) AV_RB(16, p) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, v) AV_WB(16, p, v) +#endif + +#ifndef AV_RL16 +# define AV_RL16(p) AV_RL(16, p) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, v) AV_WL(16, p, v) +#endif + +#ifndef AV_RB32 +# define AV_RB32(p) AV_RB(32, p) +#endif +#ifndef AV_WB32 +# define AV_WB32(p, v) AV_WB(32, p, v) +#endif + +#ifndef AV_RL32 +# define AV_RL32(p) AV_RL(32, p) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, v) AV_WL(32, p, v) +#endif + +#ifndef AV_RB64 +# define AV_RB64(p) AV_RB(64, p) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, v) AV_WB(64, p, v) +#endif + +#ifndef AV_RL64 +# define AV_RL64(p) AV_RL(64, p) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, v) AV_WL(64, p, v) +#endif + +#ifndef AV_RB24 +# define AV_RB24(x) \ + ((((const uint8_t*)(x))[0] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[2]) +#endif +#ifndef AV_WB24 +# define AV_WB24(p, d) do { \ + ((uint8_t*)(p))[2] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[0] = (d)>>16; \ + } while(0) +#endif + +#ifndef AV_RL24 +# define AV_RL24(x) \ + ((((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL24 +# define AV_WL24(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + } while(0) +#endif + +#ifndef AV_RB48 +# define AV_RB48(x) \ + (((uint64_t)((const uint8_t*)(x))[0] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 8) | \ + (uint64_t)((const uint8_t*)(x))[5]) +#endif +#ifndef AV_WB48 +# define AV_WB48(p, darg) do { \ + uint64_t d = (darg); \ + ((uint8_t*)(p))[5] = (d); \ + ((uint8_t*)(p))[4] = (d)>>8; \ + ((uint8_t*)(p))[3] = (d)>>16; \ + ((uint8_t*)(p))[2] = (d)>>24; \ + ((uint8_t*)(p))[1] = (d)>>32; \ + ((uint8_t*)(p))[0] = (d)>>40; \ + } while(0) +#endif + +#ifndef AV_RL48 +# define AV_RL48(x) \ + (((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL48 +# define AV_WL48(p, darg) do { \ + uint64_t d = (darg); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + } while(0) +#endif + +/* + * The AV_[RW]NA macros access naturally aligned data + * in a type-safe way. + */ + +#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s) +#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#ifndef AV_RN16A +# define AV_RN16A(p) AV_RNA(16, p) +#endif + +#ifndef AV_RN32A +# define AV_RN32A(p) AV_RNA(32, p) +#endif + +#ifndef AV_RN64A +# define AV_RN64A(p) AV_RNA(64, p) +#endif + +#ifndef AV_WN16A +# define AV_WN16A(p, v) AV_WNA(16, p, v) +#endif + +#ifndef AV_WN32A +# define AV_WN32A(p, v) AV_WNA(32, p, v) +#endif + +#ifndef AV_WN64A +# define AV_WN64A(p, v) AV_WNA(64, p, v) +#endif + +#if AV_HAVE_BIGENDIAN +# define AV_RLA(s, p) av_bswap##s(AV_RN##s##A(p)) +# define AV_WLA(s, p, v) AV_WN##s##A(p, av_bswap##s(v)) +#else +# define AV_RLA(s, p) AV_RN##s##A(p) +# define AV_WLA(s, p, v) AV_WN##s##A(p, v) +#endif + +#ifndef AV_RL64A +# define AV_RL64A(p) AV_RLA(64, p) +#endif +#ifndef AV_WL64A +# define AV_WL64A(p, v) AV_WLA(64, p, v) +#endif + +/* + * The AV_COPYxxU macros are suitable for copying data to/from unaligned + * memory locations. + */ + +#define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s)); + +#ifndef AV_COPY16U +# define AV_COPY16U(d, s) AV_COPYU(16, d, s) +#endif + +#ifndef AV_COPY32U +# define AV_COPY32U(d, s) AV_COPYU(32, d, s) +#endif + +#ifndef AV_COPY64U +# define AV_COPY64U(d, s) AV_COPYU(64, d, s) +#endif + +#ifndef AV_COPY128U +# define AV_COPY128U(d, s) \ + do { \ + AV_COPY64U(d, s); \ + AV_COPY64U((char *)(d) + 8, (const char *)(s) + 8); \ + } while(0) +#endif + +/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be + * naturally aligned. They may be implemented using MMX, + * so emms_c() must be called before using any float code + * afterwards. + */ + +#define AV_COPY(n, d, s) \ + (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n) + +#ifndef AV_COPY16 +# define AV_COPY16(d, s) AV_COPY(16, d, s) +#endif + +#ifndef AV_COPY32 +# define AV_COPY32(d, s) AV_COPY(32, d, s) +#endif + +#ifndef AV_COPY64 +# define AV_COPY64(d, s) AV_COPY(64, d, s) +#endif + +#ifndef AV_COPY128 +# define AV_COPY128(d, s) \ + do { \ + AV_COPY64(d, s); \ + AV_COPY64((char*)(d)+8, (char*)(s)+8); \ + } while(0) +#endif + +#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b)) + +#ifndef AV_SWAP64 +# define AV_SWAP64(a, b) AV_SWAP(64, a, b) +#endif + +#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0) + +#ifndef AV_ZERO16 +# define AV_ZERO16(d) AV_ZERO(16, d) +#endif + +#ifndef AV_ZERO32 +# define AV_ZERO32(d) AV_ZERO(32, d) +#endif + +#ifndef AV_ZERO64 +# define AV_ZERO64(d) AV_ZERO(64, d) +#endif + +#ifndef AV_ZERO128 +# define AV_ZERO128(d) \ + do { \ + AV_ZERO64(d); \ + AV_ZERO64((char*)(d)+8); \ + } while(0) +#endif + +#endif /* AVUTIL_INTREADWRITE_H */ diff --git a/ffmpeg/inc/libavutil/lfg.h b/ffmpeg/inc/libavutil/lfg.h new file mode 100644 index 0000000..2b66920 --- /dev/null +++ b/ffmpeg/inc/libavutil/lfg.h @@ -0,0 +1,80 @@ +/* + * Lagged Fibonacci PRNG + * Copyright (c) 2008 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LFG_H +#define AVUTIL_LFG_H + +#include + +/** + * Context structure for the Lagged Fibonacci PRNG. + * The exact layout, types and content of this struct may change and should + * not be accessed directly. Only its sizeof() is guranteed to stay the same + * to allow easy instanciation. + */ +typedef struct AVLFG { + unsigned int state[64]; + int index; +} AVLFG; + +void av_lfg_init(AVLFG *c, unsigned int seed); + +/** + * Seed the state of the ALFG using binary data. + * + * Return value: 0 on success, negative value (AVERROR) on failure. + */ +int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length); + +/** + * Get the next random unsigned 32-bit number using an ALFG. + * + * Please also consider a simple LCG like state= state*1664525+1013904223, + * it may be good enough and faster for your specific use case. + */ +static inline unsigned int av_lfg_get(AVLFG *c){ + unsigned a = c->state[c->index & 63] = c->state[(c->index-24) & 63] + c->state[(c->index-55) & 63]; + c->index += 1U; + return a; +} + +/** + * Get the next random unsigned 32-bit number using a MLFG. + * + * Please also consider av_lfg_get() above, it is faster. + */ +static inline unsigned int av_mlfg_get(AVLFG *c){ + unsigned int a= c->state[(c->index-55) & 63]; + unsigned int b= c->state[(c->index-24) & 63]; + a = c->state[c->index & 63] = 2*a*b+a+b; + c->index += 1U; + return a; +} + +/** + * Get the next two numbers generated by a Box-Muller Gaussian + * generator using the random numbers issued by lfg. + * + * @param out array where the two generated numbers are placed + */ +void av_bmg_get(AVLFG *lfg, double out[2]); + +#endif /* AVUTIL_LFG_H */ diff --git a/ffmpeg/inc/libavutil/log.h b/ffmpeg/inc/libavutil/log.h new file mode 100644 index 0000000..9c14188 --- /dev/null +++ b/ffmpeg/inc/libavutil/log.h @@ -0,0 +1,383 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOG_H +#define AVUTIL_LOG_H + +#include +#include "avutil.h" +#include "attributes.h" +#include "version.h" + +typedef enum { + AV_CLASS_CATEGORY_NA = 0, + AV_CLASS_CATEGORY_INPUT, + AV_CLASS_CATEGORY_OUTPUT, + AV_CLASS_CATEGORY_MUXER, + AV_CLASS_CATEGORY_DEMUXER, + AV_CLASS_CATEGORY_ENCODER, + AV_CLASS_CATEGORY_DECODER, + AV_CLASS_CATEGORY_FILTER, + AV_CLASS_CATEGORY_BITSTREAM_FILTER, + AV_CLASS_CATEGORY_SWSCALER, + AV_CLASS_CATEGORY_SWRESAMPLER, + AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40, + AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, + AV_CLASS_CATEGORY_DEVICE_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_INPUT, + AV_CLASS_CATEGORY_NB ///< not part of ABI/API +}AVClassCategory; + +#define AV_IS_INPUT_DEVICE(category) \ + (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_INPUT)) + +#define AV_IS_OUTPUT_DEVICE(category) \ + (((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT) || \ + ((category) == AV_CLASS_CATEGORY_DEVICE_OUTPUT)) + +struct AVOptionRanges; + +/** + * Describe the class of an AVClass context structure. That is an + * arbitrary struct of which the first field is a pointer to an + * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). + */ +typedef struct AVClass { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * A pointer to a function which returns the name of a context + * instance ctx associated with the class. + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; + + /** + * LIBAVUTIL_VERSION with which this structure was created. + * This is used to allow fields to be added without requiring major + * version bumps everywhere. + */ + + int version; + + /** + * Offset in the structure where log_level_offset is stored. + * 0 means there is no such variable + */ + int log_level_offset_offset; + + /** + * Offset in the structure where a pointer to the parent context for + * logging is stored. For example a decoder could pass its AVCodecContext + * to eval as such a parent context, which an av_log() implementation + * could then leverage to display the parent context. + * The offset can be NULL. + */ + int parent_log_context_offset; + + /** + * Return next AVOptions-enabled child or NULL + */ + void* (*child_next)(void *obj, void *prev); + + /** + * Return an AVClass corresponding to the next potential + * AVOptions-enabled child. + * + * The difference between child_next and this is that + * child_next iterates over _already existing_ objects, while + * child_class_next iterates over _all possible_ children. + */ + const struct AVClass* (*child_class_next)(const struct AVClass *prev); + + /** + * Category used for visualization (like color) + * This is only set if the category is equal for all objects using this class. + * available since version (51 << 16 | 56 << 8 | 100) + */ + AVClassCategory category; + + /** + * Callback to return the category. + * available since version (51 << 16 | 59 << 8 | 100) + */ + AVClassCategory (*get_category)(void* ctx); + + /** + * Callback to return the supported/allowed ranges. + * available since version (52.12) + */ + int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); +} AVClass; + +/** + * @addtogroup lavu_log + * + * @{ + * + * @defgroup lavu_log_constants Logging Constants + * + * @{ + */ + +/** + * Print no output. + */ +#define AV_LOG_QUIET -8 + +/** + * Something went really wrong and we will crash now. + */ +#define AV_LOG_PANIC 0 + +/** + * Something went wrong and recovery is not possible. + * For example, no header was found for a format which depends + * on headers or an illegal combination of parameters is used. + */ +#define AV_LOG_FATAL 8 + +/** + * Something went wrong and cannot losslessly be recovered. + * However, not all future data is affected. + */ +#define AV_LOG_ERROR 16 + +/** + * Something somehow does not look correct. This may or may not + * lead to problems. An example would be the use of '-vstrict -2'. + */ +#define AV_LOG_WARNING 24 + +/** + * Standard information. + */ +#define AV_LOG_INFO 32 + +/** + * Detailed information. + */ +#define AV_LOG_VERBOSE 40 + +/** + * Stuff which is only useful for libav* developers. + */ +#define AV_LOG_DEBUG 48 + +/** + * Extremely verbose debugging, useful for libav* development. + */ +#define AV_LOG_TRACE 56 + +#define AV_LOG_MAX_OFFSET (AV_LOG_TRACE - AV_LOG_QUIET) + +/** + * @} + */ + +/** + * Sets additional colors for extended debugging sessions. + * @code + av_log(ctx, AV_LOG_DEBUG|AV_LOG_C(134), "Message in purple\n"); + @endcode + * Requires 256color terminal support. Uses outside debugging is not + * recommended. + */ +#define AV_LOG_C(x) ((x) << 8) + +/** + * Send the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log_set_callback + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct or NULL if general log. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + */ +void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4); + +/** + * Send the specified message to the log once with the initial_level and then with + * the subsequent_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct or NULL if general log. + * @param initial_level importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant" for the first occurance. + * @param subsequent_level importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant" after the first occurance. + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param state a variable to keep trak of if a message has already been printed + * this must be initialized to 0 before the first use. The same state + * must not be accessed by 2 Threads simultaneously. + */ +void av_log_once(void* avcl, int initial_level, int subsequent_level, int *state, const char *fmt, ...) av_printf_format(5, 6); + + +/** + * Send the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log_set_callback + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +void av_vlog(void *avcl, int level, const char *fmt, va_list vl); + +/** + * Get the current log level + * + * @see lavu_log_constants + * + * @return Current log level + */ +int av_log_get_level(void); + +/** + * Set the log level + * + * @see lavu_log_constants + * + * @param level Logging level + */ +void av_log_set_level(int level); + +/** + * Set the logging callback + * + * @note The callback must be thread safe, even if the application does not use + * threads itself as some codecs are multithreaded. + * + * @see av_log_default_callback + * + * @param callback A logging function with a compatible signature. + */ +void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)); + +/** + * Default logging callback + * + * It prints the message to stderr, optionally colorizing it. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +void av_log_default_callback(void *avcl, int level, const char *fmt, + va_list vl); + +/** + * Return the context name + * + * @param ctx The AVClass context + * + * @return The AVClass class_name + */ +const char* av_default_item_name(void* ctx); +AVClassCategory av_default_get_category(void *ptr); + +/** + * Format a line of log the same way as the default callback. + * @param line buffer to receive the formatted line + * @param line_size size of the buffer + * @param print_prefix used to store whether the prefix must be printed; + * must point to a persistent integer initially set to 1 + */ +void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix); + +/** + * Format a line of log the same way as the default callback. + * @param line buffer to receive the formatted line; + * may be NULL if line_size is 0 + * @param line_size size of the buffer; at most line_size-1 characters will + * be written to the buffer, plus one null terminator + * @param print_prefix used to store whether the prefix must be printed; + * must point to a persistent integer initially set to 1 + * @return Returns a negative value if an error occurred, otherwise returns + * the number of characters that would have been written for a + * sufficiently large buffer, not including the terminating null + * character. If the return value is not less than line_size, it means + * that the log message was truncated to fit the buffer. + */ +int av_log_format_line2(void *ptr, int level, const char *fmt, va_list vl, + char *line, int line_size, int *print_prefix); + +/** + * Skip repeated messages, this requires the user app to use av_log() instead of + * (f)printf as the 2 would otherwise interfere and lead to + * "Last message repeated x times" messages below (f)printf messages with some + * bad luck. + * Also to receive the last, "last repeated" line if any, the user app must + * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end + */ +#define AV_LOG_SKIP_REPEATED 1 + +/** + * Include the log severity in messages originating from codecs. + * + * Results in messages such as: + * [rawvideo @ 0xDEADBEEF] [error] encode did not produce valid pts + */ +#define AV_LOG_PRINT_LEVEL 2 + +void av_log_set_flags(int arg); +int av_log_get_flags(void); + +/** + * @} + */ + +#endif /* AVUTIL_LOG_H */ diff --git a/ffmpeg/inc/libavutil/lzo.h b/ffmpeg/inc/libavutil/lzo.h new file mode 100644 index 0000000..c034039 --- /dev/null +++ b/ffmpeg/inc/libavutil/lzo.h @@ -0,0 +1,66 @@ +/* + * LZO 1x decompression + * copyright (c) 2006 Reimar Doeffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LZO_H +#define AVUTIL_LZO_H + +/** + * @defgroup lavu_lzo LZO + * @ingroup lavu_crypto + * + * @{ + */ + +#include + +/** @name Error flags returned by av_lzo1x_decode + * @{ */ +/// end of the input buffer reached before decoding finished +#define AV_LZO_INPUT_DEPLETED 1 +/// decoded data did not fit into output buffer +#define AV_LZO_OUTPUT_FULL 2 +/// a reference to previously decoded data was wrong +#define AV_LZO_INVALID_BACKPTR 4 +/// a non-specific error in the compressed bitstream +#define AV_LZO_ERROR 8 +/** @} */ + +#define AV_LZO_INPUT_PADDING 8 +#define AV_LZO_OUTPUT_PADDING 12 + +/** + * @brief Decodes LZO 1x compressed data. + * @param out output buffer + * @param outlen size of output buffer, number of bytes left are returned here + * @param in input buffer + * @param inlen size of input buffer, number of bytes left are returned here + * @return 0 on success, otherwise a combination of the error flags above + * + * Make sure all buffers are appropriately padded, in must provide + * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes. + */ +int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen); + +/** + * @} + */ + +#endif /* AVUTIL_LZO_H */ diff --git a/ffmpeg/inc/libavutil/macros.h b/ffmpeg/inc/libavutil/macros.h new file mode 100644 index 0000000..2007ee5 --- /dev/null +++ b/ffmpeg/inc/libavutil/macros.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu + * Utility Preprocessor macros + */ + +#ifndef AVUTIL_MACROS_H +#define AVUTIL_MACROS_H + +/** + * @addtogroup preproc_misc Preprocessor String Macros + * + * String manipulation macros + * + * @{ + */ + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_GLUE(a, b) a ## b +#define AV_JOIN(a, b) AV_GLUE(a, b) + +/** + * @} + */ + +#define AV_PRAGMA(s) _Pragma(#s) + +#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) + +#endif /* AVUTIL_MACROS_H */ diff --git a/ffmpeg/inc/libavutil/mastering_display_metadata.h b/ffmpeg/inc/libavutil/mastering_display_metadata.h new file mode 100644 index 0000000..c23b07c --- /dev/null +++ b/ffmpeg/inc/libavutil/mastering_display_metadata.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016 Neil Birkbeck + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MASTERING_DISPLAY_METADATA_H +#define AVUTIL_MASTERING_DISPLAY_METADATA_H + +#include "frame.h" +#include "rational.h" + + +/** + * Mastering display metadata capable of representing the color volume of + * the display used to master the content (SMPTE 2086:2014). + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with av_mastering_display_metadata_alloc() + * and its size is not a part of the public ABI. + */ +typedef struct AVMasteringDisplayMetadata { + /** + * CIE 1931 xy chromaticity coords of color primaries (r, g, b order). + */ + AVRational display_primaries[3][2]; + + /** + * CIE 1931 xy chromaticity coords of white point. + */ + AVRational white_point[2]; + + /** + * Min luminance of mastering display (cd/m^2). + */ + AVRational min_luminance; + + /** + * Max luminance of mastering display (cd/m^2). + */ + AVRational max_luminance; + + /** + * Flag indicating whether the display primaries (and white point) are set. + */ + int has_primaries; + + /** + * Flag indicating whether the luminance (min_ and max_) have been set. + */ + int has_luminance; + +} AVMasteringDisplayMetadata; + +/** + * Allocate an AVMasteringDisplayMetadata structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVMasteringDisplayMetadata filled with default values or NULL + * on failure. + */ +AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void); + +/** + * Allocate a complete AVMasteringDisplayMetadata and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVMasteringDisplayMetadata structure to be filled by caller. + */ +AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame); + +/** + * Content light level needed by to transmit HDR over HDMI (CTA-861.3). + * + * To be used as payload of a AVFrameSideData or AVPacketSideData with the + * appropriate type. + * + * @note The struct should be allocated with av_content_light_metadata_alloc() + * and its size is not a part of the public ABI. + */ +typedef struct AVContentLightMetadata { + /** + * Max content light level (cd/m^2). + */ + unsigned MaxCLL; + + /** + * Max average light level per frame (cd/m^2). + */ + unsigned MaxFALL; +} AVContentLightMetadata; + +/** + * Allocate an AVContentLightMetadata structure and set its fields to + * default values. The resulting struct can be freed using av_freep(). + * + * @return An AVContentLightMetadata filled with default values or NULL + * on failure. + */ +AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size); + +/** + * Allocate a complete AVContentLightMetadata and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVContentLightMetadata structure to be filled by caller. + */ +AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_MASTERING_DISPLAY_METADATA_H */ diff --git a/ffmpeg/inc/libavutil/mathematics.h b/ffmpeg/inc/libavutil/mathematics.h new file mode 100644 index 0000000..5490180 --- /dev/null +++ b/ffmpeg/inc/libavutil/mathematics.h @@ -0,0 +1,242 @@ +/* + * copyright (c) 2005-2012 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @addtogroup lavu_math + * Mathematical utilities for working with timestamp and time base. + */ + +#ifndef AVUTIL_MATHEMATICS_H +#define AVUTIL_MATHEMATICS_H + +#include +#include +#include "attributes.h" +#include "rational.h" +#include "intfloat.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#endif +#ifndef M_LOG2_10 +#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ +#endif +#ifndef M_PHI +#define M_PHI 1.61803398874989484820 /* phi / golden ratio */ +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#endif +#ifndef NAN +#define NAN av_int2float(0x7fc00000) +#endif +#ifndef INFINITY +#define INFINITY av_int2float(0x7f800000) +#endif + +/** + * @addtogroup lavu_math + * + * @{ + */ + +/** + * Rounding methods. + */ +enum AVRounding { + AV_ROUND_ZERO = 0, ///< Round toward zero. + AV_ROUND_INF = 1, ///< Round away from zero. + AV_ROUND_DOWN = 2, ///< Round toward -infinity. + AV_ROUND_UP = 3, ///< Round toward +infinity. + AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. + /** + * Flag telling rescaling functions to pass `INT64_MIN`/`MAX` through + * unchanged, avoiding special cases for #AV_NOPTS_VALUE. + * + * Unlike other values of the enumeration AVRounding, this value is a + * bitmask that must be used in conjunction with another value of the + * enumeration through a bitwise OR, in order to set behavior for normal + * cases. + * + * @code{.c} + * av_rescale_rnd(3, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); + * // Rescaling 3: + * // Calculating 3 * 1 / 2 + * // 3 / 2 is rounded up to 2 + * // => 2 + * + * av_rescale_rnd(AV_NOPTS_VALUE, 1, 2, AV_ROUND_UP | AV_ROUND_PASS_MINMAX); + * // Rescaling AV_NOPTS_VALUE: + * // AV_NOPTS_VALUE == INT64_MIN + * // AV_NOPTS_VALUE is passed through + * // => AV_NOPTS_VALUE + * @endcode + */ + AV_ROUND_PASS_MINMAX = 8192, +}; + +/** + * Compute the greatest common divisor of two integer operands. + * + * @param a,b Operands + * @return GCD of a and b up to sign; if a >= 0 and b >= 0, return value is >= 0; + * if a == 0 and b == 0, returns 0. + */ +int64_t av_const av_gcd(int64_t a, int64_t b); + +/** + * Rescale a 64-bit integer with rounding to nearest. + * + * The operation is mathematically equivalent to `a * b / c`, but writing that + * directly can overflow. + * + * This function is equivalent to av_rescale_rnd() with #AV_ROUND_NEAR_INF. + * + * @see av_rescale_rnd(), av_rescale_q(), av_rescale_q_rnd() + */ +int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; + +/** + * Rescale a 64-bit integer with specified rounding. + * + * The operation is mathematically equivalent to `a * b / c`, but writing that + * directly can overflow, and does not support different rounding methods. + * + * @see av_rescale(), av_rescale_q(), av_rescale_q_rnd() + */ +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) av_const; + +/** + * Rescale a 64-bit integer by 2 rational numbers. + * + * The operation is mathematically equivalent to `a * bq / cq`. + * + * This function is equivalent to av_rescale_q_rnd() with #AV_ROUND_NEAR_INF. + * + * @see av_rescale(), av_rescale_rnd(), av_rescale_q_rnd() + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; + +/** + * Rescale a 64-bit integer by 2 rational numbers with specified rounding. + * + * The operation is mathematically equivalent to `a * bq / cq`. + * + * @see av_rescale(), av_rescale_rnd(), av_rescale_q() + */ +int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, + enum AVRounding rnd) av_const; + +/** + * Compare two timestamps each in its own time base. + * + * @return One of the following values: + * - -1 if `ts_a` is before `ts_b` + * - 1 if `ts_a` is after `ts_b` + * - 0 if they represent the same position + * + * @warning + * The result of the function is undefined if one of the timestamps is outside + * the `int64_t` range when represented in the other's timebase. + */ +int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); + +/** + * Compare the remainders of two integer operands divided by a common divisor. + * + * In other words, compare the least significant `log2(mod)` bits of integers + * `a` and `b`. + * + * @code{.c} + * av_compare_mod(0x11, 0x02, 0x10) < 0 // since 0x11 % 0x10 (0x1) < 0x02 % 0x10 (0x2) + * av_compare_mod(0x11, 0x02, 0x20) > 0 // since 0x11 % 0x20 (0x11) > 0x02 % 0x20 (0x02) + * @endcode + * + * @param a,b Operands + * @param mod Divisor; must be a power of 2 + * @return + * - a negative value if `a % mod < b % mod` + * - a positive value if `a % mod > b % mod` + * - zero if `a % mod == b % mod` + */ +int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod); + +/** + * Rescale a timestamp while preserving known durations. + * + * This function is designed to be called per audio packet to scale the input + * timestamp to a different time base. Compared to a simple av_rescale_q() + * call, this function is robust against possible inconsistent frame durations. + * + * The `last` parameter is a state variable that must be preserved for all + * subsequent calls for the same stream. For the first call, `*last` should be + * initialized to #AV_NOPTS_VALUE. + * + * @param[in] in_tb Input time base + * @param[in] in_ts Input timestamp + * @param[in] fs_tb Duration time base; typically this is finer-grained + * (greater) than `in_tb` and `out_tb` + * @param[in] duration Duration till the next call to this function (i.e. + * duration of the current packet/frame) + * @param[in,out] last Pointer to a timestamp expressed in terms of + * `fs_tb`, acting as a state variable + * @param[in] out_tb Output timebase + * @return Timestamp expressed in terms of `out_tb` + * + * @note In the context of this function, "duration" is in term of samples, not + * seconds. + */ +int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb); + +/** + * Add a value to a timestamp. + * + * This function guarantees that when the same value is repeatly added that + * no accumulation of rounding errors occurs. + * + * @param[in] ts Input timestamp + * @param[in] ts_tb Input timestamp time base + * @param[in] inc Value to be added + * @param[in] inc_tb Time base of `inc` + */ +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc); + + +/** + * @} + */ + +#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/ffmpeg/inc/libavutil/md5.h b/ffmpeg/inc/libavutil/md5.h new file mode 100644 index 0000000..ca72ccb --- /dev/null +++ b/ffmpeg/inc/libavutil/md5.h @@ -0,0 +1,98 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_md5 + * Public header for MD5 hash function implementation. + */ + +#ifndef AVUTIL_MD5_H +#define AVUTIL_MD5_H + +#include +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_md5 MD5 + * @ingroup lavu_hash + * MD5 hash function implementation. + * + * @{ + */ + +extern const int av_md5_size; + +struct AVMD5; + +/** + * Allocate an AVMD5 context. + */ +struct AVMD5 *av_md5_alloc(void); + +/** + * Initialize MD5 hashing. + * + * @param ctx pointer to the function context (of size av_md5_size) + */ +void av_md5_init(struct AVMD5 *ctx); + +/** + * Update hash value. + * + * @param ctx hash function context + * @param src input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, int len); +#else +void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param ctx hash function context + * @param dst buffer where output digest value is stored + */ +void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); + +/** + * Hash an array of data. + * + * @param dst The output buffer to write the digest into + * @param src The data to hash + * @param len The length of the data, in bytes + */ +#if FF_API_CRYPTO_SIZE_T +void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len); +#else +void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len); +#endif + +/** + * @} + */ + +#endif /* AVUTIL_MD5_H */ diff --git a/ffmpeg/inc/libavutil/mem.h b/ffmpeg/inc/libavutil/mem.h new file mode 100644 index 0000000..5fb1a02 --- /dev/null +++ b/ffmpeg/inc/libavutil/mem.h @@ -0,0 +1,700 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_mem + * Memory handling functions + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#include +#include + +#include "attributes.h" +#include "error.h" +#include "avutil.h" + +/** + * @addtogroup lavu_mem + * Utilities for manipulating memory. + * + * FFmpeg has several applications of memory that are not required of a typical + * program. For example, the computing-heavy components like video decoding and + * encoding can be sped up significantly through the use of aligned memory. + * + * However, for each of FFmpeg's applications of memory, there might not be a + * recognized or standardized API for that specific use. Memory alignment, for + * instance, varies wildly depending on operating systems, architectures, and + * compilers. Hence, this component of @ref libavutil is created to make + * dealing with memory consistently possible on all platforms. + * + * @{ + * + * @defgroup lavu_mem_macros Alignment Macros + * Helper macros for declaring aligned variables. + * @{ + */ + +/** + * @def DECLARE_ALIGNED(n,t,v) + * Declare a variable that is aligned in memory. + * + * @code{.c} + * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42; + * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128]; + * + * // The default-alignment equivalent would be + * uint16_t aligned_int = 42; + * uint8_t aligned_array[128]; + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_ALIGNED(n,t,v) + * Declare an aligned variable appropriate for use in inline assembly code. + * + * @code{.c} + * DECLARE_ASM_ALIGNED(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +/** + * @def DECLARE_ASM_CONST(n,t,v) + * Declare a static constant aligned variable appropriate for use in inline + * assembly code. + * + * @code{.c} + * DECLARE_ASM_CONST(16, uint64_t, pw_08) = UINT64_C(0x0008000800080008); + * @endcode + * + * @param n Minimum alignment in bytes + * @param t Type of the variable (or array element) + * @param v Name of the variable + */ + +#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__DJGPP__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v +#elif defined(__GNUC__) || defined(__clang__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_ALIGNED(n,t,v) t av_used __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) static const t av_used __attribute__ ((aligned (n))) v +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + +/** + * @} + */ + +/** + * @defgroup lavu_mem_attrs Function Attributes + * Function attributes applicable to memory handling functions. + * + * These function attributes can help compilers emit more useful warnings, or + * generate better code. + * @{ + */ + +/** + * @def av_malloc_attrib + * Function attribute denoting a malloc-like function. + * + * @see Function attribute `malloc` in GCC's documentation + */ + +#if AV_GCC_VERSION_AT_LEAST(3,1) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #define av_malloc_attrib +#endif + +/** + * @def av_alloc_size(...) + * Function attribute used on a function that allocates memory, whose size is + * given by the specified parameter(s). + * + * @code{.c} + * void *av_malloc(size_t size) av_alloc_size(1); + * void *av_calloc(size_t nmemb, size_t size) av_alloc_size(1, 2); + * @endcode + * + * @param ... One or two parameter indexes, separated by a comma + * + * @see Function attribute `alloc_size` in GCC's documentation + */ + +#if AV_GCC_VERSION_AT_LEAST(4,3) + #define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__))) +#else + #define av_alloc_size(...) +#endif + +/** + * @} + */ + +/** + * @defgroup lavu_mem_funcs Heap Management + * Functions responsible for allocating, freeing, and copying memory. + * + * All memory allocation functions have a built-in upper limit of `INT_MAX` + * bytes. This may be changed with av_max_alloc(), although exercise extreme + * caution when doing so. + * + * @{ + */ + +/** + * Allocate a memory block with alignment suitable for all memory accesses + * (including vectors if available on the CPU). + * + * @param size Size in bytes for the memory block to be allocated + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * @see av_mallocz() + */ +void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate a memory block with alignment suitable for all memory accesses + * (including vectors if available on the CPU) and zero all the bytes of the + * block. + * + * @param size Size in bytes for the memory block to be allocated + * @return Pointer to the allocated block, or `NULL` if it cannot be allocated + * @see av_malloc() + */ +void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocate a memory block for an array with av_malloc(). + * + * The allocated memory will have size `size * nmemb` bytes. + * + * @param nmemb Number of element + * @param size Size of a single element + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * @see av_malloc() + */ +av_alloc_size(1, 2) void *av_malloc_array(size_t nmemb, size_t size); + +/** + * Allocate a memory block for an array with av_mallocz(). + * + * The allocated memory will have size `size * nmemb` bytes. + * + * @param nmemb Number of elements + * @param size Size of the single element + * @return Pointer to the allocated block, or `NULL` if the block cannot + * be allocated + * + * @see av_mallocz() + * @see av_malloc_array() + */ +av_alloc_size(1, 2) void *av_mallocz_array(size_t nmemb, size_t size); + +/** + * Non-inlined equivalent of av_mallocz_array(). + * + * Created for symmetry with the calloc() C function. + */ +void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib; + +/** + * Allocate, reallocate, or free a block of memory. + * + * If `ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is + * zero, free the memory block pointed to by `ptr`. Otherwise, expand or + * shrink that block of memory according to `size`. + * + * @param ptr Pointer to a memory block already allocated with + * av_realloc() or `NULL` + * @param size Size in bytes of the memory block to be allocated or + * reallocated + * + * @return Pointer to a newly-reallocated block or `NULL` if the block + * cannot be reallocated or the function is used to free the memory block + * + * @warning Unlike av_malloc(), the returned pointer is not guaranteed to be + * correctly aligned. + * @see av_fast_realloc() + * @see av_reallocp() + */ +void *av_realloc(void *ptr, size_t size) av_alloc_size(2); + +/** + * Allocate, reallocate, or free a block of memory through a pointer to a + * pointer. + * + * If `*ptr` is `NULL` and `size` > 0, allocate a new block. If `size` is + * zero, free the memory block pointed to by `*ptr`. Otherwise, expand or + * shrink that block of memory according to `size`. + * + * @param[in,out] ptr Pointer to a pointer to a memory block already allocated + * with av_realloc(), or a pointer to `NULL`. The pointer + * is updated on success, or freed on failure. + * @param[in] size Size in bytes for the memory block to be allocated or + * reallocated + * + * @return Zero on success, an AVERROR error code on failure + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. + */ +av_warn_unused_result +int av_reallocp(void *ptr, size_t size); + +/** + * Allocate, reallocate, or free a block of memory. + * + * This function does the same thing as av_realloc(), except: + * - It takes two size arguments and allocates `nelem * elsize` bytes, + * after checking the result of the multiplication for integer overflow. + * - It frees the input block in case of failure, thus avoiding the memory + * leak with the classic + * @code{.c} + * buf = realloc(buf); + * if (!buf) + * return -1; + * @endcode + * pattern. + */ +void *av_realloc_f(void *ptr, size_t nelem, size_t elsize); + +/** + * Allocate, reallocate, or free an array. + * + * If `ptr` is `NULL` and `nmemb` > 0, allocate a new block. If + * `nmemb` is zero, free the memory block pointed to by `ptr`. + * + * @param ptr Pointer to a memory block already allocated with + * av_realloc() or `NULL` + * @param nmemb Number of elements in the array + * @param size Size of the single element of the array + * + * @return Pointer to a newly-reallocated block or NULL if the block + * cannot be reallocated or the function is used to free the memory block + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. + * @see av_reallocp_array() + */ +av_alloc_size(2, 3) void *av_realloc_array(void *ptr, size_t nmemb, size_t size); + +/** + * Allocate, reallocate, or free an array through a pointer to a pointer. + * + * If `*ptr` is `NULL` and `nmemb` > 0, allocate a new block. If `nmemb` is + * zero, free the memory block pointed to by `*ptr`. + * + * @param[in,out] ptr Pointer to a pointer to a memory block already + * allocated with av_realloc(), or a pointer to `NULL`. + * The pointer is updated on success, or freed on failure. + * @param[in] nmemb Number of elements + * @param[in] size Size of the single element + * + * @return Zero on success, an AVERROR error code on failure + * + * @warning Unlike av_malloc(), the allocated memory is not guaranteed to be + * correctly aligned. + */ +int av_reallocp_array(void *ptr, size_t nmemb, size_t size); + +/** + * Reallocate the given buffer if it is not large enough, otherwise do nothing. + * + * If the given buffer is `NULL`, then a new uninitialized buffer is allocated. + * + * If the given buffer is not large enough, and reallocation fails, `NULL` is + * returned and `*size` is set to 0, but the original buffer is not changed or + * freed. + * + * A typical use pattern follows: + * + * @code{.c} + * uint8_t *buf = ...; + * uint8_t *new_buf = av_fast_realloc(buf, ¤t_size, size_needed); + * if (!new_buf) { + * // Allocation failed; clean up original buffer + * av_freep(&buf); + * return AVERROR(ENOMEM); + * } + * @endcode + * + * @param[in,out] ptr Already allocated buffer, or `NULL` + * @param[in,out] size Pointer to the size of buffer `ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `ptr` + * @return `ptr` if the buffer is large enough, a pointer to newly reallocated + * buffer if the buffer was not large enough, or `NULL` in case of + * error + * @see av_realloc() + * @see av_fast_malloc() + */ +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Allocate a buffer, reusing the given one if large enough. + * + * Contrary to av_fast_realloc(), the current buffer contents might not be + * preserved and on error the old buffer is freed, thus no special handling to + * avoid memleaks is necessary. + * + * `*ptr` is allowed to be `NULL`, in which case allocation always happens if + * `size_needed` is greater than 0. + * + * @code{.c} + * uint8_t *buf = ...; + * av_fast_malloc(&buf, ¤t_size, size_needed); + * if (!buf) { + * // Allocation failed; buf already freed + * return AVERROR(ENOMEM); + * } + * @endcode + * + * @param[in,out] ptr Pointer to pointer to an already allocated buffer. + * `*ptr` will be overwritten with pointer to new + * buffer on success or `NULL` on failure + * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `*ptr` + * @see av_realloc() + * @see av_fast_mallocz() + */ +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Allocate and clear a buffer, reusing the given one if large enough. + * + * Like av_fast_malloc(), but all newly allocated space is initially cleared. + * Reused buffer is not cleared. + * + * `*ptr` is allowed to be `NULL`, in which case allocation always happens if + * `size_needed` is greater than 0. + * + * @param[in,out] ptr Pointer to pointer to an already allocated buffer. + * `*ptr` will be overwritten with pointer to new + * buffer on success or `NULL` on failure + * @param[in,out] size Pointer to the size of buffer `*ptr`. `*size` is + * updated to the new allocated size, in particular 0 + * in case of failure. + * @param[in] min_size Desired minimal size of buffer `*ptr` + * @see av_fast_malloc() + */ +void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size); + +/** + * Free a memory block which has been allocated with a function of av_malloc() + * or av_realloc() family. + * + * @param ptr Pointer to the memory block which should be freed. + * + * @note `ptr = NULL` is explicitly allowed. + * @note It is recommended that you use av_freep() instead, to prevent leaving + * behind dangling pointers. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Free a memory block which has been allocated with a function of av_malloc() + * or av_realloc() family, and set the pointer pointing to it to `NULL`. + * + * @code{.c} + * uint8_t *buf = av_malloc(16); + * av_free(buf); + * // buf now contains a dangling pointer to freed memory, and accidental + * // dereference of buf will result in a use-after-free, which may be a + * // security risk. + * + * uint8_t *buf = av_malloc(16); + * av_freep(&buf); + * // buf is now NULL, and accidental dereference will only result in a + * // NULL-pointer dereference. + * @endcode + * + * @param ptr Pointer to the pointer to the memory block which should be freed + * @note `*ptr = NULL` is safe and leads to no action. + * @see av_free() + */ +void av_freep(void *ptr); + +/** + * Duplicate a string. + * + * @param s String to be duplicated + * @return Pointer to a newly-allocated string containing a + * copy of `s` or `NULL` if the string cannot be allocated + * @see av_strndup() + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Duplicate a substring of a string. + * + * @param s String to be duplicated + * @param len Maximum length of the resulting string (not counting the + * terminating byte) + * @return Pointer to a newly-allocated string containing a + * substring of `s` or `NULL` if the string cannot be allocated + */ +char *av_strndup(const char *s, size_t len) av_malloc_attrib; + +/** + * Duplicate a buffer with av_malloc(). + * + * @param p Buffer to be duplicated + * @param size Size in bytes of the buffer copied + * @return Pointer to a newly allocated buffer containing a + * copy of `p` or `NULL` if the buffer cannot be allocated + */ +void *av_memdup(const void *p, size_t size); + +/** + * Overlapping memcpy() implementation. + * + * @param dst Destination buffer + * @param back Number of bytes back to start copying (i.e. the initial size of + * the overlapping window); must be > 0 + * @param cnt Number of bytes to copy; must be >= 0 + * + * @note `cnt > back` is valid, this will copy the bytes we just copied, + * thus creating a repeating pattern with a period length of `back`. + */ +void av_memcpy_backptr(uint8_t *dst, int back, int cnt); + +/** + * @} + */ + +/** + * @defgroup lavu_mem_dynarray Dynamic Array + * + * Utilities to make an array grow when needed. + * + * Sometimes, the programmer would want to have an array that can grow when + * needed. The libavutil dynamic array utilities fill that need. + * + * libavutil supports two systems of appending elements onto a dynamically + * allocated array, the first one storing the pointer to the value in the + * array, and the second storing the value directly. In both systems, the + * caller is responsible for maintaining a variable containing the length of + * the array, as well as freeing of the array after use. + * + * The first system stores pointers to values in a block of dynamically + * allocated memory. Since only pointers are stored, the function does not need + * to know the size of the type. Both av_dynarray_add() and + * av_dynarray_add_nofree() implement this system. + * + * @code + * type **array = NULL; //< an array of pointers to values + * int nb = 0; //< a variable to keep track of the length of the array + * + * type to_be_added = ...; + * type to_be_added2 = ...; + * + * av_dynarray_add(&array, &nb, &to_be_added); + * if (nb == 0) + * return AVERROR(ENOMEM); + * + * av_dynarray_add(&array, &nb, &to_be_added2); + * if (nb == 0) + * return AVERROR(ENOMEM); + * + * // Now: + * // nb == 2 + * // &to_be_added == array[0] + * // &to_be_added2 == array[1] + * + * av_freep(&array); + * @endcode + * + * The second system stores the value directly in a block of memory. As a + * result, the function has to know the size of the type. av_dynarray2_add() + * implements this mechanism. + * + * @code + * type *array = NULL; //< an array of values + * int nb = 0; //< a variable to keep track of the length of the array + * + * type to_be_added = ...; + * type to_be_added2 = ...; + * + * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), NULL); + * if (!addr) + * return AVERROR(ENOMEM); + * memcpy(addr, &to_be_added, sizeof(to_be_added)); + * + * // Shortcut of the above. + * type *addr = av_dynarray2_add((void **)&array, &nb, sizeof(*array), + * (const void *)&to_be_added2); + * if (!addr) + * return AVERROR(ENOMEM); + * + * // Now: + * // nb == 2 + * // to_be_added == array[0] + * // to_be_added2 == array[1] + * + * av_freep(&array); + * @endcode + * + * @{ + */ + +/** + * Add the pointer to an element to a dynamic array. + * + * The array to grow is supposed to be an array of pointers to + * structures, and the element to add must be a pointer to an already + * allocated structure. + * + * The array is reallocated when its size reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the number pointed to by `nb_ptr` + * is incremented. + * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and + * `*nb_ptr` is set to 0. + * + * @param[in,out] tab_ptr Pointer to the array to grow + * @param[in,out] nb_ptr Pointer to the number of elements in the array + * @param[in] elem Element to add + * @see av_dynarray_add_nofree(), av_dynarray2_add() + */ +void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem); + +/** + * Add an element to a dynamic array. + * + * Function has the same functionality as av_dynarray_add(), + * but it doesn't free memory on fails. It returns error code + * instead and leave current buffer untouched. + * + * @return >=0 on success, negative otherwise + * @see av_dynarray_add(), av_dynarray2_add() + */ +av_warn_unused_result +int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem); + +/** + * Add an element of size `elem_size` to a dynamic array. + * + * The array is reallocated when its number of elements reaches powers of 2. + * Therefore, the amortized cost of adding an element is constant. + * + * In case of success, the pointer to the array is updated in order to + * point to the new grown array, and the number pointed to by `nb_ptr` + * is incremented. + * In case of failure, the array is freed, `*tab_ptr` is set to `NULL` and + * `*nb_ptr` is set to 0. + * + * @param[in,out] tab_ptr Pointer to the array to grow + * @param[in,out] nb_ptr Pointer to the number of elements in the array + * @param[in] elem_size Size in bytes of an element in the array + * @param[in] elem_data Pointer to the data of the element to add. If + * `NULL`, the space of the newly added element is + * allocated but left uninitialized. + * + * @return Pointer to the data of the element to copy in the newly allocated + * space + * @see av_dynarray_add(), av_dynarray_add_nofree() + */ +void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, + const uint8_t *elem_data); + +/** + * @} + */ + +/** + * @defgroup lavu_mem_misc Miscellaneous Functions + * + * Other functions related to memory allocation. + * + * @{ + */ + +/** + * Multiply two `size_t` values checking for overflow. + * + * @param[in] a,b Operands of multiplication + * @param[out] r Pointer to the result of the operation + * @return 0 on success, AVERROR(EINVAL) on overflow + */ +static inline int av_size_mult(size_t a, size_t b, size_t *r) +{ + size_t t = a * b; + /* Hack inspired from glibc: don't try the division if nelem and elsize + * are both less than sqrt(SIZE_MAX). */ + if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b) + return AVERROR(EINVAL); + *r = t; + return 0; +} + +/** + * Set the maximum size that may be allocated in one block. + * + * The value specified with this function is effective for all libavutil's @ref + * lavu_mem_funcs "heap management functions." + * + * By default, the max value is defined as `INT_MAX`. + * + * @param max Value to be set as the new maximum size + * + * @warning Exercise extreme caution when using this function. Don't touch + * this if you do not understand the full consequence of doing so. + */ +void av_max_alloc(size_t max); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_MEM_H */ diff --git a/ffmpeg/inc/libavutil/motion_vector.h b/ffmpeg/inc/libavutil/motion_vector.h new file mode 100644 index 0000000..ec29556 --- /dev/null +++ b/ffmpeg/inc/libavutil/motion_vector.h @@ -0,0 +1,57 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MOTION_VECTOR_H +#define AVUTIL_MOTION_VECTOR_H + +#include + +typedef struct AVMotionVector { + /** + * Where the current macroblock comes from; negative value when it comes + * from the past, positive value when it comes from the future. + * XXX: set exact relative ref frame reference instead of a +/- 1 "direction". + */ + int32_t source; + /** + * Width and height of the block. + */ + uint8_t w, h; + /** + * Absolute source position. Can be outside the frame area. + */ + int16_t src_x, src_y; + /** + * Absolute destination position. Can be outside the frame area. + */ + int16_t dst_x, dst_y; + /** + * Extra flag information. + * Currently unused. + */ + uint64_t flags; + /** + * Motion vector + * src_x = dst_x + motion_x / motion_scale + * src_y = dst_y + motion_y / motion_scale + */ + int32_t motion_x, motion_y; + uint16_t motion_scale; +} AVMotionVector; + +#endif /* AVUTIL_MOTION_VECTOR_H */ diff --git a/ffmpeg/inc/libavutil/murmur3.h b/ffmpeg/inc/libavutil/murmur3.h new file mode 100644 index 0000000..1b09175 --- /dev/null +++ b/ffmpeg/inc/libavutil/murmur3.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2013 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_murmur3 + * Public header for MurmurHash3 hash function implementation. + */ + +#ifndef AVUTIL_MURMUR3_H +#define AVUTIL_MURMUR3_H + +#include + +#include "version.h" + +/** + * @defgroup lavu_murmur3 Murmur3 + * @ingroup lavu_hash + * MurmurHash3 hash function implementation. + * + * MurmurHash3 is a non-cryptographic hash function, of which three + * incompatible versions were created by its inventor Austin Appleby: + * + * - 32-bit output + * - 128-bit output for 32-bit platforms + * - 128-bit output for 64-bit platforms + * + * FFmpeg only implements the last variant: 128-bit output designed for 64-bit + * platforms. Even though the hash function was designed for 64-bit platforms, + * the function in reality works on 32-bit systems too, only with reduced + * performance. + * + * @anchor lavu_murmur3_seedinfo + * By design, MurmurHash3 requires a seed to operate. In response to this, + * libavutil provides two functions for hash initiation, one that requires a + * seed (av_murmur3_init_seeded()) and one that uses a fixed arbitrary integer + * as the seed, and therefore does not (av_murmur3_init()). + * + * To make hashes comparable, you should provide the same seed for all calls to + * this hash function -- if you are supplying one yourself, that is. + * + * @{ + */ + +/** + * Allocate an AVMurMur3 hash context. + * + * @return Uninitialized hash context or `NULL` in case of error + */ +struct AVMurMur3 *av_murmur3_alloc(void); + +/** + * Initialize or reinitialize an AVMurMur3 hash context with a seed. + * + * @param[out] c Hash context + * @param[in] seed Random seed + * + * @see av_murmur3_init() + * @see @ref lavu_murmur3_seedinfo "Detailed description" on a discussion of + * seeds for MurmurHash3. + */ +void av_murmur3_init_seeded(struct AVMurMur3 *c, uint64_t seed); + +/** + * Initialize or reinitialize an AVMurMur3 hash context. + * + * Equivalent to av_murmur3_init_seeded() with a built-in seed. + * + * @param[out] c Hash context + * + * @see av_murmur3_init_seeded() + * @see @ref lavu_murmur3_seedinfo "Detailed description" on a discussion of + * seeds for MurmurHash3. + */ +void av_murmur3_init(struct AVMurMur3 *c); + +/** + * Update hash context with new data. + * + * @param[out] c Hash context + * @param[in] src Input data to update hash with + * @param[in] len Number of bytes to read from `src` + */ +#if FF_API_CRYPTO_SIZE_T +void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, int len); +#else +void av_murmur3_update(struct AVMurMur3 *c, const uint8_t *src, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param[in,out] c Hash context + * @param[out] dst Buffer where output digest value is stored + */ +void av_murmur3_final(struct AVMurMur3 *c, uint8_t dst[16]); + +/** + * @} + */ + +#endif /* AVUTIL_MURMUR3_H */ diff --git a/ffmpeg/inc/libavutil/opt.h b/ffmpeg/inc/libavutil/opt.h new file mode 100644 index 0000000..e461195 --- /dev/null +++ b/ffmpeg/inc/libavutil/opt.h @@ -0,0 +1,871 @@ +/* + * AVOptions + * copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_OPT_H +#define AVUTIL_OPT_H + +/** + * @file + * AVOptions + */ + +#include "rational.h" +#include "avutil.h" +#include "dict.h" +#include "log.h" +#include "pixfmt.h" +#include "samplefmt.h" +#include "version.h" + +/** + * @defgroup avoptions AVOptions + * @ingroup lavu_data + * @{ + * AVOptions provide a generic system to declare options on arbitrary structs + * ("objects"). An option can have a help text, a type and a range of possible + * values. Options may then be enumerated, read and written to. + * + * @section avoptions_implement Implementing AVOptions + * This section describes how to add AVOptions capabilities to a struct. + * + * All AVOptions-related information is stored in an AVClass. Therefore + * the first member of the struct should be a pointer to an AVClass describing it. + * The option field of the AVClass must be set to a NULL-terminated static array + * of AVOptions. Each AVOption must have a non-empty name, a type, a default + * value and for number-type AVOptions also a range of allowed values. It must + * also declare an offset in bytes from the start of the struct, where the field + * associated with this AVOption is located. Other fields in the AVOption struct + * should also be set when applicable, but are not required. + * + * The following example illustrates an AVOptions-enabled struct: + * @code + * typedef struct test_struct { + * const AVClass *class; + * int int_opt; + * char *str_opt; + * uint8_t *bin_opt; + * int bin_len; + * } test_struct; + * + * static const AVOption test_options[] = { + * { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt), + * AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX }, + * { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt), + * AV_OPT_TYPE_STRING }, + * { "test_bin", "This is a test option of binary type.", offsetof(test_struct, bin_opt), + * AV_OPT_TYPE_BINARY }, + * { NULL }, + * }; + * + * static const AVClass test_class = { + * .class_name = "test class", + * .item_name = av_default_item_name, + * .option = test_options, + * .version = LIBAVUTIL_VERSION_INT, + * }; + * @endcode + * + * Next, when allocating your struct, you must ensure that the AVClass pointer + * is set to the correct value. Then, av_opt_set_defaults() can be called to + * initialize defaults. After that the struct is ready to be used with the + * AVOptions API. + * + * When cleaning up, you may use the av_opt_free() function to automatically + * free all the allocated string and binary options. + * + * Continuing with the above example: + * + * @code + * test_struct *alloc_test_struct(void) + * { + * test_struct *ret = av_mallocz(sizeof(*ret)); + * ret->class = &test_class; + * av_opt_set_defaults(ret); + * return ret; + * } + * void free_test_struct(test_struct **foo) + * { + * av_opt_free(*foo); + * av_freep(foo); + * } + * @endcode + * + * @subsection avoptions_implement_nesting Nesting + * It may happen that an AVOptions-enabled struct contains another + * AVOptions-enabled struct as a member (e.g. AVCodecContext in + * libavcodec exports generic options, while its priv_data field exports + * codec-specific options). In such a case, it is possible to set up the + * parent struct to export a child's options. To do that, simply + * implement AVClass.child_next() and AVClass.child_class_next() in the + * parent struct's AVClass. + * Assuming that the test_struct from above now also contains a + * child_struct field: + * + * @code + * typedef struct child_struct { + * AVClass *class; + * int flags_opt; + * } child_struct; + * static const AVOption child_opts[] = { + * { "test_flags", "This is a test option of flags type.", + * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX }, + * { NULL }, + * }; + * static const AVClass child_class = { + * .class_name = "child class", + * .item_name = av_default_item_name, + * .option = child_opts, + * .version = LIBAVUTIL_VERSION_INT, + * }; + * + * void *child_next(void *obj, void *prev) + * { + * test_struct *t = obj; + * if (!prev && t->child_struct) + * return t->child_struct; + * return NULL + * } + * const AVClass child_class_next(const AVClass *prev) + * { + * return prev ? NULL : &child_class; + * } + * @endcode + * Putting child_next() and child_class_next() as defined above into + * test_class will now make child_struct's options accessible through + * test_struct (again, proper setup as described above needs to be done on + * child_struct right after it is created). + * + * From the above example it might not be clear why both child_next() + * and child_class_next() are needed. The distinction is that child_next() + * iterates over actually existing objects, while child_class_next() + * iterates over all possible child classes. E.g. if an AVCodecContext + * was initialized to use a codec which has private options, then its + * child_next() will return AVCodecContext.priv_data and finish + * iterating. OTOH child_class_next() on AVCodecContext.av_class will + * iterate over all available codecs with private options. + * + * @subsection avoptions_implement_named_constants Named constants + * It is possible to create named constants for options. Simply set the unit + * field of the option the constants should apply to a string and + * create the constants themselves as options of type AV_OPT_TYPE_CONST + * with their unit field set to the same string. + * Their default_val field should contain the value of the named + * constant. + * For example, to add some named constants for the test_flags option + * above, put the following into the child_opts array: + * @code + * { "test_flags", "This is a test option of flags type.", + * offsetof(child_struct, flags_opt), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, "test_unit" }, + * { "flag1", "This is a flag with value 16", 0, AV_OPT_TYPE_CONST, { .i64 = 16 }, 0, 0, "test_unit" }, + * @endcode + * + * @section avoptions_use Using AVOptions + * This section deals with accessing options in an AVOptions-enabled struct. + * Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or + * AVFormatContext in libavformat. + * + * @subsection avoptions_use_examine Examining AVOptions + * The basic functions for examining options are av_opt_next(), which iterates + * over all options defined for one object, and av_opt_find(), which searches + * for an option with the given name. + * + * The situation is more complicated with nesting. An AVOptions-enabled struct + * may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag + * to av_opt_find() will make the function search children recursively. + * + * For enumerating there are basically two cases. The first is when you want to + * get all options that may potentially exist on the struct and its children + * (e.g. when constructing documentation). In that case you should call + * av_opt_child_class_next() recursively on the parent struct's AVClass. The + * second case is when you have an already initialized struct with all its + * children and you want to get all options that can be actually written or read + * from it. In that case you should call av_opt_child_next() recursively (and + * av_opt_next() on each result). + * + * @subsection avoptions_use_get_set Reading and writing AVOptions + * When setting options, you often have a string read directly from the + * user. In such a case, simply passing it to av_opt_set() is enough. For + * non-string type options, av_opt_set() will parse the string according to the + * option type. + * + * Similarly av_opt_get() will read any option type and convert it to a string + * which will be returned. Do not forget that the string is allocated, so you + * have to free it with av_free(). + * + * In some cases it may be more convenient to put all options into an + * AVDictionary and call av_opt_set_dict() on it. A specific case of this + * are the format/codec open functions in lavf/lavc which take a dictionary + * filled with option as a parameter. This makes it possible to set some options + * that cannot be set otherwise, since e.g. the input file format is not known + * before the file is actually opened. + */ + +enum AVOptionType{ + AV_OPT_TYPE_FLAGS, + AV_OPT_TYPE_INT, + AV_OPT_TYPE_INT64, + AV_OPT_TYPE_DOUBLE, + AV_OPT_TYPE_FLOAT, + AV_OPT_TYPE_STRING, + AV_OPT_TYPE_RATIONAL, + AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length + AV_OPT_TYPE_DICT, + AV_OPT_TYPE_UINT64, + AV_OPT_TYPE_CONST, + AV_OPT_TYPE_IMAGE_SIZE, ///< offset must point to two consecutive integers + AV_OPT_TYPE_PIXEL_FMT, + AV_OPT_TYPE_SAMPLE_FMT, + AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational + AV_OPT_TYPE_DURATION, + AV_OPT_TYPE_COLOR, + AV_OPT_TYPE_CHANNEL_LAYOUT, + AV_OPT_TYPE_BOOL, +}; + +/** + * AVOption + */ +typedef struct AVOption { + const char *name; + + /** + * short English help text + * @todo What about other languages? + */ + const char *help; + + /** + * The offset relative to the context structure where the option + * value is stored. It should be 0 for named constants. + */ + int offset; + enum AVOptionType type; + + /** + * the default value for scalar options + */ + union { + int64_t i64; + double dbl; + const char *str; + /* TODO those are unused now */ + AVRational q; + } default_val; + double min; ///< minimum valid value for the option + double max; ///< maximum valid value for the option + + int flags; +#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding +#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding +#define AV_OPT_FLAG_AUDIO_PARAM 8 +#define AV_OPT_FLAG_VIDEO_PARAM 16 +#define AV_OPT_FLAG_SUBTITLE_PARAM 32 +/** + * The option is intended for exporting values to the caller. + */ +#define AV_OPT_FLAG_EXPORT 64 +/** + * The option may not be set through the AVOptions API, only read. + * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set. + */ +#define AV_OPT_FLAG_READONLY 128 +#define AV_OPT_FLAG_BSF_PARAM (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering +#define AV_OPT_FLAG_RUNTIME_PARAM (1<<15) ///< a generic parameter which can be set by the user at runtime +#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering +#define AV_OPT_FLAG_DEPRECATED (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information +#define AV_OPT_FLAG_CHILD_CONSTS (1<<18) ///< set if option constants can also reside in child objects +//FIXME think about enc-audio, ... style flags + + /** + * The logical unit to which the option belongs. Non-constant + * options and corresponding named constants share the same + * unit. May be NULL. + */ + const char *unit; +} AVOption; + +/** + * A single allowed range of values, or a single allowed value. + */ +typedef struct AVOptionRange { + const char *str; + /** + * Value range. + * For string ranges this represents the min/max length. + * For dimensions this represents the min/max pixel count or width/height in multi-component case. + */ + double value_min, value_max; + /** + * Value's component range. + * For string this represents the unicode range for chars, 0-127 limits to ASCII. + */ + double component_min, component_max; + /** + * Range flag. + * If set to 1 the struct encodes a range, if set to 0 a single value. + */ + int is_range; +} AVOptionRange; + +/** + * List of AVOptionRange structs. + */ +typedef struct AVOptionRanges { + /** + * Array of option ranges. + * + * Most of option types use just one component. + * Following describes multi-component option types: + * + * AV_OPT_TYPE_IMAGE_SIZE: + * component index 0: range of pixel count (width * height). + * component index 1: range of width. + * component index 2: range of height. + * + * @note To obtain multi-component version of this structure, user must + * provide AV_OPT_MULTI_COMPONENT_RANGE to av_opt_query_ranges or + * av_opt_query_ranges_default function. + * + * Multi-component range can be read as in following example: + * + * @code + * int range_index, component_index; + * AVOptionRanges *ranges; + * AVOptionRange *range[3]; //may require more than 3 in the future. + * av_opt_query_ranges(&ranges, obj, key, AV_OPT_MULTI_COMPONENT_RANGE); + * for (range_index = 0; range_index < ranges->nb_ranges; range_index++) { + * for (component_index = 0; component_index < ranges->nb_components; component_index++) + * range[component_index] = ranges->range[ranges->nb_ranges * component_index + range_index]; + * //do something with range here. + * } + * av_opt_freep_ranges(&ranges); + * @endcode + */ + AVOptionRange **range; + /** + * Number of ranges per component. + */ + int nb_ranges; + /** + * Number of componentes. + */ + int nb_components; +} AVOptionRanges; + +/** + * Show the obj options. + * + * @param req_flags requested flags for the options to show. Show only the + * options for which it is opt->flags & req_flags. + * @param rej_flags rejected flags for the options to show. Show only the + * options for which it is !(opt->flags & req_flags). + * @param av_log_obj log context to use for showing the options + */ +int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags); + +/** + * Set the values of all AVOption fields to their default values. + * + * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass) + */ +void av_opt_set_defaults(void *s); + +/** + * Set the values of all AVOption fields to their default values. Only these + * AVOption fields for which (opt->flags & mask) == flags will have their + * default applied to s. + * + * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass) + * @param mask combination of AV_OPT_FLAG_* + * @param flags combination of AV_OPT_FLAG_* + */ +void av_opt_set_defaults2(void *s, int mask, int flags); + +/** + * Parse the key/value pairs list in opts. For each key/value pair + * found, stores the value in the field in ctx that is named like the + * key. ctx must be an AVClass context, storing is done using + * AVOptions. + * + * @param opts options string to parse, may be NULL + * @param key_val_sep a 0-terminated list of characters used to + * separate key from value + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other + * @return the number of successfully set key/value pairs, or a negative + * value corresponding to an AVERROR code in case of error: + * AVERROR(EINVAL) if opts cannot be parsed, + * the error code issued by av_opt_set() if a key/value pair + * cannot be set + */ +int av_set_options_string(void *ctx, const char *opts, + const char *key_val_sep, const char *pairs_sep); + +/** + * Parse the key-value pairs list in opts. For each key=value pair found, + * set the value of the corresponding option in ctx. + * + * @param ctx the AVClass object to set options on + * @param opts the options string, key-value pairs separated by a + * delimiter + * @param shorthand a NULL-terminated array of options names for shorthand + * notation: if the first field in opts has no key part, + * the key is taken from the first element of shorthand; + * then again for the second, etc., until either opts is + * finished, shorthand is finished or a named option is + * found; after that, all options must be named + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value, for example '=' + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other, for example ':' or ',' + * @return the number of successfully set key=value pairs, or a negative + * value corresponding to an AVERROR code in case of error: + * AVERROR(EINVAL) if opts cannot be parsed, + * the error code issued by av_set_string3() if a key/value pair + * cannot be set + * + * Options names must use only the following characters: a-z A-Z 0-9 - . / _ + * Separators must use characters distinct from option names and from each + * other. + */ +int av_opt_set_from_string(void *ctx, const char *opts, + const char *const *shorthand, + const char *key_val_sep, const char *pairs_sep); +/** + * Free all allocated objects in obj. + */ +void av_opt_free(void *obj); + +/** + * Check whether a particular flag is set in a flags field. + * + * @param field_name the name of the flag field option + * @param flag_name the name of the flag to check + * @return non-zero if the flag is set, zero if the flag isn't set, + * isn't of the right type, or the flags field doesn't exist. + */ +int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name); + +/** + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict(void *obj, struct AVDictionary **options); + + +/** + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags); + +/** + * Extract a key-value pair from the beginning of a string. + * + * @param ropts pointer to the options string, will be updated to + * point to the rest of the string (one of the pairs_sep + * or the final NUL) + * @param key_val_sep a 0-terminated list of characters used to separate + * key from value, for example '=' + * @param pairs_sep a 0-terminated list of characters used to separate + * two pairs from each other, for example ':' or ',' + * @param flags flags; see the AV_OPT_FLAG_* values below + * @param rkey parsed key; must be freed using av_free() + * @param rval parsed value; must be freed using av_free() + * + * @return >=0 for success, or a negative value corresponding to an + * AVERROR code in case of error; in particular: + * AVERROR(EINVAL) if no key is present + * + */ +int av_opt_get_key_value(const char **ropts, + const char *key_val_sep, const char *pairs_sep, + unsigned flags, + char **rkey, char **rval); + +enum { + + /** + * Accept to parse a value without a key; the key will then be returned + * as NULL. + */ + AV_OPT_FLAG_IMPLICIT_KEY = 1, +}; + +/** + * @defgroup opt_eval_funcs Evaluating option strings + * @{ + * This group of functions can be used to evaluate option strings + * and get numbers out of them. They do the same thing as av_opt_set(), + * except the result is written into the caller-supplied pointer. + * + * @param obj a struct whose first element is a pointer to AVClass. + * @param o an option for which the string is to be evaluated. + * @param val string to be evaluated. + * @param *_out value of the string will be written here. + * + * @return 0 on success, a negative number on failure. + */ +int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int *flags_out); +int av_opt_eval_int (void *obj, const AVOption *o, const char *val, int *int_out); +int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t *int64_out); +int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float *float_out); +int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double *double_out); +int av_opt_eval_q (void *obj, const AVOption *o, const char *val, AVRational *q_out); +/** + * @} + */ + +#define AV_OPT_SEARCH_CHILDREN (1 << 0) /**< Search in possible children of the + given object first. */ +/** + * The obj passed to av_opt_find() is fake -- only a double pointer to AVClass + * instead of a required pointer to a struct containing AVClass. This is + * useful for searching for options without needing to allocate the corresponding + * object. + */ +#define AV_OPT_SEARCH_FAKE_OBJ (1 << 1) + +/** + * In av_opt_get, return NULL if the option has a pointer type and is set to NULL, + * rather than returning an empty string. + */ +#define AV_OPT_ALLOW_NULL (1 << 2) + +/** + * Allows av_opt_query_ranges and av_opt_query_ranges_default to return more than + * one component for certain option types. + * @see AVOptionRanges for details. + */ +#define AV_OPT_MULTI_COMPONENT_RANGE (1 << 12) + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * Alternatively a double pointer to an AVClass, if + * AV_OPT_SEARCH_FAKE_OBJ search flag is set. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return A pointer to the option found, or NULL if no option + * was found. + * + * @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable + * directly with av_opt_set(). Use special calls which take an options + * AVDictionary (e.g. avformat_open_input()) to set options found with this + * flag. + */ +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags); + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * Alternatively a double pointer to an AVClass, if + * AV_OPT_SEARCH_FAKE_OBJ search flag is set. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * @param[out] target_obj if non-NULL, an object to which the option belongs will be + * written here. It may be different from obj if AV_OPT_SEARCH_CHILDREN is present + * in search_flags. This parameter is ignored if search_flags contain + * AV_OPT_SEARCH_FAKE_OBJ. + * + * @return A pointer to the option found, or NULL if no option + * was found. + */ +const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags, void **target_obj); + +/** + * Iterate over all AVOptions belonging to obj. + * + * @param obj an AVOptions-enabled struct or a double pointer to an + * AVClass describing it. + * @param prev result of the previous call to av_opt_next() on this object + * or NULL + * @return next AVOption or NULL + */ +const AVOption *av_opt_next(const void *obj, const AVOption *prev); + +/** + * Iterate over AVOptions-enabled children of obj. + * + * @param prev result of a previous call to this function or NULL + * @return next AVOptions-enabled child or NULL + */ +void *av_opt_child_next(void *obj, void *prev); + +/** + * Iterate over potential AVOptions-enabled children of parent. + * + * @param prev result of a previous call to this function or NULL + * @return AVClass corresponding to next potential child or NULL + */ +const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev); + +/** + * @defgroup opt_set_funcs Option setting functions + * @{ + * Those functions set the field of obj with the given name to value. + * + * @param[in] obj A struct whose first element is a pointer to an AVClass. + * @param[in] name the name of the field to set + * @param[in] val The value to set. In case of av_opt_set() if the field is not + * of a string type, then the given string is parsed. + * SI postfixes and some named scalars are supported. + * If the field is of a numeric type, it has to be a numeric or named + * scalar. Behavior with more than one scalar and +- infix operators + * is undefined. + * If the field is of a flags type, it has to be a sequence of numeric + * scalars or named flags separated by '+' or '-'. Prefixing a flag + * with '+' causes it to be set without affecting the other flags; + * similarly, '-' unsets a flag. + * If the field is of a dictionary type, it has to be a ':' separated list of + * key=value parameters. Values containing ':' special characters must be + * escaped. + * @param search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN + * is passed here, then the option may be set on a child of obj. + * + * @return 0 if the value has been set, or an AVERROR code in case of + * error: + * AVERROR_OPTION_NOT_FOUND if no matching option exists + * AVERROR(ERANGE) if the value is out of range + * AVERROR(EINVAL) if the value is not valid + */ +int av_opt_set (void *obj, const char *name, const char *val, int search_flags); +int av_opt_set_int (void *obj, const char *name, int64_t val, int search_flags); +int av_opt_set_double (void *obj, const char *name, double val, int search_flags); +int av_opt_set_q (void *obj, const char *name, AVRational val, int search_flags); +int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags); +int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags); +int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags); +int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags); +int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags); +int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags); +/** + * @note Any old dictionary present is discarded and replaced with a copy of the new one. The + * caller still owns val is and responsible for freeing it. + */ +int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags); + +/** + * Set a binary option to an integer list. + * + * @param obj AVClass object to set options on + * @param name name of the binary option + * @param val pointer to an integer list (must have the correct type with + * regard to the contents of the list) + * @param term list terminator (usually 0 or -1) + * @param flags search flags + */ +#define av_opt_set_int_list(obj, name, val, term, flags) \ + (av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \ + AVERROR(EINVAL) : \ + av_opt_set_bin(obj, name, (const uint8_t *)(val), \ + av_int_list_length(val, term) * sizeof(*(val)), flags)) + +/** + * @} + */ + +/** + * @defgroup opt_get_funcs Option getting functions + * @{ + * Those functions get a value of the option with the given name from an object. + * + * @param[in] obj a struct whose first element is a pointer to an AVClass. + * @param[in] name name of the option to get. + * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN + * is passed here, then the option may be found in a child of obj. + * @param[out] out_val value of the option will be written here + * @return >=0 on success, a negative error code otherwise + */ +/** + * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller + * + * @note if AV_OPT_ALLOW_NULL is set in search_flags in av_opt_get, and the + * option is of type AV_OPT_TYPE_STRING, AV_OPT_TYPE_BINARY or AV_OPT_TYPE_DICT + * and is set to NULL, *out_val will be set to NULL instead of an allocated + * empty string. + */ +int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); +int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); +int av_opt_get_double (void *obj, const char *name, int search_flags, double *out_val); +int av_opt_get_q (void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out); +int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt); +int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt); +int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout); +/** + * @param[out] out_val The returned dictionary is a copy of the actual value and must + * be freed with av_dict_free() by the caller + */ +int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val); +/** + * @} + */ +/** + * Gets a pointer to the requested field in a struct. + * This function allows accessing a struct even when its fields are moved or + * renamed since the application making the access has been compiled, + * + * @returns a pointer to the field, it can be cast to the correct type and read + * or written to. + */ +void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name); + +/** + * Free an AVOptionRanges struct and set it to NULL. + */ +void av_opt_freep_ranges(AVOptionRanges **ranges); + +/** + * Get a list of allowed ranges for the given option. + * + * The returned list may depend on other fields in obj like for example profile. + * + * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored + * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance + * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges + * + * The result must be freed with av_opt_freep_ranges. + * + * @return number of compontents returned on success, a negative errro code otherwise + */ +int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags); + +/** + * Copy options from src object into dest object. + * + * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object. + * Original memory allocated for such options is freed unless both src and dest options points to the same memory. + * + * @param dest Object to copy from + * @param src Object to copy into + * @return 0 on success, negative on error + */ +int av_opt_copy(void *dest, const void *src); + +/** + * Get a default list of allowed ranges for the given option. + * + * This list is constructed without using the AVClass.query_ranges() callback + * and can be used as fallback from within the callback. + * + * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored + * AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance + * AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges + * + * The result must be freed with av_opt_free_ranges. + * + * @return number of compontents returned on success, a negative errro code otherwise + */ +int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags); + +/** + * Check if given option is set to its default value. + * + * Options o must belong to the obj. This function must not be called to check child's options state. + * @see av_opt_is_set_to_default_by_name(). + * + * @param obj AVClass object to check option on + * @param o option to be checked + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default(void *obj, const AVOption *o); + +/** + * Check if given option is set to its default value. + * + * @param obj AVClass object to check option on + * @param name option name + * @param search_flags combination of AV_OPT_SEARCH_* + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags); + + +#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only. +#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only. + +/** + * Serialize object's options. + * + * Create a string containing object's serialized options. + * Such string may be passed back to av_opt_set_from_string() in order to restore option values. + * A key/value or pairs separator occurring in the serialized value or + * name string are escaped through the av_escape() function. + * + * @param[in] obj AVClass object to serialize + * @param[in] opt_flags serialize options with all the specified flags set (AV_OPT_FLAG) + * @param[in] flags combination of AV_OPT_SERIALIZE_* flags + * @param[out] buffer Pointer to buffer that will be allocated with string containg serialized options. + * Buffer must be freed by the caller when is no longer needed. + * @param[in] key_val_sep character used to separate key from value + * @param[in] pairs_sep character used to separate two pairs from each other + * @return >= 0 on success, negative on error + * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same. + */ +int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, + const char key_val_sep, const char pairs_sep); +/** + * @} + */ + +#endif /* AVUTIL_OPT_H */ diff --git a/ffmpeg/inc/libavutil/parseutils.h b/ffmpeg/inc/libavutil/parseutils.h new file mode 100644 index 0000000..e66d24b --- /dev/null +++ b/ffmpeg/inc/libavutil/parseutils.h @@ -0,0 +1,193 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PARSEUTILS_H +#define AVUTIL_PARSEUTILS_H + +#include + +#include "rational.h" + +/** + * @file + * misc parsing utilities + */ + +/** + * Parse str and store the parsed ratio in q. + * + * Note that a ratio with infinite (1/0) or negative value is + * considered valid, so you should check on the returned value if you + * want to exclude those values. + * + * The undefined value can be expressed using the "0:0" string. + * + * @param[in,out] q pointer to the AVRational which will contain the ratio + * @param[in] str the string to parse: it has to be a string in the format + * num:den, a float number or an expression + * @param[in] max the maximum allowed numerator and denominator + * @param[in] log_offset log level offset which is applied to the log + * level of log_ctx + * @param[in] log_ctx parent logging context + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_ratio(AVRational *q, const char *str, int max, + int log_offset, void *log_ctx); + +#define av_parse_ratio_quiet(rate, str, max) \ + av_parse_ratio(rate, str, max, AV_LOG_MAX_OFFSET, NULL) + +/** + * Parse str and put in width_ptr and height_ptr the detected values. + * + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * height value + * @param[in] str the string to parse: it has to be a string in the format + * width x height or a valid video size abbreviation. + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parse str and store the detected values in *rate. + * + * @param[in,out] rate pointer to the AVRational which will contain the detected + * frame rate + * @param[in] str the string to parse: it has to be a string in the format + * rate_num / rate_den, a float number or a valid video rate abbreviation + * @return >= 0 on success, a negative error code otherwise + */ +int av_parse_video_rate(AVRational *rate, const char *str); + +/** + * Put the RGBA values that correspond to color_string in rgba_color. + * + * @param color_string a string specifying a color. It can be the name of + * a color (case insensitive match) or a [0x|#]RRGGBB[AA] sequence, + * possibly followed by "@" and a string representing the alpha + * component. + * The alpha component may be a string composed by "0x" followed by an + * hexadecimal number or a decimal number between 0.0 and 1.0, which + * represents the opacity value (0x00/0.0 means completely transparent, + * 0xff/1.0 completely opaque). + * If the alpha component is not specified then 0xff is assumed. + * The string "random" will result in a random color. + * @param slen length of the initial part of color_string containing the + * color. It can be set to -1 if color_string is a null terminated string + * containing nothing else than the color. + * @return >= 0 in case of success, a negative value in case of + * failure (for example if color_string cannot be parsed). + */ +int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, + void *log_ctx); + +/** + * Get the name of a color from the internal table of hard-coded named + * colors. + * + * This function is meant to enumerate the color names recognized by + * av_parse_color(). + * + * @param color_idx index of the requested color, starting from 0 + * @param rgbp if not NULL, will point to a 3-elements array with the color value in RGB + * @return the color name string or NULL if color_idx is not in the array + */ +const char *av_get_known_color_name(int color_idx, const uint8_t **rgb); + +/** + * Parse timestr and return in *time a corresponding number of + * microseconds. + * + * @param timeval puts here the number of microseconds corresponding + * to the string in timestr. If the string represents a duration, it + * is the number of microseconds contained in the time interval. If + * the string is a date, is the number of microseconds since 1st of + * January, 1970 up to the time of the parsed date. If timestr cannot + * be successfully parsed, set *time to INT64_MIN. + + * @param timestr a string representing a date or a duration. + * - If a date the syntax is: + * @code + * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH:MM:SS[.m...]]]}|{HHMMSS[.m...]]]}}[Z] + * now + * @endcode + * If the value is "now" it takes the current time. + * Time is local time unless Z is appended, in which case it is + * interpreted as UTC. + * If the year-month-day part is not specified it takes the current + * year-month-day. + * - If a duration the syntax is: + * @code + * [-][HH:]MM:SS[.m...] + * [-]S+[.m...] + * @endcode + * @param duration flag which tells how to interpret timestr, if not + * zero timestr is interpreted as a duration, otherwise as a date + * @return >= 0 in case of success, a negative value corresponding to an + * AVERROR code otherwise + */ +int av_parse_time(int64_t *timeval, const char *timestr, int duration); + +/** + * Attempt to find a specific tag in a URL. + * + * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. + * Return 1 if found. + */ +int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +/** + * Simplified version of strptime + * + * Parse the input string p according to the format string fmt and + * store its results in the structure dt. + * This implementation supports only a subset of the formats supported + * by the standard strptime(). + * + * The supported input field descriptors are listed below. + * - %H: the hour as a decimal number, using a 24-hour clock, in the + * range '00' through '23' + * - %J: hours as a decimal number, in the range '0' through INT_MAX + * - %M: the minute as a decimal number, using a 24-hour clock, in the + * range '00' through '59' + * - %S: the second as a decimal number, using a 24-hour clock, in the + * range '00' through '59' + * - %Y: the year as a decimal number, using the Gregorian calendar + * - %m: the month as a decimal number, in the range '1' through '12' + * - %d: the day of the month as a decimal number, in the range '1' + * through '31' + * - %T: alias for '%H:%M:%S' + * - %%: a literal '%' + * + * @return a pointer to the first character not processed in this function + * call. In case the input string contains more characters than + * required by the format string the return value points right after + * the last consumed input character. In case the whole input string + * is consumed the return value points to the null byte at the end of + * the string. On failure NULL is returned. + */ +char *av_small_strptime(const char *p, const char *fmt, struct tm *dt); + +/** + * Convert the decomposed UTC time in tm to a time_t value. + */ +time_t av_timegm(struct tm *tm); + +#endif /* AVUTIL_PARSEUTILS_H */ diff --git a/ffmpeg/inc/libavutil/pixdesc.h b/ffmpeg/inc/libavutil/pixdesc.h new file mode 100644 index 0000000..c055810 --- /dev/null +++ b/ffmpeg/inc/libavutil/pixdesc.h @@ -0,0 +1,440 @@ +/* + * pixel format descriptor + * Copyright (c) 2009 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXDESC_H +#define AVUTIL_PIXDESC_H + +#include + +#include "attributes.h" +#include "pixfmt.h" +#include "version.h" + +typedef struct AVComponentDescriptor { + /** + * Which of the 4 planes contains the component. + */ + int plane; + + /** + * Number of elements between 2 horizontally consecutive pixels. + * Elements are bits for bitstream formats, bytes otherwise. + */ + int step; + + /** + * Number of elements before the component of the first pixel. + * Elements are bits for bitstream formats, bytes otherwise. + */ + int offset; + + /** + * Number of least significant bits that must be shifted away + * to get the value. + */ + int shift; + + /** + * Number of bits in the component. + */ + int depth; + +#if FF_API_PLUS1_MINUS1 + /** deprecated, use step instead */ + attribute_deprecated int step_minus1; + + /** deprecated, use depth instead */ + attribute_deprecated int depth_minus1; + + /** deprecated, use offset instead */ + attribute_deprecated int offset_plus1; +#endif +} AVComponentDescriptor; + +/** + * Descriptor that unambiguously describes how the bits of a pixel are + * stored in the up to 4 data planes of an image. It also stores the + * subsampling factors and number of components. + * + * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV + * and all the YUV variants) AVPixFmtDescriptor just stores how values + * are stored not what these values represent. + */ +typedef struct AVPixFmtDescriptor { + const char *name; + uint8_t nb_components; ///< The number of components each pixel has, (1-4) + + /** + * Amount to shift the luma width right to find the chroma width. + * For YV12 this is 1 for example. + * chroma_width = AV_CEIL_RSHIFT(luma_width, log2_chroma_w) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_w; + + /** + * Amount to shift the luma height right to find the chroma height. + * For YV12 this is 1 for example. + * chroma_height= AV_CEIL_RSHIFT(luma_height, log2_chroma_h) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + uint8_t log2_chroma_h; + + /** + * Combination of AV_PIX_FMT_FLAG_... flags. + */ + uint64_t flags; + + /** + * Parameters that describe how pixels are packed. + * If the format has 1 or 2 components, then luma is 0. + * If the format has 3 or 4 components: + * if the RGB flag is set then 0 is red, 1 is green and 2 is blue; + * otherwise 0 is luma, 1 is chroma-U and 2 is chroma-V. + * + * If present, the Alpha channel is always the last component. + */ + AVComponentDescriptor comp[4]; + + /** + * Alternative comma-separated names. + */ + const char *alias; +} AVPixFmtDescriptor; + +/** + * Pixel format is big-endian. + */ +#define AV_PIX_FMT_FLAG_BE (1 << 0) +/** + * Pixel format has a palette in data[1], values are indexes in this palette. + */ +#define AV_PIX_FMT_FLAG_PAL (1 << 1) +/** + * All values of a component are bit-wise packed end to end. + */ +#define AV_PIX_FMT_FLAG_BITSTREAM (1 << 2) +/** + * Pixel format is an HW accelerated format. + */ +#define AV_PIX_FMT_FLAG_HWACCEL (1 << 3) +/** + * At least one pixel component is not in the first data plane. + */ +#define AV_PIX_FMT_FLAG_PLANAR (1 << 4) +/** + * The pixel format contains RGB-like data (as opposed to YUV/grayscale). + */ +#define AV_PIX_FMT_FLAG_RGB (1 << 5) + +/** + * The pixel format is "pseudo-paletted". This means that it contains a + * fixed palette in the 2nd plane but the palette is fixed/constant for each + * PIX_FMT. This allows interpreting the data as if it was PAL8, which can + * in some cases be simpler. Or the data can be interpreted purely based on + * the pixel format without using the palette. + * An example of a pseudo-paletted format is AV_PIX_FMT_GRAY8 + * + * @deprecated This flag is deprecated, and will be removed. When it is removed, + * the extra palette allocation in AVFrame.data[1] is removed as well. Only + * actual paletted formats (as indicated by AV_PIX_FMT_FLAG_PAL) will have a + * palette. Starting with FFmpeg versions which have this flag deprecated, the + * extra "pseudo" palette is already ignored, and API users are not required to + * allocate a palette for AV_PIX_FMT_FLAG_PSEUDOPAL formats (it was required + * before the deprecation, though). + */ +#define AV_PIX_FMT_FLAG_PSEUDOPAL (1 << 6) + +/** + * The pixel format has an alpha channel. This is set on all formats that + * support alpha in some way, including AV_PIX_FMT_PAL8. The alpha is always + * straight, never pre-multiplied. + * + * If a codec or a filter does not support alpha, it should set all alpha to + * opaque, or use the equivalent pixel formats without alpha component, e.g. + * AV_PIX_FMT_RGB0 (or AV_PIX_FMT_RGB24 etc.) instead of AV_PIX_FMT_RGBA. + */ +#define AV_PIX_FMT_FLAG_ALPHA (1 << 7) + +/** + * The pixel format is following a Bayer pattern + */ +#define AV_PIX_FMT_FLAG_BAYER (1 << 8) + +/** + * The pixel format contains IEEE-754 floating point values. Precision (double, + * single, or half) should be determined by the pixel size (64, 32, or 16 bits). + */ +#define AV_PIX_FMT_FLAG_FLOAT (1 << 9) + +/** + * Return the number of bits per pixel used by the pixel format + * described by pixdesc. Note that this is not the same as the number + * of bits per sample. + * + * The returned number of bits refers to the number of bits actually + * used for storing the pixel information, that is padding bits are + * not counted. + */ +int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); + +/** + * Return the number of bits per pixel for the pixel format + * described by pixdesc, including any padding or unused bits. + */ +int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); + +/** + * @return a pixel format descriptor for provided pixel format or NULL if + * this pixel format is unknown. + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt); + +/** + * Iterate over all pixel format descriptors known to libavutil. + * + * @param prev previous descriptor. NULL to get the first descriptor. + * + * @return next descriptor or NULL after the last descriptor + */ +const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev); + +/** + * @return an AVPixelFormat id described by desc, or AV_PIX_FMT_NONE if desc + * is not a valid pointer to a pixel format descriptor. + */ +enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc); + +/** + * Utility function to access log2_chroma_w log2_chroma_h from + * the pixel format AVPixFmtDescriptor. + * + * @param[in] pix_fmt the pixel format + * @param[out] h_shift store log2_chroma_w (horizontal/width shift) + * @param[out] v_shift store log2_chroma_h (vertical/height shift) + * + * @return 0 on success, AVERROR(ENOSYS) on invalid or unknown pixel format + */ +int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, + int *h_shift, int *v_shift); + +/** + * @return number of planes in pix_fmt, a negative AVERROR if pix_fmt is not a + * valid pixel format. + */ +int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt); + +/** + * @return the name for provided color range or NULL if unknown. + */ +const char *av_color_range_name(enum AVColorRange range); + +/** + * @return the AVColorRange value for name or an AVError if not found. + */ +int av_color_range_from_name(const char *name); + +/** + * @return the name for provided color primaries or NULL if unknown. + */ +const char *av_color_primaries_name(enum AVColorPrimaries primaries); + +/** + * @return the AVColorPrimaries value for name or an AVError if not found. + */ +int av_color_primaries_from_name(const char *name); + +/** + * @return the name for provided color transfer or NULL if unknown. + */ +const char *av_color_transfer_name(enum AVColorTransferCharacteristic transfer); + +/** + * @return the AVColorTransferCharacteristic value for name or an AVError if not found. + */ +int av_color_transfer_from_name(const char *name); + +/** + * @return the name for provided color space or NULL if unknown. + */ +const char *av_color_space_name(enum AVColorSpace space); + +/** + * @return the AVColorSpace value for name or an AVError if not found. + */ +int av_color_space_from_name(const char *name); + +/** + * @return the name for provided chroma location or NULL if unknown. + */ +const char *av_chroma_location_name(enum AVChromaLocation location); + +/** + * @return the AVChromaLocation value for name or an AVError if not found. + */ +int av_chroma_location_from_name(const char *name); + +/** + * Return the pixel format corresponding to name. + * + * If there is no pixel format with name name, then looks for a + * pixel format with the name corresponding to the native endian + * format of name. + * For example in a little-endian system, first looks for "gray16", + * then for "gray16le". + * + * Finally if no pixel format has been found, returns AV_PIX_FMT_NONE. + */ +enum AVPixelFormat av_get_pix_fmt(const char *name); + +/** + * Return the short name for a pixel format, NULL in case pix_fmt is + * unknown. + * + * @see av_get_pix_fmt(), av_get_pix_fmt_string() + */ +const char *av_get_pix_fmt_name(enum AVPixelFormat pix_fmt); + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or a header if pix_fmt is negative. + * + * @param buf the buffer where to write the string + * @param buf_size the size of buf + * @param pix_fmt the number of the pixel format to print the + * corresponding info string, or a negative value to print the + * corresponding header. + */ +char *av_get_pix_fmt_string(char *buf, int buf_size, + enum AVPixelFormat pix_fmt); + +/** + * Read a line from an image, and write the values of the + * pixel format component c to dst. + * + * @param data the array containing the pointers to the planes of the image + * @param linesize the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to read + * @param y the vertical coordinate of the first pixel to read + * @param w the width of the line to read, that is the number of + * values to write to dst + * @param read_pal_component if not zero and the format is a paletted + * format writes the values corresponding to the palette + * component c in data[1] to dst, rather than the palette indexes in + * data[0]. The behavior is undefined if the format is not paletted. + * @param dst_element_size size of elements in dst array (2 or 4 byte) + */ +void av_read_image_line2(void *dst, const uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int read_pal_component, + int dst_element_size); + +void av_read_image_line(uint16_t *dst, const uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int read_pal_component); + +/** + * Write the values from src to the pixel format component c of an + * image line. + * + * @param src array containing the values to write + * @param data the array containing the pointers to the planes of the + * image to write into. It is supposed to be zeroed. + * @param linesize the array containing the linesizes of the image + * @param desc the pixel format descriptor for the image + * @param x the horizontal coordinate of the first pixel to write + * @param y the vertical coordinate of the first pixel to write + * @param w the width of the line to write, that is the number of + * values to write to the image line + * @param src_element_size size of elements in src array (2 or 4 byte) + */ +void av_write_image_line2(const void *src, uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w, int src_element_size); + +void av_write_image_line(const uint16_t *src, uint8_t *data[4], + const int linesize[4], const AVPixFmtDescriptor *desc, + int x, int y, int c, int w); + +/** + * Utility function to swap the endianness of a pixel format. + * + * @param[in] pix_fmt the pixel format + * + * @return pixel format with swapped endianness if it exists, + * otherwise AV_PIX_FMT_NONE + */ +enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt); + +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ + +/** + * Compute what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * av_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur + * (maximum loss for an invalid dst_pix_fmt). + */ +int av_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, + enum AVPixelFormat src_pix_fmt, + int has_alpha); + +/** + * Compute what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * av_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur + * (maximum loss for an invalid dst_pix_fmt). + */ +enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, + enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + +#endif /* AVUTIL_PIXDESC_H */ diff --git a/ffmpeg/inc/libavutil/pixelutils.h b/ffmpeg/inc/libavutil/pixelutils.h new file mode 100644 index 0000000..a8dbc15 --- /dev/null +++ b/ffmpeg/inc/libavutil/pixelutils.h @@ -0,0 +1,52 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXELUTILS_H +#define AVUTIL_PIXELUTILS_H + +#include +#include +#include "common.h" + +/** + * Sum of abs(src1[x] - src2[x]) + */ +typedef int (*av_pixelutils_sad_fn)(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +/** + * Get a potentially optimized pointer to a Sum-of-absolute-differences + * function (see the av_pixelutils_sad_fn prototype). + * + * @param w_bits 1< + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXFMT_H +#define AVUTIL_PIXFMT_H + +/** + * @file + * pixel format definitions + */ + +#include "libavutil/avconfig.h" +#include "version.h" + +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 + +/** + * Pixel format. + * + * @note + * AV_PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA + * color is put together as: + * (A << 24) | (R << 16) | (G << 8) | B + * This is stored as BGRA on little-endian CPU architectures and ARGB on + * big-endian CPUs. + * + * @note + * If the resolution is not a multiple of the chroma subsampling factor + * then the chroma plane resolution must be rounded up. + * + * @par + * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized + * image data is stored in AVFrame.data[0]. The palette is transported in + * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is + * formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is + * also endian-specific). Note also that the individual RGB32 palette + * components stored in AVFrame.data[1] should be in the range 0..255. + * This is important as many custom PAL8 video codecs that were designed + * to run on the IBM VGA graphics adapter use 6-bit palette components. + * + * @par + * For all the 8 bits per pixel formats, an RGB32 palette is in data[1] like + * for pal8. This palette is filled in automatically by the function + * allocating the picture. + */ +enum AVPixelFormat { + AV_PIX_FMT_NONE = -1, + AV_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + AV_PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr + AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... + AV_PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... + AV_PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + AV_PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) + AV_PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) + AV_PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) + AV_PIX_FMT_GRAY8, ///< Y , 8bpp + AV_PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb + AV_PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb + AV_PIX_FMT_PAL8, ///< 8 bits with AV_PIX_FMT_RGB32 palette + AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range + AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range + AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range + AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 + AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 + AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) + AV_PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AV_PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) + AV_PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) + AV_PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AV_PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) + AV_PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + AV_PIX_FMT_NV21, ///< as above, but U and V bytes are swapped + + AV_PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... + AV_PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... + AV_PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... + AV_PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... + + AV_PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian + AV_PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian + AV_PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) + AV_PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range + AV_PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) + AV_PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian + AV_PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian + + AV_PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian + AV_PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian + AV_PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined + AV_PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined + + AV_PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian + AV_PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian + AV_PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined + AV_PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined + +#if FF_API_VAAPI + /** @name Deprecated pixel formats */ + /**@{*/ + AV_PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers + AV_PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers + AV_PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a VASurfaceID + /**@}*/ + AV_PIX_FMT_VAAPI = AV_PIX_FMT_VAAPI_VLD, +#else + /** + * Hardware acceleration through VA-API, data[3] contains a + * VASurfaceID. + */ + AV_PIX_FMT_VAAPI, +#endif + + AV_PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer + + AV_PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4X 4R 4G 4B(lsb), big-endian, X=unused/undefined + AV_PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), little-endian, X=unused/undefined + AV_PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4X 4B 4G 4R(lsb), big-endian, X=unused/undefined + AV_PIX_FMT_YA8, ///< 8 bits gray, 8 bits alpha + + AV_PIX_FMT_Y400A = AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 + AV_PIX_FMT_GRAY8A= AV_PIX_FMT_YA8, ///< alias for AV_PIX_FMT_YA8 + + AV_PIX_FMT_BGR48BE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian + AV_PIX_FMT_BGR48LE, ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian + + /** + * The following 12 formats have the disadvantage of needing 1 format for each bit depth. + * Notice that each 9/10 bits sample is stored in 16 bits with extra padding. + * If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately is better. + */ + AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P10LE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV422P10BE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P10LE,///< planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV444P9BE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P9LE, ///< planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P10BE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_GBRP, ///< planar GBR 4:4:4 24bpp + AV_PIX_FMT_GBR24P = AV_PIX_FMT_GBRP, // alias for #AV_PIX_FMT_GBRP + AV_PIX_FMT_GBRP9BE, ///< planar GBR 4:4:4 27bpp, big-endian + AV_PIX_FMT_GBRP9LE, ///< planar GBR 4:4:4 27bpp, little-endian + AV_PIX_FMT_GBRP10BE, ///< planar GBR 4:4:4 30bpp, big-endian + AV_PIX_FMT_GBRP10LE, ///< planar GBR 4:4:4 30bpp, little-endian + AV_PIX_FMT_GBRP16BE, ///< planar GBR 4:4:4 48bpp, big-endian + AV_PIX_FMT_GBRP16LE, ///< planar GBR 4:4:4 48bpp, little-endian + AV_PIX_FMT_YUVA422P, ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples) + AV_PIX_FMT_YUVA444P, ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples) + AV_PIX_FMT_YUVA420P9BE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian + AV_PIX_FMT_YUVA420P9LE, ///< planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian + AV_PIX_FMT_YUVA422P9BE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian + AV_PIX_FMT_YUVA422P9LE, ///< planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian + AV_PIX_FMT_YUVA444P9BE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian + AV_PIX_FMT_YUVA444P9LE, ///< planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian + AV_PIX_FMT_YUVA420P10BE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) + AV_PIX_FMT_YUVA420P10LE, ///< planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) + AV_PIX_FMT_YUVA422P10BE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA422P10LE, ///< planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA444P10BE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA444P10LE, ///< planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA420P16BE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian) + AV_PIX_FMT_YUVA420P16LE, ///< planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian) + AV_PIX_FMT_YUVA422P16BE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian) + AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian) + AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian) + + AV_PIX_FMT_VDPAU, ///< HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface + + AV_PIX_FMT_XYZ12LE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as little-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_XYZ12BE, ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_NV16, ///< interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + AV_PIX_FMT_NV20LE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_NV20BE, ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + + AV_PIX_FMT_RGBA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian + AV_PIX_FMT_RGBA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian + AV_PIX_FMT_BGRA64BE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian + AV_PIX_FMT_BGRA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian + + AV_PIX_FMT_YVYU422, ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb + + AV_PIX_FMT_YA16BE, ///< 16 bits gray, 16 bits alpha (big-endian) + AV_PIX_FMT_YA16LE, ///< 16 bits gray, 16 bits alpha (little-endian) + + AV_PIX_FMT_GBRAP, ///< planar GBRA 4:4:4:4 32bpp + AV_PIX_FMT_GBRAP16BE, ///< planar GBRA 4:4:4:4 64bpp, big-endian + AV_PIX_FMT_GBRAP16LE, ///< planar GBRA 4:4:4:4 64bpp, little-endian + /** + * HW acceleration through QSV, data[3] contains a pointer to the + * mfxFrameSurface1 structure. + */ + AV_PIX_FMT_QSV, + /** + * HW acceleration though MMAL, data[3] contains a pointer to the + * MMAL_BUFFER_HEADER_T structure. + */ + AV_PIX_FMT_MMAL, + + AV_PIX_FMT_D3D11VA_VLD, ///< HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer + + /** + * HW acceleration through CUDA. data[i] contain CUdeviceptr pointers + * exactly as for system memory frames. + */ + AV_PIX_FMT_CUDA, + + AV_PIX_FMT_0RGB, ///< packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined + AV_PIX_FMT_RGB0, ///< packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined + AV_PIX_FMT_0BGR, ///< packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined + AV_PIX_FMT_BGR0, ///< packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined + + AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + AV_PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + AV_PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + AV_PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + AV_PIX_FMT_GBRP12BE, ///< planar GBR 4:4:4 36bpp, big-endian + AV_PIX_FMT_GBRP12LE, ///< planar GBR 4:4:4 36bpp, little-endian + AV_PIX_FMT_GBRP14BE, ///< planar GBR 4:4:4 42bpp, big-endian + AV_PIX_FMT_GBRP14LE, ///< planar GBR 4:4:4 42bpp, little-endian + AV_PIX_FMT_YUVJ411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV411P and setting color_range + + AV_PIX_FMT_BAYER_BGGR8, ///< bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples + AV_PIX_FMT_BAYER_RGGB8, ///< bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples + AV_PIX_FMT_BAYER_GBRG8, ///< bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples + AV_PIX_FMT_BAYER_GRBG8, ///< bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples + AV_PIX_FMT_BAYER_BGGR16LE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian + AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian + AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian + AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian + AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian + + AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing + + AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian + AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian + AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian + AV_PIX_FMT_YUV440P12BE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian + AV_PIX_FMT_AYUV64LE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), little-endian + AV_PIX_FMT_AYUV64BE, ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), big-endian + + AV_PIX_FMT_VIDEOTOOLBOX, ///< hardware decoding through Videotoolbox + + AV_PIX_FMT_P010LE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian + AV_PIX_FMT_P010BE, ///< like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, big-endian + + AV_PIX_FMT_GBRAP12BE, ///< planar GBR 4:4:4:4 48bpp, big-endian + AV_PIX_FMT_GBRAP12LE, ///< planar GBR 4:4:4:4 48bpp, little-endian + + AV_PIX_FMT_GBRAP10BE, ///< planar GBR 4:4:4:4 40bpp, big-endian + AV_PIX_FMT_GBRAP10LE, ///< planar GBR 4:4:4:4 40bpp, little-endian + + AV_PIX_FMT_MEDIACODEC, ///< hardware decoding through MediaCodec + + AV_PIX_FMT_GRAY12BE, ///< Y , 12bpp, big-endian + AV_PIX_FMT_GRAY12LE, ///< Y , 12bpp, little-endian + AV_PIX_FMT_GRAY10BE, ///< Y , 10bpp, big-endian + AV_PIX_FMT_GRAY10LE, ///< Y , 10bpp, little-endian + + AV_PIX_FMT_P016LE, ///< like NV12, with 16bpp per component, little-endian + AV_PIX_FMT_P016BE, ///< like NV12, with 16bpp per component, big-endian + + /** + * Hardware surfaces for Direct3D11. + * + * This is preferred over the legacy AV_PIX_FMT_D3D11VA_VLD. The new D3D11 + * hwaccel API and filtering support AV_PIX_FMT_D3D11 only. + * + * data[0] contains a ID3D11Texture2D pointer, and data[1] contains the + * texture array index of the frame as intptr_t if the ID3D11Texture2D is + * an array texture (or always 0 if it's a normal texture). + */ + AV_PIX_FMT_D3D11, + + AV_PIX_FMT_GRAY9BE, ///< Y , 9bpp, big-endian + AV_PIX_FMT_GRAY9LE, ///< Y , 9bpp, little-endian + + AV_PIX_FMT_GBRPF32BE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, big-endian + AV_PIX_FMT_GBRPF32LE, ///< IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian + AV_PIX_FMT_GBRAPF32BE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, big-endian + AV_PIX_FMT_GBRAPF32LE, ///< IEEE-754 single precision planar GBRA 4:4:4:4, 128bpp, little-endian + + /** + * DRM-managed buffers exposed through PRIME buffer sharing. + * + * data[0] points to an AVDRMFrameDescriptor. + */ + AV_PIX_FMT_DRM_PRIME, + /** + * Hardware surfaces for OpenCL. + * + * data[i] contain 2D image objects (typed in C as cl_mem, used + * in OpenCL as image2d_t) for each plane of the surface. + */ + AV_PIX_FMT_OPENCL, + + AV_PIX_FMT_GRAY14BE, ///< Y , 14bpp, big-endian + AV_PIX_FMT_GRAY14LE, ///< Y , 14bpp, little-endian + + AV_PIX_FMT_GRAYF32BE, ///< IEEE-754 single precision Y, 32bpp, big-endian + AV_PIX_FMT_GRAYF32LE, ///< IEEE-754 single precision Y, 32bpp, little-endian + + AV_PIX_FMT_YUVA422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, big-endian + AV_PIX_FMT_YUVA422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), 12b alpha, little-endian + AV_PIX_FMT_YUVA444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, big-endian + AV_PIX_FMT_YUVA444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), 12b alpha, little-endian + + AV_PIX_FMT_NV24, ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + AV_PIX_FMT_NV42, ///< as above, but U and V bytes are swapped + + /** + * Vulkan hardware images. + * + * data[0] points to an AVVkFrame + */ + AV_PIX_FMT_VULKAN, + + AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, big-endian + AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, little-endian + + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions +}; + +#if AV_HAVE_BIGENDIAN +# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##be +#else +# define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##le +#endif + +#define AV_PIX_FMT_RGB32 AV_PIX_FMT_NE(ARGB, BGRA) +#define AV_PIX_FMT_RGB32_1 AV_PIX_FMT_NE(RGBA, ABGR) +#define AV_PIX_FMT_BGR32 AV_PIX_FMT_NE(ABGR, RGBA) +#define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB) +#define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0) +#define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0) + +#define AV_PIX_FMT_GRAY9 AV_PIX_FMT_NE(GRAY9BE, GRAY9LE) +#define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE) +#define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE) +#define AV_PIX_FMT_GRAY14 AV_PIX_FMT_NE(GRAY14BE, GRAY14LE) +#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE) +#define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE) +#define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE) +#define AV_PIX_FMT_RGB565 AV_PIX_FMT_NE(RGB565BE, RGB565LE) +#define AV_PIX_FMT_RGB555 AV_PIX_FMT_NE(RGB555BE, RGB555LE) +#define AV_PIX_FMT_RGB444 AV_PIX_FMT_NE(RGB444BE, RGB444LE) +#define AV_PIX_FMT_RGBA64 AV_PIX_FMT_NE(RGBA64BE, RGBA64LE) +#define AV_PIX_FMT_BGR48 AV_PIX_FMT_NE(BGR48BE, BGR48LE) +#define AV_PIX_FMT_BGR565 AV_PIX_FMT_NE(BGR565BE, BGR565LE) +#define AV_PIX_FMT_BGR555 AV_PIX_FMT_NE(BGR555BE, BGR555LE) +#define AV_PIX_FMT_BGR444 AV_PIX_FMT_NE(BGR444BE, BGR444LE) +#define AV_PIX_FMT_BGRA64 AV_PIX_FMT_NE(BGRA64BE, BGRA64LE) + +#define AV_PIX_FMT_YUV420P9 AV_PIX_FMT_NE(YUV420P9BE , YUV420P9LE) +#define AV_PIX_FMT_YUV422P9 AV_PIX_FMT_NE(YUV422P9BE , YUV422P9LE) +#define AV_PIX_FMT_YUV444P9 AV_PIX_FMT_NE(YUV444P9BE , YUV444P9LE) +#define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE) +#define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE) +#define AV_PIX_FMT_YUV440P10 AV_PIX_FMT_NE(YUV440P10BE, YUV440P10LE) +#define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE) +#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE) +#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE) +#define AV_PIX_FMT_YUV440P12 AV_PIX_FMT_NE(YUV440P12BE, YUV440P12LE) +#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE) +#define AV_PIX_FMT_YUV420P14 AV_PIX_FMT_NE(YUV420P14BE, YUV420P14LE) +#define AV_PIX_FMT_YUV422P14 AV_PIX_FMT_NE(YUV422P14BE, YUV422P14LE) +#define AV_PIX_FMT_YUV444P14 AV_PIX_FMT_NE(YUV444P14BE, YUV444P14LE) +#define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE) +#define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE) +#define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE) + +#define AV_PIX_FMT_GBRP9 AV_PIX_FMT_NE(GBRP9BE , GBRP9LE) +#define AV_PIX_FMT_GBRP10 AV_PIX_FMT_NE(GBRP10BE, GBRP10LE) +#define AV_PIX_FMT_GBRP12 AV_PIX_FMT_NE(GBRP12BE, GBRP12LE) +#define AV_PIX_FMT_GBRP14 AV_PIX_FMT_NE(GBRP14BE, GBRP14LE) +#define AV_PIX_FMT_GBRP16 AV_PIX_FMT_NE(GBRP16BE, GBRP16LE) +#define AV_PIX_FMT_GBRAP10 AV_PIX_FMT_NE(GBRAP10BE, GBRAP10LE) +#define AV_PIX_FMT_GBRAP12 AV_PIX_FMT_NE(GBRAP12BE, GBRAP12LE) +#define AV_PIX_FMT_GBRAP16 AV_PIX_FMT_NE(GBRAP16BE, GBRAP16LE) + +#define AV_PIX_FMT_BAYER_BGGR16 AV_PIX_FMT_NE(BAYER_BGGR16BE, BAYER_BGGR16LE) +#define AV_PIX_FMT_BAYER_RGGB16 AV_PIX_FMT_NE(BAYER_RGGB16BE, BAYER_RGGB16LE) +#define AV_PIX_FMT_BAYER_GBRG16 AV_PIX_FMT_NE(BAYER_GBRG16BE, BAYER_GBRG16LE) +#define AV_PIX_FMT_BAYER_GRBG16 AV_PIX_FMT_NE(BAYER_GRBG16BE, BAYER_GRBG16LE) + +#define AV_PIX_FMT_GBRPF32 AV_PIX_FMT_NE(GBRPF32BE, GBRPF32LE) +#define AV_PIX_FMT_GBRAPF32 AV_PIX_FMT_NE(GBRAPF32BE, GBRAPF32LE) + +#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE) + +#define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE) +#define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE) +#define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE) +#define AV_PIX_FMT_YUVA420P10 AV_PIX_FMT_NE(YUVA420P10BE, YUVA420P10LE) +#define AV_PIX_FMT_YUVA422P10 AV_PIX_FMT_NE(YUVA422P10BE, YUVA422P10LE) +#define AV_PIX_FMT_YUVA444P10 AV_PIX_FMT_NE(YUVA444P10BE, YUVA444P10LE) +#define AV_PIX_FMT_YUVA422P12 AV_PIX_FMT_NE(YUVA422P12BE, YUVA422P12LE) +#define AV_PIX_FMT_YUVA444P12 AV_PIX_FMT_NE(YUVA444P12BE, YUVA444P12LE) +#define AV_PIX_FMT_YUVA420P16 AV_PIX_FMT_NE(YUVA420P16BE, YUVA420P16LE) +#define AV_PIX_FMT_YUVA422P16 AV_PIX_FMT_NE(YUVA422P16BE, YUVA422P16LE) +#define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE) + +#define AV_PIX_FMT_XYZ12 AV_PIX_FMT_NE(XYZ12BE, XYZ12LE) +#define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE) +#define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE) +#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE) +#define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) + +#define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE) + +/** + * Chromaticity coordinates of the source primaries. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1. + */ +enum AVColorPrimaries { + AVCOL_PRI_RESERVED0 = 0, + AVCOL_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B + AVCOL_PRI_UNSPECIFIED = 2, + AVCOL_PRI_RESERVED = 3, + AVCOL_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + + AVCOL_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM + AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above + AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C + AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 + AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) + AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428, + AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 + AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 + AVCOL_PRI_EBU3213 = 22, ///< EBU Tech. 3213-E / JEDEC P22 phosphors + AVCOL_PRI_JEDEC_P22 = AVCOL_PRI_EBU3213, + AVCOL_PRI_NB ///< Not part of ABI +}; + +/** + * Color Transfer Characteristic. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2. + */ +enum AVColorTransferCharacteristic { + AVCOL_TRC_RESERVED0 = 0, + AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 + AVCOL_TRC_UNSPECIFIED = 2, + AVCOL_TRC_RESERVED = 3, + AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG + AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC + AVCOL_TRC_SMPTE240M = 7, + AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" + AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" + AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" + AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 + AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut + AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) + AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system + AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system + AVCOL_TRC_SMPTE2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems + AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084, + AVCOL_TRC_SMPTE428 = 17, ///< SMPTE ST 428-1 + AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428, + AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" + AVCOL_TRC_NB ///< Not part of ABI +}; + +/** + * YUV colorspace type. + * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.3. + */ +enum AVColorSpace { + AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) + AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + AVCOL_SPC_UNSPECIFIED = 2, + AVCOL_SPC_RESERVED = 3, + AVCOL_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + AVCOL_SPC_SMPTE240M = 7, ///< functionally identical to above + AVCOL_SPC_YCGCO = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + AVCOL_SPC_YCOCG = AVCOL_SPC_YCGCO, + AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system + AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system + AVCOL_SPC_SMPTE2085 = 11, ///< SMPTE 2085, Y'D'zD'x + AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system + AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system + AVCOL_SPC_ICTCP = 14, ///< ITU-R BT.2100-0, ICtCp + AVCOL_SPC_NB ///< Not part of ABI +}; + +/** + * MPEG vs JPEG YUV range. + */ +enum AVColorRange { + AVCOL_RANGE_UNSPECIFIED = 0, + AVCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges + AVCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges + AVCOL_RANGE_NB ///< Not part of ABI +}; + +/** + * Location of chroma samples. + * + * Illustration showing the location of the first (top left) chroma sample of the + * image, the left shows only luma, the right + * shows the location of the chroma sample, the 2 could be imagined to overlay + * each other but are drawn separately due to limitations of ASCII + * + * 1st 2nd 1st 2nd horizontal luma sample positions + * v v v v + * ______ ______ + *1st luma line > |X X ... |3 4 X ... X are luma samples, + * | |1 2 1-6 are possible chroma positions + *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position + */ +enum AVChromaLocation { + AVCHROMA_LOC_UNSPECIFIED = 0, + AVCHROMA_LOC_LEFT = 1, ///< MPEG-2/4 4:2:0, H.264 default for 4:2:0 + AVCHROMA_LOC_CENTER = 2, ///< MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0 + AVCHROMA_LOC_TOPLEFT = 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 + AVCHROMA_LOC_TOP = 4, + AVCHROMA_LOC_BOTTOMLEFT = 5, + AVCHROMA_LOC_BOTTOM = 6, + AVCHROMA_LOC_NB ///< Not part of ABI +}; + +#endif /* AVUTIL_PIXFMT_H */ diff --git a/ffmpeg/inc/libavutil/random_seed.h b/ffmpeg/inc/libavutil/random_seed.h new file mode 100644 index 0000000..0462a04 --- /dev/null +++ b/ffmpeg/inc/libavutil/random_seed.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2009 Baptiste Coudurier + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RANDOM_SEED_H +#define AVUTIL_RANDOM_SEED_H + +#include +/** + * @addtogroup lavu_crypto + * @{ + */ + +/** + * Get a seed to use in conjunction with random functions. + * This function tries to provide a good seed at a best effort bases. + * Its possible to call this function multiple times if more bits are needed. + * It can be quite slow, which is why it should only be used as seed for a faster + * PRNG. The quality of the seed depends on the platform. + */ +uint32_t av_get_random_seed(void); + +/** + * @} + */ + +#endif /* AVUTIL_RANDOM_SEED_H */ diff --git a/ffmpeg/inc/libavutil/rational.h b/ffmpeg/inc/libavutil/rational.h new file mode 100644 index 0000000..cbb08a0 --- /dev/null +++ b/ffmpeg/inc/libavutil/rational.h @@ -0,0 +1,220 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_math_rational + * Utilties for rational number calculation. + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_RATIONAL_H +#define AVUTIL_RATIONAL_H + +#include +#include +#include "attributes.h" + +/** + * @defgroup lavu_math_rational AVRational + * @ingroup lavu_math + * Rational number calculation. + * + * While rational numbers can be expressed as floating-point numbers, the + * conversion process is a lossy one, so are floating-point operations. On the + * other hand, the nature of FFmpeg demands highly accurate calculation of + * timestamps. This set of rational number utilities serves as a generic + * interface for manipulating rational numbers as pairs of numerators and + * denominators. + * + * Many of the functions that operate on AVRational's have the suffix `_q`, in + * reference to the mathematical symbol "ℚ" (Q) which denotes the set of all + * rational numbers. + * + * @{ + */ + +/** + * Rational number (pair of numerator and denominator). + */ +typedef struct AVRational{ + int num; ///< Numerator + int den; ///< Denominator +} AVRational; + +/** + * Create an AVRational. + * + * Useful for compilers that do not support compound literals. + * + * @note The return value is not reduced. + * @see av_reduce() + */ +static inline AVRational av_make_q(int num, int den) +{ + AVRational r = { num, den }; + return r; +} + +/** + * Compare two rationals. + * + * @param a First rational + * @param b Second rational + * + * @return One of the following values: + * - 0 if `a == b` + * - 1 if `a > b` + * - -1 if `a < b` + * - `INT_MIN` if one of the values is of the form `0 / 0` + */ +static inline int av_cmp_q(AVRational a, AVRational b){ + const int64_t tmp= a.num * (int64_t)b.den - b.num * (int64_t)a.den; + + if(tmp) return (int)((tmp ^ a.den ^ b.den)>>63)|1; + else if(b.den && a.den) return 0; + else if(a.num && b.num) return (a.num>>31) - (b.num>>31); + else return INT_MIN; +} + +/** + * Convert an AVRational to a `double`. + * @param a AVRational to convert + * @return `a` in floating-point form + * @see av_d2q() + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * Reduce a fraction. + * + * This is useful for framerate calculations. + * + * @param[out] dst_num Destination numerator + * @param[out] dst_den Destination denominator + * @param[in] num Source numerator + * @param[in] den Source denominator + * @param[in] max Maximum allowed values for `dst_num` & `dst_den` + * @return 1 if the operation is exact, 0 otherwise + */ +int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); + +/** + * Multiply two rationals. + * @param b First rational + * @param c Second rational + * @return b*c + */ +AVRational av_mul_q(AVRational b, AVRational c) av_const; + +/** + * Divide one rational by another. + * @param b First rational + * @param c Second rational + * @return b/c + */ +AVRational av_div_q(AVRational b, AVRational c) av_const; + +/** + * Add two rationals. + * @param b First rational + * @param c Second rational + * @return b+c + */ +AVRational av_add_q(AVRational b, AVRational c) av_const; + +/** + * Subtract one rational from another. + * @param b First rational + * @param c Second rational + * @return b-c + */ +AVRational av_sub_q(AVRational b, AVRational c) av_const; + +/** + * Invert a rational. + * @param q value + * @return 1 / q + */ +static av_always_inline AVRational av_inv_q(AVRational q) +{ + AVRational r = { q.den, q.num }; + return r; +} + +/** + * Convert a double precision floating point number to a rational. + * + * In case of infinity, the returned value is expressed as `{1, 0}` or + * `{-1, 0}` depending on the sign. + * + * @param d `double` to convert + * @param max Maximum allowed numerator and denominator + * @return `d` in AVRational form + * @see av_q2d() + */ +AVRational av_d2q(double d, int max) av_const; + +/** + * Find which of the two rationals is closer to another rational. + * + * @param q Rational to be compared against + * @param q1,q2 Rationals to be tested + * @return One of the following values: + * - 1 if `q1` is nearer to `q` than `q2` + * - -1 if `q2` is nearer to `q` than `q1` + * - 0 if they have the same distance + */ +int av_nearer_q(AVRational q, AVRational q1, AVRational q2); + +/** + * Find the value in a list of rationals nearest a given reference rational. + * + * @param q Reference rational + * @param q_list Array of rationals terminated by `{0, 0}` + * @return Index of the nearest value found in the array + */ +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); + +/** + * Convert an AVRational to a IEEE 32-bit `float` expressed in fixed-point + * format. + * + * @param q Rational to be converted + * @return Equivalent floating-point value, expressed as an unsigned 32-bit + * integer. + * @note The returned value is platform-indepedant. + */ +uint32_t av_q2intfloat(AVRational q); + +/** + * Return the best rational so that a and b are multiple of it. + * If the resulting denominator is larger than max_den, return def. + */ +AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def); + +/** + * @} + */ + +#endif /* AVUTIL_RATIONAL_H */ diff --git a/ffmpeg/inc/libavutil/rc4.h b/ffmpeg/inc/libavutil/rc4.h new file mode 100644 index 0000000..029cd2a --- /dev/null +++ b/ffmpeg/inc/libavutil/rc4.h @@ -0,0 +1,66 @@ +/* + * RC4 encryption/decryption/pseudo-random number generator + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_RC4_H +#define AVUTIL_RC4_H + +#include + +/** + * @defgroup lavu_rc4 RC4 + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVRC4 { + uint8_t state[256]; + int x, y; +} AVRC4; + +/** + * Allocate an AVRC4 context. + */ +AVRC4 *av_rc4_alloc(void); + +/** + * @brief Initializes an AVRC4 context. + * + * @param key_bits must be a multiple of 8 + * @param decrypt 0 for encryption, 1 for decryption, currently has no effect + * @return zero on success, negative value otherwise + */ +int av_rc4_init(struct AVRC4 *d, const uint8_t *key, int key_bits, int decrypt); + +/** + * @brief Encrypts / decrypts using the RC4 algorithm. + * + * @param count number of bytes + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst, may be NULL + * @param iv not (yet) used for RC4, should be NULL + * @param decrypt 0 for encryption, 1 for decryption, not (yet) used + */ +void av_rc4_crypt(struct AVRC4 *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_RC4_H */ diff --git a/ffmpeg/inc/libavutil/replaygain.h b/ffmpeg/inc/libavutil/replaygain.h new file mode 100644 index 0000000..b49bf1a --- /dev/null +++ b/ffmpeg/inc/libavutil/replaygain.h @@ -0,0 +1,50 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_REPLAYGAIN_H +#define AVUTIL_REPLAYGAIN_H + +#include + +/** + * ReplayGain information (see + * http://wiki.hydrogenaudio.org/index.php?title=ReplayGain_1.0_specification). + * The size of this struct is a part of the public ABI. + */ +typedef struct AVReplayGain { + /** + * Track replay gain in microbels (divide by 100000 to get the value in dB). + * Should be set to INT32_MIN when unknown. + */ + int32_t track_gain; + /** + * Peak track amplitude, with 100000 representing full scale (but values + * may overflow). 0 when unknown. + */ + uint32_t track_peak; + /** + * Same as track_gain, but for the whole album. + */ + int32_t album_gain; + /** + * Same as track_peak, but for the whole album, + */ + uint32_t album_peak; +} AVReplayGain; + +#endif /* AVUTIL_REPLAYGAIN_H */ diff --git a/ffmpeg/inc/libavutil/ripemd.h b/ffmpeg/inc/libavutil/ripemd.h new file mode 100644 index 0000000..0db6858 --- /dev/null +++ b/ffmpeg/inc/libavutil/ripemd.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_ripemd + * Public header for RIPEMD hash function implementation. + */ + +#ifndef AVUTIL_RIPEMD_H +#define AVUTIL_RIPEMD_H + +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_ripemd RIPEMD + * @ingroup lavu_hash + * RIPEMD hash function implementation. + * + * @{ + */ + +extern const int av_ripemd_size; + +struct AVRIPEMD; + +/** + * Allocate an AVRIPEMD context. + */ +struct AVRIPEMD *av_ripemd_alloc(void); + +/** + * Initialize RIPEMD hashing. + * + * @param context pointer to the function context (of size av_ripemd_size) + * @param bits number of bits in digest (128, 160, 256 or 320 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_ripemd_init(struct AVRIPEMD* context, int bits); + +/** + * Update hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, unsigned int len); +#else +void av_ripemd_update(struct AVRIPEMD* context, const uint8_t* data, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_ripemd_final(struct AVRIPEMD* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_RIPEMD_H */ diff --git a/ffmpeg/inc/libavutil/samplefmt.h b/ffmpeg/inc/libavutil/samplefmt.h new file mode 100644 index 0000000..8cd43ae --- /dev/null +++ b/ffmpeg/inc/libavutil/samplefmt.h @@ -0,0 +1,272 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_SAMPLEFMT_H +#define AVUTIL_SAMPLEFMT_H + +#include + +#include "avutil.h" +#include "attributes.h" + +/** + * @addtogroup lavu_audio + * @{ + * + * @defgroup lavu_sampfmts Audio sample formats + * + * Audio sample format enumeration and related convenience functions. + * @{ + */ + +/** + * Audio sample formats + * + * - The data described by the sample format is always in native-endian order. + * Sample values can be expressed by native C types, hence the lack of a signed + * 24-bit sample format even though it is a common raw audio data format. + * + * - The floating-point formats are based on full volume being in the range + * [-1.0, 1.0]. Any values outside this range are beyond full volume level. + * + * - The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg + * (such as AVFrame in libavcodec) is as follows: + * + * @par + * For planar sample formats, each audio channel is in a separate data plane, + * and linesize is the buffer size, in bytes, for a single plane. All data + * planes must be the same size. For packed sample formats, only the first data + * plane is used, and samples for each channel are interleaved. In this case, + * linesize is the buffer size, in bytes, for the 1 plane. + * + */ +enum AVSampleFormat { + AV_SAMPLE_FMT_NONE = -1, + AV_SAMPLE_FMT_U8, ///< unsigned 8 bits + AV_SAMPLE_FMT_S16, ///< signed 16 bits + AV_SAMPLE_FMT_S32, ///< signed 32 bits + AV_SAMPLE_FMT_FLT, ///< float + AV_SAMPLE_FMT_DBL, ///< double + + AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar + AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar + AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar + AV_SAMPLE_FMT_FLTP, ///< float, planar + AV_SAMPLE_FMT_DBLP, ///< double, planar + AV_SAMPLE_FMT_S64, ///< signed 64 bits + AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar + + AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically +}; + +/** + * Return the name of sample_fmt, or NULL if sample_fmt is not + * recognized. + */ +const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt); + +/** + * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE + * on error. + */ +enum AVSampleFormat av_get_sample_fmt(const char *name); + +/** + * Return the planar<->packed alternative form of the given sample format, or + * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the + * requested planar/packed format, the format returned is the same as the + * input. + */ +enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar); + +/** + * Get the packed alternative form of the given sample format. + * + * If the passed sample_fmt is already in packed format, the format returned is + * the same as the input. + * + * @return the packed alternative form of the given sample format or + AV_SAMPLE_FMT_NONE on error. + */ +enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt); + +/** + * Get the planar alternative form of the given sample format. + * + * If the passed sample_fmt is already in planar format, the format returned is + * the same as the input. + * + * @return the planar alternative form of the given sample format or + AV_SAMPLE_FMT_NONE on error. + */ +enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt); + +/** + * Generate a string corresponding to the sample format with + * sample_fmt, or a header if sample_fmt is negative. + * + * @param buf the buffer where to write the string + * @param buf_size the size of buf + * @param sample_fmt the number of the sample format to print the + * corresponding info string, or a negative value to print the + * corresponding header. + * @return the pointer to the filled buffer or NULL if sample_fmt is + * unknown or in case of other errors + */ +char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt); + +/** + * Return number of bytes per sample. + * + * @param sample_fmt the sample format + * @return number of bytes per sample or zero if unknown for the given + * sample format + */ +int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt); + +/** + * Check if the sample format is planar. + * + * @param sample_fmt the sample format to inspect + * @return 1 if the sample format is planar, 0 if it is interleaved + */ +int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); + +/** + * Get the required buffer size for the given audio parameters. + * + * @param[out] linesize calculated linesize, may be NULL + * @param nb_channels the number of channels + * @param nb_samples the number of samples in a single channel + * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return required buffer size, or negative error code on failure + */ +int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align); + +/** + * @} + * + * @defgroup lavu_sampmanip Samples manipulation + * + * Functions that manipulate audio samples + * @{ + */ + +/** + * Fill plane data pointers and linesize for samples with sample + * format sample_fmt. + * + * The audio_data array is filled with the pointers to the samples data planes: + * for planar, set the start point of each channel's data within the buffer, + * for packed, set the start point of the entire buffer only. + * + * The value pointed to by linesize is set to the aligned size of each + * channel's data buffer for planar layout, or to the aligned size of the + * buffer for all channels for packed layout. + * + * The buffer in buf must be big enough to contain all the samples + * (use av_samples_get_buffer_size() to compute its minimum size), + * otherwise the audio_data pointers will point to invalid data. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param[out] audio_data array to be filled with the pointer for each channel + * @param[out] linesize calculated linesize, may be NULL + * @param buf the pointer to a buffer containing the samples + * @param nb_channels the number of channels + * @param nb_samples the number of samples in a single channel + * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return >=0 on success or a negative error code on failure + * @todo return minimum size in bytes required for the buffer in case + * of success at the next bump + */ +int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, + const uint8_t *buf, + int nb_channels, int nb_samples, + enum AVSampleFormat sample_fmt, int align); + +/** + * Allocate a samples buffer for nb_samples samples, and fill data pointers and + * linesize accordingly. + * The allocated samples buffer can be freed by using av_freep(&audio_data[0]) + * Allocated data will be initialized to silence. + * + * @see enum AVSampleFormat + * The documentation for AVSampleFormat describes the data layout. + * + * @param[out] audio_data array to be filled with the pointer for each channel + * @param[out] linesize aligned size for audio buffer(s), may be NULL + * @param nb_channels number of audio channels + * @param nb_samples number of samples per channel + * @param align buffer size alignment (0 = default, 1 = no alignment) + * @return >=0 on success or a negative error code on failure + * @todo return the size of the allocated buffer in case of success at the next bump + * @see av_samples_fill_arrays() + * @see av_samples_alloc_array_and_samples() + */ +int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align); + +/** + * Allocate a data pointers array, samples buffer for nb_samples + * samples, and fill data pointers and linesize accordingly. + * + * This is the same as av_samples_alloc(), but also allocates the data + * pointers array. + * + * @see av_samples_alloc() + */ +int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, + int nb_samples, enum AVSampleFormat sample_fmt, int align); + +/** + * Copy samples from src to dst. + * + * @param dst destination array of pointers to data planes + * @param src source array of pointers to data planes + * @param dst_offset offset in samples at which the data will be written to dst + * @param src_offset offset in samples at which the data will be read from src + * @param nb_samples number of samples to be copied + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, + int src_offset, int nb_samples, int nb_channels, + enum AVSampleFormat sample_fmt); + +/** + * Fill an audio buffer with silence. + * + * @param audio_data array of pointers to data planes + * @param offset offset in samples at which to start filling + * @param nb_samples number of samples to fill + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, + int nb_channels, enum AVSampleFormat sample_fmt); + +/** + * @} + * @} + */ +#endif /* AVUTIL_SAMPLEFMT_H */ diff --git a/ffmpeg/inc/libavutil/sha.h b/ffmpeg/inc/libavutil/sha.h new file mode 100644 index 0000000..c0180e5 --- /dev/null +++ b/ffmpeg/inc/libavutil/sha.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_sha + * Public header for SHA-1 & SHA-256 hash function implementations. + */ + +#ifndef AVUTIL_SHA_H +#define AVUTIL_SHA_H + +#include +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_sha SHA + * @ingroup lavu_hash + * SHA-1 and SHA-256 (Secure Hash Algorithm) hash function implementations. + * + * This module supports the following SHA hash functions: + * + * - SHA-1: 160 bits + * - SHA-224: 224 bits, as a variant of SHA-2 + * - SHA-256: 256 bits, as a variant of SHA-2 + * + * @see For SHA-384, SHA-512, and variants thereof, see @ref lavu_sha512. + * + * @{ + */ + +extern const int av_sha_size; + +struct AVSHA; + +/** + * Allocate an AVSHA context. + */ +struct AVSHA *av_sha_alloc(void); + +/** + * Initialize SHA-1 or SHA-2 hashing. + * + * @param context pointer to the function context (of size av_sha_size) + * @param bits number of bits in digest (SHA-1 - 160 bits, SHA-2 224 or 256 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_sha_init(struct AVSHA* context, int bits); + +/** + * Update hash value. + * + * @param ctx hash function context + * @param data input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, unsigned int len); +#else +void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_sha_final(struct AVSHA* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_SHA_H */ diff --git a/ffmpeg/inc/libavutil/sha512.h b/ffmpeg/inc/libavutil/sha512.h new file mode 100644 index 0000000..bef714b --- /dev/null +++ b/ffmpeg/inc/libavutil/sha512.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2007 Michael Niedermayer + * Copyright (C) 2013 James Almer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu_sha512 + * Public header for SHA-512 implementation. + */ + +#ifndef AVUTIL_SHA512_H +#define AVUTIL_SHA512_H + +#include +#include + +#include "attributes.h" +#include "version.h" + +/** + * @defgroup lavu_sha512 SHA-512 + * @ingroup lavu_hash + * SHA-512 (Secure Hash Algorithm) hash function implementations. + * + * This module supports the following SHA-2 hash functions: + * + * - SHA-512/224: 224 bits + * - SHA-512/256: 256 bits + * - SHA-384: 384 bits + * - SHA-512: 512 bits + * + * @see For SHA-1, SHA-256, and variants thereof, see @ref lavu_sha. + * + * @{ + */ + +extern const int av_sha512_size; + +struct AVSHA512; + +/** + * Allocate an AVSHA512 context. + */ +struct AVSHA512 *av_sha512_alloc(void); + +/** + * Initialize SHA-2 512 hashing. + * + * @param context pointer to the function context (of size av_sha512_size) + * @param bits number of bits in digest (224, 256, 384 or 512 bits) + * @return zero if initialization succeeded, -1 otherwise + */ +int av_sha512_init(struct AVSHA512* context, int bits); + +/** + * Update hash value. + * + * @param context hash function context + * @param data input data to update hash with + * @param len input data length + */ +#if FF_API_CRYPTO_SIZE_T +void av_sha512_update(struct AVSHA512* context, const uint8_t* data, unsigned int len); +#else +void av_sha512_update(struct AVSHA512* context, const uint8_t* data, size_t len); +#endif + +/** + * Finish hashing and output digest value. + * + * @param context hash function context + * @param digest buffer where output digest value is stored + */ +void av_sha512_final(struct AVSHA512* context, uint8_t *digest); + +/** + * @} + */ + +#endif /* AVUTIL_SHA512_H */ diff --git a/ffmpeg/inc/libavutil/spherical.h b/ffmpeg/inc/libavutil/spherical.h new file mode 100644 index 0000000..cef759c --- /dev/null +++ b/ffmpeg/inc/libavutil/spherical.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2016 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Spherical video + */ + +#ifndef AVUTIL_SPHERICAL_H +#define AVUTIL_SPHERICAL_H + +#include +#include + +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_spherical Spherical video mapping + * @{ + */ + +/** + * @addtogroup lavu_video_spherical + * A spherical video file contains surfaces that need to be mapped onto a + * sphere. Depending on how the frame was converted, a different distortion + * transformation or surface recomposition function needs to be applied before + * the video should be mapped and displayed. + */ + +/** + * Projection of the video surface(s) on a sphere. + */ +enum AVSphericalProjection { + /** + * Video represents a sphere mapped on a flat surface using + * equirectangular projection. + */ + AV_SPHERICAL_EQUIRECTANGULAR, + + /** + * Video frame is split into 6 faces of a cube, and arranged on a + * 3x2 layout. Faces are oriented upwards for the front, left, right, + * and back faces. The up face is oriented so the top of the face is + * forwards and the down face is oriented so the top of the face is + * to the back. + */ + AV_SPHERICAL_CUBEMAP, + + /** + * Video represents a portion of a sphere mapped on a flat surface + * using equirectangular projection. The @ref bounding fields indicate + * the position of the current video in a larger surface. + */ + AV_SPHERICAL_EQUIRECTANGULAR_TILE, +}; + +/** + * This structure describes how to handle spherical videos, outlining + * information about projection, initial layout, and any other view modifier. + * + * @note The struct must be allocated with av_spherical_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVSphericalMapping { + /** + * Projection type. + */ + enum AVSphericalProjection projection; + + /** + * @name Initial orientation + * @{ + * There fields describe additional rotations applied to the sphere after + * the video frame is mapped onto it. The sphere is rotated around the + * viewer, who remains stationary. The order of transformation is always + * yaw, followed by pitch, and finally by roll. + * + * The coordinate system matches the one defined in OpenGL, where the + * forward vector (z) is coming out of screen, and it is equivalent to + * a rotation matrix of R = r_y(yaw) * r_x(pitch) * r_z(roll). + * + * A positive yaw rotates the portion of the sphere in front of the viewer + * toward their right. A positive pitch rotates the portion of the sphere + * in front of the viewer upwards. A positive roll tilts the portion of + * the sphere in front of the viewer to the viewer's right. + * + * These values are exported as 16.16 fixed point. + * + * See this equirectangular projection as example: + * + * @code{.unparsed} + * Yaw + * -180 0 180 + * 90 +-------------+-------------+ 180 + * | | | up + * P | | | y| forward + * i | ^ | | /z + * t 0 +-------------X-------------+ 0 Roll | / + * c | | | | / + * h | | | 0|/_____right + * | | | x + * -90 +-------------+-------------+ -180 + * + * X - the default camera center + * ^ - the default up vector + * @endcode + */ + int32_t yaw; ///< Rotation around the up vector [-180, 180]. + int32_t pitch; ///< Rotation around the right vector [-90, 90]. + int32_t roll; ///< Rotation around the forward vector [-180, 180]. + /** + * @} + */ + + /** + * @name Bounding rectangle + * @anchor bounding + * @{ + * These fields indicate the location of the current tile, and where + * it should be mapped relative to the original surface. They are + * exported as 0.32 fixed point, and can be converted to classic + * pixel values with av_spherical_bounds(). + * + * @code{.unparsed} + * +----------------+----------+ + * | |bound_top | + * | +--------+ | + * | bound_left |tile | | + * +<---------->| |<--->+bound_right + * | +--------+ | + * | | | + * | bound_bottom| | + * +----------------+----------+ + * @endcode + * + * If needed, the original video surface dimensions can be derived + * by adding the current stream or frame size to the related bounds, + * like in the following example: + * + * @code{c} + * original_width = tile->width + bound_left + bound_right; + * original_height = tile->height + bound_top + bound_bottom; + * @endcode + * + * @note These values are valid only for the tiled equirectangular + * projection type (@ref AV_SPHERICAL_EQUIRECTANGULAR_TILE), + * and should be ignored in all other cases. + */ + uint32_t bound_left; ///< Distance from the left edge + uint32_t bound_top; ///< Distance from the top edge + uint32_t bound_right; ///< Distance from the right edge + uint32_t bound_bottom; ///< Distance from the bottom edge + /** + * @} + */ + + /** + * Number of pixels to pad from the edge of each cube face. + * + * @note This value is valid for only for the cubemap projection type + * (@ref AV_SPHERICAL_CUBEMAP), and should be ignored in all other + * cases. + */ + uint32_t padding; +} AVSphericalMapping; + +/** + * Allocate a AVSphericalVideo structure and initialize its fields to default + * values. + * + * @return the newly allocated struct or NULL on failure + */ +AVSphericalMapping *av_spherical_alloc(size_t *size); + +/** + * Convert the @ref bounding fields from an AVSphericalVideo + * from 0.32 fixed point to pixels. + * + * @param map The AVSphericalVideo map to read bound values from. + * @param width Width of the current frame or stream. + * @param height Height of the current frame or stream. + * @param left Pixels from the left edge. + * @param top Pixels from the top edge. + * @param right Pixels from the right edge. + * @param bottom Pixels from the bottom edge. + */ +void av_spherical_tile_bounds(const AVSphericalMapping *map, + size_t width, size_t height, + size_t *left, size_t *top, + size_t *right, size_t *bottom); + +/** + * Provide a human-readable name of a given AVSphericalProjection. + * + * @param projection The input AVSphericalProjection. + * + * @return The name of the AVSphericalProjection, or "unknown". + */ +const char *av_spherical_projection_name(enum AVSphericalProjection projection); + +/** + * Get the AVSphericalProjection form a human-readable name. + * + * @param name The input string. + * + * @return The AVSphericalProjection value, or -1 if not found. + */ +int av_spherical_from_name(const char *name); +/** + * @} + * @} + */ + +#endif /* AVUTIL_SPHERICAL_H */ diff --git a/ffmpeg/inc/libavutil/stereo3d.h b/ffmpeg/inc/libavutil/stereo3d.h new file mode 100644 index 0000000..d421aac --- /dev/null +++ b/ffmpeg/inc/libavutil/stereo3d.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2013 Vittorio Giovara + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Stereoscopic video + */ + +#ifndef AVUTIL_STEREO3D_H +#define AVUTIL_STEREO3D_H + +#include + +#include "frame.h" + +/** + * @addtogroup lavu_video + * @{ + * + * @defgroup lavu_video_stereo3d Stereo3D types and functions + * @{ + */ + +/** + * @addtogroup lavu_video_stereo3d + * A stereoscopic video file consists in multiple views embedded in a single + * frame, usually describing two views of a scene. This file describes all + * possible codec-independent view arrangements. + * */ + +/** + * List of possible 3D Types + */ +enum AVStereo3DType { + /** + * Video is not stereoscopic (and metadata has to be there). + */ + AV_STEREO3D_2D, + + /** + * Views are next to each other. + * + * @code{.unparsed} + * LLLLRRRR + * LLLLRRRR + * LLLLRRRR + * ... + * @endcode + */ + AV_STEREO3D_SIDEBYSIDE, + + /** + * Views are on top of each other. + * + * @code{.unparsed} + * LLLLLLLL + * LLLLLLLL + * RRRRRRRR + * RRRRRRRR + * @endcode + */ + AV_STEREO3D_TOPBOTTOM, + + /** + * Views are alternated temporally. + * + * @code{.unparsed} + * frame0 frame1 frame2 ... + * LLLLLLLL RRRRRRRR LLLLLLLL + * LLLLLLLL RRRRRRRR LLLLLLLL + * LLLLLLLL RRRRRRRR LLLLLLLL + * ... ... ... + * @endcode + */ + AV_STEREO3D_FRAMESEQUENCE, + + /** + * Views are packed in a checkerboard-like structure per pixel. + * + * @code{.unparsed} + * LRLRLRLR + * RLRLRLRL + * LRLRLRLR + * ... + * @endcode + */ + AV_STEREO3D_CHECKERBOARD, + + /** + * Views are next to each other, but when upscaling + * apply a checkerboard pattern. + * + * @code{.unparsed} + * LLLLRRRR L L L L R R R R + * LLLLRRRR => L L L L R R R R + * LLLLRRRR L L L L R R R R + * LLLLRRRR L L L L R R R R + * @endcode + */ + AV_STEREO3D_SIDEBYSIDE_QUINCUNX, + + /** + * Views are packed per line, as if interlaced. + * + * @code{.unparsed} + * LLLLLLLL + * RRRRRRRR + * LLLLLLLL + * ... + * @endcode + */ + AV_STEREO3D_LINES, + + /** + * Views are packed per column. + * + * @code{.unparsed} + * LRLRLRLR + * LRLRLRLR + * LRLRLRLR + * ... + * @endcode + */ + AV_STEREO3D_COLUMNS, +}; + +/** + * List of possible view types. + */ +enum AVStereo3DView { + /** + * Frame contains two packed views. + */ + AV_STEREO3D_VIEW_PACKED, + + /** + * Frame contains only the left view. + */ + AV_STEREO3D_VIEW_LEFT, + + /** + * Frame contains only the right view. + */ + AV_STEREO3D_VIEW_RIGHT, +}; + +/** + * Inverted views, Right/Bottom represents the left view. + */ +#define AV_STEREO3D_FLAG_INVERT (1 << 0) + +/** + * Stereo 3D type: this structure describes how two videos are packed + * within a single video surface, with additional information as needed. + * + * @note The struct must be allocated with av_stereo3d_alloc() and + * its size is not a part of the public ABI. + */ +typedef struct AVStereo3D { + /** + * How views are packed within the video. + */ + enum AVStereo3DType type; + + /** + * Additional information about the frame packing. + */ + int flags; + + /** + * Determines which views are packed. + */ + enum AVStereo3DView view; +} AVStereo3D; + +/** + * Allocate an AVStereo3D structure and set its fields to default values. + * The resulting struct can be freed using av_freep(). + * + * @return An AVStereo3D filled with default values or NULL on failure. + */ +AVStereo3D *av_stereo3d_alloc(void); + +/** + * Allocate a complete AVFrameSideData and add it to the frame. + * + * @param frame The frame which side data is added to. + * + * @return The AVStereo3D structure to be filled by caller. + */ +AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame); + +/** + * Provide a human-readable name of a given stereo3d type. + * + * @param type The input stereo3d type value. + * + * @return The name of the stereo3d value, or "unknown". + */ +const char *av_stereo3d_type_name(unsigned int type); + +/** + * Get the AVStereo3DType form a human-readable name. + * + * @param name The input string. + * + * @return The AVStereo3DType value, or -1 if not found. + */ +int av_stereo3d_from_name(const char *name); + +/** + * @} + * @} + */ + +#endif /* AVUTIL_STEREO3D_H */ diff --git a/ffmpeg/inc/libavutil/tea.h b/ffmpeg/inc/libavutil/tea.h new file mode 100644 index 0000000..dd929bd --- /dev/null +++ b/ffmpeg/inc/libavutil/tea.h @@ -0,0 +1,71 @@ +/* + * A 32-bit implementation of the TEA algorithm + * Copyright (c) 2015 Vesselin Bontchev + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TEA_H +#define AVUTIL_TEA_H + +#include + +/** + * @file + * @brief Public header for libavutil TEA algorithm + * @defgroup lavu_tea TEA + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_tea_size; + +struct AVTEA; + +/** + * Allocate an AVTEA context + * To free the struct: av_free(ptr) + */ +struct AVTEA *av_tea_alloc(void); + +/** + * Initialize an AVTEA context. + * + * @param ctx an AVTEA context + * @param key a key of 16 bytes used for encryption/decryption + * @param rounds the number of rounds in TEA (64 is the "standard") + */ +void av_tea_init(struct AVTEA *ctx, const uint8_t key[16], int rounds); + +/** + * Encrypt or decrypt a buffer using a previously initialized context. + * + * @param ctx an AVTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_tea_crypt(struct AVTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_TEA_H */ diff --git a/ffmpeg/inc/libavutil/threadmessage.h b/ffmpeg/inc/libavutil/threadmessage.h new file mode 100644 index 0000000..42ce655 --- /dev/null +++ b/ffmpeg/inc/libavutil/threadmessage.h @@ -0,0 +1,115 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with FFmpeg; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_THREADMESSAGE_H +#define AVUTIL_THREADMESSAGE_H + +typedef struct AVThreadMessageQueue AVThreadMessageQueue; + +typedef enum AVThreadMessageFlags { + + /** + * Perform non-blocking operation. + * If this flag is set, send and recv operations are non-blocking and + * return AVERROR(EAGAIN) immediately if they can not proceed. + */ + AV_THREAD_MESSAGE_NONBLOCK = 1, + +} AVThreadMessageFlags; + +/** + * Allocate a new message queue. + * + * @param mq pointer to the message queue + * @param nelem maximum number of elements in the queue + * @param elsize size of each element in the queue + * @return >=0 for success; <0 for error, in particular AVERROR(ENOSYS) if + * lavu was built without thread support + */ +int av_thread_message_queue_alloc(AVThreadMessageQueue **mq, + unsigned nelem, + unsigned elsize); + +/** + * Free a message queue. + * + * The message queue must no longer be in use by another thread. + */ +void av_thread_message_queue_free(AVThreadMessageQueue **mq); + +/** + * Send a message on the queue. + */ +int av_thread_message_queue_send(AVThreadMessageQueue *mq, + void *msg, + unsigned flags); + +/** + * Receive a message from the queue. + */ +int av_thread_message_queue_recv(AVThreadMessageQueue *mq, + void *msg, + unsigned flags); + +/** + * Set the sending error code. + * + * If the error code is set to non-zero, av_thread_message_queue_send() will + * return it immediately. Conventional values, such as AVERROR_EOF or + * AVERROR(EAGAIN), can be used to cause the sending thread to stop or + * suspend its operation. + */ +void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, + int err); + +/** + * Set the receiving error code. + * + * If the error code is set to non-zero, av_thread_message_queue_recv() will + * return it immediately when there are no longer available messages. + * Conventional values, such as AVERROR_EOF or AVERROR(EAGAIN), can be used + * to cause the receiving thread to stop or suspend its operation. + */ +void av_thread_message_queue_set_err_recv(AVThreadMessageQueue *mq, + int err); + +/** + * Set the optional free message callback function which will be called if an + * operation is removing messages from the queue. + */ +void av_thread_message_queue_set_free_func(AVThreadMessageQueue *mq, + void (*free_func)(void *msg)); + +/** + * Return the current number of messages in the queue. + * + * @return the current number of messages or AVERROR(ENOSYS) if lavu was built + * without thread support + */ +int av_thread_message_queue_nb_elems(AVThreadMessageQueue *mq); + +/** + * Flush the message queue + * + * This function is mostly equivalent to reading and free-ing every message + * except that it will be done in a single operation (no lock/unlock between + * reads). + */ +void av_thread_message_flush(AVThreadMessageQueue *mq); + +#endif /* AVUTIL_THREADMESSAGE_H */ diff --git a/ffmpeg/inc/libavutil/time.h b/ffmpeg/inc/libavutil/time.h new file mode 100644 index 0000000..dc169b0 --- /dev/null +++ b/ffmpeg/inc/libavutil/time.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000-2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TIME_H +#define AVUTIL_TIME_H + +#include + +/** + * Get the current time in microseconds. + */ +int64_t av_gettime(void); + +/** + * Get the current time in microseconds since some unspecified starting point. + * On platforms that support it, the time comes from a monotonic clock + * This property makes this time source ideal for measuring relative time. + * The returned values may not be monotonic on platforms where a monotonic + * clock is not available. + */ +int64_t av_gettime_relative(void); + +/** + * Indicates with a boolean result if the av_gettime_relative() time source + * is monotonic. + */ +int av_gettime_relative_is_monotonic(void); + +/** + * Sleep for a period of time. Although the duration is expressed in + * microseconds, the actual delay may be rounded to the precision of the + * system timer. + * + * @param usec Number of microseconds to sleep. + * @return zero on success or (negative) error code. + */ +int av_usleep(unsigned usec); + +#endif /* AVUTIL_TIME_H */ diff --git a/ffmpeg/inc/libavutil/timecode.h b/ffmpeg/inc/libavutil/timecode.h new file mode 100644 index 0000000..37c1361 --- /dev/null +++ b/ffmpeg/inc/libavutil/timecode.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier + * Copyright (c) 2011-2012 Smartjog S.A.S, Clément Bœsch + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Timecode helpers header + */ + +#ifndef AVUTIL_TIMECODE_H +#define AVUTIL_TIMECODE_H + +#include +#include "rational.h" + +#define AV_TIMECODE_STR_SIZE 23 + +enum AVTimecodeFlag { + AV_TIMECODE_FLAG_DROPFRAME = 1<<0, ///< timecode is drop frame + AV_TIMECODE_FLAG_24HOURSMAX = 1<<1, ///< timecode wraps after 24 hours + AV_TIMECODE_FLAG_ALLOWNEGATIVE = 1<<2, ///< negative time values are allowed +}; + +typedef struct { + int start; ///< timecode frame start (first base frame number) + uint32_t flags; ///< flags such as drop frame, +24 hours support, ... + AVRational rate; ///< frame rate in rational form + unsigned fps; ///< frame per second; must be consistent with the rate field +} AVTimecode; + +/** + * Adjust frame number for NTSC drop frame time code. + * + * @param framenum frame number to adjust + * @param fps frame per second, 30 or 60 + * @return adjusted frame number + * @warning adjustment is only valid in NTSC 29.97 and 59.94 + */ +int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); + +/** + * Convert frame number to SMPTE 12M binary representation. + * + * @param tc timecode data correctly initialized + * @param framenum frame number + * @return the SMPTE binary representation + * + * @note Frame number adjustment is automatically done in case of drop timecode, + * you do NOT have to call av_timecode_adjust_ntsc_framenum2(). + * @note The frame number is relative to tc->start. + * @note Color frame (CF), binary group flags (BGF) and biphase mark polarity + * correction (PC) bits are set to zero. + */ +uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum); + +/** + * Load timecode string in buf. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tc timecode data correctly initialized + * @param framenum frame number + * @return the buf parameter + * + * @note Timecode representation can be a negative timecode and have more than + * 24 hours, but will only be honored if the flags are correctly set. + * @note The frame number is relative to tc->start. + */ +char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum); + +/** + * Get the timecode string from the SMPTE timecode format. + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tcsmpte the 32-bit SMPTE timecode + * @param prevent_df prevent the use of a drop flag when it is known the DF bit + * is arbitrary + * @return the buf parameter + */ +char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df); + +/** + * Get the timecode string from the 25-bit timecode format (MPEG GOP format). + * + * @param buf destination buffer, must be at least AV_TIMECODE_STR_SIZE long + * @param tc25bit the 25-bits timecode + * @return the buf parameter + */ +char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit); + +/** + * Init a timecode struct with the passed parameters. + * + * @param log_ctx a pointer to an arbitrary struct of which the first field + * is a pointer to an AVClass struct (used for av_log) + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param flags miscellaneous flags such as drop frame, +24 hours, ... + * (see AVTimecodeFlag) + * @param frame_start the first frame number + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx); + +/** + * Parse timecode representation (hh:mm:ss[:;.]ff). + * + * @param log_ctx a pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct (used for av_log). + * @param tc pointer to an allocated AVTimecode + * @param rate frame rate in rational form + * @param str timecode string which will determine the frame start + * @return 0 on success, AVERROR otherwise + */ +int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx); + +/** + * Check if the timecode feature is available for the given frame rate + * + * @return 0 if supported, <0 otherwise + */ +int av_timecode_check_frame_rate(AVRational rate); + +#endif /* AVUTIL_TIMECODE_H */ diff --git a/ffmpeg/inc/libavutil/timestamp.h b/ffmpeg/inc/libavutil/timestamp.h new file mode 100644 index 0000000..e082f01 --- /dev/null +++ b/ffmpeg/inc/libavutil/timestamp.h @@ -0,0 +1,78 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * timestamp utils, mostly useful for debugging/logging purposes + */ + +#ifndef AVUTIL_TIMESTAMP_H +#define AVUTIL_TIMESTAMP_H + +#include "common.h" + +#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) && !defined(PRId64) +#error missing -D__STDC_FORMAT_MACROS / #define __STDC_FORMAT_MACROS +#endif + +#define AV_TS_MAX_STRING_SIZE 32 + +/** + * Fill the provided buffer with a string containing a timestamp + * representation. + * + * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE + * @param ts the timestamp to represent + * @return the buffer in input + */ +static inline char *av_ts_make_string(char *buf, int64_t ts) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%" PRId64, ts); + return buf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2str(ts) av_ts_make_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts) + +/** + * Fill the provided buffer with a string containing a timestamp time + * representation. + * + * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE + * @param ts the timestamp to represent + * @param tb the timebase of the timestamp + * @return the buffer in input + */ +static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts); + return buf; +} + +/** + * Convenience macro, the return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb) + +#endif /* AVUTIL_TIMESTAMP_H */ diff --git a/ffmpeg/inc/libavutil/tree.h b/ffmpeg/inc/libavutil/tree.h new file mode 100644 index 0000000..d5e0aeb --- /dev/null +++ b/ffmpeg/inc/libavutil/tree.h @@ -0,0 +1,138 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * A tree container. + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_TREE_H +#define AVUTIL_TREE_H + +#include "attributes.h" +#include "version.h" + +/** + * @addtogroup lavu_tree AVTree + * @ingroup lavu_data + * + * Low-complexity tree container + * + * Insertion, removal, finding equal, largest which is smaller than and + * smallest which is larger than, all have O(log n) worst-case complexity. + * @{ + */ + + +struct AVTreeNode; +extern const int av_tree_node_size; + +/** + * Allocate an AVTreeNode. + */ +struct AVTreeNode *av_tree_node_alloc(void); + +/** + * Find an element. + * @param root a pointer to the root node of the tree + * @param next If next is not NULL, then next[0] will contain the previous + * element and next[1] the next element. If either does not exist, + * then the corresponding entry in next is unchanged. + * @param cmp compare function used to compare elements in the tree, + * API identical to that of Standard C's qsort + * It is guaranteed that the first and only the first argument to cmp() + * will be the key parameter to av_tree_find(), thus it could if the + * user wants, be a different type (like an opaque context). + * @return An element with cmp(key, elem) == 0 or NULL if no such element + * exists in the tree. + */ +void *av_tree_find(const struct AVTreeNode *root, void *key, + int (*cmp)(const void *key, const void *b), void *next[2]); + +/** + * Insert or remove an element. + * + * If *next is NULL, then the supplied element will be removed if it exists. + * If *next is non-NULL, then the supplied element will be inserted, unless + * it already exists in the tree. + * + * @param rootp A pointer to a pointer to the root node of the tree; note that + * the root node can change during insertions, this is required + * to keep the tree balanced. + * @param key pointer to the element key to insert in the tree + * @param next Used to allocate and free AVTreeNodes. For insertion the user + * must set it to an allocated and zeroed object of at least + * av_tree_node_size bytes size. av_tree_insert() will set it to + * NULL if it has been consumed. + * For deleting elements *next is set to NULL by the user and + * av_tree_insert() will set it to the AVTreeNode which was + * used for the removed element. + * This allows the use of flat arrays, which have + * lower overhead compared to many malloced elements. + * You might want to define a function like: + * @code + * void *tree_insert(struct AVTreeNode **rootp, void *key, + * int (*cmp)(void *key, const void *b), + * AVTreeNode **next) + * { + * if (!*next) + * *next = av_mallocz(av_tree_node_size); + * return av_tree_insert(rootp, key, cmp, next); + * } + * void *tree_remove(struct AVTreeNode **rootp, void *key, + * int (*cmp)(void *key, const void *b, AVTreeNode **next)) + * { + * av_freep(next); + * return av_tree_insert(rootp, key, cmp, next); + * } + * @endcode + * @param cmp compare function used to compare elements in the tree, API identical + * to that of Standard C's qsort + * @return If no insertion happened, the found element; if an insertion or + * removal happened, then either key or NULL will be returned. + * Which one it is depends on the tree state and the implementation. You + * should make no assumptions that it's one or the other in the code. + */ +void *av_tree_insert(struct AVTreeNode **rootp, void *key, + int (*cmp)(const void *key, const void *b), + struct AVTreeNode **next); + +void av_tree_destroy(struct AVTreeNode *t); + +/** + * Apply enu(opaque, &elem) to all the elements in the tree in a given range. + * + * @param cmp a comparison function that returns < 0 for an element below the + * range, > 0 for an element above the range and == 0 for an + * element inside the range + * + * @note The cmp function should use the same ordering used to construct the + * tree. + */ +void av_tree_enumerate(struct AVTreeNode *t, void *opaque, + int (*cmp)(void *opaque, void *elem), + int (*enu)(void *opaque, void *elem)); + +/** + * @} + */ + +#endif /* AVUTIL_TREE_H */ diff --git a/ffmpeg/inc/libavutil/twofish.h b/ffmpeg/inc/libavutil/twofish.h new file mode 100644 index 0000000..813cfec --- /dev/null +++ b/ffmpeg/inc/libavutil/twofish.h @@ -0,0 +1,70 @@ +/* + * An implementation of the TwoFish algorithm + * Copyright (c) 2015 Supraja Meedinti + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TWOFISH_H +#define AVUTIL_TWOFISH_H + +#include + + +/** + * @file + * @brief Public header for libavutil TWOFISH algorithm + * @defgroup lavu_twofish TWOFISH + * @ingroup lavu_crypto + * @{ + */ + +extern const int av_twofish_size; + +struct AVTWOFISH; + +/** + * Allocate an AVTWOFISH context + * To free the struct: av_free(ptr) + */ +struct AVTWOFISH *av_twofish_alloc(void); + +/** + * Initialize an AVTWOFISH context. + * + * @param ctx an AVTWOFISH context + * @param key a key of size ranging from 1 to 32 bytes used for encryption/decryption + * @param key_bits number of keybits: 128, 192, 256 If less than the required, padded with zeroes to nearest valid value; return value is 0 if key_bits is 128/192/256, -1 if less than 0, 1 otherwise + */ +int av_twofish_init(struct AVTWOFISH *ctx, const uint8_t *key, int key_bits); + +/** + * Encrypt or decrypt a buffer using a previously initialized context + * + * @param ctx an AVTWOFISH context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 16 byte blocks + * @paran iv initialization vector for CBC mode, NULL for ECB mode + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_twofish_crypt(struct AVTWOFISH *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t* iv, int decrypt); + +/** + * @} + */ +#endif /* AVUTIL_TWOFISH_H */ diff --git a/ffmpeg/inc/libavutil/tx.h b/ffmpeg/inc/libavutil/tx.h new file mode 100644 index 0000000..418e8ec --- /dev/null +++ b/ffmpeg/inc/libavutil/tx.h @@ -0,0 +1,117 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_TX_H +#define AVUTIL_TX_H + +#include +#include + +typedef struct AVTXContext AVTXContext; + +typedef struct AVComplexFloat { + float re, im; +} AVComplexFloat; + +typedef struct AVComplexDouble { + double re, im; +} AVComplexDouble; + +typedef struct AVComplexInt32 { + int32_t re, im; +} AVComplexInt32; + +enum AVTXType { + /** + * Standard complex to complex FFT with sample data type AVComplexFloat. + * Output is not 1/len normalized. Scaling currently unsupported. + * The stride parameter is ignored. + */ + AV_TX_FLOAT_FFT = 0, + /** + * Standard MDCT with sample data type of float and a scale type of + * float. Length is the frame size, not the window size (which is 2x frame) + * For forward transforms, the stride specifies the spacing between each + * sample in the output array in bytes. The input must be a flat array. + * For inverse transforms, the stride specifies the spacing between each + * sample in the input array in bytes. The output will be a flat array. + * Stride must be a non-zero multiple of sizeof(float). + */ + AV_TX_FLOAT_MDCT = 1, + /** + * Same as AV_TX_FLOAT_FFT with a data type of AVComplexDouble. + */ + AV_TX_DOUBLE_FFT = 2, + /** + * Same as AV_TX_FLOAT_MDCT with data and scale type of double. + * Stride must be a non-zero multiple of sizeof(double). + */ + AV_TX_DOUBLE_MDCT = 3, + /** + * Same as AV_TX_FLOAT_FFT with a data type of AVComplexInt32. + */ + AV_TX_INT32_FFT = 4, + /** + * Same as AV_TX_FLOAT_MDCT with data type of int32_t and scale type of float. + * Only scale values less than or equal to 1.0 are supported. + * Stride must be a non-zero multiple of sizeof(int32_t). + */ + AV_TX_INT32_MDCT = 5, +}; + +/** + * Function pointer to a function to perform the transform. + * + * @note Using a different context than the one allocated during av_tx_init() + * is not allowed. + * + * @param s the transform context + * @param out the output array + * @param in the input array + * @param stride the input or output stride in bytes + * + * The out and in arrays must be aligned to the maximum required by the CPU + * architecture. + * The stride must follow the constraints the transform type has specified. + */ +typedef void (*av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride); + +/** + * Initialize a transform context with the given configuration + * Currently power of two lengths from 2 to 131072 are supported, along with + * any length decomposable to a power of two and either 3, 5 or 15. + * + * @param ctx the context to allocate, will be NULL on error + * @param tx pointer to the transform function pointer to set + * @param type type the type of transform + * @param inv whether to do an inverse or a forward transform + * @param len the size of the transform in samples + * @param scale pointer to the value to scale the output if supported by type + * @param flags currently unused + * + * @return 0 on success, negative error code on failure + */ +int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, + int inv, int len, const void *scale, uint64_t flags); + +/** + * Frees a context and sets ctx to NULL, does nothing when ctx == NULL + */ +void av_tx_uninit(AVTXContext **ctx); + +#endif /* AVUTIL_TX_H */ diff --git a/ffmpeg/inc/libavutil/version.h b/ffmpeg/inc/libavutil/version.h new file mode 100644 index 0000000..0ff722f --- /dev/null +++ b/ffmpeg/inc/libavutil/version.h @@ -0,0 +1,139 @@ +/* + * copyright (c) 2003 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @ingroup lavu + * Libavutil version macros + */ + +#ifndef AVUTIL_VERSION_H +#define AVUTIL_VERSION_H + +#include "macros.h" + +/** + * @addtogroup version_utils + * + * Useful to check and match library version in order to maintain + * backward compatibility. + * + * The FFmpeg libraries follow a versioning sheme very similar to + * Semantic Versioning (http://semver.org/) + * The difference is that the component called PATCH is called MICRO in FFmpeg + * and its value is reset to 100 instead of 0 to keep it above or equal to 100. + * Also we do not increase MICRO for every bugfix or change in git master. + * + * Prior to FFmpeg 3.2 point releases did not change any lib version number to + * avoid aliassing different git master checkouts. + * Starting with FFmpeg 3.2, the released library versions will occupy + * a separate MAJOR.MINOR that is not used on the master development branch. + * That is if we branch a release of master 55.10.123 we will bump to 55.11.100 + * for the release and master will continue at 55.12.100 after it. Each new + * point release will then bump the MICRO improving the usefulness of the lib + * versions. + * + * @{ + */ + +#define AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c)) +#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c +#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) + +/** + * Extract version components from the full ::AV_VERSION_INT int as returned + * by functions like ::avformat_version() and ::avcodec_version() + */ +#define AV_VERSION_MAJOR(a) ((a) >> 16) +#define AV_VERSION_MINOR(a) (((a) & 0x00FF00) >> 8) +#define AV_VERSION_MICRO(a) ((a) & 0xFF) + +/** + * @} + */ + +/** + * @defgroup lavu_ver Version and Build diagnostics + * + * Macros and function useful to check at compiletime and at runtime + * which version of libavutil is in use. + * + * @{ + */ + +#define LIBAVUTIL_VERSION_MAJOR 56 +#define LIBAVUTIL_VERSION_MINOR 51 +#define LIBAVUTIL_VERSION_MICRO 100 + +#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + +/** + * @defgroup lavu_depr_guards Deprecation Guards + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + * + * @note, when bumping the major version it is recommended to manually + * disable each FF_API_* in its own commit instead of disabling them all + * at once through the bump. This improves the git bisect-ability of the change. + * + * @{ + */ + +#ifndef FF_API_VAAPI +#define FF_API_VAAPI (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_FRAME_QP +#define FF_API_FRAME_QP (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PLUS1_MINUS1 +#define FF_API_PLUS1_MINUS1 (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_ERROR_FRAME +#define FF_API_ERROR_FRAME (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PKT_PTS +#define FF_API_PKT_PTS (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_CRYPTO_SIZE_T +#define FF_API_CRYPTO_SIZE_T (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_FRAME_GET_SET +#define FF_API_FRAME_GET_SET (LIBAVUTIL_VERSION_MAJOR < 57) +#endif +#ifndef FF_API_PSEUDOPAL +#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) +#endif + + +/** + * @} + * @} + */ + +#endif /* AVUTIL_VERSION_H */ diff --git a/ffmpeg/inc/libavutil/video_enc_params.h b/ffmpeg/inc/libavutil/video_enc_params.h new file mode 100644 index 0000000..43fa443 --- /dev/null +++ b/ffmpeg/inc/libavutil/video_enc_params.h @@ -0,0 +1,163 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_VIDEO_ENC_PARAMS_H +#define AVUTIL_VIDEO_ENC_PARAMS_H + +#include +#include + +#include "libavutil/avassert.h" +#include "libavutil/frame.h" + +enum AVVideoEncParamsType { + AV_VIDEO_ENC_PARAMS_NONE = -1, + /** + * VP9 stores: + * - per-frame base (luma AC) quantizer index, exported as AVVideoEncParams.qp + * - deltas for luma DC, chroma AC and chroma DC, exported in the + * corresponding entries in AVVideoEncParams.delta_qp + * - per-segment delta, exported as for each block as AVVideoBlockParams.delta_qp + * + * To compute the resulting quantizer index for a block: + * - for luma AC, add the base qp and the per-block delta_qp, saturating to + * unsigned 8-bit. + * - for luma DC and chroma AC/DC, add the corresponding + * AVVideoBlockParams.delta_qp to the luma AC index, again saturating to + * unsigned 8-bit. + */ + AV_VIDEO_ENC_PARAMS_VP9, + + /** + * H.264 stores: + * - in PPS (per-picture): + * * initial QP_Y (luma) value, exported as AVVideoEncParams.qp + * * delta(s) for chroma QP values (same for both, or each separately), + * exported as in the corresponding entries in AVVideoEncParams.delta_qp + * - per-slice QP delta, not exported directly, added to the per-MB value + * - per-MB delta; not exported directly; the final per-MB quantizer + * parameter - QP_Y - minus the value in AVVideoEncParams.qp is exported + * as AVVideoBlockParams.qp_delta. + */ + AV_VIDEO_ENC_PARAMS_H264, +}; + +/** + * Video encoding parameters for a given frame. This struct is allocated along + * with an optional array of per-block AVVideoBlockParams descriptors. + * Must be allocated with av_video_enc_params_alloc(). + */ +typedef struct AVVideoEncParams { + /** + * Number of blocks in the array. + * + * May be 0, in which case no per-block information is present. In this case + * the values of blocks_offset / block_size are unspecified and should not + * be accessed. + */ + unsigned int nb_blocks; + /** + * Offset in bytes from the beginning of this structure at which the array + * of blocks starts. + */ + size_t blocks_offset; + /* + * Size of each block in bytes. May not match sizeof(AVVideoBlockParams). + */ + size_t block_size; + + /** + * Type of the parameters (the codec they are used with). + */ + enum AVVideoEncParamsType type; + + /** + * Base quantisation parameter for the frame. The final quantiser for a + * given block in a given plane is obtained from this value, possibly + * combined with {@code delta_qp} and the per-block delta in a manner + * documented for each type. + */ + int32_t qp; + + /** + * Quantisation parameter offset from the base (per-frame) qp for a given + * plane (first index) and AC/DC coefficients (second index). + */ + int32_t delta_qp[4][2]; +} AVVideoEncParams; + +/** + * Data structure for storing block-level encoding information. + * It is allocated as a part of AVVideoEncParams and should be retrieved with + * av_video_enc_params_block(). + * + * sizeof(AVVideoBlockParams) is not a part of the ABI and new fields may be + * added to it. + */ +typedef struct AVVideoBlockParams { + /** + * Distance in luma pixels from the top-left corner of the visible frame + * to the top-left corner of the block. + * Can be negative if top/right padding is present on the coded frame. + */ + int src_x, src_y; + /** + * Width and height of the block in luma pixels. + */ + int w, h; + + /** + * Difference between this block's final quantization parameter and the + * corresponding per-frame value. + */ + int32_t delta_qp; +} AVVideoBlockParams; + +/* + * Get the block at the specified {@code idx}. Must be between 0 and nb_blocks. + */ +static av_always_inline AVVideoBlockParams* +av_video_enc_params_block(AVVideoEncParams *par, unsigned int idx) +{ + av_assert0(idx < par->nb_blocks); + return (AVVideoBlockParams *)((uint8_t *)par + par->blocks_offset + + idx * par->block_size); +} + +/** + * Allocates memory for AVVideoEncParams of the given type, plus an array of + * {@code nb_blocks} AVVideoBlockParams and initializes the variables. Can be + * freed with a normal av_free() call. + * + * @param out_size if non-NULL, the size in bytes of the resulting data array is + * written here. + */ +AVVideoEncParams *av_video_enc_params_alloc(enum AVVideoEncParamsType type, + unsigned int nb_blocks, size_t *out_size); + +/** + * Allocates memory for AVEncodeInfoFrame plus an array of + * {@code nb_blocks} AVEncodeInfoBlock in the given AVFrame {@code frame} + * as AVFrameSideData of type AV_FRAME_DATA_ENCODE_INFO + * and initializes the variables. + */ +AVVideoEncParams* +av_video_enc_params_create_side_data(AVFrame *frame, enum AVVideoEncParamsType type, + unsigned int nb_blocks); + +#endif /* AVUTIL_VIDEO_ENC_PARAMS_H */ diff --git a/ffmpeg/inc/libavutil/xtea.h b/ffmpeg/inc/libavutil/xtea.h new file mode 100644 index 0000000..735427c --- /dev/null +++ b/ffmpeg/inc/libavutil/xtea.h @@ -0,0 +1,94 @@ +/* + * A 32-bit implementation of the XTEA algorithm + * Copyright (c) 2012 Samuel Pitoiset + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_XTEA_H +#define AVUTIL_XTEA_H + +#include + +/** + * @file + * @brief Public header for libavutil XTEA algorithm + * @defgroup lavu_xtea XTEA + * @ingroup lavu_crypto + * @{ + */ + +typedef struct AVXTEA { + uint32_t key[16]; +} AVXTEA; + +/** + * Allocate an AVXTEA context. + */ +AVXTEA *av_xtea_alloc(void); + +/** + * Initialize an AVXTEA context. + * + * @param ctx an AVXTEA context + * @param key a key of 16 bytes used for encryption/decryption, + * interpreted as big endian 32 bit numbers + */ +void av_xtea_init(struct AVXTEA *ctx, const uint8_t key[16]); + +/** + * Initialize an AVXTEA context. + * + * @param ctx an AVXTEA context + * @param key a key of 16 bytes used for encryption/decryption, + * interpreted as little endian 32 bit numbers + */ +void av_xtea_le_init(struct AVXTEA *ctx, const uint8_t key[16]); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, + * in big endian format. + * + * @param ctx an AVXTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_xtea_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * Encrypt or decrypt a buffer using a previously initialized context, + * in little endian format. + * + * @param ctx an AVXTEA context + * @param dst destination array, can be equal to src + * @param src source array, can be equal to dst + * @param count number of 8 byte blocks + * @param iv initialization vector for CBC mode, if NULL then ECB will be used + * @param decrypt 0 for encryption, 1 for decryption + */ +void av_xtea_le_crypt(struct AVXTEA *ctx, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int decrypt); + +/** + * @} + */ + +#endif /* AVUTIL_XTEA_H */ diff --git a/ffmpeg/inc/libswresample/swresample.h b/ffmpeg/inc/libswresample/swresample.h new file mode 100644 index 0000000..c7b84fb --- /dev/null +++ b/ffmpeg/inc/libswresample/swresample.h @@ -0,0 +1,579 @@ +/* + * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at) + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWRESAMPLE_SWRESAMPLE_H +#define SWRESAMPLE_SWRESAMPLE_H + +/** + * @file + * @ingroup lswr + * libswresample public header + */ + +/** + * @defgroup lswr libswresample + * @{ + * + * Audio resampling, sample format conversion and mixing library. + * + * Interaction with lswr is done through SwrContext, which is + * allocated with swr_alloc() or swr_alloc_set_opts(). It is opaque, so all parameters + * must be set with the @ref avoptions API. + * + * The first thing you will need to do in order to use lswr is to allocate + * SwrContext. This can be done with swr_alloc() or swr_alloc_set_opts(). If you + * are using the former, you must set options through the @ref avoptions API. + * The latter function provides the same feature, but it allows you to set some + * common options in the same statement. + * + * For example the following code will setup conversion from planar float sample + * format to interleaved signed 16-bit integer, downsampling from 48kHz to + * 44.1kHz and downmixing from 5.1 channels to stereo (using the default mixing + * matrix). This is using the swr_alloc() function. + * @code + * SwrContext *swr = swr_alloc(); + * av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); + * av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); + * av_opt_set_int(swr, "in_sample_rate", 48000, 0); + * av_opt_set_int(swr, "out_sample_rate", 44100, 0); + * av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); + * av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + * @endcode + * + * The same job can be done using swr_alloc_set_opts() as well: + * @code + * SwrContext *swr = swr_alloc_set_opts(NULL, // we're allocating a new context + * AV_CH_LAYOUT_STEREO, // out_ch_layout + * AV_SAMPLE_FMT_S16, // out_sample_fmt + * 44100, // out_sample_rate + * AV_CH_LAYOUT_5POINT1, // in_ch_layout + * AV_SAMPLE_FMT_FLTP, // in_sample_fmt + * 48000, // in_sample_rate + * 0, // log_offset + * NULL); // log_ctx + * @endcode + * + * Once all values have been set, it must be initialized with swr_init(). If + * you need to change the conversion parameters, you can change the parameters + * using @ref AVOptions, as described above in the first example; or by using + * swr_alloc_set_opts(), but with the first argument the allocated context. + * You must then call swr_init() again. + * + * The conversion itself is done by repeatedly calling swr_convert(). + * Note that the samples may get buffered in swr if you provide insufficient + * output space or if sample rate conversion is done, which requires "future" + * samples. Samples that do not require future input can be retrieved at any + * time by using swr_convert() (in_count can be set to 0). + * At the end of conversion the resampling buffer can be flushed by calling + * swr_convert() with NULL in and 0 in_count. + * + * The samples used in the conversion process can be managed with the libavutil + * @ref lavu_sampmanip "samples manipulation" API, including av_samples_alloc() + * function used in the following example. + * + * The delay between input and output, can at any time be found by using + * swr_get_delay(). + * + * The following code demonstrates the conversion loop assuming the parameters + * from above and caller-defined functions get_input() and handle_output(): + * @code + * uint8_t **input; + * int in_samples; + * + * while (get_input(&input, &in_samples)) { + * uint8_t *output; + * int out_samples = av_rescale_rnd(swr_get_delay(swr, 48000) + + * in_samples, 44100, 48000, AV_ROUND_UP); + * av_samples_alloc(&output, NULL, 2, out_samples, + * AV_SAMPLE_FMT_S16, 0); + * out_samples = swr_convert(swr, &output, out_samples, + * input, in_samples); + * handle_output(output, out_samples); + * av_freep(&output); + * } + * @endcode + * + * When the conversion is finished, the conversion + * context and everything associated with it must be freed with swr_free(). + * A swr_close() function is also available, but it exists mainly for + * compatibility with libavresample, and is not required to be called. + * + * There will be no memory leak if the data is not completely flushed before + * swr_free(). + */ + +#include +#include "libavutil/channel_layout.h" +#include "libavutil/frame.h" +#include "libavutil/samplefmt.h" + +#include "libswresample/version.h" + +/** + * @name Option constants + * These constants are used for the @ref avoptions interface for lswr. + * @{ + * + */ + +#define SWR_FLAG_RESAMPLE 1 ///< Force resampling even if equal sample rate +//TODO use int resample ? +//long term TODO can we enable this dynamically? + +/** Dithering algorithms */ +enum SwrDitherType { + SWR_DITHER_NONE = 0, + SWR_DITHER_RECTANGULAR, + SWR_DITHER_TRIANGULAR, + SWR_DITHER_TRIANGULAR_HIGHPASS, + + SWR_DITHER_NS = 64, ///< not part of API/ABI + SWR_DITHER_NS_LIPSHITZ, + SWR_DITHER_NS_F_WEIGHTED, + SWR_DITHER_NS_MODIFIED_E_WEIGHTED, + SWR_DITHER_NS_IMPROVED_E_WEIGHTED, + SWR_DITHER_NS_SHIBATA, + SWR_DITHER_NS_LOW_SHIBATA, + SWR_DITHER_NS_HIGH_SHIBATA, + SWR_DITHER_NB, ///< not part of API/ABI +}; + +/** Resampling Engines */ +enum SwrEngine { + SWR_ENGINE_SWR, /**< SW Resampler */ + SWR_ENGINE_SOXR, /**< SoX Resampler */ + SWR_ENGINE_NB, ///< not part of API/ABI +}; + +/** Resampling Filter Types */ +enum SwrFilterType { + SWR_FILTER_TYPE_CUBIC, /**< Cubic */ + SWR_FILTER_TYPE_BLACKMAN_NUTTALL, /**< Blackman Nuttall windowed sinc */ + SWR_FILTER_TYPE_KAISER, /**< Kaiser windowed sinc */ +}; + +/** + * @} + */ + +/** + * The libswresample context. Unlike libavcodec and libavformat, this structure + * is opaque. This means that if you would like to set options, you must use + * the @ref avoptions API and cannot directly set values to members of the + * structure. + */ +typedef struct SwrContext SwrContext; + +/** + * Get the AVClass for SwrContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + * @return the AVClass of SwrContext + */ +const AVClass *swr_get_class(void); + +/** + * @name SwrContext constructor functions + * @{ + */ + +/** + * Allocate SwrContext. + * + * If you use this function you will need to set the parameters (manually or + * with swr_alloc_set_opts()) before calling swr_init(). + * + * @see swr_alloc_set_opts(), swr_init(), swr_free() + * @return NULL on error, allocated context otherwise + */ +struct SwrContext *swr_alloc(void); + +/** + * Initialize context after user parameters have been set. + * @note The context must be configured using the AVOption API. + * + * @see av_opt_set_int() + * @see av_opt_set_dict() + * + * @param[in,out] s Swr context to initialize + * @return AVERROR error code in case of failure. + */ +int swr_init(struct SwrContext *s); + +/** + * Check whether an swr context has been initialized or not. + * + * @param[in] s Swr context to check + * @see swr_init() + * @return positive if it has been initialized, 0 if not initialized + */ +int swr_is_initialized(struct SwrContext *s); + +/** + * Allocate SwrContext if needed and set/reset common parameters. + * + * This function does not require s to be allocated with swr_alloc(). On the + * other hand, swr_alloc() can use swr_alloc_set_opts() to set the parameters + * on the allocated context. + * + * @param s existing Swr context if available, or NULL if not + * @param out_ch_layout output channel layout (AV_CH_LAYOUT_*) + * @param out_sample_fmt output sample format (AV_SAMPLE_FMT_*). + * @param out_sample_rate output sample rate (frequency in Hz) + * @param in_ch_layout input channel layout (AV_CH_LAYOUT_*) + * @param in_sample_fmt input sample format (AV_SAMPLE_FMT_*). + * @param in_sample_rate input sample rate (frequency in Hz) + * @param log_offset logging level offset + * @param log_ctx parent logging context, can be NULL + * + * @see swr_init(), swr_free() + * @return NULL on error, allocated context otherwise + */ +struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, + int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, + int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, + int log_offset, void *log_ctx); + +/** + * @} + * + * @name SwrContext destructor functions + * @{ + */ + +/** + * Free the given SwrContext and set the pointer to NULL. + * + * @param[in] s a pointer to a pointer to Swr context + */ +void swr_free(struct SwrContext **s); + +/** + * Closes the context so that swr_is_initialized() returns 0. + * + * The context can be brought back to life by running swr_init(), + * swr_init() can also be used without swr_close(). + * This function is mainly provided for simplifying the usecase + * where one tries to support libavresample and libswresample. + * + * @param[in,out] s Swr context to be closed + */ +void swr_close(struct SwrContext *s); + +/** + * @} + * + * @name Core conversion functions + * @{ + */ + +/** Convert audio. + * + * in and in_count can be set to 0 to flush the last few samples out at the + * end. + * + * If more input is provided than output space, then the input will be buffered. + * You can avoid this buffering by using swr_get_out_samples() to retrieve an + * upper bound on the required number of output samples for the given number of + * input samples. Conversion will run directly without copying whenever possible. + * + * @param s allocated Swr context, with parameters set + * @param out output buffers, only the first one need be set in case of packed audio + * @param out_count amount of space available for output in samples per channel + * @param in input buffers, only the first one need to be set in case of packed audio + * @param in_count number of input samples available in one channel + * + * @return number of samples output per channel, negative value on error + */ +int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, + const uint8_t **in , int in_count); + +/** + * Convert the next timestamp from input to output + * timestamps are in 1/(in_sample_rate * out_sample_rate) units. + * + * @note There are 2 slightly differently behaving modes. + * @li When automatic timestamp compensation is not used, (min_compensation >= FLT_MAX) + * in this case timestamps will be passed through with delays compensated + * @li When automatic timestamp compensation is used, (min_compensation < FLT_MAX) + * in this case the output timestamps will match output sample numbers. + * See ffmpeg-resampler(1) for the two modes of compensation. + * + * @param s[in] initialized Swr context + * @param pts[in] timestamp for the next input sample, INT64_MIN if unknown + * @see swr_set_compensation(), swr_drop_output(), and swr_inject_silence() are + * function used internally for timestamp compensation. + * @return the output timestamp for the next output sample + */ +int64_t swr_next_pts(struct SwrContext *s, int64_t pts); + +/** + * @} + * + * @name Low-level option setting functions + * These functons provide a means to set low-level options that is not possible + * with the AVOption API. + * @{ + */ + +/** + * Activate resampling compensation ("soft" compensation). This function is + * internally called when needed in swr_next_pts(). + * + * @param[in,out] s allocated Swr context. If it is not initialized, + * or SWR_FLAG_RESAMPLE is not set, swr_init() is + * called with the flag set. + * @param[in] sample_delta delta in PTS per sample + * @param[in] compensation_distance number of samples to compensate for + * @return >= 0 on success, AVERROR error codes if: + * @li @c s is NULL, + * @li @c compensation_distance is less than 0, + * @li @c compensation_distance is 0 but sample_delta is not, + * @li compensation unsupported by resampler, or + * @li swr_init() fails when called. + */ +int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance); + +/** + * Set a customized input channel mapping. + * + * @param[in,out] s allocated Swr context, not yet initialized + * @param[in] channel_map customized input channel mapping (array of channel + * indexes, -1 for a muted channel) + * @return >= 0 on success, or AVERROR error code in case of failure. + */ +int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map); + +/** + * Generate a channel mixing matrix. + * + * This function is the one used internally by libswresample for building the + * default mixing matrix. It is made public just as a utility function for + * building custom matrices. + * + * @param in_layout input channel layout + * @param out_layout output channel layout + * @param center_mix_level mix level for the center channel + * @param surround_mix_level mix level for the surround channel(s) + * @param lfe_mix_level mix level for the low-frequency effects channel + * @param rematrix_maxval if 1.0, coefficients will be normalized to prevent + * overflow. if INT_MAX, coefficients will not be + * normalized. + * @param[out] matrix mixing coefficients; matrix[i + stride * o] is + * the weight of input channel i in output channel o. + * @param stride distance between adjacent input channels in the + * matrix array + * @param matrix_encoding matrixed stereo downmix mode (e.g. dplii) + * @param log_ctx parent logging context, can be NULL + * @return 0 on success, negative AVERROR code on failure + */ +int swr_build_matrix(uint64_t in_layout, uint64_t out_layout, + double center_mix_level, double surround_mix_level, + double lfe_mix_level, double rematrix_maxval, + double rematrix_volume, double *matrix, + int stride, enum AVMatrixEncoding matrix_encoding, + void *log_ctx); + +/** + * Set a customized remix matrix. + * + * @param s allocated Swr context, not yet initialized + * @param matrix remix coefficients; matrix[i + stride * o] is + * the weight of input channel i in output channel o + * @param stride offset between lines of the matrix + * @return >= 0 on success, or AVERROR error code in case of failure. + */ +int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride); + +/** + * @} + * + * @name Sample handling functions + * @{ + */ + +/** + * Drops the specified number of output samples. + * + * This function, along with swr_inject_silence(), is called by swr_next_pts() + * if needed for "hard" compensation. + * + * @param s allocated Swr context + * @param count number of samples to be dropped + * + * @return >= 0 on success, or a negative AVERROR code on failure + */ +int swr_drop_output(struct SwrContext *s, int count); + +/** + * Injects the specified number of silence samples. + * + * This function, along with swr_drop_output(), is called by swr_next_pts() + * if needed for "hard" compensation. + * + * @param s allocated Swr context + * @param count number of samples to be dropped + * + * @return >= 0 on success, or a negative AVERROR code on failure + */ +int swr_inject_silence(struct SwrContext *s, int count); + +/** + * Gets the delay the next input sample will experience relative to the next output sample. + * + * Swresample can buffer data if more input has been provided than available + * output space, also converting between sample rates needs a delay. + * This function returns the sum of all such delays. + * The exact delay is not necessarily an integer value in either input or + * output sample rate. Especially when downsampling by a large value, the + * output sample rate may be a poor choice to represent the delay, similarly + * for upsampling and the input sample rate. + * + * @param s swr context + * @param base timebase in which the returned delay will be: + * @li if it's set to 1 the returned delay is in seconds + * @li if it's set to 1000 the returned delay is in milliseconds + * @li if it's set to the input sample rate then the returned + * delay is in input samples + * @li if it's set to the output sample rate then the returned + * delay is in output samples + * @li if it's the least common multiple of in_sample_rate and + * out_sample_rate then an exact rounding-free delay will be + * returned + * @returns the delay in 1 / @c base units. + */ +int64_t swr_get_delay(struct SwrContext *s, int64_t base); + +/** + * Find an upper bound on the number of samples that the next swr_convert + * call will output, if called with in_samples of input samples. This + * depends on the internal state, and anything changing the internal state + * (like further swr_convert() calls) will may change the number of samples + * swr_get_out_samples() returns for the same number of input samples. + * + * @param in_samples number of input samples. + * @note any call to swr_inject_silence(), swr_convert(), swr_next_pts() + * or swr_set_compensation() invalidates this limit + * @note it is recommended to pass the correct available buffer size + * to all functions like swr_convert() even if swr_get_out_samples() + * indicates that less would be used. + * @returns an upper bound on the number of samples that the next swr_convert + * will output or a negative value to indicate an error + */ +int swr_get_out_samples(struct SwrContext *s, int in_samples); + +/** + * @} + * + * @name Configuration accessors + * @{ + */ + +/** + * Return the @ref LIBSWRESAMPLE_VERSION_INT constant. + * + * This is useful to check if the build-time libswresample has the same version + * as the run-time one. + * + * @returns the unsigned int-typed version + */ +unsigned swresample_version(void); + +/** + * Return the swr build-time configuration. + * + * @returns the build-time @c ./configure flags + */ +const char *swresample_configuration(void); + +/** + * Return the swr license. + * + * @returns the license of libswresample, determined at build-time + */ +const char *swresample_license(void); + +/** + * @} + * + * @name AVFrame based API + * @{ + */ + +/** + * Convert the samples in the input AVFrame and write them to the output AVFrame. + * + * Input and output AVFrames must have channel_layout, sample_rate and format set. + * + * If the output AVFrame does not have the data pointers allocated the nb_samples + * field will be set using av_frame_get_buffer() + * is called to allocate the frame. + * + * The output AVFrame can be NULL or have fewer allocated samples than required. + * In this case, any remaining samples not written to the output will be added + * to an internal FIFO buffer, to be returned at the next call to this function + * or to swr_convert(). + * + * If converting sample rate, there may be data remaining in the internal + * resampling delay buffer. swr_get_delay() tells the number of + * remaining samples. To get this data as output, call this function or + * swr_convert() with NULL input. + * + * If the SwrContext configuration does not match the output and + * input AVFrame settings the conversion does not take place and depending on + * which AVFrame is not matching AVERROR_OUTPUT_CHANGED, AVERROR_INPUT_CHANGED + * or the result of a bitwise-OR of them is returned. + * + * @see swr_delay() + * @see swr_convert() + * @see swr_get_delay() + * + * @param swr audio resample context + * @param output output AVFrame + * @param input input AVFrame + * @return 0 on success, AVERROR on failure or nonmatching + * configuration. + */ +int swr_convert_frame(SwrContext *swr, + AVFrame *output, const AVFrame *input); + +/** + * Configure or reconfigure the SwrContext using the information + * provided by the AVFrames. + * + * The original resampling context is reset even on failure. + * The function calls swr_close() internally if the context is open. + * + * @see swr_close(); + * + * @param swr audio resample context + * @param output output AVFrame + * @param input input AVFrame + * @return 0 on success, AVERROR on failure. + */ +int swr_config_frame(SwrContext *swr, const AVFrame *out, const AVFrame *in); + +/** + * @} + * @} + */ + +#endif /* SWRESAMPLE_SWRESAMPLE_H */ diff --git a/ffmpeg/inc/libswresample/version.h b/ffmpeg/inc/libswresample/version.h new file mode 100644 index 0000000..2577391 --- /dev/null +++ b/ffmpeg/inc/libswresample/version.h @@ -0,0 +1,45 @@ +/* + * Version macros. + * + * This file is part of libswresample + * + * libswresample is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libswresample is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libswresample; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWRESAMPLE_VERSION_H +#define SWRESAMPLE_VERSION_H + +/** + * @file + * Libswresample version macros + */ + +#include "libavutil/avutil.h" + +#define LIBSWRESAMPLE_VERSION_MAJOR 3 +#define LIBSWRESAMPLE_VERSION_MINOR 7 +#define LIBSWRESAMPLE_VERSION_MICRO 100 + +#define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ + LIBSWRESAMPLE_VERSION_MINOR, \ + LIBSWRESAMPLE_VERSION_MICRO) +#define LIBSWRESAMPLE_VERSION AV_VERSION(LIBSWRESAMPLE_VERSION_MAJOR, \ + LIBSWRESAMPLE_VERSION_MINOR, \ + LIBSWRESAMPLE_VERSION_MICRO) +#define LIBSWRESAMPLE_BUILD LIBSWRESAMPLE_VERSION_INT + +#define LIBSWRESAMPLE_IDENT "SwR" AV_STRINGIFY(LIBSWRESAMPLE_VERSION) + +#endif /* SWRESAMPLE_VERSION_H */ diff --git a/ffmpeg/inc/libswscale/swscale.h b/ffmpeg/inc/libswscale/swscale.h new file mode 100644 index 0000000..7713f51 --- /dev/null +++ b/ffmpeg/inc/libswscale/swscale.h @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2001-2011 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWSCALE_SWSCALE_H +#define SWSCALE_SWSCALE_H + +/** + * @file + * @ingroup libsws + * external API header + */ + +#include + +#include "libavutil/avutil.h" +#include "libavutil/log.h" +#include "libavutil/pixfmt.h" +#include "version.h" + +/** + * @defgroup libsws libswscale + * Color conversion and scaling library. + * + * @{ + * + * Return the LIBSWSCALE_VERSION_INT constant. + */ +unsigned swscale_version(void); + +/** + * Return the libswscale build-time configuration. + */ +const char *swscale_configuration(void); + +/** + * Return the libswscale license. + */ +const char *swscale_license(void); + +/* values for the flags, the stuff on the command line is different */ +#define SWS_FAST_BILINEAR 1 +#define SWS_BILINEAR 2 +#define SWS_BICUBIC 4 +#define SWS_X 8 +#define SWS_POINT 0x10 +#define SWS_AREA 0x20 +#define SWS_BICUBLIN 0x40 +#define SWS_GAUSS 0x80 +#define SWS_SINC 0x100 +#define SWS_LANCZOS 0x200 +#define SWS_SPLINE 0x400 + +#define SWS_SRC_V_CHR_DROP_MASK 0x30000 +#define SWS_SRC_V_CHR_DROP_SHIFT 16 + +#define SWS_PARAM_DEFAULT 123456 + +#define SWS_PRINT_INFO 0x1000 + +//the following 3 flags are not completely implemented +//internal chrominance subsampling info +#define SWS_FULL_CHR_H_INT 0x2000 +//input subsampling info +#define SWS_FULL_CHR_H_INP 0x4000 +#define SWS_DIRECT_BGR 0x8000 +#define SWS_ACCURATE_RND 0x40000 +#define SWS_BITEXACT 0x80000 +#define SWS_ERROR_DIFFUSION 0x800000 + +#define SWS_MAX_REDUCE_CUTOFF 0.002 + +#define SWS_CS_ITU709 1 +#define SWS_CS_FCC 4 +#define SWS_CS_ITU601 5 +#define SWS_CS_ITU624 5 +#define SWS_CS_SMPTE170M 5 +#define SWS_CS_SMPTE240M 7 +#define SWS_CS_DEFAULT 5 +#define SWS_CS_BT2020 9 + +/** + * Return a pointer to yuv<->rgb coefficients for the given colorspace + * suitable for sws_setColorspaceDetails(). + * + * @param colorspace One of the SWS_CS_* macros. If invalid, + * SWS_CS_DEFAULT is used. + */ +const int *sws_getCoefficients(int colorspace); + +// when used for filters they must have an odd number of elements +// coeffs cannot be shared between vectors +typedef struct SwsVector { + double *coeff; ///< pointer to the list of coefficients + int length; ///< number of coefficients in the vector +} SwsVector; + +// vectors can be shared +typedef struct SwsFilter { + SwsVector *lumH; + SwsVector *lumV; + SwsVector *chrH; + SwsVector *chrV; +} SwsFilter; + +struct SwsContext; + +/** + * Return a positive value if pix_fmt is a supported input format, 0 + * otherwise. + */ +int sws_isSupportedInput(enum AVPixelFormat pix_fmt); + +/** + * Return a positive value if pix_fmt is a supported output format, 0 + * otherwise. + */ +int sws_isSupportedOutput(enum AVPixelFormat pix_fmt); + +/** + * @param[in] pix_fmt the pixel format + * @return a positive value if an endianness conversion for pix_fmt is + * supported, 0 otherwise. + */ +int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt); + +/** + * Allocate an empty SwsContext. This must be filled and passed to + * sws_init_context(). For filling see AVOptions, options.c and + * sws_setColorspaceDetails(). + */ +struct SwsContext *sws_alloc_context(void); + +/** + * Initialize the swscaler context sws_context. + * + * @return zero or positive value on success, a negative value on + * error + */ +av_warn_unused_result +int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter); + +/** + * Free the swscaler context swsContext. + * If swsContext is NULL, then does nothing. + */ +void sws_freeContext(struct SwsContext *swsContext); + +/** + * Allocate and return an SwsContext. You need it to perform + * scaling/conversion operations using sws_scale(). + * + * @param srcW the width of the source image + * @param srcH the height of the source image + * @param srcFormat the source image format + * @param dstW the width of the destination image + * @param dstH the height of the destination image + * @param dstFormat the destination image format + * @param flags specify which algorithm and options to use for rescaling + * @param param extra parameters to tune the used scaler + * For SWS_BICUBIC param[0] and [1] tune the shape of the basis + * function, param[0] tunes f(1) and param[1] f´(1) + * For SWS_GAUSS param[0] tunes the exponent and thus cutoff + * frequency + * For SWS_LANCZOS param[0] tunes the width of the window function + * @return a pointer to an allocated context, or NULL in case of error + * @note this function is to be removed after a saner alternative is + * written + */ +struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, + int dstW, int dstH, enum AVPixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); + +/** + * Scale the image slice in srcSlice and put the resulting scaled + * slice in the image in dst. A slice is a sequence of consecutive + * rows in an image. + * + * Slices have to be provided in sequential order, either in + * top-bottom or bottom-top order. If slices are provided in + * non-sequential order the behavior of the function is undefined. + * + * @param c the scaling context previously created with + * sws_getContext() + * @param srcSlice the array containing the pointers to the planes of + * the source slice + * @param srcStride the array containing the strides for each plane of + * the source image + * @param srcSliceY the position in the source image of the slice to + * process, that is the number (counted starting from + * zero) in the image of the first row of the slice + * @param srcSliceH the height of the source slice, that is the number + * of rows in the slice + * @param dst the array containing the pointers to the planes of + * the destination image + * @param dstStride the array containing the strides for each plane of + * the destination image + * @return the height of the output slice + */ +int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], + const int srcStride[], int srcSliceY, int srcSliceH, + uint8_t *const dst[], const int dstStride[]); + +/** + * @param dstRange flag indicating the while-black range of the output (1=jpeg / 0=mpeg) + * @param srcRange flag indicating the while-black range of the input (1=jpeg / 0=mpeg) + * @param table the yuv2rgb coefficients describing the output yuv space, normally ff_yuv2rgb_coeffs[x] + * @param inv_table the yuv2rgb coefficients describing the input yuv space, normally ff_yuv2rgb_coeffs[x] + * @param brightness 16.16 fixed point brightness correction + * @param contrast 16.16 fixed point contrast correction + * @param saturation 16.16 fixed point saturation correction + * @return -1 if not supported + */ +int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], + int srcRange, const int table[4], int dstRange, + int brightness, int contrast, int saturation); + +/** + * @return -1 if not supported + */ +int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, + int *srcRange, int **table, int *dstRange, + int *brightness, int *contrast, int *saturation); + +/** + * Allocate and return an uninitialized vector with length coefficients. + */ +SwsVector *sws_allocVec(int length); + +/** + * Return a normalized Gaussian curve used to filter stuff + * quality = 3 is high quality, lower is lower quality. + */ +SwsVector *sws_getGaussianVec(double variance, double quality); + +/** + * Scale all the coefficients of a by the scalar value. + */ +void sws_scaleVec(SwsVector *a, double scalar); + +/** + * Scale all the coefficients of a so that their sum equals height. + */ +void sws_normalizeVec(SwsVector *a, double height); + +#if FF_API_SWS_VECTOR +attribute_deprecated SwsVector *sws_getConstVec(double c, int length); +attribute_deprecated SwsVector *sws_getIdentityVec(void); +attribute_deprecated void sws_convVec(SwsVector *a, SwsVector *b); +attribute_deprecated void sws_addVec(SwsVector *a, SwsVector *b); +attribute_deprecated void sws_subVec(SwsVector *a, SwsVector *b); +attribute_deprecated void sws_shiftVec(SwsVector *a, int shift); +attribute_deprecated SwsVector *sws_cloneVec(SwsVector *a); +attribute_deprecated void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level); +#endif + +void sws_freeVec(SwsVector *a); + +SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, + float lumaSharpen, float chromaSharpen, + float chromaHShift, float chromaVShift, + int verbose); +void sws_freeFilter(SwsFilter *filter); + +/** + * Check if context can be reused, otherwise reallocate a new one. + * + * If context is NULL, just calls sws_getContext() to get a new + * context. Otherwise, checks if the parameters are the ones already + * saved in context. If that is the case, returns the current + * context. Otherwise, frees context and gets a new context with + * the new parameters. + * + * Be warned that srcFilter and dstFilter are not checked, they + * are assumed to remain the same. + */ +struct SwsContext *sws_getCachedContext(struct SwsContext *context, + int srcW, int srcH, enum AVPixelFormat srcFormat, + int dstW, int dstH, enum AVPixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); + +/** + * Convert an 8-bit paletted frame into a frame with a color depth of 32 bits. + * + * The output frame will have the same packed format as the palette. + * + * @param src source frame buffer + * @param dst destination frame buffer + * @param num_pixels number of pixels to convert + * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src + */ +void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); + +/** + * Convert an 8-bit paletted frame into a frame with a color depth of 24 bits. + * + * With the palette format "ABCD", the destination frame ends up with the format "ABC". + * + * @param src source frame buffer + * @param dst destination frame buffer + * @param num_pixels number of pixels to convert + * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src + */ +void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette); + +/** + * Get the AVClass for swsContext. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *sws_get_class(void); + +/** + * @} + */ + +#endif /* SWSCALE_SWSCALE_H */ diff --git a/ffmpeg/inc/libswscale/version.h b/ffmpeg/inc/libswscale/version.h new file mode 100644 index 0000000..3aec51f --- /dev/null +++ b/ffmpeg/inc/libswscale/version.h @@ -0,0 +1,53 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWSCALE_VERSION_H +#define SWSCALE_VERSION_H + +/** + * @file + * swscale version macros + */ + +#include "libavutil/version.h" + +#define LIBSWSCALE_VERSION_MAJOR 5 +#define LIBSWSCALE_VERSION_MINOR 7 +#define LIBSWSCALE_VERSION_MICRO 100 + +#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT + +#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION) + +/** + * FF_API_* defines may be placed below to indicate public API that will be + * dropped at a future version bump. The defines themselves are not part of + * the public API and may change, break or disappear at any time. + */ + +#ifndef FF_API_SWS_VECTOR +#define FF_API_SWS_VECTOR (LIBSWSCALE_VERSION_MAJOR < 6) +#endif + +#endif /* SWSCALE_VERSION_H */ diff --git a/ffmpeg/lib/libavcodec.so b/ffmpeg/lib/libavcodec.so new file mode 120000 index 0000000..c0cd279 --- /dev/null +++ b/ffmpeg/lib/libavcodec.so @@ -0,0 +1 @@ +libavcodec.so.58.91.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavcodec.so.58 b/ffmpeg/lib/libavcodec.so.58 new file mode 120000 index 0000000..c0cd279 --- /dev/null +++ b/ffmpeg/lib/libavcodec.so.58 @@ -0,0 +1 @@ +libavcodec.so.58.91.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavcodec.so.58.91.100 b/ffmpeg/lib/libavcodec.so.58.91.100 new file mode 100755 index 0000000..0be2b1f Binary files /dev/null and b/ffmpeg/lib/libavcodec.so.58.91.100 differ diff --git a/ffmpeg/lib/libavdevice.so b/ffmpeg/lib/libavdevice.so new file mode 120000 index 0000000..f6b563d --- /dev/null +++ b/ffmpeg/lib/libavdevice.so @@ -0,0 +1 @@ +libavdevice.so.58.10.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavdevice.so.58 b/ffmpeg/lib/libavdevice.so.58 new file mode 120000 index 0000000..f6b563d --- /dev/null +++ b/ffmpeg/lib/libavdevice.so.58 @@ -0,0 +1 @@ +libavdevice.so.58.10.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavdevice.so.58.10.100 b/ffmpeg/lib/libavdevice.so.58.10.100 new file mode 100755 index 0000000..f596134 Binary files /dev/null and b/ffmpeg/lib/libavdevice.so.58.10.100 differ diff --git a/ffmpeg/lib/libavfilter.so b/ffmpeg/lib/libavfilter.so new file mode 120000 index 0000000..3b14b07 --- /dev/null +++ b/ffmpeg/lib/libavfilter.so @@ -0,0 +1 @@ +libavfilter.so.7.85.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavfilter.so.7 b/ffmpeg/lib/libavfilter.so.7 new file mode 120000 index 0000000..3b14b07 --- /dev/null +++ b/ffmpeg/lib/libavfilter.so.7 @@ -0,0 +1 @@ +libavfilter.so.7.85.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavfilter.so.7.85.100 b/ffmpeg/lib/libavfilter.so.7.85.100 new file mode 100755 index 0000000..219bae9 Binary files /dev/null and b/ffmpeg/lib/libavfilter.so.7.85.100 differ diff --git a/ffmpeg/lib/libavformat.so b/ffmpeg/lib/libavformat.so new file mode 120000 index 0000000..0d07a3f --- /dev/null +++ b/ffmpeg/lib/libavformat.so @@ -0,0 +1 @@ +libavformat.so.58.45.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavformat.so.58 b/ffmpeg/lib/libavformat.so.58 new file mode 120000 index 0000000..0d07a3f --- /dev/null +++ b/ffmpeg/lib/libavformat.so.58 @@ -0,0 +1 @@ +libavformat.so.58.45.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavformat.so.58.45.100 b/ffmpeg/lib/libavformat.so.58.45.100 new file mode 100755 index 0000000..7e84ade Binary files /dev/null and b/ffmpeg/lib/libavformat.so.58.45.100 differ diff --git a/ffmpeg/lib/libavutil.so b/ffmpeg/lib/libavutil.so new file mode 120000 index 0000000..52fa54e --- /dev/null +++ b/ffmpeg/lib/libavutil.so @@ -0,0 +1 @@ +libavutil.so.56.51.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavutil.so.56 b/ffmpeg/lib/libavutil.so.56 new file mode 120000 index 0000000..52fa54e --- /dev/null +++ b/ffmpeg/lib/libavutil.so.56 @@ -0,0 +1 @@ +libavutil.so.56.51.100 \ No newline at end of file diff --git a/ffmpeg/lib/libavutil.so.56.51.100 b/ffmpeg/lib/libavutil.so.56.51.100 new file mode 100755 index 0000000..bae5f5f Binary files /dev/null and b/ffmpeg/lib/libavutil.so.56.51.100 differ diff --git a/ffmpeg/lib/libswresample.so b/ffmpeg/lib/libswresample.so new file mode 120000 index 0000000..b020890 --- /dev/null +++ b/ffmpeg/lib/libswresample.so @@ -0,0 +1 @@ +libswresample.so.3.7.100 \ No newline at end of file diff --git a/ffmpeg/lib/libswresample.so.3 b/ffmpeg/lib/libswresample.so.3 new file mode 120000 index 0000000..b020890 --- /dev/null +++ b/ffmpeg/lib/libswresample.so.3 @@ -0,0 +1 @@ +libswresample.so.3.7.100 \ No newline at end of file diff --git a/ffmpeg/lib/libswresample.so.3.7.100 b/ffmpeg/lib/libswresample.so.3.7.100 new file mode 100755 index 0000000..c851baa Binary files /dev/null and b/ffmpeg/lib/libswresample.so.3.7.100 differ diff --git a/ffmpeg/lib/libswscale.so b/ffmpeg/lib/libswscale.so new file mode 120000 index 0000000..36f853d --- /dev/null +++ b/ffmpeg/lib/libswscale.so @@ -0,0 +1 @@ +libswscale.so.5.7.100 \ No newline at end of file diff --git a/ffmpeg/lib/libswscale.so.5 b/ffmpeg/lib/libswscale.so.5 new file mode 120000 index 0000000..36f853d --- /dev/null +++ b/ffmpeg/lib/libswscale.so.5 @@ -0,0 +1 @@ +libswscale.so.5.7.100 \ No newline at end of file diff --git a/ffmpeg/lib/libswscale.so.5.7.100 b/ffmpeg/lib/libswscale.so.5.7.100 new file mode 100755 index 0000000..7d9e130 Binary files /dev/null and b/ffmpeg/lib/libswscale.so.5.7.100 differ diff --git a/ffmpeg/lib/pkgconfig/libavcodec.pc b/ffmpeg/lib/pkgconfig/libavcodec.pc new file mode 100644 index 0000000..cbb6df8 --- /dev/null +++ b/ffmpeg/lib/pkgconfig/libavcodec.pc @@ -0,0 +1,14 @@ +prefix=./output +exec_prefix=${prefix} +libdir=./output/lib +includedir=./output/include + +Name: libavcodec +Description: FFmpeg codec library +Version: 58.91.100 +Requires: +Requires.private: libswresample >= 3.7.100, libavutil >= 56.51.100 +Conflicts: +Libs: -L${libdir} -lavcodec +Libs.private: -pthread -lm +Cflags: -I${includedir} diff --git a/ffmpeg/lib/pkgconfig/libavdevice.pc b/ffmpeg/lib/pkgconfig/libavdevice.pc new file mode 100644 index 0000000..e64ded8 --- /dev/null +++ b/ffmpeg/lib/pkgconfig/libavdevice.pc @@ -0,0 +1,14 @@ +prefix=./output +exec_prefix=${prefix} +libdir=./output/lib +includedir=./output/include + +Name: libavdevice +Description: FFmpeg device handling library +Version: 58.10.100 +Requires: +Requires.private: libavfilter >= 7.85.100, libswscale >= 5.7.100, libavformat >= 58.45.100, libavcodec >= 58.91.100, libswresample >= 3.7.100, libavutil >= 56.51.100 +Conflicts: +Libs: -L${libdir} -lavdevice +Libs.private: -lm +Cflags: -I${includedir} diff --git a/ffmpeg/lib/pkgconfig/libavfilter.pc b/ffmpeg/lib/pkgconfig/libavfilter.pc new file mode 100644 index 0000000..9d8d19d --- /dev/null +++ b/ffmpeg/lib/pkgconfig/libavfilter.pc @@ -0,0 +1,14 @@ +prefix=./output +exec_prefix=${prefix} +libdir=./output/lib +includedir=./output/include + +Name: libavfilter +Description: FFmpeg audio/video filtering library +Version: 7.85.100 +Requires: +Requires.private: libswscale >= 5.7.100, libavformat >= 58.45.100, libavcodec >= 58.91.100, libswresample >= 3.7.100, libavutil >= 56.51.100 +Conflicts: +Libs: -L${libdir} -lavfilter +Libs.private: -pthread -lm +Cflags: -I${includedir} diff --git a/ffmpeg/lib/pkgconfig/libavformat.pc b/ffmpeg/lib/pkgconfig/libavformat.pc new file mode 100644 index 0000000..80b9547 --- /dev/null +++ b/ffmpeg/lib/pkgconfig/libavformat.pc @@ -0,0 +1,14 @@ +prefix=./output +exec_prefix=${prefix} +libdir=./output/lib +includedir=./output/include + +Name: libavformat +Description: FFmpeg container format library +Version: 58.45.100 +Requires: +Requires.private: libavcodec >= 58.91.100, libswresample >= 3.7.100, libavutil >= 56.51.100 +Conflicts: +Libs: -L${libdir} -lavformat +Libs.private: -lm +Cflags: -I${includedir} diff --git a/ffmpeg/lib/pkgconfig/libavutil.pc b/ffmpeg/lib/pkgconfig/libavutil.pc new file mode 100644 index 0000000..13ff208 --- /dev/null +++ b/ffmpeg/lib/pkgconfig/libavutil.pc @@ -0,0 +1,14 @@ +prefix=./output +exec_prefix=${prefix} +libdir=./output/lib +includedir=./output/include + +Name: libavutil +Description: FFmpeg utility library +Version: 56.51.100 +Requires: +Requires.private: +Conflicts: +Libs: -L${libdir} -lavutil +Libs.private: -pthread -lm +Cflags: -I${includedir} diff --git a/ffmpeg/lib/pkgconfig/libswresample.pc b/ffmpeg/lib/pkgconfig/libswresample.pc new file mode 100644 index 0000000..7c4ce43 --- /dev/null +++ b/ffmpeg/lib/pkgconfig/libswresample.pc @@ -0,0 +1,14 @@ +prefix=./output +exec_prefix=${prefix} +libdir=./output/lib +includedir=./output/include + +Name: libswresample +Description: FFmpeg audio resampling library +Version: 3.7.100 +Requires: +Requires.private: libavutil >= 56.51.100 +Conflicts: +Libs: -L${libdir} -lswresample +Libs.private: -lm +Cflags: -I${includedir} diff --git a/ffmpeg/lib/pkgconfig/libswscale.pc b/ffmpeg/lib/pkgconfig/libswscale.pc new file mode 100644 index 0000000..2e161e3 --- /dev/null +++ b/ffmpeg/lib/pkgconfig/libswscale.pc @@ -0,0 +1,14 @@ +prefix=./output +exec_prefix=${prefix} +libdir=./output/lib +includedir=./output/include + +Name: libswscale +Description: FFmpeg image rescaling library +Version: 5.7.100 +Requires: +Requires.private: libavutil >= 56.51.100 +Conflicts: +Libs: -L${libdir} -lswscale +Libs.private: -lm +Cflags: -I${includedir} diff --git a/main.cpp b/main.cpp new file mode 100755 index 0000000..ca6764a --- /dev/null +++ b/main.cpp @@ -0,0 +1,516 @@ +#include +#include +#include +#include +#include "yolov5.h" +#include +#include +#include "vertix.h" + +/*Include ffmpeg header file*/ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#ifdef __cplusplus +}; +#endif + +#include "MppDecode.h" +#include "rga.h" +#include "pose_body.h" +#include "rknn.h" + +long max_time_elapsed = 0; +char *server = NULL; + +void deInit(MppPacket *packet, MppFrame *frame, MppCtx ctx, char *buf, MpiDecLoopData data) +{ + if (packet) + { + mpp_packet_deinit(packet); + packet = NULL; + } + + if (frame) + { + mpp_frame_deinit(frame); + frame = NULL; + } + + if (ctx) + { + mpp_destroy(ctx); + ctx = NULL; + } + + if (buf) + { + mpp_free(buf); + buf = NULL; + } + + if (data.pkt_grp) + { + mpp_buffer_group_put(data.pkt_grp); + data.pkt_grp = NULL; + } + + if (data.frm_grp) + { + mpp_buffer_group_put(data.frm_grp); + data.frm_grp = NULL; + } + + if (data.fp_output) + { + fclose(data.fp_output); + data.fp_output = NULL; + } + + if (data.fp_input) + { + fclose(data.fp_input); + data.fp_input = NULL; + } +} + +void usage(char *name) +{ + printf("\nUsage: %s [-s $rtsp-stream-address] \n\t -s specify the rtsp address, like \"rtsp://admin:$password@$ip:554/h264/ch1/main/av_stream\"\n", name); +} + +void example_server(char *name) +{ + printf("\nexample server: rtsp://admin:JEGSSI@172.28.1.208:554/h264/ch1/main/av_stream\n"); +} + +static const char *help_info[100] = { + "rtsp server URL", + "show example server", + // "model name from /usr/local/models/", + "model name from ./models/", + "camera id", + "type id", + "upload port", + "workspace, use comma spearated coordinate, like 0,1,2,3" + "threshold, like 0.7, default is 0.6"}; + +static struct option long_options[] = { + {"server", required_argument, NULL, 's'}, + {"example", no_argument, NULL, 'e'}, + {"model", required_argument, NULL, 'm'}, + {"camera-id", required_argument, NULL, 'c'}, + {"type-id", required_argument, NULL, 't'}, + {"upload-port", required_argument, NULL, 'p'}, + {"workspace", required_argument, NULL, 'w'}, + {"threshold", required_argument, NULL, 'r'}, + {0, 0, 0}}; + +void print_usage(char *cmd) +{ + printf("Usage: %s [OPTION]\n\nGetting help:\n", cmd); + struct option *opt; + for (int i = 0;; i++) + { + opt = long_options + i; + if (opt->name == NULL) + { + break; + } + printf(" -%c, -%s\t%s\n", opt->val, opt->name, help_info[i]); + } +} + +float *parse_workspace_point(char *input, int maxnumber, int *size) +{ + printf("got workspace points: %s\n", input); + float *result = (float *)malloc(sizeof(float) * maxnumber); + int count = 0; + char *token = strtok(input, ","); + while (token != NULL && count < maxnumber) + { + printf("token > %s\n", token); + int k = atoi(token); + printf("converted to int is %d\n", k); + result[count++] = float(k); + printf("stored is %f\n", result[count - 1]); + token = strtok(NULL, ","); + } + *size = count; + return result; +} + +void parse_options(int argc, char **argv) +{ + int c; + + bool polygon_inited = false; + char *workspace_points = (char*)""; + float *points; + int thresh; + conf_threshold = DEFAULT_CONF_THRESHOLD; + char *cmd = argv[0]; + while (1) + { + int option_index = 0; + c = getopt_long_only(argc, argv, "es:m:w:c:t:p:r:", long_options, &option_index); + if (c == -1) + { + break; + } + switch (c) + { + case 'c': + CameraID = optarg; + break; + case 't': + TypeID = atoi(optarg); + break; + case 'p': + UploadPort = atoi(optarg); + break; + case 's': + server = optarg; + break; + case 'e': + example_server(cmd); + exit(0); + case 'w': + workspace_points = optarg; + int workspace_size; + points = parse_workspace_point(workspace_points, 50, &workspace_size); + + init_polygon(points, workspace_size); + polygon_inited = true; + free(points); + break; + case 'm': + global_model = optarg; + break; + case 'r': + thresh = atoi(optarg); + if (thresh < 50) { + thresh = 50; + } else if (thresh > 90) { + thresh = 90; + } + conf_threshold = (float)thresh / 100.0; + break; + default: + print_usage(cmd); + exit(-1); + } + } + + if (!polygon_inited) { + init_polygon(NULL, 0); + } +} + +int main(int argc, char *argv[]) +{ + int o; + // const char *optstring = "es:m:h:u:p:c:"; + + /* + char tempbuf[20]; + for (int i = 0;; i++) { + cJSON *obj = cJSON_CreateObject(); + cJSON_AddNumberToObject(obj, "index", i); + cJSON_AddStringToObject(obj, "name", "hello"); + publishCJSONInfo("sensor/a", obj, 0); + cJSON_Delete(obj); + sleep(1); + } + */ + + // char *server = "rtsp://admin:JEGSSI@172.28.1.208:554/h264/ch1/main/av_stream"; + char *tempm = (char *)malloc(sizeof(char) * 128); + + parse_options(argc, argv); + if (CameraID == NULL) + { + printf("no camera id specified"); + return -1; + } + if (global_model == NULL) + { + global_model = (char*)"yolov5s"; + } + + char targetdir[120]; + mkdir("/usr"); + mkdir("/usr/data"); + mkdir("/usr/data/camera"); + printf("mkdir camera"); + snprintf(targetdir, 120, "/usr/data/camera/%s", CameraID); + mkdir(targetdir); + snprintf(targetdir, 120, "/usr/data/camera/%s/picsave", CameraID); + mkdir(targetdir); + snprintf(targetdir, 120, "/usr/data/camera/%s/frames", CameraID); + char rmdir[200]; + snprintf(rmdir, 200, "rm -rf %s", targetdir); + system(rmdir); + mkdir(targetdir); + + // initMQTTClient(); + /* + if (global_model == NULL) + { + sprintf(tempm, "%s", "coco"); + global_model = tempm; + } + */ + + // do_init_model(); + + int ret; + memset(&rknn_app_ctx, 0, sizeof(rknn_app_context_t)); + + init_post_process(); + + char model_path[128]; + snprintf(model_path, 127, "%s/%s.rknn", MODELDIR, global_model); + + ret = init_yolov5_model(model_path, &rknn_app_ctx, print_object_detect_result); + if (ret != 0) + { + printf("init_yolov5_model fail! ret=%d model_path=%s\n", ret, model_path); + + deinit_post_process(); + + ret = release_yolov5_model(&rknn_app_ctx); + if (ret != 0) + { + printf("release_yolov5_model fail! ret=%d\n", ret); + } + return -1; + } + + printf("server: %s\n", server); + + // initRkRga(); + // if (init_pose_body_context() != 0) + // { + // printf("failed to init pose_body context"); + // return -1; + // } + AVFormatContext *pFormatCtx = NULL; + AVDictionary *options = NULL; + AVPacket *av_packet = NULL; + // char filepath[] = "rtsp://admin:openiot123456@192.168.1.64:554/h264/ch1/main/av_stream";// rtsp 地址 + // char filepath[] = "rtsp://admin:JEGSSI@172.28.1.208:554/h264/ch1/main/av_stream"; + // char filepath[] = "rtsp://admin:openiot123456@192.168.1.64:554/h264/ch39/sub/av_stream";// rtsp 地址 + // char filepath[] = "rtsp://192.168.180.1:8554/cam";// rtsp 地址 + // char filepath[] = "/root/test.h264";// rtsp 地址 + + // av_register_all(); // 函数在ffmpeg4.0以上版本已经被废弃,所以4.0以下版本就需要注册初始函数 + avformat_network_init(); + // av_dict_set(&options, "buffer_size", "1024000", 0); //设置缓存大小,1080p可将值跳到最大 + av_dict_set(&options, "buffer_size", "10240000", 0); // 设置缓存大小,1080p可将值跳到最大 + av_dict_set(&options, "rtsp_transport", "tcp", 0); // 以tcp的方式打开, + av_dict_set(&options, "stimeout", "5000000", 0); // 设置超时断开链接时间,单位us + av_dict_set(&options, "max_delay", "500000", 0); // 设置最大时延 + + // pFormatCtx = avformat_alloc_context(); // 用来申请AVFormatContext类型变量并初始化默认参数,申请的空间 + pFormatCtx = avformat_alloc_context(); // 用来申请AVFormatContext类型变量并初始化默认参数,申请的空间 + + // 打开网络流或文件流 + if (avformat_open_input(&pFormatCtx, server, NULL, &options) != 0) + { + printf("Couldn't open input stream.\n"); + return 0; + } + + // 获取视频文件信息 + if (avformat_find_stream_info(pFormatCtx, NULL) < 0) + { + printf("Couldn't find stream information.\n"); + return 0; + } + + // 查找码流中是否有视频流 + int videoindex = -1; + unsigned i = 0; + for (i = 0; i < pFormatCtx->nb_streams; i++) + if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) + { + videoindex = i; + break; + } + if (videoindex == -1) + { + printf("Didn't find a video stream.\n"); + return 0; + } + + av_packet = (AVPacket *)av_malloc(sizeof(AVPacket)); // 申请空间,存放的每一帧数据 (h264、h265) + + //// 初始化 + MPP_RET ret2 = MPP_OK; + size_t file_size = 0; + + // base flow context + MppCtx ctx = NULL; + MppApi *mpi = NULL; + + // input / output + MppPacket packet = NULL; + MppFrame frame = NULL; + + MpiCmd mpi_cmd = MPP_CMD_BASE; + MppParam param = NULL; + RK_U32 need_split = 1; + // MppPollType timeout = 5; + + // paramter for resource malloc + // RK_U32 width = 2560; + // RK_U32 height = 1440; + RK_U32 width = 1080; + RK_U32 height = 768; + MppCodingType type = MPP_VIDEO_CodingAVC; + + // resources + char *buf = NULL; + size_t packet_size = 8 * 1024 * 1024; + MppBuffer pkt_buf = NULL; + MppBuffer frm_buf = NULL; + + MpiDecLoopData data; + + mpp_log("mpi_dec_test start\n"); + memset(&data, 0, sizeof(data)); + + /* + data.fp_output = fopen("./tenoutput.yuv", "w+"); + if (NULL == data.fp_output) { + mpp_err("failed to open output file %s\n", "tenoutput.yuv"); + deInit(&packet, &frame, ctx, buf, data); + } + */ + + mpp_log("mpi_dec_test decoder test start w %d h %d type %d\n", width, height, type); + + // decoder demo + ret2 = mpp_create(&ctx, &mpi); + + if (MPP_OK != ret2) + { + mpp_err("mpp_create failed\n"); + deInit(&packet, &frame, ctx, buf, data); + } + + // NOTE: decoder split mode need to be set before init + mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE; + param = &need_split; + ret2 = mpi->control(ctx, mpi_cmd, param); + if (MPP_OK != ret2) + { + mpp_err("mpi->control failed\n"); + deInit(&packet, &frame, ctx, buf, data); + } + + mpi_cmd = MPP_SET_INPUT_BLOCK; + param = &need_split; + ret2 = mpi->control(ctx, mpi_cmd, param); + if (MPP_OK != ret2) + { + mpp_err("mpi->control failed\n"); + deInit(&packet, &frame, ctx, buf, data); + } + + ret2 = mpp_init(ctx, MPP_CTX_DEC, type); + if (MPP_OK != ret2) + { + mpp_err("mpp_init failed\n"); + deInit(&packet, &frame, ctx, buf, data); + } + + data.ctx = ctx; + data.mpi = mpi; + data.eos = 0; + data.packet_size = packet_size; + data.frame = frame; + data.frame_count = 0; + + int count = 0; + + current_time_gap_t gap; + char outfilename[128]; + + get_current_time_gap(&gap); + time_t next = gap.next_gap; + + snprintf(outfilename, 128, "/usr/data/camera/%s/%ld.h264", CameraID, convert_time_to_name(gap.now_gap)); + + FILE *fpSave = fopen(outfilename, "ab"); + + int errorcount = 0; + + // 这边可以调整i的大小来改变文件中的视频时间,每 +1 就是一帧数据 + + struct timeval tpend1, tpend2; + long usec1 = 0; + gettimeofday(&tpend1, NULL); + + for (;;) + { + if (errorcount > 50) + { + printf("error count expires 50(%d), exitting...\n", errorcount); + break; + } + // printf("try reading...\n"); + if (av_read_frame(pFormatCtx, av_packet) >= 0) + { + printf("errorcount set to 0"); + errorcount = 0; + if (av_packet->stream_index == videoindex) + { + // mpp_log("--------------\ndata size is: %d\n-------------", av_packet->size); + + count++; + printf("handling [%d]th frame\n", count); + decode_simple(&data, av_packet); + + if (fpSave != NULL) + { + fwrite(av_packet->data, av_packet->size, 1, fpSave); + time_t now = time(NULL); + if (now >= next) + { + fclose(fpSave); + get_current_time_gap(&gap); + next = gap.next_gap; + + snprintf(outfilename, 128, "/usr/data/camera/%s/%ld.h264", CameraID, convert_time_to_name(gap.now_gap)); + // snprintf(outfilename, 20, "%ld.h264", convert_time_to_name(gap.now_gap)); + FILE *fpSave = fopen(outfilename, "ab"); + } + } + } + if (av_packet != NULL) + av_packet_unref(av_packet); + // mpp_log("%d", i); + } + else + { + errorcount++; + } + } + + printf("max time elapsed: %f\n", (float)max_time_elapsed / CLOCKS_PER_SEC * 1000); + // fclose(fpSave); + deInit(&packet, &frame, ctx, buf, data); + av_free(av_packet); + avformat_close_input(&pFormatCtx); + printf("done\n"); + + deinit_post_process(); + + release_yolov5_model(&rknn_app_ctx); +} diff --git a/mpp/inc/dictionary.h b/mpp/inc/dictionary.h new file mode 100755 index 0000000..d04b6ce --- /dev/null +++ b/mpp/inc/dictionary.h @@ -0,0 +1,173 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file dictionary.h + @author N. Devillard + @brief Implements a dictionary for string variables. + + This module implements a simple dictionary object, i.e. a list + of string/string associations. This object is useful to store e.g. + informations retrieved from a configuration file (ini files). +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _DICTIONARY_H_ +#define _DICTIONARY_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + New types + ---------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dictionary object + + This object contains a list of string/string associations. Each + association is identified by a unique string key. Looking up values + in the dictionary is speeded up by the use of a (hopefully collision-free) + hash function. + */ +/*-------------------------------------------------------------------------*/ +typedef struct _dictionary_ { + int n ; /** Number of entries in dictionary */ + ssize_t size ; /** Storage size */ + char ** val ; /** List of string values */ + char ** key ; /** List of string keys */ + unsigned * hash ; /** List of hash values for keys */ +} dictionary ; + + +/*--------------------------------------------------------------------------- + Function prototypes + ---------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ +/** + @brief Compute the hash key for a string. + @param key Character string to use for key. + @return 1 unsigned int on at least 32 bits. + + This hash function has been taken from an Article in Dr Dobbs Journal. + This is normally a collision-free function, distributing keys evenly. + The key is stored anyway in the struct so that collision can be avoided + by comparing the key itself in last resort. + */ +/*--------------------------------------------------------------------------*/ +unsigned dictionary_hash(const char * key); + +/*-------------------------------------------------------------------------*/ +/** + @brief Create a new dictionary object. + @param size Optional initial size of the dictionary. + @return 1 newly allocated dictionary objet. + + This function allocates a new dictionary object of given size and returns + it. If you do not know in advance (roughly) the number of entries in the + dictionary, give size=0. + */ +/*--------------------------------------------------------------------------*/ +dictionary * dictionary_new(size_t size); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a dictionary object + @param d dictionary object to deallocate. + @return void + + Deallocate a dictionary object and all memory associated to it. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_del(dictionary * vd); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get a value from a dictionary. + @param d dictionary object to search. + @param key Key to look for in the dictionary. + @param def Default value to return if key not found. + @return 1 pointer to internally allocated character string. + + This function locates a key in a dictionary and returns a pointer to its + value, or the passed 'def' pointer if no such key can be found in + dictionary. The returned character pointer points to data internal to the + dictionary object, you should not try to free it or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char * dictionary_get(const dictionary * d, const char * key, const char * def); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set a value in a dictionary. + @param d dictionary object to modify. + @param key Key to modify or add. + @param val Value to add. + @return int 0 if Ok, anything else otherwise + + If the given key is found in the dictionary, the associated value is + replaced by the provided one. If the key cannot be found in the + dictionary, it is added to it. + + It is Ok to provide a NULL value for val, but NULL values for the dictionary + or the key are considered as errors: the function will return immediately + in such a case. + + Notice that if you dictionary_set a variable to NULL, a call to + dictionary_get will return a NULL value: the variable will be found, and + its value (NULL) is returned. In other words, setting the variable + content to NULL is equivalent to deleting the variable from the + dictionary. It is not possible (in this implementation) to have a key in + the dictionary without value. + + This function returns non-zero in case of failure. + */ +/*--------------------------------------------------------------------------*/ +int dictionary_set(dictionary * vd, const char * key, const char * val); + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete a key in a dictionary + @param d dictionary object to modify. + @param key Key to remove. + @return void + + This function deletes a key in a dictionary. Nothing is done if the + key cannot be found. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_unset(dictionary * d, const char * key); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump + @param f Opened file pointer. + @return void + + Dumps a dictionary onto an opened file pointer. Key pairs are printed out + as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as + output file pointers. + */ +/*--------------------------------------------------------------------------*/ +void dictionary_dump(const dictionary * d, FILE * out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpp/inc/iniparser.h b/mpp/inc/iniparser.h new file mode 100755 index 0000000..37ff7b7 --- /dev/null +++ b/mpp/inc/iniparser.h @@ -0,0 +1,358 @@ + +/*-------------------------------------------------------------------------*/ +/** + @file iniparser.h + @author N. Devillard + @brief Parser for ini files. +*/ +/*--------------------------------------------------------------------------*/ + +#ifndef _INIPARSER_H_ +#define _INIPARSER_H_ + +/*--------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------*/ + +#include +#include +#include + +/* + * The following #include is necessary on many Unixes but not Linux. + * It is not needed for Windows platforms. + * Uncomment it if needed. + */ +/* #include */ + +#include "dictionary.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------*/ +/** + @brief Configure a function to receive the error messages. + @param errback Function to call. + + By default, the error will be printed on stderr. If a null pointer is passed + as errback the error callback will be switched back to default. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_set_error_callback(int (*errback)(const char *, ...)); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get number of sections in a dictionary + @param d Dictionary to examine + @return int Number of sections found in dictionary + + This function returns the number of sections found in a dictionary. + The test to recognize sections is done on the string stored in the + dictionary: a section name is given as "section" whereas a key is + stored as "section:key", thus the test looks for entries that do not + contain a colon. + + This clearly fails in the case a section name contains a colon, but + this should simply be avoided. + + This function returns -1 in case of error. + */ +/*--------------------------------------------------------------------------*/ + +int iniparser_getnsec(const dictionary * d); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get name for section n in a dictionary. + @param d Dictionary to examine + @param n Section number (from 0 to nsec-1). + @return Pointer to char string + + This function locates the n-th section in a dictionary and returns + its name as a pointer to a string statically allocated inside the + dictionary. Do not free or modify the returned string! + + This function returns NULL in case of error. + */ +/*--------------------------------------------------------------------------*/ + +const char * iniparser_getsecname(const dictionary * d, int n); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary to a loadable ini file + @param d Dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given dictionary into a loadable ini file. + It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dump_ini(const dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Save a dictionary section to a loadable ini file + @param d Dictionary to dump + @param s Section name of dictionary to dump + @param f Opened file pointer to dump to + @return void + + This function dumps a given section of a given dictionary into a loadable ini + file. It is Ok to specify @c stderr or @c stdout as output files. + */ +/*--------------------------------------------------------------------------*/ + +void iniparser_dumpsection_ini(const dictionary * d, const char * s, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Dump a dictionary to an opened file pointer. + @param d Dictionary to dump. + @param f Opened file pointer to dump to. + @return void + + This function prints out the contents of a dictionary, one element by + line, onto the provided file pointer. It is OK to specify @c stderr + or @c stdout as output files. This function is meant for debugging + purposes mostly. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_dump(const dictionary * d, FILE * f); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @return Number of keys in section + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getsecnkeys(const dictionary * d, const char * s); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the number of keys in a section of a dictionary. + @param d Dictionary to examine + @param s Section name of dictionary to examine + @param keys Already allocated array to store the keys in + @return The pointer passed as `keys` argument or NULL in case of error + + This function queries a dictionary and finds all keys in a given section. + The keys argument should be an array of pointers which size has been + determined by calling `iniparser_getsecnkeys` function prior to this one. + + Each pointer in the returned char pointer-to-pointer is pointing to + a string allocated in the dictionary; do not free or modify them. + */ +/*--------------------------------------------------------------------------*/ +const char ** iniparser_getseckeys(const dictionary * d, const char * s, const char ** keys); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key + @param d Dictionary to search + @param key Key string to look for + @param def Default value to return if key not found. + @return pointer to statically allocated character string + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the pointer passed as 'def' is returned. + The returned char pointer is pointing to a string allocated in + the dictionary, do not free or modify it. + */ +/*--------------------------------------------------------------------------*/ +const char * iniparser_getstring(const dictionary * d, const char * key, const char * def); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(const dictionary * d, const char * key, int notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an long int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + */ +/*--------------------------------------------------------------------------*/ +long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a double + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return double + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + */ +/*--------------------------------------------------------------------------*/ +double iniparser_getdouble(const dictionary * d, const char * key, double notfound); + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to a boolean + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + A true boolean is found if one of the following is matched: + + - A string starting with 'y' + - A string starting with 'Y' + - A string starting with 't' + - A string starting with 'T' + - A string starting with '1' + + A false boolean is found if one of the following is matched: + + - A string starting with 'n' + - A string starting with 'N' + - A string starting with 'f' + - A string starting with 'F' + - A string starting with '0' + + The notfound value returned if no boolean is identified, does not + necessarily have to be 0 or 1. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getboolean(const dictionary * d, const char * key, int notfound); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Set an entry in a dictionary. + @param ini Dictionary to modify. + @param entry Entry to modify (entry name) + @param val New value to associate to the entry. + @return int 0 if Ok, -1 otherwise. + + If the given entry can be found in the dictionary, it is modified to + contain the provided value. If it cannot be found, the entry is created. + It is Ok to set val to NULL. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_set(dictionary * ini, const char * entry, const char * val); + + +/*-------------------------------------------------------------------------*/ +/** + @brief Delete an entry in a dictionary + @param ini Dictionary to modify + @param entry Entry to delete (entry name) + @return void + + If the given entry can be found, it is deleted from the dictionary. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_unset(dictionary * ini, const char * entry); + +/*-------------------------------------------------------------------------*/ +/** + @brief Finds out if a given entry exists in a dictionary + @param ini Dictionary to search + @param entry Name of the entry to look for + @return integer 1 if entry exists, 0 otherwise + + Finds out if a given entry exists in the dictionary. Since sections + are stored as keys with NULL associated values, this is the only way + of querying for the presence of sections in a dictionary. + */ +/*--------------------------------------------------------------------------*/ +int iniparser_find_entry(const dictionary * ini, const char * entry) ; + +/*-------------------------------------------------------------------------*/ +/** + @brief Parse an ini file and return an allocated dictionary object + @param ininame Name of the ini file to read. + @return Pointer to newly allocated dictionary + + This is the parser for ini files. This function is called, providing + the name of the file to be read. It returns a dictionary object that + should not be accessed directly, but through accessor functions + instead. + + The returned dictionary must be freed using iniparser_freedict(). + */ +/*--------------------------------------------------------------------------*/ +dictionary * iniparser_load(const char * ininame); + +/*-------------------------------------------------------------------------*/ +/** + @brief Free all memory associated to an ini dictionary + @param d Dictionary to free + @return void + + Free all memory associated to an ini dictionary. + It is mandatory to call this function before the dictionary object + gets out of the current context. + */ +/*--------------------------------------------------------------------------*/ +void iniparser_freedict(dictionary * d); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpp/inc/mpi_enc_utils.h b/mpp/inc/mpi_enc_utils.h new file mode 100755 index 0000000..f811e13 --- /dev/null +++ b/mpp/inc/mpi_enc_utils.h @@ -0,0 +1,71 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPI_ENC_UTILS_H__ +#define __MPI_ENC_UTILS_H__ + +#include + +#include "rk_venc_cmd.h" + +typedef struct MpiEncTestArgs_t { + char *file_input; + char *file_output; + MppCodingType type; + MppFrameFormat format; + RK_S32 num_frames; + RK_S32 loop_cnt; + + RK_S32 width; + RK_S32 height; + RK_S32 hor_stride; + RK_S32 ver_stride; + + RK_S32 bps_target; + RK_S32 fps_in_flex; + RK_S32 fps_in_num; + RK_S32 fps_in_den; + RK_S32 fps_out_flex; + RK_S32 fps_out_num; + RK_S32 fps_out_den; + + RK_S32 gop_mode; + + MppEncHeaderMode header_mode; + + MppEncSliceSplit split; +} MpiEncTestArgs; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpi_enc_gen_gop_ref(MppEncGopRef *ref, RK_S32 gop_mode); +MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBuffer osd_buf, RK_U32 frame_cnt); +MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 *table); + +MpiEncTestArgs *mpi_enc_test_cmd_get(void); +MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **argv); +MPP_RET mpi_enc_test_cmd_put(MpiEncTestArgs* cmd); + +MPP_RET mpi_enc_test_cmd_show_opt(MpiEncTestArgs* cmd); +void mpi_enc_test_help(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPI_ENC_UTILS_H__*/ diff --git a/mpp/inc/mpi_impl.h b/mpp/inc/mpi_impl.h new file mode 100755 index 0000000..3e93a4f --- /dev/null +++ b/mpp/inc/mpi_impl.h @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPI_IMPL_H__ +#define __MPI_IMPL_H__ + +#include "mpp.h" + +#define MPI_DBG_FUNCTION (0x00000001) + +#define mpi_dbg(flag, fmt, ...) _mpp_dbg(mpi_debug, flag, fmt, ## __VA_ARGS__) +#define mpi_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpi_debug, flag, fmt, ## __VA_ARGS__) + +#define mpi_dbg_func(fmt, ...) mpi_dbg_f(MPI_DBG_FUNCTION, fmt, ## __VA_ARGS__) + +typedef struct MpiImpl_t MpiImpl; + +struct MpiImpl_t { + MpiImpl *check; + MppCtxType type; + MppCodingType coding; + + MppApi *api; + Mpp *ctx; +}; + +extern RK_U32 mpi_debug; + +#endif /*__MPI_IMPL_H__*/ diff --git a/mpp/inc/mpp.h b/mpp/inc/mpp.h new file mode 100755 index 0000000..3221035 --- /dev/null +++ b/mpp/inc/mpp.h @@ -0,0 +1,195 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_H__ +#define __MPP_H__ + +#include "mpp_queue.h" +#include "mpp_task_impl.h" + +#include "mpp_dec.h" +#include "mpp_enc.h" +#include "mpp_impl.h" + +#define MPP_DBG_FUNCTION (0x00000001) +#define MPP_DBG_PACKET (0x00000002) +#define MPP_DBG_FRAME (0x00000004) +#define MPP_DBG_BUFFER (0x00000008) + +/* + * mpp notify event flags + * When event happens mpp will signal deocder / encoder with different flag. + * These event will wake up the codec thread or hal thread + */ +#define MPP_INPUT_ENQUEUE (0x00000001) +#define MPP_OUTPUT_DEQUEUE (0x00000002) +#define MPP_INPUT_DEQUEUE (0x00000004) +#define MPP_OUTPUT_ENQUEUE (0x00000008) +#define MPP_RESET (0xFFFFFFFF) + +/* mpp dec event flags */ +#define MPP_DEC_NOTIFY_PACKET_ENQUEUE (MPP_INPUT_ENQUEUE) +#define MPP_DEC_NOTIFY_FRAME_DEQUEUE (MPP_OUTPUT_DEQUEUE) +#define MPP_DEC_NOTIFY_EXT_BUF_GRP_READY (0x00000010) +#define MPP_DEC_NOTIFY_INFO_CHG_DONE (0x00000020) +#define MPP_DEC_NOTIFY_BUFFER_VALID (0x00000040) +#define MPP_DEC_NOTIFY_TASK_ALL_DONE (0x00000080) +#define MPP_DEC_NOTIFY_TASK_HND_VALID (0x00000100) +#define MPP_DEC_NOTIFY_TASK_PREV_DONE (0x00000200) +#define MPP_DEC_NOTIFY_BUFFER_MATCH (0x00000400) +#define MPP_DEC_RESET (MPP_RESET) + +/* mpp enc event flags */ +#define MPP_ENC_NOTIFY_FRAME_ENQUEUE (MPP_INPUT_ENQUEUE) +#define MPP_ENC_NOTIFY_PACKET_DEQUEUE (MPP_OUTPUT_DEQUEUE) +#define MPP_ENC_NOTIFY_FRAME_DEQUEUE (MPP_INPUT_DEQUEUE) +#define MPP_ENC_NOTIFY_PACKET_ENQUEUE (MPP_OUTPUT_ENQUEUE) +#define MPP_ENC_CONTROL (0x00000010) +#define MPP_ENC_RESET (MPP_RESET) + +/* + * mpp hierarchy + * + * mpp layer create mpp_dec or mpp_dec instance + * mpp_dec create its parser and hal module + * mpp_enc create its control and hal module + * + * +-------+ + * | | + * +-------------+ mpp +-------------+ + * | | | | + * | +-------+ | + * | | + * | | + * | | + * +-----+-----+ +-----+-----+ + * | | | | + * +---+ mpp_dec +--+ +--+ mpp_enc +---+ + * | | | | | | | | + * | +-----------+ | | +-----------+ | + * | | | | + * | | | | + * | | | | + * +-------v------+ +-----v-----+ +-----v-----+ +------v-------+ + * | | | | | | | | + * | dec_parser | | dec_hal | | enc_hal | | enc_control | + * | | | | | | | | + * +--------------+ +-----------+ +-----------+ +--------------+ + */ + +#ifdef __cplusplus + +class Mpp +{ +public: + Mpp(); + ~Mpp(); + MPP_RET init(MppCtxType type, MppCodingType coding); + MPP_RET put_packet(MppPacket packet); + MPP_RET get_frame(MppFrame *frame); + + MPP_RET put_frame(MppFrame frame); + MPP_RET get_packet(MppPacket *packet); + + MPP_RET poll(MppPortType type, MppPollType timeout); + MPP_RET dequeue(MppPortType type, MppTask *task); + MPP_RET enqueue(MppPortType type, MppTask task); + + MPP_RET reset(); + MPP_RET control(MpiCmd cmd, MppParam param); + + MPP_RET notify(RK_U32 flag); + MPP_RET notify(MppBufferGroup group); + + mpp_list *mPackets; + mpp_list *mFrames; + mpp_list *mTimeStamps; + /* counters for debug */ + RK_U32 mPacketPutCount; + RK_U32 mPacketGetCount; + RK_U32 mFramePutCount; + RK_U32 mFrameGetCount; + RK_U32 mTaskPutCount; + RK_U32 mTaskGetCount; + + /* + * packet buffer group + * - packets in I/O, can be ion buffer or normal buffer + * frame buffer group + * - frames in I/O, normally should be a ion buffer group + */ + MppBufferGroup mPacketGroup; + MppBufferGroup mFrameGroup; + RK_U32 mExternalFrameGroup; + + /* + * Mpp task queue for advance task mode + */ + MppPort mInputPort; + MppPort mOutputPort; + + MppTaskQueue mInputTaskQueue; + MppTaskQueue mOutputTaskQueue; + + MppPollType mInputTimeout; + MppPollType mOutputTimeout; + + MppTask mInputTask; + + MppDec mDec; + MppEnc mEnc; + + RK_U32 mEncVersion; + +private: + void clear(); + + MppCtxType mType; + MppCodingType mCoding; + + RK_U32 mInitDone; + RK_U32 mMultiFrame; + + RK_U32 mStatus; + + /* decoder paramter before init */ + RK_U32 mParserFastMode; + RK_U32 mParserNeedSplit; + RK_U32 mParserInternalPts; /* for MPEG2/MPEG4 */ + + /* backup extra packet for seek */ + MppPacket mExtraPacket; + + /* dump info for debug */ + MppDump mDump; + + MPP_RET control_mpp(MpiCmd cmd, MppParam param); + MPP_RET control_osal(MpiCmd cmd, MppParam param); + MPP_RET control_codec(MpiCmd cmd, MppParam param); + MPP_RET control_dec(MpiCmd cmd, MppParam param); + MPP_RET control_enc(MpiCmd cmd, MppParam param); + MPP_RET control_isp(MpiCmd cmd, MppParam param); + + Mpp(const Mpp &); + Mpp &operator=(const Mpp &); +}; + + +extern "C" { +} +#endif + +#endif /*__MPP_H__*/ diff --git a/mpp/inc/mpp_2str.h b/mpp/inc/mpp_2str.h new file mode 100755 index 0000000..ac0bee7 --- /dev/null +++ b/mpp/inc/mpp_2str.h @@ -0,0 +1,34 @@ +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_2STR_H__ +#define __MPP_2STR_H__ + +#include "rk_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const char *strof_ctx_type(MppCtxType type); +const char *strof_coding_type(MppCodingType coding); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpp/inc/mpp_allocator.h b/mpp/inc/mpp_allocator.h new file mode 100755 index 0000000..18643f0 --- /dev/null +++ b/mpp/inc/mpp_allocator.h @@ -0,0 +1,55 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ALLOCATOR_H__ +#define __MPP_ALLOCATOR_H__ + +#include "rk_type.h" +#include "mpp_buffer.h" + +typedef void *MppAllocator; + +typedef struct MppAllocatorCfg_t { + // input + size_t alignment; + RK_U32 flags; +} MppAllocatorCfg; + +typedef struct MppAllocatorApi_t { + RK_U32 size; + RK_U32 version; + + MPP_RET (*alloc)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*free)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*import)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*release)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*mmap)(MppAllocator allocator, MppBufferInfo *data); +} MppAllocatorApi; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_allocator_get(MppAllocator *allocator, + MppAllocatorApi **api, MppBufferType type); +MPP_RET mpp_allocator_put(MppAllocator *allocator); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_ALLOCATOR_H__*/ + diff --git a/mpp/inc/mpp_bitput.h b/mpp/inc/mpp_bitput.h new file mode 100755 index 0000000..5dc05df --- /dev/null +++ b/mpp/inc/mpp_bitput.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BITPUT_H__ +#define __MPP_BITPUT_H__ + +#include +#include + +#include "rk_type.h" +#include "mpp_log.h" +#include "mpp_common.h" +#include "mpp_err.h" + +typedef struct bitput_ctx_t { + RK_U32 buflen; //!< max buf length, 64bit uint + RK_U32 index; //!< current uint position + RK_U64 *pbuf; //!< outpacket data + RK_U64 bvalue; //!< buffer value, 64 bit + RK_U8 bitpos; //!< bit pos in 64bit + RK_U32 size; //!< data size,except header +} BitputCtx_t; + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 mpp_set_bitput_ctx(BitputCtx_t *bp, RK_U64 *data, RK_U32 len); +void mpp_put_bits(BitputCtx_t *bp, RK_U64 invalue, RK_S32 lbits); +void mpp_put_align(BitputCtx_t *bp, RK_S32 align_bits, int flag); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpp/inc/mpp_bitread.h b/mpp/inc/mpp_bitread.h new file mode 100755 index 0000000..7ecef90 --- /dev/null +++ b/mpp/inc/mpp_bitread.h @@ -0,0 +1,167 @@ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef __MPP_BITREAD_H__ +#define __MPP_BITREAD_H__ + +#include +#include + +#include "mpp_log.h" +#include "mpp_common.h" +#include "mpp_err.h" + +#define __BITREAD_ERR __bitread_error + +#define READ_ONEBIT(bitctx, out)\ + do {\ + RK_S32 _out; \ + bitctx->ret = mpp_read_bits(bitctx, 1, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define READ_BITS(bitctx, num_bits, out)\ + do {\ + RK_S32 _out; \ + bitctx->ret = mpp_read_bits(bitctx, num_bits, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define READ_BITS_LONG(bitctx, num_bits, out)\ + do {\ + RK_U32 _out; \ + bitctx->ret = mpp_read_longbits(bitctx, num_bits, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define SHOW_BITS(bitctx, num_bits, out)\ + do {\ + RK_S32 _out; \ + bitctx->ret = mpp_show_bits(bitctx, num_bits, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define SHOW_BITS_LONG(bitctx, num_bits, out)\ + do {\ + RK_U32 _out; \ + bitctx->ret = mpp_show_longbits(bitctx, num_bits, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define SKIP_BITS(bitctx, num_bits)\ + do {\ + bitctx->ret = mpp_skip_bits(bitctx, num_bits); \ + if (bitctx->ret) { goto __BITREAD_ERR; }\ + } while (0) + +#define SKIP_BITS_LONG(bitctx, num_bits)\ + do {\ + bitctx->ret = mpp_skip_longbits(bitctx, num_bits); \ + if (bitctx->ret) { goto __BITREAD_ERR; }\ + } while (0) + +#define READ_UE(bitctx, out)\ + do {\ + RK_U32 _out; \ + bitctx->ret = mpp_read_ue(bitctx, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define READ_SE(bitctx, out)\ + do {\ + RK_S32 _out; \ + bitctx->ret = mpp_read_se(bitctx, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +typedef struct bitread_ctx_t { + // Pointer to the next unread (not in curr_byte_) byte in the stream. + RK_U8 *data_; + // Bytes left in the stream (without the curr_byte_). + RK_U32 bytes_left_; + // Contents of the current byte; first unread bit starting at position + // 8 - num_remaining_bits_in_curr_byte_ from MSB. + RK_S64 curr_byte_; + // Number of bits remaining in curr_byte_ + RK_S32 num_remaining_bits_in_curr_byte_; + // Used in emulation prevention three byte detection (see spec). + // Initially set to 0xffff to accept all initial two-byte sequences. + RK_S64 prev_two_bytes_; + // Number of emulation presentation bytes (0x000003) we met. + RK_S64 emulation_prevention_bytes_; + // count PPS SPS SEI read bits + RK_S32 used_bits; + RK_U8 *buf; + RK_S32 buf_len; + // ctx + MPP_RET ret; + RK_S32 need_prevention_detection; +} BitReadCtx_t; + + +#ifdef __cplusplus +extern "C" { +#endif + +//!< set bit read context +void mpp_set_bitread_ctx(BitReadCtx_t *bitctx, RK_U8 *data, RK_S32 size); + +//!< Read bits (1-31) +MPP_RET mpp_read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); + +//!< Read bits (1-32) +MPP_RET mpp_read_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); + +//!< Show bits (1-31) +MPP_RET mpp_show_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); + +//!< Show bits (1-32) +MPP_RET mpp_show_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); + +//!< skip bits(1-31) +MPP_RET mpp_skip_bits(BitReadCtx_t *bitctx, RK_S32 num_bits); + +//!< skip bits(1-32) +MPP_RET mpp_skip_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits); + +//!< read ue(1-32) +MPP_RET mpp_read_ue(BitReadCtx_t *bitctx, RK_U32* val); + +//!< read se(1-31) +MPP_RET mpp_read_se(BitReadCtx_t *bitctx, RK_S32* val); + +//!< set whether detect 0x03 (used in h264 and h265) +void mpp_set_pre_detection(BitReadCtx_t *bitctx); + +//!< check whether has more rbsp data(used in h264) +RK_U32 mpp_has_more_rbsp_data(BitReadCtx_t * bitctx); + +//!< align bits and get current pointer +RK_U8 *mpp_align_get_bits(BitReadCtx_t *bitctx); + +#ifdef __cplusplus +} +#endif + + +#endif /* __MPP_BITREAD_H__ */ diff --git a/mpp/inc/mpp_bitwrite.h b/mpp/inc/mpp_bitwrite.h new file mode 100755 index 0000000..26e4398 --- /dev/null +++ b/mpp/inc/mpp_bitwrite.h @@ -0,0 +1,67 @@ +/* + * Copyright 2015 - 2017 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BITWRITER_H__ +#define __MPP_BITWRITER_H__ + +#include "rk_type.h" +#include "mpp_err.h" + +/* + * Mpp bitstream writer for H.264/H.265 + */ +typedef struct MppWriteCtx_t { + RK_U8 *buffer; /* point to first byte of stream */ + RK_U8 *stream; /* Pointer to next byte of stream */ + RK_U32 size; /* Byte size of stream buffer */ + RK_U32 byte_cnt; /* Byte counter */ + RK_U32 byte_buffer; /* Byte buffer */ + RK_U32 buffered_bits; /* Amount of bits in byte buffer, [0-7] */ + RK_U32 zero_bytes; /* Amount of consecutive zero bytes */ + RK_S32 overflow; /* This will signal a buffer overflow */ + RK_U32 emul_cnt; /* Counter for emulation_3_byte, needed in SEI */ +} MppWriteCtx; + +MPP_RET mpp_writer_init(MppWriteCtx *ctx, void *p, RK_S32 size); +MPP_RET mpp_writer_reset(MppWriteCtx *ctx); + +/* check overflow status */ +MPP_RET mpp_writer_status(MppWriteCtx *ctx); + +/* write raw bit without emulation prevention 0x03 byte */ +void mpp_writer_put_raw_bits(MppWriteCtx *ctx, RK_S32 val, RK_S32 len); + +/* write bit with emulation prevention 0x03 byte */ +void mpp_writer_put_bits(MppWriteCtx *ctx, RK_S32 val, RK_S32 len); + +/* insert zero bits until byte-aligned */ +void mpp_writer_align_zero(MppWriteCtx *ctx); + +/* insert one bits until byte-aligned */ +void mpp_writer_align_one(MppWriteCtx *ctx); + +/* insert one bit then pad to byte-align with zero */ +void mpp_writer_trailing(MppWriteCtx * ctx); + +void mpp_writer_put_ue(MppWriteCtx *ctx, RK_U32 val); +void mpp_writer_put_se(MppWriteCtx *ctx, RK_S32 val); + +RK_S32 mpp_writer_bytes(MppWriteCtx *ctx); +RK_S32 mpp_writer_bits(MppWriteCtx *ctx); + +RK_S32 mpp_exp_golomb_signed(RK_S32 val); + +#endif /* __MPP_BITWRITER_H__ */ diff --git a/mpp/inc/mpp_buf_slot.h b/mpp/inc/mpp_buf_slot.h new file mode 100755 index 0000000..e773dfa --- /dev/null +++ b/mpp/inc/mpp_buf_slot.h @@ -0,0 +1,259 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BUF_SLOT_H__ +#define __MPP_BUF_SLOT_H__ + +#include "mpp_frame.h" + +/* + * mpp_dec will alloc 18 decoded picture buffer slot + * buffer slot is for transferring information between parser / mpp/ hal + * it represent the dpb routine in logical + * + * basic working flow: + * + * buf_slot parser hal + * + * + + + + * | | | + * | +--------+--------+ | + * | | | | + * | | do parsing here | | + * | | | | + * | +--------+--------+ | + * | | | + * | get_slot | | + * | <--------------------------+ | + * | get unused dpb slot for | | + * | current decoder output | | + * | | | + * | update dpb refer status | | + * | <--------------------------+ | + * | parser will send marking | | + * | operation to dpb slot | | + * | including: | | + * | ref/unref/output/display | | + * | | | + * | | | + * | | set buffer status to hal | + * +-------------------------------------------------------> | + * | | | + * | | +--------+--------+ + * | | | | + * | | | reg generation | + * | | | | + * | | +--------+--------+ + * | | | + * | | get buffer address info | + * | <-------------------------------------------------------+ + * | | used buffer index to get | + * | | physical address or iommu | + * | | address for hardware | + * | | | + * | | +--------+--------+ + * | | | | + * | | | set/wait hw | + * | | | | + * | | +--------+--------+ + * | | | + * | | update the output status | + * | <-------------------------------------------------------+ + * | | mark picture is available | + * | | for output and generate | + * | | output frame information | + * + + + + * + * typical buffer status transfer + * + * -> unused initial + * -> set_hw_dst by parser + * -> set_buffer by mpp - do alloc buffer here / info change here + * -> clr_hw_dst by hal() + * + * next four step can be different order + * -> set_dpb_ref by parser + * -> set_display by parser - slot ready to display, can be output + * -> clr_display by mpp - output buffer struct + * -> clr_dpb_ref by parser + * + * -> set_unused automatic clear and dec buffer ref + * + */ + +typedef void* MppBufSlots; + +/* + * buffer slot index range is 0~254, 0xff (255) will indicated the invalid index + */ +#define SLOT_IDX_BUTT (0xff) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * called by mpp context + * + * init / deinit - normal initialize and de-initialize function + * setup - called by parser when slot information changed + * is_changed - called by mpp to detect whether info change flow is needed + * ready - called by mpp when info changed is done + * + * typical info change flow: + * + * mpp_buf_slot_setup called in parser with changed equal to 1 + * mpp_buf_slot_is_changed called in mpp and found info change + * + * do info change outside + * + * mpp_buf_slot_ready called in mpp when info change is done + * + */ +MPP_RET mpp_buf_slot_init(MppBufSlots *slots); +MPP_RET mpp_buf_slot_deinit(MppBufSlots slots); +MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count); +RK_U32 mpp_buf_slot_is_changed(MppBufSlots slots); +MPP_RET mpp_buf_slot_ready(MppBufSlots slots); +size_t mpp_buf_slot_get_size(MppBufSlots slots); +/* + * called by parser + * + * mpp_buf_slot_get_unused + * - parser need a new slot for output, on field mode alloc one buffer for two field + * + * mpp_buf_slot_set_dpb_ref + * - mark a slot to be used as reference frame in dpb + * + * mpp_buf_slot_clr_dpb_ref + * - mark a slot to be unused as reference frame and remove from dpb + * + * mpp_buf_slot_set_hw_dst + * - mark a slot to be output destination buffer + * - NOTE: the frame information MUST be set here + * + * mpp_buf_slot_set_display + * - mark a slot to be can be display + * - NOTE: set display will generate a MppFrame for buffer slot internal usage + * for example store pts / buffer address, etc. + * + * mpp_buf_slot_inc_hw_ref + * - MUST be called once when one slot is used in hardware decoding as reference frame + * + * called by mpp + * + * mpp_buf_slot_get_hw_dst + * - mpp_dec need to get the output slot index to check buffer status + * + * mpp_buf_slot_clr_display + * - mark a slot has been send out to display + * - NOTE: will be called inside mpp_buf_slot_get_display + * + * called by hal + * + * mpp_buf_slot_clr_hw_dst + * - mark a slot's buffer is already decoded by hardware + * - NOTE: this call will clear used as output flag + * + * mpp_buf_slot_dec_hw_ref + * - when hal finished on hardware decoding it MUST be called once for each used slot + */ +MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index); + +/* + * mpp_buf_slot_set_buffer + * - called by dec thread when find a output index has not buffer + * + * mpp_buf_slot_get_buffer + * - called by hal module on register generation + * + * mpp_buf_slot_get_display + * - called by hal thread to output a display slot's frame info + * NOTE: get display will generate a new MppFrame for external mpp_frame_deinit call + * So that external mpp_frame_deinit will not release the MppFrame used in buf_slot + */ + +/* + * NOTE: + * buffer slot will be used both for frame and packet + * when buffer slot is used for packet management only inc_hw_ref and dec_hw_ref is used + */ + +typedef enum SlotUsageType_e { + SLOT_CODEC_READY, // bit flag for buffer is prepared by codec + SLOT_CODEC_USE, // bit flag for buffer is used as reference by codec + SLOT_HAL_INPUT, // counter for buffer is used as hardware input + SLOT_HAL_OUTPUT, // counter + bit flag for buffer is used as hardware output + SLOT_QUEUE_USE, // bit flag for buffer is hold in different queues + SLOT_USAGE_BUTT, +} SlotUsageType; + +MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); +MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); + +// TODO: can be extended here +typedef enum SlotQueueType_e { + QUEUE_OUTPUT, // queue for mpp output to user + QUEUE_DISPLAY, // queue for decoder output display + QUEUE_DEINTERLACE, // queue for deinterlace process + QUEUE_COLOR_CONVERT, // queue for color convertion process + QUEUE_BUTT, +} SlotQueueType; + +MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type); +MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type); + +typedef enum SlotPropType_e { + SLOT_EOS, + SLOT_FRAME, + SLOT_BUFFER, + SLOT_FRAME_PTR, + SLOT_PROP_BUTT, +} SlotPropType; + +MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); +MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); + +typedef enum SlotsPropType_e { + SLOTS_EOS, + SLOTS_NUMERATOR, // numerator of buffer size scale ratio + SLOTS_DENOMINATOR, // denominator of buffer size scale ratio + SLOTS_HOR_ALIGN, // input must be buf_align function pointer + SLOTS_VER_ALIGN, // input must be buf_align function pointer + SLOTS_LEN_ALIGN, + SLOTS_COUNT, + SLOTS_SIZE, + SLOTS_FRAME_INFO, + SLOTS_PROP_BUTT, +} SlotsPropType; + +typedef RK_U32 (*AlignFunc)(RK_U32 val); + +RK_U32 mpp_slots_is_empty(MppBufSlots slots, SlotQueueType type); +RK_S32 mpp_slots_get_used_count(MppBufSlots slots); +RK_S32 mpp_slots_get_unused_count(MppBufSlots slots); +MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val); +MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val); +MPP_RET mpp_buf_slot_reset(MppBufSlots slots, RK_S32 index); //rest slot status when info_change no ok + +// special one for generate default frame to slot at index and return pointer +MPP_RET mpp_buf_slot_default_info(MppBufSlots slots, RK_S32 index, void *val); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_BUF_SLOT_H__*/ diff --git a/mpp/inc/mpp_buffer.h b/mpp/inc/mpp_buffer.h new file mode 100755 index 0000000..f7d8905 --- /dev/null +++ b/mpp/inc/mpp_buffer.h @@ -0,0 +1,316 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BUFFER_H__ +#define __MPP_BUFFER_H__ + +#include "rk_type.h" +#include "mpp_err.h" + +/* + * MppBuffer module has several functions: + * + * 1. buffer get / put / reference management / external commit / get info. + * this part is the basic user interface for MppBuffer. + * + * function: + * + * mpp_buffer_get + * mpp_buffer_put + * mpp_buffer_inc_ref + * mpp_buffer_commit + * mpp_buffer_info_get + * + * 2. user buffer working flow control abstraction. + * buffer should attach to certain group, and buffer mode control the buffer usage flow. + * this part is also a part of user interface. + * + * function: + * + * mpp_buffer_group_get + * mpp_buffer_group_normal_get + * mpp_buffer_group_limit_get + * mpp_buffer_group_put + * mpp_buffer_group_limit_config + * + * 3. buffer allocator management + * this part is for allocator on different os, it does not have user interface + * it will support normal buffer, Android ion buffer, Linux v4l2 vb2 buffer + * user can only use MppBufferType to choose. + * + */ + +/* + * mpp buffer group support two work flow mode: + * + * normal flow: all buffer are generated by MPP + * under this mode, buffer pool is maintained internally + * + * typical call flow: + * + * mpp_buffer_group_get() return A + * mpp_buffer_get(A) return a ref +1 -> used + * mpp_buffer_inc_ref(a) ref +1 + * mpp_buffer_put(a) ref -1 + * mpp_buffer_put(a) ref -1 -> unused + * mpp_buffer_group_put(A) + * + * commit flow: all buffer are commited out of MPP + * under this mode, buffers is commit by external api. + * normally MPP only use it but not generate it. + * + * typical call flow: + * + * ==== external allocator ==== + * mpp_buffer_group_get() return A + * mpp_buffer_commit(A, x) + * mpp_buffer_commit(A, y) + * + * ======= internal user ====== + * mpp_buffer_get(A) return a + * mpp_buffer_get(A) return b + * mpp_buffer_put(a) + * mpp_buffer_put(b) + * + * ==== external allocator ==== + * mpp_buffer_group_put(A) + * + * NOTE: commit interface required group handle to record group information + */ + +/* + * mpp buffer group has two buffer limit mode: normal and limit + * + * normal mode: allows any buffer size and always general new buffer is no unused buffer + * is available. + * This mode normally use with normal flow and is used for table / stream buffer + * + * limit mode : restrict the buffer's size and count in the buffer group. if try to calloc + * buffer with different size or extra count it will fail. + * This mode normally use with commit flow and is used for frame buffer + */ + +/* + * NOTE: normal mode is recommanded to work with normal flow, working with limit mode is not. + * limit mode is recommanded to work with commit flow, working with normal mode is not. + */ +typedef enum { + MPP_BUFFER_INTERNAL, + MPP_BUFFER_EXTERNAL, + MPP_BUFFER_MODE_BUTT, +} MppBufferMode; + +/* + * the mpp buffer has serval types: + * + * normal : normal malloc buffer for unit test or hardware simulation + * ion : use ion device under Android/Linux, MppBuffer will encapsulte ion file handle + * ext_dma : the DMABUF(DMA buffers) come from the application + * drm : use the drm device interface for memory management + */ +typedef enum { + MPP_BUFFER_TYPE_NORMAL, + MPP_BUFFER_TYPE_ION, + MPP_BUFFER_TYPE_EXT_DMA, + MPP_BUFFER_TYPE_DRM, + MPP_BUFFER_TYPE_BUTT, +} MppBufferType; + +#define MPP_BUFFER_TYPE_MASK 0x0000FFFF + +/* + * MPP_BUFFER_FLAGS cooperate with MppBufferType + * 16 high bits of MppBufferType are used in flags + * + * eg: + * DRM CMA buffer : MPP_BUFFER_TYPE_DRM | MPP_BUFFER_FLAGS_CONTIG + * = 0x00010003 + * DRM SECURE buffer: MPP_BUFFER_TYPE_DRM | MPP_BUFFER_FLAGS_SECURE + * = 0x00080003 + * + * flags originate from drm_rockchip_gem_mem_type + */ + +#define MPP_BUFFER_FLAGS_MASK 0x000f0000 //ROCKCHIP_BO_MASK << 16 +#define MPP_BUFFER_FLAGS_CONTIG 0x00010000 //ROCKCHIP_BO_CONTIG << 16 +#define MPP_BUFFER_FLAGS_CACHABLE 0x00020000 //ROCKCHIP_BO_CACHABLE << 16 +#define MPP_BUFFER_FLAGS_WC 0x00040000 //ROCKCHIP_BO_WC << 16 +#define MPP_BUFFER_FLAGS_SECURE 0x00080000 //ROCKCHIP_BO_SECURE << 16 + +/* + * MppBufferInfo variable's meaning is different in different MppBufferType + * + * Common + * index - the buffer index used to track buffer in buffer pool + * size - the buffer size + * + * MPP_BUFFER_TYPE_NORMAL + * + * ptr - virtual address of normal malloced buffer + * fd - unused and set to -1, the allocator would return its + * internal buffer counter number + * + * MPP_BUFFER_TYPE_ION + * + * ptr - virtual address of ion buffer in user space + * hnd - ion handle in user space + * fd - ion buffer file handle for map / unmap + * + */ +typedef struct MppBufferInfo_t { + MppBufferType type; + size_t size; + void *ptr; + void *hnd; + int fd; + int index; +} MppBufferInfo; + +#define BUFFER_GROUP_SIZE_DEFAULT (SZ_1M*80) + +/* + * mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer) + * + * 1. group - specified the MppBuffer to be attached to. + * group can be NULL then this buffer will attached to default legecy group + * Default to NULL on mpp_buffer_import case + * + * 2. info - input information for the output MppBuffer + * info can NOT be NULL. It must contain at least one of ptr/fd. + * + * 3. buffer - generated MppBuffer from MppBufferInfo. + * buffer can be NULL then the buffer is commit to group with unused status. + * Otherwise generated buffer will be directly got and ref_count increased. + * Default to NULL on mpp_buffer_commit case + * + * mpp_buffer_commit usage: + * + * Add a external buffer info to group. This buffer will be on unused status. + * Typical usage is on Android. MediaPlayer gralloc Graphic buffer then commit these buffer + * to decoder's buffer group. Then decoder will recycle these buffer and return buffer reference + * to MediaPlayer for display. + * + * mpp_buffer_import usage: + * + * Transfer a external buffer info to MppBuffer but it is not expected to attached to certain + * buffer group. So the group is set to NULL. Then this buffer can be used for MppFrame/MppPacket. + * Typical usage is for image processing. Image processing normally will be a oneshot operation + * It does not need complicated group management. But in other hand mpp still need to know the + * imported buffer is leak or not and trace its usage inside mpp process. So we attach this kind + * of buffer to default misc buffer group for management. + */ +#define mpp_buffer_commit(group, info) \ + mpp_buffer_import_with_tag(group, info, NULL, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_import(buffer, info) \ + mpp_buffer_import_with_tag(NULL, info, buffer, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_get(group, buffer, size) \ + mpp_buffer_get_with_tag(group, buffer, size, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_put(buffer) \ + mpp_buffer_put_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_inc_ref(buffer) \ + mpp_buffer_inc_ref_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_info_get(buffer, info) \ + mpp_buffer_info_get_with_caller(buffer, info, __FUNCTION__) + +#define mpp_buffer_read(buffer, offset, data, size) \ + mpp_buffer_read_with_caller(buffer, offset, data, size, __FUNCTION__) + +#define mpp_buffer_write(buffer, offset, data, size) \ + mpp_buffer_write_with_caller(buffer, offset, data, size, __FUNCTION__) + +#define mpp_buffer_get_ptr(buffer) \ + mpp_buffer_get_ptr_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_get_fd(buffer) \ + mpp_buffer_get_fd_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_get_size(buffer) \ + mpp_buffer_get_size_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_get_index(buffer) \ + mpp_buffer_get_index_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_set_index(buffer, index) \ + mpp_buffer_set_index_with_caller(buffer, index, __FUNCTION__) + +#define mpp_buffer_get_offset(buffer) \ + mpp_buffer_get_offset_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_set_offset(buffer, offset) \ + mpp_buffer_set_offset_with_caller(buffer, offset, __FUNCTION__) + +#define mpp_buffer_group_get_internal(group, type, ...) \ + mpp_buffer_group_get(group, type, MPP_BUFFER_INTERNAL, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_group_get_external(group, type, ...) \ + mpp_buffer_group_get(group, type, MPP_BUFFER_EXTERNAL, MODULE_TAG, __FUNCTION__) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MppBuffer interface + * these interface will change value of group and buffer so before calling functions + * parameter need to be checked. + * + * IMPORTANT: + * mpp_buffer_import_with_tag - compounded interface for commit and import + * + */ +MPP_RET mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer, + const char *tag, const char *caller); +MPP_RET mpp_buffer_get_with_tag(MppBufferGroup group, MppBuffer *buffer, size_t size, + const char *tag, const char *caller); +MPP_RET mpp_buffer_put_with_caller(MppBuffer buffer, const char *caller); +MPP_RET mpp_buffer_inc_ref_with_caller(MppBuffer buffer, const char *caller); + +MPP_RET mpp_buffer_info_get_with_caller(MppBuffer buffer, MppBufferInfo *info, const char *caller); +MPP_RET mpp_buffer_read_with_caller(MppBuffer buffer, size_t offset, void *data, size_t size, const char *caller); +MPP_RET mpp_buffer_write_with_caller(MppBuffer buffer, size_t offset, void *data, size_t size, const char *caller); +void *mpp_buffer_get_ptr_with_caller(MppBuffer buffer, const char *caller); +int mpp_buffer_get_fd_with_caller(MppBuffer buffer, const char *caller); +size_t mpp_buffer_get_size_with_caller(MppBuffer buffer, const char *caller); +int mpp_buffer_get_index_with_caller(MppBuffer buffer, const char *caller); +MPP_RET mpp_buffer_set_index_with_caller(MppBuffer buffer, int index, const char *caller); +size_t mpp_buffer_get_offset_with_caller(MppBuffer buffer, const char *caller); +MPP_RET mpp_buffer_set_offset_with_caller(MppBuffer buffer, size_t offset, const char *caller); + +MPP_RET mpp_buffer_group_get(MppBufferGroup *group, MppBufferType type, MppBufferMode mode, + const char *tag, const char *caller); +MPP_RET mpp_buffer_group_put(MppBufferGroup group); +MPP_RET mpp_buffer_group_clear(MppBufferGroup group); +RK_S32 mpp_buffer_group_unused(MppBufferGroup group); +size_t mpp_buffer_group_usage(MppBufferGroup group); +MppBufferMode mpp_buffer_group_mode(MppBufferGroup group); +MppBufferType mpp_buffer_group_type(MppBufferGroup group); + +/* + * size : 0 - no limit, other - max buffer size + * count : 0 - no limit, other - max buffer count + */ +MPP_RET mpp_buffer_group_limit_config(MppBufferGroup group, size_t size, RK_S32 count); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_BUFFER_H__*/ diff --git a/mpp/inc/mpp_buffer_impl.h b/mpp/inc/mpp_buffer_impl.h new file mode 100755 index 0000000..76b6fb4 --- /dev/null +++ b/mpp/inc/mpp_buffer_impl.h @@ -0,0 +1,163 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BUFFER_IMPL_H__ +#define __MPP_BUFFER_IMPL_H__ + +#include "mpp_list.h" +#include "mpp_common.h" +#include "mpp_allocator.h" + +#define MPP_BUF_DBG_FUNCTION (0x00000001) +#define MPP_BUF_DBG_OPS_RUNTIME (0x00000002) +#define MPP_BUF_DBG_OPS_HISTORY (0x00000004) +#define MPP_BUF_DBG_CLR_ON_EXIT (0x00000010) +#define MPP_BUF_DBG_DUMP_ON_EXIT (0x00000020) +#define MPP_BUF_DBG_CHECK_SIZE (0x00000100) + +#define mpp_buf_dbg(flag, fmt, ...) _mpp_dbg(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) +#define mpp_buf_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) + +#define MPP_BUF_FUNCTION_ENTER() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "enter\n") +#define MPP_BUF_FUNCTION_LEAVE() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "leave\n") +#define MPP_BUF_FUNCTION_LEAVE_OK() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "success\n") +#define MPP_BUF_FUNCTION_LEAVE_FAIL() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "failed\n") + +typedef struct MppBufferImpl_t MppBufferImpl; +typedef struct MppBufferGroupImpl_t MppBufferGroupImpl; +typedef void (*MppBufCallback)(void *, void *); + +// use index instead of pointer to avoid invalid pointer +struct MppBufferImpl_t { + char tag[MPP_TAG_SIZE]; + const char *caller; + RK_U32 group_id; + RK_S32 buffer_id; + MppBufferMode mode; + + MppBufferInfo info; + size_t offset; + + /* used for buf on group reset mode + set disard value to 1 when frame refcount no zero , + we will delay relesase buffer after refcount to zero, + not put this buf to unused list + */ + RK_S32 discard; + // used flag is for used/unused list detection + RK_U32 used; + RK_U32 internal; + RK_S32 ref_count; + struct list_head list_status; +}; + +struct MppBufferGroupImpl_t { + char tag[MPP_TAG_SIZE]; + const char *caller; + RK_U32 group_id; + MppBufferMode mode; + MppBufferType type; + // used in limit mode only + size_t limit_size; + RK_S32 limit_count; + // status record + size_t limit; + size_t usage; + RK_S32 buffer_id; + RK_S32 buffer_count; + RK_S32 count_used; + RK_S32 count_unused; + + MppAllocator allocator; + MppAllocatorApi *alloc_api; + + // thread that will be signal on buffer return + MppBufCallback callback; + void *arg; + + // buffer force clear mode flag + RK_U32 clear_on_exit; + // is_orphan: 0 - normal group 1 - orphan group + RK_U32 is_orphan; + + // buffer log function + RK_U32 log_runtime_en; + RK_U32 log_history_en; + RK_U32 log_count; + struct list_head list_logs; + + // link to the other MppBufferGroupImpl + struct list_head list_group; + + // link to list_status in MppBufferImpl + struct list_head list_used; + struct list_head list_unused; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern RK_U32 mpp_buffer_debug; + +/* + * mpp_buffer_create : create a unused buffer with parameter tag/size/data + * if input buffer is NULL then buffer will be register to unused list + * otherwise the buffer will be register to used list and set to paramter buffer + * + * mpp_buffer_mmap : The created mpp_buffer can not be accessed directly. + * It required map to access. This is an optimization + * for reducing virtual memory usage. + * + * mpp_buffer_get_unused : get unused buffer with size. it will first search + * the unused list. if failed it will create on from + * group allocator. + * + * mpp_buffer_ref_inc : increase buffer's reference counter. if it is unused + * then it will be moved to used list. + * + * mpp_buffer_ref_dec : decrease buffer's reference counter. if the reference + * reduce to zero buffer will be moved to unused list. + * + * normal call flow will be like this: + * + * mpp_buffer_create - create a unused buffer + * mpp_buffer_get_unused - get the unused buffer + * mpp_buffer_ref_inc/dec - use the buffer + * mpp_buffer_destory - destroy the buffer + */ +MPP_RET mpp_buffer_create(const char *tag, const char *caller, MppBufferGroupImpl *group, MppBufferInfo *info, MppBufferImpl **buffer); +MPP_RET mpp_buffer_mmap(MppBufferImpl *buffer, const char* caller); +MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller); +MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller); +MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size); +RK_U32 mpp_buffer_to_addr(MppBuffer buffer, size_t offset); + +MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); +MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p); +MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p); +MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p, + MppBufCallback callback, void *arg); +// mpp_buffer_group helper function +void mpp_buffer_group_dump(MppBufferGroupImpl *p); +void mpp_buffer_service_dump(); +MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_BUFFER_IMPL_H__*/ diff --git a/mpp/inc/mpp_common.h b/mpp/inc/mpp_common.h new file mode 100755 index 0000000..0aca15f --- /dev/null +++ b/mpp/inc/mpp_common.h @@ -0,0 +1,219 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_COMMON_H__ +#define __MPP_COMMON_H__ + +#include "rk_type.h" + +#define MPP_TAG_SIZE 32 + +#define MPP_ABS(x) ((x) < (0) ? -(x) : (x)) + +#define MPP_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MPP_MAX3(a, b, c) MPP_MAX(MPP_MAX(a,b),c) +#define MPP_MAX4(a, b, c, d) MPP_MAX((a), MPP_MAX3((b), (c), (d))) + +#define MPP_MIN(a,b) ((a) > (b) ? (b) : (a)) +#define MPP_MIN3(a,b,c) MPP_MIN(MPP_MIN(a,b),c) +#define MPP_MIN4(a, b, c, d) MPP_MIN((a), MPP_MIN3((b), (c), (d))) + +#define MPP_DIV(a, b) ((b) ? (a) / (b) : (a)) + +#define MPP_CLIP3(l, h, v) ((v) < (l) ? (l) : ((v) > (h) ? (h) : (v))) +#define MPP_SIGN(a) ((a) < (0) ? (-1) : (1)) +#define MPP_DIV_SIGN(a, b) (((a) + (MPP_SIGN(a) * (b)) / 2) / (b)) + +#define MPP_SWAP(type, a, b) do {type SWAP_tmp = b; b = a; a = SWAP_tmp;} while(0) +#define MPP_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#define MPP_ALIGN(x, a) (((x)+(a)-1)&~((a)-1)) +#define MPP_VSWAP(a, b) { a ^= b; b ^= a; a ^= b; } + +#define MPP_RB16(x) ((((const RK_U8*)(x))[0] << 8) | ((const RK_U8*)(x))[1]) +#define MPP_WB16(p, d) do { \ + ((RK_U8*)(p))[1] = (d); \ + ((RK_U8*)(p))[0] = (d)>>8; } while(0) + +#define MPP_RL16(x) ((((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[0]) +#define MPP_WL16(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; } while(0) + +#define MPP_RB32(x) ((((const RK_U8*)(x))[0] << 24) | \ + (((const RK_U8*)(x))[1] << 16) | \ + (((const RK_U8*)(x))[2] << 8) | \ + ((const RK_U8*)(x))[3]) +#define MPP_WB32(p, d) do { \ + ((RK_U8*)(p))[3] = (d); \ + ((RK_U8*)(p))[2] = (d)>>8; \ + ((RK_U8*)(p))[1] = (d)>>16; \ + ((RK_U8*)(p))[0] = (d)>>24; } while(0) + +#define MPP_RL32(x) ((((const RK_U8*)(x))[3] << 24) | \ + (((const RK_U8*)(x))[2] << 16) | \ + (((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[0]) +#define MPP_WL32(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[2] = (d)>>16; \ + ((RK_U8*)(p))[3] = (d)>>24; } while(0) + +#define MPP_RB64(x) (((RK_U64)((const RK_U8*)(x))[0] << 56) | \ + ((RK_U64)((const RK_U8*)(x))[1] << 48) | \ + ((RK_U64)((const RK_U8*)(x))[2] << 40) | \ + ((RK_U64)((const RK_U8*)(x))[3] << 32) | \ + ((RK_U64)((const RK_U8*)(x))[4] << 24) | \ + ((RK_U64)((const RK_U8*)(x))[5] << 16) | \ + ((RK_U64)((const RK_U8*)(x))[6] << 8) | \ + (RK_U64)((const RK_U8*)(x))[7]) +#define MPP_WB64(p, d) do { \ + ((RK_U8*)(p))[7] = (d); \ + ((RK_U8*)(p))[6] = (d)>>8; \ + ((RK_U8*)(p))[5] = (d)>>16; \ + ((RK_U8*)(p))[4] = (d)>>24; \ + ((RK_U8*)(p))[3] = (d)>>32; \ + ((RK_U8*)(p))[2] = (d)>>40; \ + ((RK_U8*)(p))[1] = (d)>>48; \ + ((RK_U8*)(p))[0] = (d)>>56; } while(0) + +#define MPP_RL64(x) (((RK_U64)((const RK_U8*)(x))[7] << 56) | \ + ((RK_U64)((const RK_U8*)(x))[6] << 48) | \ + ((RK_U64)((const RK_U8*)(x))[5] << 40) | \ + ((RK_U64)((const RK_U8*)(x))[4] << 32) | \ + ((RK_U64)((const RK_U8*)(x))[3] << 24) | \ + ((RK_U64)((const RK_U8*)(x))[2] << 16) | \ + ((RK_U64)((const RK_U8*)(x))[1] << 8) | \ + (RK_U64)((const RK_U8*)(x))[0]) +#define MPP_WL64(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[2] = (d)>>16; \ + ((RK_U8*)(p))[3] = (d)>>24; \ + ((RK_U8*)(p))[4] = (d)>>32; \ + ((RK_U8*)(p))[5] = (d)>>40; \ + ((RK_U8*)(p))[6] = (d)>>48; \ + ((RK_U8*)(p))[7] = (d)>>56; } while(0) + +#define MPP_RB24(x) ((((const RK_U8*)(x))[0] << 16) | \ + (((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[2]) +#define MPP_WB24(p, d) do { \ + ((RK_U8*)(p))[2] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[0] = (d)>>16; } while(0) + +#define MPP_RL24(x) ((((const RK_U8*)(x))[2] << 16) | \ + (((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[0]) + +#define MPP_WL24(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[2] = (d)>>16; } while(0) + +#include +#if defined(_WIN32) && !defined(__MINGW32CE__) +#define snprintf _snprintf +#define fseeko _fseeki64 + +#include +#include +#include +#define chdir _chdir +#define mkdir _mkdir +#define access _access +#define off_t _off_t + +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ + +#elif defined(__MINGW32CE__) +#define fseeko fseeko64 +#else +#include +#include +#include +#include +#define mkdir(x) mkdir(x, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) +#endif + +#define container_of(ptr, type, member) \ + ((type *)((char *)(ptr) - offsetof(type, member))) + +#define __RETURN __Return +#define __FAILED __failed + +#define ARG_T(t) t +#define ARG_N(a,b,c,d,N,...) N +#define ARG_N_HELPER(...) ARG_T(ARG_N(__VA_ARGS__)) +#define COUNT_ARG(...) ARG_N_HELPER(__VA_ARGS__,4,3,2,1,0) + +#define SZ_1K (1024) +#define SZ_2K (SZ_1K*2) +#define SZ_4K (SZ_1K*4) +#define SZ_8K (SZ_1K*8) +#define SZ_16K (SZ_1K*16) +#define SZ_32K (SZ_1K*32) +#define SZ_64K (SZ_1K*64) +#define SZ_128K (SZ_1K*128) +#define SZ_256K (SZ_1K*256) +#define SZ_512K (SZ_1K*512) +#define SZ_1M (SZ_1K*SZ_1K) +#define SZ_2M (SZ_1M*2) +#define SZ_4M (SZ_1M*4) +#define SZ_8M (SZ_1M*8) +#define SZ_16M (SZ_1M*16) +#define SZ_32M (SZ_1M*32) +#define SZ_64M (SZ_1M*64) +#define SZ_80M (SZ_1M*80) +#define SZ_128M (SZ_1M*128) + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 mpp_log2(RK_U32 v); +RK_S32 mpp_log2_16bit(RK_U32 v); + +static __inline RK_S32 mpp_ceil_log2(RK_S32 x) +{ + return mpp_log2((x - 1) << 1); +} + +static __inline RK_S32 mpp_clip(RK_S32 a, RK_S32 amin, RK_S32 amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +static __inline RK_U32 mpp_is_32bit() +{ + return ((sizeof(void *) == 4) ? (1) : (0)); +} + +RK_S32 axb_div_c(RK_S32 a, RK_S32 b, RK_S32 c); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_COMMON_H__*/ + diff --git a/mpp/inc/mpp_enc_cfg.h b/mpp/inc/mpp_enc_cfg.h new file mode 100755 index 0000000..e7e75d8 --- /dev/null +++ b/mpp/inc/mpp_enc_cfg.h @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ENC_CFG_H__ +#define __MPP_ENC_CFG_H__ + +#include "rk_venc_cmd.h" +#include "rc_data.h" + +/* + * MppEncCfgSet shows the relationship between different configuration + * Due to the huge amount of configurable parameters we need to setup + * only minimum amount of necessary parameters. + * + * For normal user rc and prep config are enough. + */ +typedef struct MppEncCfgSet_t { + // esential config + MppEncPrepCfg prep; + MppEncRcCfg rc; + + // codec detail config + MppEncCodecCfg codec; + + MppEncSliceSplit split; + MppEncGopRef gop_ref; + MppEncROICfg roi; + MppEncOSDPltCfg plt_cfg; + MppEncOSDPlt plt_data; +} MppEncCfgSet; + +#endif /*__MPP_ENC_H__*/ diff --git a/mpp/inc/mpp_env.h b/mpp/inc/mpp_env.h new file mode 100755 index 0000000..b2fb733 --- /dev/null +++ b/mpp/inc/mpp_env.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ENV_H__ +#define __MPP_ENV_H__ + +#include "rk_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 mpp_env_get_u32(const char *name, RK_U32 *value, RK_U32 default_value); +RK_S32 mpp_env_get_str(const char *name, const char **value, const char *default_value); + +RK_S32 mpp_env_set_u32(const char *name, RK_U32 value); +RK_S32 mpp_env_set_str(const char *name, char *value); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_ENV_H__*/ + diff --git a/mpp/inc/mpp_err.h b/mpp/inc/mpp_err.h new file mode 100755 index 0000000..469c681 --- /dev/null +++ b/mpp/inc/mpp_err.h @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ERR_H__ +#define __MPP_ERR_H__ + +#define RK_OK 0 +#define RK_SUCCESS 0 + +typedef enum { + MPP_SUCCESS = RK_SUCCESS, + MPP_OK = RK_OK, + + MPP_NOK = -1, + MPP_ERR_UNKNOW = -2, + MPP_ERR_NULL_PTR = -3, + MPP_ERR_MALLOC = -4, + MPP_ERR_OPEN_FILE = -5, + MPP_ERR_VALUE = -6, + MPP_ERR_READ_BIT = -7, + MPP_ERR_TIMEOUT = -8, + MPP_ERR_PERM = -9, + + MPP_ERR_BASE = -1000, + + /* The error in stream processing */ + MPP_ERR_LIST_STREAM = MPP_ERR_BASE - 1, + MPP_ERR_INIT = MPP_ERR_BASE - 2, + MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3, + MPP_ERR_STREAM = MPP_ERR_BASE - 4, + MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5, + MPP_ERR_NOMEM = MPP_ERR_BASE - 6, + MPP_ERR_PROTOL = MPP_ERR_BASE - 7, + MPP_FAIL_SPLIT_FRAME = MPP_ERR_BASE - 8, + MPP_ERR_VPUHW = MPP_ERR_BASE - 9, + MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11, + MPP_ERR_BUFFER_FULL = MPP_ERR_BASE - 12, + MPP_ERR_DISPLAY_FULL = MPP_ERR_BASE - 13, +} MPP_RET; + +#endif /*__MPP_ERR_H__*/ diff --git a/mpp/inc/mpp_frame.h b/mpp/inc/mpp_frame.h new file mode 100755 index 0000000..6e9034d --- /dev/null +++ b/mpp/inc/mpp_frame.h @@ -0,0 +1,327 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_FRAME_H__ +#define __MPP_FRAME_H__ + +#include "mpp_buffer.h" +#include "mpp_meta.h" + +/* + * bit definition for mode flag in MppFrame + */ +/* progressive frame */ +#define MPP_FRAME_FLAG_FRAME (0x00000000) +/* top field only */ +#define MPP_FRAME_FLAG_TOP_FIELD (0x00000001) +/* bottom field only */ +#define MPP_FRAME_FLAG_BOT_FIELD (0x00000002) +/* paired field */ +#define MPP_FRAME_FLAG_PAIRED_FIELD (MPP_FRAME_FLAG_TOP_FIELD|MPP_FRAME_FLAG_BOT_FIELD) +/* paired field with field order of top first */ +#define MPP_FRAME_FLAG_TOP_FIRST (0x00000004) +/* paired field with field order of bottom first */ +#define MPP_FRAME_FLAG_BOT_FIRST (0x00000008) +/* paired field with unknown field order (MBAFF) */ +#define MPP_FRAME_FLAG_DEINTERLACED (MPP_FRAME_FLAG_TOP_FIRST|MPP_FRAME_FLAG_BOT_FIRST) +#define MPP_FRAME_FLAG_FIELD_ORDER_MASK (0x0000000C) +// for multiview stream +#define MPP_FRAME_FLAG_VIEW_ID_MASK (0x000000f0) + +#define MPP_FRAME_FLAG_IEP_DEI_MASK (0x00000f00) +#define MPP_FRAME_FLAG_IEP_DEI_I2O1 (0x00000100) +#define MPP_FRAME_FLAG_IEP_DEI_I4O2 (0x00000200) +#define MPP_FRAME_FLAG_IEP_DEI_I4O1 (0x00000300) + +/* + * MPEG vs JPEG YUV range. + */ +typedef enum { + MPP_FRAME_RANGE_UNSPECIFIED = 0, + MPP_FRAME_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges + MPP_FRAME_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges + MPP_FRAME_RANGE_NB, ///< Not part of ABI +} MppFrameColorRange; + +/* + * Chromaticity coordinates of the source primaries. + */ +typedef enum { + MPP_FRAME_PRI_RESERVED0 = 0, + MPP_FRAME_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B + MPP_FRAME_PRI_UNSPECIFIED = 2, + MPP_FRAME_PRI_RESERVED = 3, + MPP_FRAME_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + + MPP_FRAME_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM + MPP_FRAME_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + MPP_FRAME_PRI_SMPTE240M = 7, ///< functionally identical to above + MPP_FRAME_PRI_FILM = 8, ///< colour filters using Illuminant C + MPP_FRAME_PRI_BT2020 = 9, ///< ITU-R BT2020 + MPP_FRAME_PRI_SMPTEST428_1 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ) + MPP_FRAME_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011) / DCI P3 + MPP_FRAME_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 (2010) / P3 D65 / Display P3 + MPP_FRAME_PRI_NB, ///< Not part of ABI +} MppFrameColorPrimaries; + +/* + * Color Transfer Characteristic. + */ +typedef enum { + MPP_FRAME_TRC_RESERVED0 = 0, + MPP_FRAME_TRC_BT709 = 1, ///< also ITU-R BT1361 + MPP_FRAME_TRC_UNSPECIFIED = 2, + MPP_FRAME_TRC_RESERVED = 3, + MPP_FRAME_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + MPP_FRAME_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG + MPP_FRAME_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC + MPP_FRAME_TRC_SMPTE240M = 7, + MPP_FRAME_TRC_LINEAR = 8, ///< "Linear transfer characteristics" + MPP_FRAME_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" + MPP_FRAME_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" + MPP_FRAME_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 + MPP_FRAME_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut + MPP_FRAME_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) + MPP_FRAME_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10 bit system + MPP_FRAME_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12 bit system + MPP_FRAME_TRC_SMPTEST2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems + MPP_FRAME_TRC_SMPTEST428_1 = 17, ///< SMPTE ST 428-1 + MPP_FRAME_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma" + MPP_FRAME_TRC_NB, ///< Not part of ABI +} MppFrameColorTransferCharacteristic; + +/* + * YUV colorspace type. + */ +typedef enum { + MPP_FRAME_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) + MPP_FRAME_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + MPP_FRAME_SPC_UNSPECIFIED = 2, + MPP_FRAME_SPC_RESERVED = 3, + MPP_FRAME_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + MPP_FRAME_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + MPP_FRAME_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above + MPP_FRAME_SPC_SMPTE240M = 7, + MPP_FRAME_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + MPP_FRAME_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system + MPP_FRAME_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system + MPP_FRAME_SPC_NB, ///< Not part of ABI +} MppFrameColorSpace; + +/* + * Location of chroma samples. + * + * Illustration showing the location of the first (top left) chroma sample of the + * image, the left shows only luma, the right + * shows the location of the chroma sample, the 2 could be imagined to overlay + * each other but are drawn separately due to limitations of ASCII + * + * 1st 2nd 1st 2nd horizontal luma sample positions + * v v v v + * ______ ______ + *1st luma line > |X X ... |3 4 X ... X are luma samples, + * | |1 2 1-6 are possible chroma positions + *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position + */ +typedef enum { + MPP_CHROMA_LOC_UNSPECIFIED = 0, + MPP_CHROMA_LOC_LEFT = 1, ///< mpeg2/4 4:2:0, h264 default for 4:2:0 + MPP_CHROMA_LOC_CENTER = 2, ///< mpeg1 4:2:0, jpeg 4:2:0, h263 4:2:0 + MPP_CHROMA_LOC_TOPLEFT = 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 + MPP_CHROMA_LOC_TOP = 4, + MPP_CHROMA_LOC_BOTTOMLEFT = 5, + MPP_CHROMA_LOC_BOTTOM = 6, + MPP_CHROMA_LOC_NB, ///< Not part of ABI +} MppFrameChromaLocation; + +#define MPP_FRAME_FMT_MASK (0x000fffff) + +#define MPP_FRAME_FMT_COLOR_MASK (0x000f0000) +#define MPP_FRAME_FMT_YUV (0x00000000) +#define MPP_FRAME_FMT_RGB (0x00010000) + +#define MPP_FRAME_FBC_MASK (0x00f00000) +#define MPP_FRAME_FBC_NONE (0x00000000) +#define MPP_FRAME_FBC_AFBC_V1 (0x00100000) + +#define MPP_FRAME_FMT_IS_YUV(fmt) (((fmt & MPP_FRAME_FMT_COLOR_MASK) == MPP_FRAME_FMT_YUV) && \ + ((fmt & MPP_FRAME_FMT_MASK) < MPP_FMT_YUV_BUTT)) +#define MPP_FRAME_FMT_IS_RGB(fmt) (((fmt & MPP_FRAME_FMT_COLOR_MASK) == MPP_FRAME_FMT_RGB) && \ + ((fmt & MPP_FRAME_FMT_MASK) < MPP_FMT_RGB_BUTT)) + +/* + * For MPP_FRAME_FBC_AFBC_V1 the 16byte aligned stride is used. + */ +#define MPP_FRAME_FMT_IS_FBC(fmt) (fmt & MPP_FRAME_FBC_MASK) + + +/* mpp color format index definition */ +typedef enum { + MPP_FMT_YUV420SP = MPP_FRAME_FMT_YUV, /* YYYY... UV... (NV12) */ + /* + * A rockchip specific pixel format, without gap between pixel aganist + * the P010_10LE/P010_10BE + */ + MPP_FMT_YUV420SP_10BIT, + MPP_FMT_YUV422SP, /* YYYY... UVUV... (NV16) */ + MPP_FMT_YUV422SP_10BIT, ///< Not part of ABI + MPP_FMT_YUV420P, /* YYYY... U...V... (I420) */ + MPP_FMT_YUV420SP_VU, /* YYYY... VUVUVU... (NV21) */ + MPP_FMT_YUV422P, /* YYYY... UU...VV...(422P) */ + MPP_FMT_YUV422SP_VU, /* YYYY... VUVUVU... (NV61) */ + MPP_FMT_YUV422_YUYV, /* YUYVYUYV... (YUY2) */ + MPP_FMT_YUV422_YVYU, /* YVYUYVYU... (YVY2) */ + MPP_FMT_YUV422_UYVY, /* UYVYUYVY... (UYVY) */ + MPP_FMT_YUV422_VYUY, /* VYUYVYUY... (VYUY) */ + MPP_FMT_YUV400, /* YYYY... */ + MPP_FMT_YUV440SP, /* YYYY... UVUV... */ + MPP_FMT_YUV411SP, /* YYYY... UV... */ + MPP_FMT_YUV444SP, /* YYYY... UVUVUVUV... */ + MPP_FMT_YUV_BUTT, + + MPP_FMT_RGB565 = MPP_FRAME_FMT_RGB, /* 16-bit RGB */ + MPP_FMT_BGR565, /* 16-bit RGB */ + MPP_FMT_RGB555, /* 15-bit RGB */ + MPP_FMT_BGR555, /* 15-bit RGB */ + MPP_FMT_RGB444, /* 12-bit RGB */ + MPP_FMT_BGR444, /* 12-bit RGB */ + MPP_FMT_RGB888, /* 24-bit RGB */ + MPP_FMT_BGR888, /* 24-bit RGB */ + MPP_FMT_RGB101010, /* 30-bit RGB */ + MPP_FMT_BGR101010, /* 30-bit RGB */ + MPP_FMT_ARGB8888, /* 32-bit RGB */ + MPP_FMT_ABGR8888, /* 32-bit RGB */ + MPP_FMT_BGRA8888, /* 32-bit RGB */ + MPP_FMT_RGBA8888, /* 32-bit RGB */ + MPP_FMT_RGB_BUTT, + + MPP_FMT_BUTT, +} MppFrameFormat; + +/** + * Rational number (pair of numerator and denominator). + */ +typedef struct MppFrameRational { + RK_S32 num; ///< Numerator + RK_S32 den; ///< Denominator +} MppFrameRational; + +typedef struct MppFrameMasteringDisplayMetadata { + RK_U16 display_primaries[3][2]; + RK_U16 white_point[2]; + RK_U32 max_luminance; + RK_U32 min_luminance; +} MppFrameMasteringDisplayMetadata; + +typedef struct MppFrameContentLightMetadata { + RK_U16 MaxCLL; + RK_U16 MaxFALL; +} MppFrameContentLightMetadata; + +typedef enum { + MPP_FRAME_ERR_UNKNOW = 0x0001, + MPP_FRAME_ERR_UNSUPPORT = 0x0002, +} MPP_FRAME_ERR; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MppFrame interface + */ +MPP_RET mpp_frame_init(MppFrame *frame); +MPP_RET mpp_frame_deinit(MppFrame *frame); +MppFrame mpp_frame_get_next(MppFrame frame); + +/* + * normal parameter + */ +RK_U32 mpp_frame_get_width(const MppFrame frame); +void mpp_frame_set_width(MppFrame frame, RK_U32 width); +RK_U32 mpp_frame_get_height(const MppFrame frame); +void mpp_frame_set_height(MppFrame frame, RK_U32 height); +RK_U32 mpp_frame_get_hor_stride(const MppFrame frame); +void mpp_frame_set_hor_stride(MppFrame frame, RK_U32 hor_stride); +RK_U32 mpp_frame_get_ver_stride(const MppFrame frame); +void mpp_frame_set_ver_stride(MppFrame frame, RK_U32 ver_stride); +RK_U32 mpp_frame_get_mode(const MppFrame frame); +void mpp_frame_set_mode(MppFrame frame, RK_U32 mode); +RK_U32 mpp_frame_get_discard(const MppFrame frame); +void mpp_frame_set_discard(MppFrame frame, RK_U32 discard); +RK_U32 mpp_frame_get_viewid(const MppFrame frame); +void mpp_frame_set_viewid(MppFrame frame, RK_U32 viewid); +RK_U32 mpp_frame_get_poc(const MppFrame frame); +void mpp_frame_set_poc(MppFrame frame, RK_U32 poc); +RK_S64 mpp_frame_get_pts(const MppFrame frame); +void mpp_frame_set_pts(MppFrame frame, RK_S64 pts); +RK_S64 mpp_frame_get_dts(const MppFrame frame); +void mpp_frame_set_dts(MppFrame frame, RK_S64 dts); +RK_U32 mpp_frame_get_errinfo(const MppFrame frame); +void mpp_frame_set_errinfo(MppFrame frame, RK_U32 errinfo); +size_t mpp_frame_get_buf_size(const MppFrame frame); +void mpp_frame_set_buf_size(MppFrame frame, size_t buf_size); +/* + * flow control parmeter + */ +RK_U32 mpp_frame_get_eos(const MppFrame frame); +void mpp_frame_set_eos(MppFrame frame, RK_U32 eos); +RK_U32 mpp_frame_get_info_change(const MppFrame frame); +void mpp_frame_set_info_change(MppFrame frame, RK_U32 info_change); + +/* + * buffer parameter + */ +MppBuffer mpp_frame_get_buffer(const MppFrame frame); +void mpp_frame_set_buffer(MppFrame frame, MppBuffer buffer); + +/* + * meta data parameter + */ +MppMeta mpp_frame_get_meta(const MppFrame frame); +void mpp_frame_set_meta(MppFrame frame, MppMeta meta); + +/* + * color related parameter + */ +MppFrameColorRange mpp_frame_get_color_range(const MppFrame frame); +void mpp_frame_set_color_range(MppFrame frame, MppFrameColorRange color_range); +MppFrameColorPrimaries mpp_frame_get_color_primaries(const MppFrame frame); +void mpp_frame_set_color_primaries(MppFrame frame, MppFrameColorPrimaries color_primaries); +MppFrameColorTransferCharacteristic mpp_frame_get_color_trc(const MppFrame frame); +void mpp_frame_set_color_trc(MppFrame frame, MppFrameColorTransferCharacteristic color_trc); +MppFrameColorSpace mpp_frame_get_colorspace(const MppFrame frame); +void mpp_frame_set_colorspace(MppFrame frame, MppFrameColorSpace colorspace); +MppFrameChromaLocation mpp_frame_get_chroma_location(const MppFrame frame); +void mpp_frame_set_chroma_location(MppFrame frame, MppFrameChromaLocation chroma_location); +MppFrameFormat mpp_frame_get_fmt(MppFrame frame); +void mpp_frame_set_fmt(MppFrame frame, MppFrameFormat fmt); +MppFrameRational mpp_frame_get_sar(const MppFrame frame); +void mpp_frame_set_sar(MppFrame frame, MppFrameRational sar); +MppFrameMasteringDisplayMetadata mpp_frame_get_mastering_display(const MppFrame frame); +void mpp_frame_set_mastering_display(MppFrame frame, MppFrameMasteringDisplayMetadata mastering_display); +MppFrameContentLightMetadata mpp_frame_get_content_light(const MppFrame frame); +void mpp_frame_set_content_light(MppFrame frame, MppFrameContentLightMetadata content_light); + +/* + * HDR parameter + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_FRAME_H__*/ diff --git a/mpp/inc/mpp_frame_impl.h b/mpp/inc/mpp_frame_impl.h new file mode 100755 index 0000000..0a7d9de --- /dev/null +++ b/mpp/inc/mpp_frame_impl.h @@ -0,0 +1,144 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_FRAME_IMPL_H__ +#define __MPP_FRAME_IMPL_H__ + +#include "mpp_frame.h" + +typedef struct MppFrameImpl_t MppFrameImpl; + +struct MppFrameImpl_t { + const char *name; + + /* + * dimension parameter for display + */ + RK_U32 width; + RK_U32 height; + RK_U32 hor_stride; + RK_U32 ver_stride; + + /* + * interlaced related mode status + * + * 0 - frame + * 1 - top field + * 2 - bottom field + * 3 - paired top and bottom field + * 4 - deinterlaced flag + * 7 - deinterlaced paired field + */ + RK_U32 mode; + /* + * current decoded frame whether to display + * + * 0 - reserve + * 1 - discard + */ + RK_U32 discard; + /* + * send decoded frame belong which view + */ + RK_U32 viewid; + /* + * poc - picture order count + */ + RK_U32 poc; + /* + * pts - display time stamp + * dts - decode time stamp + */ + RK_S64 pts; + RK_S64 dts; + + /* + * eos - end of stream + * info_change - set when buffer resized or frame infomation changed + */ + RK_U32 eos; + RK_U32 info_change; + RK_U32 errinfo; + MppFrameColorRange color_range; + MppFrameColorPrimaries color_primaries; + MppFrameColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * It must be accessed using av_frame_get_colorspace() and + * av_frame_set_colorspace(). + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + MppFrameColorSpace colorspace; + MppFrameChromaLocation chroma_location; + + MppFrameFormat fmt; + + MppFrameRational sar; + MppFrameMasteringDisplayMetadata mastering_display; + MppFrameContentLightMetadata content_light; + + /* + * buffer information + * NOTE: buf_size only access internally + */ + MppBuffer buffer; + size_t buf_size; + + /* + * meta data information + */ + MppMeta meta; + + /* + * frame buffer compression (FBC) information + * + * NOTE: some constraint on fbc data + * 1. FBC config need two addresses but only one buffer. + * The second address should be represented by base + offset form. + * 2. FBC has header address and payload address + * Both addresses should be 4K aligned. + * 3. The header section size is default defined by: + * header size = aligned(aligned(width, 16) * aligned(height, 16) / 16, 4096) + * 4. The stride in header section is defined by: + * stride = aligned(width, 16) + */ + RK_U32 fbc_offset; + + /* + * pointer for multiple frame output at one time + */ + MppFrameImpl *next; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_frame_set_next(MppFrame frame, MppFrame next); +MPP_RET mpp_frame_copy(MppFrame frame, MppFrame next); +MPP_RET mpp_frame_info_cmp(MppFrame frame0, MppFrame frame1); +RK_U32 mpp_frame_get_fbc_offset(MppFrame frame); +RK_U32 mpp_frame_get_fbc_stride(MppFrame frame); + +MPP_RET check_is_mpp_frame(void *pointer); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_FRAME_IMPL_H__*/ diff --git a/mpp/inc/mpp_impl.h b/mpp/inc/mpp_impl.h new file mode 100755 index 0000000..d7fa406 --- /dev/null +++ b/mpp/inc/mpp_impl.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_IMPL_H__ +#define __MPP_IMPL_H__ + +#include "rk_type.h" +#include "mpp_err.h" + +typedef void* MppDump; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_dump_init(MppDump *info); +MPP_RET mpp_dump_deinit(MppDump *info); + +MPP_RET mpp_ops_init(MppDump info, MppCtxType type, MppCodingType coding); + +MPP_RET mpp_ops_dec_put_pkt(MppDump info, MppPacket pkt); +MPP_RET mpp_ops_dec_get_frm(MppDump info, MppFrame frame); +MPP_RET mpp_ops_enc_put_frm(MppDump info, MppFrame frame); +MPP_RET mpp_ops_enc_get_pkt(MppDump info, MppPacket pkt); + +MPP_RET mpp_ops_ctrl(MppDump info, MpiCmd cmd); +MPP_RET mpp_ops_reset(MppDump info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpp/inc/mpp_info.h b/mpp/inc/mpp_info.h new file mode 100755 index 0000000..f719a88 --- /dev/null +++ b/mpp/inc/mpp_info.h @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_INFO_H__ +#define __MPP_INFO_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void show_mpp_version(void); +const char *get_mpp_version(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_INFO_H__*/ diff --git a/mpp/inc/mpp_list.h b/mpp/inc/mpp_list.h new file mode 100755 index 0000000..5ac8e0f --- /dev/null +++ b/mpp/inc/mpp_list.h @@ -0,0 +1,187 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_LIST_H__ +#define __MPP_LIST_H__ + +#include "rk_type.h" + +#include "mpp_thread.h" + +/* + * two list structures are defined, one for C++, the other for C + */ + +#ifdef __cplusplus + +// desctructor of list node +typedef void *(*node_destructor)(void *); + +struct mpp_list_node; +class mpp_list +{ +public: + mpp_list(node_destructor func = NULL); + ~mpp_list(); + + // for FIFO or FILO implement + // adding functions support simple structure like C struct or C++ class pointer, + // do not support C++ object + RK_S32 add_at_head(void *data, RK_S32 size); + RK_S32 add_at_tail(void *data, RK_S32 size); + // deleting function will copy the stored data to input pointer with size as size + // if NULL is passed to deleting functions, the node will be delete directly + RK_S32 del_at_head(void *data, RK_S32 size); + RK_S32 del_at_tail(void *data, RK_S32 size); + + // direct fifo operation + RK_S32 fifo_wr(void *data, RK_S32 size); + RK_S32 fifo_rd(void *data, RK_S32 *size); + + // for status check + RK_S32 list_is_empty(); + RK_S32 list_size(); + + // for vector implement - not implemented yet + // adding function will return a key + RK_S32 add_by_key(void *data, RK_S32 size, RK_U32 *key); + RK_S32 del_by_key(void *data, RK_S32 size, RK_U32 key); + RK_S32 show_by_key(void *data, RK_U32 key); + + RK_S32 flush(); + + // open lock function for external combination usage + void lock(); + void unlock(); + RK_S32 trylock(); + + // open lock function for external auto lock + Mutex *mutex(); + + void wait(); + RK_S32 wait(RK_S64 timeout); + void signal(); + +private: + Mutex mMutex; + Condition mCondition; + + node_destructor destroy; + struct mpp_list_node *head; + RK_S32 count; + static RK_U32 keys; + static RK_U32 get_key(); + + mpp_list(const mpp_list &); + mpp_list &operator=(const mpp_list &); +}; +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ + } while (0) + +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +/* + * due to typeof gcc extension list_for_each_entry and list_for_each_entry_safe + * can not be used on windows platform + * So we add a extra type parameter to the macro + */ +#define list_for_each_entry(pos, head, type, member) \ + for (pos = list_entry((head)->next, type, member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, type, member)) + +#define list_for_each_entry_safe(pos, n, head, type, member) \ + for (pos = list_entry((head)->next, type, member), \ + n = list_entry(pos->member.next, type, member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, type, member)) + +#define list_for_each_entry_reverse(pos, head, type, member) \ + for (pos = list_entry((head)->prev, type, member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, type, member)) + +static __inline void __list_add(struct list_head * _new, + struct list_head * prev, + struct list_head * next) +{ + next->prev = _new; + _new->next = next; + _new->prev = prev; + prev->next = _new; +} + +static __inline void list_add(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head, head->next); +} + +static __inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} + +static __inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +static __inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + + INIT_LIST_HEAD(entry); +} + +static __inline int list_is_last(const struct list_head *list, const struct list_head *head) +{ + return list->next == head; +} + +static __inline int list_empty(struct list_head *head) +{ + return head->next == head; +} + +#ifdef __cplusplus +} +#endif + + +#endif /*__MPP_LIST_H__*/ diff --git a/mpp/inc/mpp_log.h b/mpp/inc/mpp_log.h new file mode 100755 index 0000000..acd9c5e --- /dev/null +++ b/mpp/inc/mpp_log.h @@ -0,0 +1,134 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_LOG_H__ +#define __MPP_LOG_H__ + +#include +#include + +#include "rk_type.h" + +/* + * mpp runtime log system usage: + * mpp_err is for error status message, it will print for sure. + * mpp_log is for important message like open/close/reset/flush, it will print too. + * mpp_dbg is for all optional message. it can be controlled by debug and flag. + */ + +#define mpp_log(fmt, ...) _mpp_log(MODULE_TAG, fmt, NULL, ## __VA_ARGS__) +#define mpp_err(fmt, ...) _mpp_err(MODULE_TAG, fmt, NULL, ## __VA_ARGS__) + +#define _mpp_dbg(debug, flag, fmt, ...) \ + do { \ + if (debug & flag) \ + mpp_log(fmt, ## __VA_ARGS__); \ + } while (0) + +#define mpp_dbg(flag, fmt, ...) _mpp_dbg(mpp_debug, flag, fmt, ## __VA_ARGS__) + +/* + * _f function will add function name to the log + */ +#define mpp_log_f(fmt, ...) _mpp_log(MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) +#define mpp_err_f(fmt, ...) _mpp_err(MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) +#define _mpp_dbg_f(debug, flag, fmt, ...) \ + do { \ + if (debug & flag) \ + mpp_log_f(fmt, ## __VA_ARGS__); \ + } while (0) + +#define mpp_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_debug, flag, fmt, ## __VA_ARGS__) + + +#define MPP_DBG_TIMING (0x00000001) +#define MPP_DBG_PTS (0x00000002) +#define MPP_DBG_INFO (0x00000004) +#define MPP_DBG_PLATFORM (0x00000010) + +#define MPP_DBG_DUMP_LOG (0x00000100) +#define MPP_DBG_DUMP_IN (0x00000200) +#define MPP_DBG_DUMP_OUT (0x00000400) +#define MPP_DBG_DUMP_CFG (0x00000800) + +#define MPP_ABORT (0x10000000) + +/* + * mpp_dbg usage: + * + * in h264d module define module debug flag variable like: h265d_debug + * then define h265d_dbg macro as follow : + * + * extern RK_U32 h265d_debug; + * + * #define H265D_DBG_FUNCTION (0x00000001) + * #define H265D_DBG_VPS (0x00000002) + * #define H265D_DBG_SPS (0x00000004) + * #define H265D_DBG_PPS (0x00000008) + * #define H265D_DBG_SLICE_HDR (0x00000010) + * + * #define h265d_dbg(flag, fmt, ...) mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__) + * + * finally use environment control the debug flag + * + * mpp_get_env_u32("h264d_debug", &h265d_debug, 0) + * + */ +/* + * sub-module debug flag usage example: + * +------+-------------------+ + * | 8bit | 24bit | + * +------+-------------------+ + * 0~15 bit: software debug print + * 16~23 bit: hardware debug print + * 24~31 bit: information print format + */ + +#define mpp_abort() do { \ + if (mpp_debug & MPP_ABORT) { \ + abort(); \ + } \ +} while (0) + +#define MPP_STRINGS(x) MPP_TO_STRING(x) +#define MPP_TO_STRING(x) #x + +#define mpp_assert(cond) do { \ + if (!(cond)) { \ + mpp_err("Assertion %s failed at %s:%d\n", \ + MPP_STRINGS(cond), __FUNCTION__, __LINE__); \ + mpp_abort(); \ + } \ +} while (0) + + +#ifdef __cplusplus +extern "C" { +#endif + +extern RK_U32 mpp_debug; + +void mpp_log_set_flag(RK_U32 flag); +RK_U32 mpp_log_get_flag(void); + +void _mpp_log(const char *tag, const char *fmt, const char *func, ...); +void _mpp_err(const char *tag, const char *fmt, const char *func, ...); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_LOG_H__*/ diff --git a/mpp/inc/mpp_mem.h b/mpp/inc/mpp_mem.h new file mode 100755 index 0000000..f3551fb --- /dev/null +++ b/mpp/inc/mpp_mem.h @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_MEM_H__ +#define __MPP_MEM_H__ + +#include + +#include "rk_type.h" +#include "mpp_err.h" + +#define mpp_malloc_with_caller(type, count, caller) \ + (type*)mpp_osal_malloc(caller, sizeof(type) * (count)) + +#define mpp_malloc(type, count) \ + (type*)mpp_osal_malloc(__FUNCTION__, sizeof(type) * (count)) + +#define mpp_malloc_size(type, size) \ + (type*)mpp_osal_malloc(__FUNCTION__, size) + +#define mpp_calloc_size(type, size) \ + (type*)mpp_osal_calloc(__FUNCTION__, size) + +#define mpp_calloc(type, count) \ + (type*)mpp_osal_calloc(__FUNCTION__, sizeof(type) * (count)) + +#define mpp_realloc(ptr, type, count) \ + (type*)mpp_osal_realloc(__FUNCTION__, ptr, sizeof(type) * (count)) + +#define mpp_free(ptr) \ + mpp_osal_free(__FUNCTION__, ptr) + +#define MPP_FREE(ptr) do { if(ptr) mpp_free(ptr); ptr = NULL; } while (0) +#define MPP_FCLOSE(fp) do { if(fp) fclose(fp); fp = NULL; } while (0) + +#ifdef __cplusplus +extern "C" { +#endif + +void *mpp_osal_malloc(const char *caller, size_t size); +void *mpp_osal_calloc(const char *caller, size_t size); +void *mpp_osal_realloc(const char *caller, void *ptr, size_t size); +void mpp_osal_free(const char *caller, void *ptr); + +void mpp_show_mem_status(); + +/* + * mpp memory usage snapshot tool + * + * usage: + * call mpp_mem_get_snapshot on context init get one snapshot + * call mpp_mem_get_snapshot on context deinit get another snapshot + * call mpp_mem_diff_snapshot to show the difference between these two snapshot + * call mpp_mem_put_snapshot twice to release these two snapshot + */ +typedef void* MppMemSnapshot; + +MPP_RET mpp_mem_get_snapshot(MppMemSnapshot *hnd); +MPP_RET mpp_mem_put_snapshot(MppMemSnapshot *hnd); +MPP_RET mpp_mem_squash_snapshot(MppMemSnapshot hnd0, MppMemSnapshot hnd1); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_MEM_H__*/ + diff --git a/mpp/inc/mpp_meta.h b/mpp/inc/mpp_meta.h new file mode 100755 index 0000000..0d20a24 --- /dev/null +++ b/mpp/inc/mpp_meta.h @@ -0,0 +1,118 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_META_H__ +#define __MPP_META_H__ + +#include +#include "rk_type.h" + +#define FOURCC_META(a, b, c, d) ((RK_U32)(a) << 24 | \ + ((RK_U32)(b) << 16) | \ + ((RK_U32)(c) << 8) | \ + ((RK_U32)(d) << 0)) + +/* + * Mpp Metadata definition + * + * Metadata is for information transmision in mpp. + * Mpp task will contain two meta data: + * + * 1. Data flow metadata + * This metadata contains information of input / output data flow. For example + * A. decoder input side task the input packet must be defined and output frame + * may not be defined. Then decoder will try malloc or use committed buffer to + * complete decoding. + * B. decoder output side task + * + * + * 2. Flow control metadata + * + */ +typedef enum MppMetaDataType_e { + /* + * mpp meta data of data flow + * reference counter will be used for these meta data type + */ + TYPE_FRAME = FOURCC_META('m', 'f', 'r', 'm'), + TYPE_PACKET = FOURCC_META('m', 'p', 'k', 't'), + TYPE_BUFFER = FOURCC_META('m', 'b', 'u', 'f'), + + /* mpp meta data of normal data type */ + TYPE_S32 = FOURCC_META('s', '3', '2', ' '), + TYPE_S64 = FOURCC_META('s', '6', '4', ' '), + TYPE_PTR = FOURCC_META('p', 't', 'r', ' '), +} MppMetaType; + +typedef enum MppMetaKey_e { + /* data flow key */ + KEY_INPUT_FRAME = FOURCC_META('i', 'f', 'r', 'm'), + KEY_INPUT_PACKET = FOURCC_META('i', 'p', 'k', 't'), + KEY_OUTPUT_FRAME = FOURCC_META('o', 'f', 'r', 'm'), + KEY_OUTPUT_PACKET = FOURCC_META('o', 'p', 'k', 't'), + /* output motion information for motion detection */ + KEY_MOTION_INFO = FOURCC_META('m', 'v', 'i', 'f'), + KEY_HDR_INFO = FOURCC_META('h', 'd', 'r', ' '), + + /* flow control key */ + KEY_INPUT_BLOCK = FOURCC_META('i', 'b', 'l', 'k'), + KEY_OUTPUT_BLOCK = FOURCC_META('o', 'b', 'l', 'k'), + KEY_INPUT_IDR_REQ = FOURCC_META('i', 'i', 'd', 'r'), /* input idr frame request flag */ + KEY_OUTPUT_INTRA = FOURCC_META('o', 'i', 'd', 'r'), /* output intra frame indicator */ + + /* mpp_frame / mpp_packet meta data info key */ + KEY_TEMPORAL_ID = FOURCC_META('t', 'l', 'i', 'd'), + KEY_LONG_REF_IDX = FOURCC_META('l', 't', 'i', 'd'), + KEY_ROI_DATA = FOURCC_META('r', 'o', 'i', ' '), + KEY_OSD_DATA = FOURCC_META('o', 's', 'd', ' '), + KEY_USER_DATA = FOURCC_META('u', 's', 'r', 'd'), + + /* input motion list for smart p rate control */ + KEY_MV_LIST = FOURCC_META('m', 'v', 'l', 't'), +} MppMetaKey; + +#define mpp_meta_get(meta) mpp_meta_get_with_tag(meta, MODULE_TAG, __FUNCTION__) + +#include "mpp_frame.h" +#include "mpp_packet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller); +MPP_RET mpp_meta_put(MppMeta meta); +RK_S32 mpp_meta_size(MppMeta meta); + +MPP_RET mpp_meta_set_s32(MppMeta meta, MppMetaKey key, RK_S32 val); +MPP_RET mpp_meta_set_s64(MppMeta meta, MppMetaKey key, RK_S64 val); +MPP_RET mpp_meta_set_ptr(MppMeta meta, MppMetaKey key, void *val); +MPP_RET mpp_meta_get_s32(MppMeta meta, MppMetaKey key, RK_S32 *val); +MPP_RET mpp_meta_get_s64(MppMeta meta, MppMetaKey key, RK_S64 *val); +MPP_RET mpp_meta_get_ptr(MppMeta meta, MppMetaKey key, void **val); + +MPP_RET mpp_meta_set_frame (MppMeta meta, MppMetaKey key, MppFrame frame); +MPP_RET mpp_meta_set_packet(MppMeta meta, MppMetaKey key, MppPacket packet); +MPP_RET mpp_meta_set_buffer(MppMeta meta, MppMetaKey key, MppBuffer buffer); +MPP_RET mpp_meta_get_frame (MppMeta meta, MppMetaKey key, MppFrame *frame); +MPP_RET mpp_meta_get_packet(MppMeta meta, MppMetaKey key, MppPacket *packet); +MPP_RET mpp_meta_get_buffer(MppMeta meta, MppMetaKey key, MppBuffer *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_META_H__*/ diff --git a/mpp/inc/mpp_meta_impl.h b/mpp/inc/mpp_meta_impl.h new file mode 100755 index 0000000..2e261b0 --- /dev/null +++ b/mpp/inc/mpp_meta_impl.h @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_META_IMPL_H__ +#define __MPP_META_IMPL_H__ + +#include "mpp_common.h" + +#include "mpp_list.h" +#include "mpp_meta.h" + +typedef struct MppMetaDef_t { + MppMetaKey key; + MppMetaType type; +} MppMetaDef; + +typedef struct MppMetaImpl_t { + char tag[MPP_TAG_SIZE]; + const char *caller; + RK_S32 meta_id; + RK_S32 ref_count; + + struct list_head list_meta; + struct list_head list_node; + RK_S32 node_count; +} MppMetaImpl; + +typedef union MppMetaVal_u { + RK_S32 val_s32; + RK_S64 val_s64; + void *val_ptr; + MppFrame frame; + MppPacket packet; + MppBuffer buffer; +} MppMetaVal; + +typedef struct MppMetaNode_t { + struct list_head list_meta; + struct list_head list_node; + MppMetaImpl *meta; + RK_S32 node_id; + + RK_S32 type_id; + MppMetaVal val; +} MppMetaNode; + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 mpp_meta_size(MppMeta meta); +MPP_RET mpp_meta_inc_ref(MppMeta meta); +MppMetaNode *mpp_meta_next_node(MppMeta meta); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_META_IMPL_H__*/ diff --git a/mpp/inc/mpp_packet.h b/mpp/inc/mpp_packet.h new file mode 100755 index 0000000..699fb6f --- /dev/null +++ b/mpp/inc/mpp_packet.h @@ -0,0 +1,88 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_PACKET_H__ +#define __MPP_PACKET_H__ + +#include "mpp_meta.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MppPacket interface + * + * mpp_packet_init = mpp_packet_new + mpp_packet_set_data + mpp_packet_set_size + * mpp_packet_copy_init = mpp_packet_init + memcpy + */ +MPP_RET mpp_packet_new(MppPacket *packet); +MPP_RET mpp_packet_init(MppPacket *packet, void *data, size_t size); +MPP_RET mpp_packet_init_with_buffer(MppPacket *packet, MppBuffer buffer); +MPP_RET mpp_packet_copy_init(MppPacket *packet, const MppPacket src); +MPP_RET mpp_packet_deinit(MppPacket *packet); + +/* + * data : ( R/W ) start address of the whole packet memory + * size : ( R/W ) total size of the whole packet memory + * pos : ( R/W ) current access position of the whole packet memory, used for buffer read/write + * length : ( R/W ) the rest length from current position to end of buffer + * NOTE: normally length is updated only by set_pos, + * so set length must be used carefully for special usage + */ +void mpp_packet_set_data(MppPacket packet, void *data); +void mpp_packet_set_size(MppPacket packet, size_t size); +void mpp_packet_set_pos(MppPacket packet, void *pos); +void mpp_packet_set_length(MppPacket packet, size_t size); + +void* mpp_packet_get_data(const MppPacket packet); +void* mpp_packet_get_pos(const MppPacket packet); +size_t mpp_packet_get_size(const MppPacket packet); +size_t mpp_packet_get_length(const MppPacket packet); + + +void mpp_packet_set_pts(MppPacket packet, RK_S64 pts); +RK_S64 mpp_packet_get_pts(const MppPacket packet); +void mpp_packet_set_dts(MppPacket packet, RK_S64 dts); +RK_S64 mpp_packet_get_dts(const MppPacket packet); + +void mpp_packet_set_flag(MppPacket packet, RK_U32 flag); +RK_U32 mpp_packet_get_flag(const MppPacket packet); + +MPP_RET mpp_packet_set_eos(MppPacket packet); +MPP_RET mpp_packet_clr_eos(MppPacket packet); +RK_U32 mpp_packet_get_eos(MppPacket packet); +MPP_RET mpp_packet_set_extra_data(MppPacket packet); + +void mpp_packet_set_buffer(MppPacket packet, MppBuffer buffer); +MppBuffer mpp_packet_get_buffer(const MppPacket packet); + +/* + * data access interface + */ +MPP_RET mpp_packet_read(MppPacket packet, size_t offset, void *data, size_t size); +MPP_RET mpp_packet_write(MppPacket packet, size_t offset, void *data, size_t size); + +/* + * meta data access interface + */ +MppMeta mpp_packet_get_meta(const MppPacket packet); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_PACKET_H__*/ diff --git a/mpp/inc/mpp_packet_impl.h b/mpp/inc/mpp_packet_impl.h new file mode 100755 index 0000000..77d8377 --- /dev/null +++ b/mpp/inc/mpp_packet_impl.h @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_PACKET_IMPL_H__ +#define __MPP_PACKET_IMPL_H__ + +#include "mpp_meta.h" + +#define MPP_PACKET_FLAG_EOS (0x00000001) +#define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002) +#define MPP_PACKET_FLAG_INTERNAL (0x00000004) + +/* + * mpp_packet_imp structure + * + * data : pointer + * size : total buffer size + * offset : valid data start offset + * length : valid data length + * pts : packet pts + * dts : packet dts + */ +typedef struct MppPacketImpl_t { + const char *name; + + void *data; + void *pos; + size_t size; + size_t length; + + RK_S64 pts; + RK_S64 dts; + + RK_U32 flag; + + MppBuffer buffer; + MppMeta meta; +} MppPacketImpl; + +#ifdef __cplusplus +extern "C" { +#endif +/* + * mpp_packet_reset is only used internelly and should NOT be used outside + */ +MPP_RET mpp_packet_reset(MppPacketImpl *packet); +MPP_RET mpp_packet_copy(MppPacket dst, MppPacket src); +MPP_RET mpp_packet_append(MppPacket dst, MppPacket src); + +/* pointer check function */ +MPP_RET check_is_mpp_packet(void *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_PACKET_IMPL_H__*/ diff --git a/mpp/inc/mpp_platform.h b/mpp/inc/mpp_platform.h new file mode 100755 index 0000000..46b466e --- /dev/null +++ b/mpp/inc/mpp_platform.h @@ -0,0 +1,101 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_PLATFORM__ +#define __MPP_PLATFORM__ + +#include "rk_type.h" + +/* + * Platform flag detection is for rockchip hardware platform detection + */ +typedef enum MppIoctlVersion_e { + IOCTL_VCODEC_SERVICE, + IOCTL_MPP_SERVICE_V1, + IOCTL_VERSION_BUTT, +} MppIoctlVersion; + +/* + * Platform video codec hardware feature + */ +typedef enum { + VPU_CLIENT_VDPU1 = 0, /* 0x00000001 */ + VPU_CLIENT_VDPU2 = 1, /* 0x00000002 */ + VPU_CLIENT_VDPU1_PP = 2, /* 0x00000004 */ + VPU_CLIENT_VDPU2_PP = 3, /* 0x00000008 */ + + VPU_CLIENT_HEVC_DEC = 8, /* 0x00000100 */ + VPU_CLIENT_RKVDEC = 9, /* 0x00000200 */ + VPU_CLIENT_AVSPLUS_DEC = 12, /* 0x00001000 */ + + VPU_CLIENT_RKVENC = 16, /* 0x00010000 */ + VPU_CLIENT_VEPU1 = 17, /* 0x00020000 */ + VPU_CLIENT_VEPU2 = 18, /* 0x00040000 */ + VPU_CLIENT_VEPU2_LITE = 19, /* 0x00080000 */ + VPU_CLIENT_VEPU22 = 24, /* 0x01000000 */ + VPU_CLIENT_BUTT, +} VPU_CLIENT2_TYPE; + +/* RK combined codec */ +#define HAVE_VDPU1 (1 << VPU_CLIENT_VDPU1) /* 0x00000001 */ +#define HAVE_VDPU2 (1 << VPU_CLIENT_VDPU2) /* 0x00000002 */ +#define HAVE_VDPU1_PP (1 << VPU_CLIENT_VDPU1_PP) /* 0x00000004 */ +#define HAVE_VDPU2_PP (1 << VPU_CLIENT_VDPU2_PP) /* 0x00000008 */ +/* RK standalone decoder */ +#define HAVE_HEVC_DEC (1 << VPU_CLIENT_HEVC_DEC) /* 0x00000100 */ +#define HAVE_RKVDEC (1 << VPU_CLIENT_RKVDEC) /* 0x00000200 */ +#define HAVE_AVSDEC (1 << VPU_CLIENT_AVSPLUS_DEC) /* 0x00001000 */ +/* RK standalone encoder */ +#define HAVE_RKVENC (1 << VPU_CLIENT_RKVENC) /* 0x00010000 */ +#define HAVE_VEPU1 (1 << VPU_CLIENT_VEPU1) /* 0x00020000 */ +#define HAVE_VEPU2 (1 << VPU_CLIENT_VEPU2) /* 0x00040000 */ +#define HAVE_VEPU2_LITE (1 << VPU_CLIENT_VEPU2_LITE) /* 0x00080000 */ +/* External encoder */ +#define HAVE_VEPU22 (1 << VPU_CLIENT_VEPU22) /* 0x01000000 */ + +/* Platform image process hardware feature */ +#define HAVE_IPP (0x00000001) +#define HAVE_RGA (0x00000002) +#define HAVE_RGA2 (0x00000004) +#define HAVE_IEP (0x00000008) + +/* Hal device id */ +typedef enum MppDeviceId_e { + DEV_VDPU, //!< vpu combined decoder + DEV_VEPU, //!< vpu combined encoder + DEV_RKVDEC, //!< rockchip h264 h265 vp9 combined decoder + DEV_RKVENC, //!< rockchip h264 h265 combined encoder + DEV_ID_BUTT, +} MppDeviceId; + +#ifdef __cplusplus +extern "C" { +#endif + +MppIoctlVersion mpp_get_ioctl_version(void); +const char *mpp_get_soc_name(void); +RK_U32 mpp_get_vcodec_type(void); +RK_U32 mpp_get_2d_hw_flag(void); +RK_U32 mpp_refresh_vcodec_type(RK_U32 vcodec_type); +const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_U32 platform); +const char *mpp_get_vcodec_dev_name(MppCtxType type, MppCodingType coding); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_PLATFORM__*/ + diff --git a/mpp/inc/mpp_queue.h b/mpp/inc/mpp_queue.h new file mode 100755 index 0000000..f5edb94 --- /dev/null +++ b/mpp/inc/mpp_queue.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_QUEUE_H__ +#define __MPP_QUEUE_H__ + +#include "mpp_list.h" + +class MppQueue: public mpp_list +{ +private: + sem_t mQueuePending; + int mFlushFlag; +public: + MppQueue(node_destructor func); + ~MppQueue(); + RK_S32 push(void *data, RK_S32 size); + RK_S32 pull(void *data, RK_S32 size); + RK_S32 flush(); +}; + +#endif diff --git a/mpp/inc/mpp_rc_api.h b/mpp/inc/mpp_rc_api.h new file mode 100755 index 0000000..6dd4b03 --- /dev/null +++ b/mpp/inc/mpp_rc_api.h @@ -0,0 +1,220 @@ +/* + * Copyright 2016 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_RC_API_H__ +#define __MPP_RC_API_H__ + +#include "mpp_err.h" +#include "mpp_rc_defs.h" + +/* + * Mpp rate control has three parts: + * + * 1. MPI user config module + * MppEncRcCfg structure is provided to user for overall rate control config + * Mpp will receive MppEncRcCfg from user, check parameter and set it to + * encoder. + * + * 2. Encoder rate control module + * Encoder will implement the rate control strategy required by users + * including CBR, VBR, AVBR and so on. + * This module only implement the target bit calculation behavior and + * quality restriction. And the quality level will be controlled by hal. + * + * 3. Hal rate control module + * Hal will implement the rate control on hardware. Hal will calculate the + * QP parameter for hardware according to the frame level target bit + * specified by the encoder. And the report the real bitrate and quality to + * encoder. + * + * The header defines the communication interfaces and structures used between + * MPI, encoder and hal. + */ + +typedef enum RcMode_e { + RC_CBR, + RC_VBR, + RC_AVBR, + RC_CVBR, + RC_QVBR, + RC_FIXQP, + RC_LEARNING, + RC_MODE_BUTT, +} RcMode; + +/* + * frame rate parameters have great effect on rate control + * + * fps_in_flex + * 0 - fix input frame rate + * 1 - variable input frame rate + * + * fps_in_num + * input frame rate numerator, if 0 then default 30 + * + * fps_in_denorm + * input frame rate denorminator, if 0 then default 1 + * + * fps_out_flex + * 0 - fix output frame rate + * 1 - variable output frame rate + * + * fps_out_num + * output frame rate numerator, if 0 then default 30 + * + * fps_out_denorm + * output frame rate denorminator, if 0 then default 1 + */ +typedef struct RcFpsCfg_t { + RK_S32 fps_in_flex; + RK_S32 fps_in_num; + RK_S32 fps_in_denorm; + RK_S32 fps_out_flex; + RK_S32 fps_out_num; + RK_S32 fps_out_denorm; +} RcFpsCfg; + +/* + * Control parameter from external config + * + * It will be updated on rc/prep/gopref config changed. + */ +typedef struct RcCfg_s { + /* encode image size */ + RK_S32 width; + RK_S32 height; + + /* Use rc_mode to find different api */ + RcMode mode; + + RcFpsCfg fps; + + /* I frame gop len */ + RK_S32 igop; + /* visual gop len */ + RK_S32 vgop; + + /* bitrate parameter */ + RK_S32 bps_min; + RK_S32 bps_target; + RK_S32 bps_max; + RK_S32 stat_times; + + /* max I frame bit ratio to P frame bit */ + RK_S32 max_i_bit_prop; + RK_S32 min_i_bit_prop; + /* layer bitrate proportion */ + RK_S32 layer_bit_prop[4]; + + /* quality parameter */ + RK_S32 init_quality; + RK_S32 max_quality; + RK_S32 min_quality; + RK_S32 max_i_quality; + RK_S32 min_i_quality; + RK_S32 i_quality_delta; + /* layer quality proportion */ + RK_S32 layer_quality_delta[4]; + + /* reencode parameter */ + RK_S32 max_reencode_times; + + /* still / motion desision parameter */ + RK_S32 min_still_prop; + RK_S32 max_still_quality; + + /* + * vbr parameter + * + * vbr_hi_prop - high proportion bitrate for reduce quality + * vbr_lo_prop - low proportion bitrate for increase quality + */ + RK_S32 vbr_hi_prop; + RK_S32 vbr_lo_prop; +} RcCfg; + +/* + * Different rate control strategy will be implemented by different API config + */ +typedef struct RcImplApi_t { + char *name; + MppCodingType type; + RK_U32 ctx_size; + + MPP_RET (*init)(void *ctx, RcCfg *cfg); + MPP_RET (*deinit)(void *ctx); + + MPP_RET (*check_drop)(void *ctx, EncRcTask *task); + + /* + * frm_start - frame level rate control frm_start. + * The EncRcTaskInfo will be output to hal for hardware to implement. + * frm_end - frame level rate control frm_end. + * The EncRcTaskInfo is returned for real quality and bitrate. + */ + MPP_RET (*frm_start)(void *ctx, EncRcTask *task); + MPP_RET (*frm_end)(void *ctx, EncRcTask *task); + + /* + * hal_start - hardware level rate control start. + * The EncRcTaskInfo will be output to hal for hardware to implement. + * hal_end - hardware level rate control end. + * The EncRcTaskInfo is returned for real quality and bitrate. + */ + MPP_RET (*hal_start)(void *ctx, EncRcTask *task); + MPP_RET (*hal_end)(void *ctx, EncRcTask *task); +} RcImplApi; + +/* + * structures for RC API register and query + */ +typedef struct RcApiBrief_t { + const char *name; + MppCodingType type; +} RcApiBrief; + +typedef struct RcApiQueryAll_t { + /* input param for query */ + RcApiBrief *brief; + RK_S32 max_count; + + /* output query count */ + RK_S32 count; +} RcApiQueryAll; + +typedef struct RcApiQueryType_t { + /* input param for query */ + RcApiBrief *brief; + RK_S32 max_count; + MppCodingType type; + + /* output query count */ + RK_S32 count; +} RcApiQueryType; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET rc_api_add(const RcImplApi *api); +MPP_RET rc_brief_get_all(RcApiQueryAll *query); +MPP_RET rc_brief_get_by_type(RcApiQueryType *query); + +#ifdef __cplusplus +} +#endif + +#endif /* __MPP_RC_API_H__ */ diff --git a/mpp/inc/mpp_rc_defs.h b/mpp/inc/mpp_rc_defs.h new file mode 100755 index 0000000..4fe1c3d --- /dev/null +++ b/mpp/inc/mpp_rc_defs.h @@ -0,0 +1,144 @@ +/* + * Copyright 2016 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RC_DEFS_H__ +#define __RC_DEFS_H__ + +#include "rk_type.h" + +/* + * EncFrmStatus controls record the encoding frame status and also control + * work flow of encoder. It is the communicat channel between encoder implement + * module, rate control module and hardware module. + * + * bit 0 ~ 31 frame status + * 0 ~ 15 current frame status + * 16 ~ 31 reference frame status + * bit 32 ~ 63 encoding flow control + */ +typedef struct EncFrmStatus_t { + /* + * bit 0 ~ 31 frame status + */ + /* + * 0 - inter frame + * 1 - intra frame + */ + RK_U32 is_intra : 1; + + /* + * Valid when is_intra is true + * 0 - normal intra frame + * 1 - IDR frame + */ + RK_U32 is_idr : 1; + + /* + * 0 - mark as reference frame + * 1 - mark as non-refernce frame + */ + RK_U32 is_non_ref : 1; + + /* + * Valid when is_non_ref is false + * 0 - mark as short-term reference frame + * 1 - mark as long-term refernce frame + */ + RK_U32 is_lt_ref : 1; + + RK_U32 reserved0 : 4; + + /* bit 8 - 15 */ + RK_U32 lt_idx : 4; + RK_U32 temporal_id : 4; + + /* distance between current frame and reference frame */ + RK_S32 ref_dist : 16; + + /* + * bit 32 ~ 63 encoder flow control flags + */ + /* + * 0 - normal frame encoding + * 1 - current frame will be dropped + */ + RK_U32 drop : 1; + + /* + * 0 - rate control module does not change frame type parameter + * 1 - rate control module changes frame type parameter reencode is needed + * to reprocess the dpb process. Also this means dpb module will follow + * the frame status parameter provided by rate control module. + */ + RK_U32 re_dpb_proc : 1; + + /* + * 0 - current frame encoding is in normal flow + * 1 - current frame encoding is in reencode flow + */ + RK_U32 reencode : 1; + + /* + * When true current frame size is super large then the frame should be reencoded. + */ + RK_U32 super_frame : 1; + + /* + * When true currnet frame is force to encoded as software skip frame + */ + RK_U32 force_pskip : 1; + RK_U32 reserved1 : 3; + + /* reencode times */ + RK_U32 reencode_times : 8; + + /* sequential index for each frame */ + RK_U32 seq_idx : 16; +} EncFrmStatus; + +/* + * communication channel between rc / hal / hardware + * + * rc -> hal bit_target / bit_max / bit_min + * hal -> hw quality_target / quality_max / quality_min + * hw -> rc / hal bit_real / quality_real / madi / madp + */ +typedef struct EncRcCommonInfo_t { + /* rc to hal */ + RK_S32 bit_target; + RK_S32 bit_max; + RK_S32 bit_min; + + RK_S32 quality_target; + RK_S32 quality_max; + RK_S32 quality_min; + + /* rc from hardware */ + RK_S32 bit_real; + RK_S32 quality_real; + RK_S32 madi; + RK_S32 madp; + + RK_S32 reserve[16]; +} EncRcTaskInfo; + +typedef struct EncRcTask_s { + EncFrmStatus frm; + EncRcTaskInfo info; + MppFrame frame; +} EncRcTask; + +#endif /* __RC_DEFS_H__ */ diff --git a/mpp/inc/mpp_runtime.h b/mpp/inc/mpp_runtime.h new file mode 100755 index 0000000..908d31c --- /dev/null +++ b/mpp/inc/mpp_runtime.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_RUNTIME__ +#define __MPP_RUNTIME__ + +#include "mpp_buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Runtime function detection is to support different binary on different + * runtime environment. This is usefull on product environemnt. + */ +RK_U32 mpp_rt_allcator_is_valid(MppBufferType type); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_RUNTIME__*/ + diff --git a/mpp/inc/mpp_task.h b/mpp/inc/mpp_task.h new file mode 100755 index 0000000..c91899e --- /dev/null +++ b/mpp/inc/mpp_task.h @@ -0,0 +1,237 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_TASK_H__ +#define __MPP_TASK_H__ + +#include "mpp_meta.h" + +/* + * Advanced task flow + * Advanced task flow introduces three concepts: port, task and item + * + * Port is from OpenMAX + * Port has two type: input port and output port which are all for data transaction. + * Port work like a queue. task will be dequeue from or enqueue to one port. + * On input side user will dequeue task from input port, setup task and enqueue task + * back to input port. + * On output side user will dequeue task from output port, get the information from + * and then enqueue task back to output port. + * + * Task indicates one transaction on the port. + * Task has two working mode: async mode and sync mode + * If mpp is work in sync mode on task enqueue function return the task has been done + * If mpp is work in async mode on task enqueue function return the task is just put + * on the task queue for process. + * Task can carry different items. Task just like a container of items + * + * Item indicates MppPacket or MppFrame which is contained in one task + */ + +/* + * One mpp task queue has two ports: input and output + * + * The whole picture is: + * Top layer mpp has two ports: mpp_input_port and mpp_output_port + * But internally these two ports belongs to two task queue. + * The mpp_input_port is the mpp_input_task_queue's input port. + * The mpp_output_port is the mpp_output_task_queue's output port. + * + * Each port uses its task queue to communication + */ +typedef enum { + MPP_PORT_INPUT, + MPP_PORT_OUTPUT, + MPP_PORT_BUTT, +} MppPortType; + +/* + * Advance task work flow mode: + ****************************************************************************** + * 1. async mode (default_val) + * + * mpp_init(type, coding, MPP_WORK_ASYNC) + * + * input thread + * a - poll(input) + * b - dequeue(input, *task) + * c - task_set_item(packet/frame) + * d - enqueue(input, task) // when enqueue return the task is not done yet + * + * output thread + * a - poll(output) + * b - dequeue(output, *task) + * c - task_get_item(frame/packet) + * d - enqueue(output, task) + ****************************************************************************** + * 2. sync mode + * + * mpp_init(type, coding, MPP_WORK_SYNC) + * + * a - poll(input) + * b - dequeue(input, *task) + * c - task_set_item(packet/frame) + * d - enqueue(task) // when enqueue return the task is finished + ****************************************************************************** + */ +typedef enum { + MPP_TASK_ASYNC, + MPP_TASK_SYNC, + MPP_TASK_WORK_MODE_BUTT, +} MppTaskWorkMode; + +/* + * Mpp port pull type + * + * MPP_POLL_BLOCK - for block poll + * MPP_POLL_NON_BLOCK - for non-block poll + * small than MPP_POLL_MAX - for poll with timeout in ms + * small than MPP_POLL_BUTT or larger than MPP_POLL_MAX is invalid value + */ +typedef enum { + MPP_POLL_BUTT = -2, + MPP_POLL_BLOCK = -1, + MPP_POLL_NON_BLOCK = 0, + MPP_POLL_MAX = 8000, +} MppPollType; + +/* + * Mpp timeout define + * MPP_TIMEOUT_BLOCK - for block poll + * MPP_TIMEOUT_NON_BLOCK - for non-block poll + * small than MPP_TIMEOUT_MAX - for poll with timeout in ms + * small than MPP_TIMEOUT_BUTT or larger than MPP_TIMEOUT_MAX is invalid value + */ +#define MPP_TIMEOUT_BUTT (-2L) +#define MPP_TIMEOUT_BLOCK (-1L) +#define MPP_TIMEOUT_NON_BLOCK (0L) +#define MPP_TIMEOUT_MAX (8000L) + +/* + * MppTask is descriptor of a task which send to mpp for process + * mpp can support different type of work mode, for example: + * + * decoder: + * + * 1. typical decoder mode: + * input - MppPacket (normal cpu buffer, need cpu copy) + * output - MppFrame (ion/drm buffer in external/internal mode) + * 2. secure decoder mode: + * input - MppPacket (externel ion/drm buffer, cpu can not access) + * output - MppFrame (ion/drm buffer in external/internal mode, cpu can not access) + * + * interface usage: + * + * typical flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, packet) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * secure flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, packet) + * task_put_item(task, MODE_OUTPUT, frame) // buffer will be specified here + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * encoder: + * + * 1. typical encoder mode: + * input - MppFrame (ion/drm buffer in external mode) + * output - MppPacket (normal cpu buffer, need cpu copy) + * 2. user input encoder mode: + * input - MppFrame (normal cpu buffer, need to build hardware table for this buffer) + * output - MppPacket (normal cpu buffer, need cpu copy) + * 3. secure encoder mode: + * input - MppFrame (ion/drm buffer in external mode, cpu can not access) + * output - MppPacket (externel ion/drm buffer, cpu can not access) + * + * typical / user input flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, frame) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &packet) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * secure flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_OUTPUT, packet) // buffer will be specified here + * task_put_item(task, MODE_INPUT, frame) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &packet) + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * NOTE: this flow can specify the output frame. User will setup both intput frame and output packet + * buffer at the input side. Then at output side when user gets a finished task user can get the output + * packet and corresponding released input frame. + * + * image processing + * + * 1. typical image process mode: + * input - MppFrame (ion/drm buffer in external mode) + * output - MppFrame (ion/drm buffer in external mode) + * + * typical / user input flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, frame) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + */ +/* NOTE: use index rather then handle to descripbe task */ + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, RK_S32 val); +MPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val); +MPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val); +MPP_RET mpp_task_meta_set_frame (MppTask task, MppMetaKey key, MppFrame frame); +MPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet); +MPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer); + +MPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, RK_S32 *val, RK_S32 default_val); +MPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val); +MPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val); +MPP_RET mpp_task_meta_get_frame (MppTask task, MppMetaKey key, MppFrame *frame); +MPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet); +MPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_QUEUE_H__*/ diff --git a/mpp/inc/mpp_task_impl.h b/mpp/inc/mpp_task_impl.h new file mode 100755 index 0000000..5b6ca02 --- /dev/null +++ b/mpp/inc/mpp_task_impl.h @@ -0,0 +1,125 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_TASK_IMPL_H__ +#define __MPP_TASK_IMPL_H__ + +#include "mpp_list.h" +#include "mpp_task.h" + +typedef void* MppPort; +typedef void* MppTaskQueue; + +/* + * mpp task status transaction + * + * mpp task is generated from mpp port. When create a mpp port the corresponding task + * will be created, too. Then external user will dequeue task from port and enqueue to + * mpp port for process. + * + * input port task work flow: + * + * description | call | status transaction + * 1. input port init | enqueue(external) | -> external_queue + * 2. input port user dequeue | dequeue(external) | external_queue -> external_hold + * 3. user setup task for processing| | + * 4. input port user enqueue | enqueue(external) | external_hold -> internal_queue + * 5. input port mpp start process | dequeue(internal) | internal_queue -> internal_hold + * 6. mpp process task | | + * 7. input port mpp task finish | enqueue(internal) | internal_hold -> external_queue + * loop to 2 + * + * output port task work flow: + * description | call | status transaction + * 1. output port init | enqueue(internal) | -> internal_queue + * 2. output port mpp task dequeue | dequeue(internal) | internal_queue -> internal_hold + * 3. mpp setup task by processed frame/packet | + * 4. output port mpp task enqueue | enqueue(internal) | internal_hold -> external_queue + * 5. output port user task dequeue | dequeue(external) | external_queue -> external_hold + * 6. user get task as output | | + * 7. output port user release task | enqueue(external) | external_hold -> external_queue + * loop to 2 + * + */ +typedef enum MppTaskStatus_e { + MPP_INPUT_PORT, /* in external queue and ready for external dequeue */ + MPP_INPUT_HOLD, /* dequeued and hold by external user, user will config */ + MPP_OUTPUT_PORT, /* in mpp internal work queue and ready for mpp dequeue */ + MPP_OUTPUT_HOLD, /* dequeued and hold by mpp internal worker, mpp is processing */ + MPP_TASK_STATUS_BUTT, +} MppTaskStatus; + +typedef struct MppTaskImpl_t { + const char *name; + struct list_head list; + MppTaskQueue queue; + RK_S32 index; + MppTaskStatus status; + + MppMeta meta; +} MppTaskImpl; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET check_mpp_task_name(MppTask task); + +/* + * Mpp task queue function: + * + * mpp_task_queue_init - create task queue structure + * mpp_task_queue_deinit - destory task queue structure + * mpp_task_queue_get_port - return input or output port of task queue + * + * Typical work flow, task mpp_dec for example: + * + * 1. Mpp layer creates one task queue in order to connect mpp input and mpp_dec input. + * 2. Mpp layer setups the task count in task queue input port. + * 3. Get input port from the task queue and assign to mpp input as mpp_input_port. + * 4. Get output port from the task queue and assign to mpp_dec input as dec_input_port. + * 5. Let the loop start. + * a. mpi user will dequeue task from mpp_input_port. + * b. mpi user will setup task. + * c. mpi user will enqueue task back to mpp_input_port. + * d. task will automatically transfer to dec_input_port. + * e. mpp_dec will dequeue task from dec_input_port. + * f. mpp_dec will process task. + * g. mpp_dec will enqueue task back to dec_input_port. + * h. task will automatically transfer to mpp_input_port. + * 6. Stop the loop. All tasks must be return to input port with idle status. + * 6. Mpp layer destory the task queue. + */ +MPP_RET mpp_task_queue_init(MppTaskQueue *queue); +MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count); +MPP_RET mpp_task_queue_deinit(MppTaskQueue queue); +MppPort mpp_task_queue_get_port(MppTaskQueue queue, MppPortType type); + +#define mpp_port_poll(port, timeout) _mpp_port_poll(__FUNCTION__, port, timeout) +#define mpp_port_dequeue(port, task) _mpp_port_dequeue(__FUNCTION__, port, task) +#define mpp_port_enqueue(port, task) _mpp_port_enqueue(__FUNCTION__, port, task) +#define mpp_port_awake(port) _mpp_port_awake(__FUNCTION__, port) + +MPP_RET _mpp_port_poll(const char *caller, MppPort port, MppPollType timeout); +MPP_RET _mpp_port_dequeue(const char *caller, MppPort port, MppTask *task); +MPP_RET _mpp_port_enqueue(const char *caller, MppPort port, MppTask task); +MPP_RET _mpp_port_awake(const char *caller, MppPort port); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_TASK_IMPL_H__*/ diff --git a/mpp/inc/mpp_thread.h b/mpp/inc/mpp_thread.h new file mode 100755 index 0000000..f89ff99 --- /dev/null +++ b/mpp/inc/mpp_thread.h @@ -0,0 +1,281 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * File : mpp_thread.h + * Description : thread library for different OS + * Author : herman.chen@rock-chips.com + * Date : 9:47 2015/7/27 + */ + +#ifndef __MPP_THREAD_H__ +#define __MPP_THREAD_H__ + +#if defined(_WIN32) && !defined(__MINGW32CE__) + +/* + * NOTE: POSIX Threads for Win32 + * Downloaded from http://www.sourceware.org/pthreads-win32/ + */ +#include "semaphore.h" +#include "pthread.h" +#pragma comment(lib, "pthreadVC2.lib") + +/* + * add pthread_setname_np for windows + */ +int pthread_setname_np(pthread_t thread, const char *name); + +#else + +#include +#include +#include +#include + +#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#endif + +#endif + +#define THREAD_NAME_LEN 16 + +typedef void *(*MppThreadFunc)(void *); + +typedef enum { + MPP_THREAD_UNINITED, + MPP_THREAD_RUNNING, + MPP_THREAD_WAITING, + MPP_THREAD_STOPPING, +} MppThreadStatus; + +#ifdef __cplusplus + +#include "mpp_log.h" + +class Mutex; +class Condition; + +/* + * for shorter type name and function name + */ +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + int trylock(); + + class Autolock + { + public: + inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } + inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } + inline ~Autolock() { mLock.unlock(); } + private: + Mutex& mLock; + }; + +private: + friend class Condition; + + pthread_mutex_t mMutex; + + Mutex(const Mutex &); + Mutex &operator = (const Mutex&); +}; + +inline Mutex::Mutex() +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mMutex, &attr); + pthread_mutexattr_destroy(&attr); +} +inline Mutex::~Mutex() +{ + pthread_mutex_destroy(&mMutex); +} +inline void Mutex::lock() +{ + pthread_mutex_lock(&mMutex); +} +inline void Mutex::unlock() +{ + pthread_mutex_unlock(&mMutex); +} +inline int Mutex::trylock() +{ + return pthread_mutex_trylock(&mMutex); +} + +typedef Mutex::Autolock AutoMutex; + + +/* + * for shorter type name and function name + */ +class Condition +{ +public: + Condition(); + Condition(int type); + ~Condition(); + RK_S32 wait(Mutex& mutex); + RK_S32 wait(Mutex* mutex); + RK_S32 timedwait(Mutex& mutex, RK_S64 timeout); + RK_S32 timedwait(Mutex* mutex, RK_S64 timeout); + RK_S32 signal(); + +private: + pthread_cond_t mCond; +}; + +inline Condition::Condition() +{ + pthread_cond_init(&mCond, NULL); +} +inline Condition::~Condition() +{ + pthread_cond_destroy(&mCond); +} +inline RK_S32 Condition::wait(Mutex& mutex) +{ + return pthread_cond_wait(&mCond, &mutex.mMutex); +} +inline RK_S32 Condition::wait(Mutex* mutex) +{ + return pthread_cond_wait(&mCond, &mutex->mMutex); +} +inline RK_S32 Condition::timedwait(Mutex& mutex, RK_S64 timeout) +{ + return timedwait(&mutex, timeout); +} +inline RK_S32 Condition::timedwait(Mutex* mutex, RK_S64 timeout) +{ + struct timespec ts; + + clock_gettime(CLOCK_REALTIME_COARSE, &ts); + + ts.tv_sec += timeout / 1000; + ts.tv_nsec += (timeout % 1000) * 1000000; + /* Prevent the out of range at nanoseconds field */ + ts.tv_sec += ts.tv_nsec / 1000000000; + ts.tv_nsec %= 1000000000; + + return pthread_cond_timedwait(&mCond, &mutex->mMutex, &ts); +} +inline RK_S32 Condition::signal() +{ + return pthread_cond_signal(&mCond); +} + +class MppMutexCond +{ +public: + MppMutexCond() {}; + ~MppMutexCond() {}; + + void lock() { mLock.lock(); } + void unlock() { mLock.unlock(); } + void wait() { mCondition.wait(mLock); } + void signal() { mCondition.signal(); } + Mutex *mutex() { return &mLock; } + +private: + Mutex mLock; + Condition mCondition; +}; + +// Thread lock / signal is distinguished by its source +typedef enum MppThreadSignal_e { + THREAD_WORK, // for working loop + THREAD_INPUT, // for thread input + THREAD_OUTPUT, // for thread output + THREAD_CONTROL, // for thread async control (reset) + THREAD_SIGNAL_BUTT, +} MppThreadSignal; + +#define THREAD_NORMAL 0 +#define THRE 0 + +class MppThread +{ +public: + MppThread(MppThreadFunc func, void *ctx, const char *name = NULL); + ~MppThread() {}; + + MppThreadStatus get_status(MppThreadSignal id = THREAD_WORK); + void set_status(MppThreadStatus status, MppThreadSignal id = THREAD_WORK); + void dump_status(); + + void start(); + void stop(); + + void lock(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + mMutexCond[id].lock(); + } + + void unlock(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + mMutexCond[id].unlock(); + } + + void wait(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + MppThreadStatus status = mStatus[id]; + + mStatus[id] = MPP_THREAD_WAITING; + mMutexCond[id].wait(); + + // check the status is not changed then restore status + if (mStatus[id] == MPP_THREAD_WAITING) + mStatus[id] = status; + } + + void signal(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + mMutexCond[id].signal(); + } + + Mutex *mutex(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + return mMutexCond[id].mutex(); + } + +private: + pthread_t mThread; + MppMutexCond mMutexCond[THREAD_SIGNAL_BUTT]; + MppThreadStatus mStatus[THREAD_SIGNAL_BUTT]; + + MppThreadFunc mFunction; + char mName[THREAD_NAME_LEN]; + void *mContext; + + MppThread(); + MppThread(const MppThread &); + MppThread &operator=(const MppThread &); +}; + +#endif + +#endif /*__MPP_THREAD_H__*/ diff --git a/mpp/inc/mpp_time.h b/mpp/inc/mpp_time.h new file mode 100755 index 0000000..2fee54a --- /dev/null +++ b/mpp/inc/mpp_time.h @@ -0,0 +1,119 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_TIME_H__ +#define __MPP_TIME_H__ + +#include "rk_type.h" +#include "mpp_thread.h" + +#if defined(_WIN32) && !defined(__MINGW32CE__) +#include +#define msleep Sleep +#define sleep(x) Sleep((x)*1000) +#else +#include +#define msleep(x) usleep((x)*1000) +#endif + +typedef void* MppClock; +typedef void* MppTimer; + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S64 mpp_time(); +void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, const char *fmt); + +/* + * Clock create / destroy / enable / disable function + * Note when clock is create it is default disabled user need to call enable + * fucntion with enable = 1 to enable the clock. + * User can use enable function with enable = 0 to disable the clock. + */ +MppClock mpp_clock_get(const char *name); +void mpp_clock_put(MppClock clock); +void mpp_clock_enable(MppClock clock, RK_U32 enable); + +/* + * Clock basic operation function: + * start : let clock start timing counter + * pause : let clock pause and return the diff to start time + * reset : let clock counter to all zero + */ +RK_S64 mpp_clock_start(MppClock clock); +RK_S64 mpp_clock_pause(MppClock clock); +RK_S64 mpp_clock_reset(MppClock clock); + +/* + * These clock helper function can only be call when clock is paused: + * mpp_clock_get_sum - Return clock sum up total value + * mpp_clock_get_count - Return clock sum up counter value + * mpp_clock_get_name - Return clock name + */ +RK_S64 mpp_clock_get_sum(MppClock clock); +RK_S64 mpp_clock_get_count(MppClock clock); +const char *mpp_clock_get_name(MppClock clock); + +/* + * MppTimer is for timer with callback function + * It will provide the ability to repeat doing something until it is + * disalble or put. + * + * Timer work flow: + * + * 1. mpp_timer_get + * 2. mpp_timer_set_callback + * 3. mpp_timer_set_timing(initial, interval) + * 4. mpp_timer_set_enable(initial, 1) + * ... running ... + * 5. mpp_timer_set_enable(initial, 0) + * 6. mpp_timer_put + */ +MppTimer mpp_timer_get(const char *name); +void mpp_timer_set_callback(MppTimer timer, MppThreadFunc func, void *ctx); +void mpp_timer_set_timing(MppTimer timer, RK_S32 initial, RK_S32 interval); +void mpp_timer_set_enable(MppTimer timer, RK_S32 enable); +void mpp_timer_put(MppTimer timer); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +class AutoTiming +{ +public: + AutoTiming(const char *name = __FUNCTION__); + ~AutoTiming(); +private: + const char *mName; + RK_S64 mStart; + RK_S64 mEnd; + + AutoTiming(const AutoTiming &); + AutoTiming &operator = (const AutoTiming&); +}; + +#endif + +#define AUTO_TIMER_STRING(name, cnt) name ## cnt +#define AUTO_TIMER_NAME_STRING(name, cnt) AUTO_TIMER_STRING(name, cnt) +#define AUTO_TIMER_NAME(name) AUTO_TIMER_NAME_STRING(name, __COUNTER__) +#define AUTO_TIMING() AutoTiming AUTO_TIMER_NAME(auto_timing)(__FUNCTION__) + +#endif /*__MPP_TIME_H__*/ diff --git a/mpp/inc/rk_mpi.h b/mpp/inc/rk_mpi.h new file mode 100755 index 0000000..43f6c51 --- /dev/null +++ b/mpp/inc/rk_mpi.h @@ -0,0 +1,205 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RK_MPI_H__ +#define __RK_MPI_H__ + +/** + * @addtogroup rk_mpi + * @brief rockchip media process interface + * + * Mpp provides application programming interface for the application layer. + */ + +#include "rk_mpi_cmd.h" +#include "mpp_task.h" + +/** + * @ingroup rk_mpi + * @brief mpp main work function set + * + * @note all api function are seperated into two sets: data io api set and control api set + * + * the data api set is for data input/output flow including: + * + * simple data api set: + * + * decode : both send video stream packet to decoder and get video frame from + * decoder at the same time. + * encode : both send video frame to encoder and get encoded video stream from + * encoder at the same time. + * + * decode_put_packet: send video stream packet to decoder only, async interface + * decode_get_frame : get video frame from decoder only, async interface + * + * encode_put_frame : send video frame to encoder only, async interface + * encode_get_packet: get encoded video packet from encoder only, async interface + * + * advance task api set: + * + * + * the control api set is for mpp context control including: + * control : similiar to ioctl in kernel driver, setup or get mpp internal parameter + * reset : clear all data in mpp context, reset to initialized status + * the simple api set is for simple codec usage including: + * + * + * reset : discard all packet and frame, reset all component, + * for both decoder and encoder + * control : control function for mpp property setting + */ +typedef struct MppApi_t { + RK_U32 size; + RK_U32 version; + + // simple data flow interface + /** + * @brief both send video stream packet to decoder and get video frame from + * decoder at the same time + * @param ctx The context of mpp + * @param packet[in] The input video stream + * @param frame[out] The output picture + * @return 0 for decode success, others for failure + */ + MPP_RET (*decode)(MppCtx ctx, MppPacket packet, MppFrame *frame); + /** + * @brief send video stream packet to decoder only, async interface + * @param ctx The context of mpp + * @param packet The input video stream + * @return 0 for success, others for failure + */ + MPP_RET (*decode_put_packet)(MppCtx ctx, MppPacket packet); + /** + * @brief get video frame from decoder only, async interface + * @param ctx The context of mpp + * @param frame The output picture + * @return 0 for success, others for failure + */ + MPP_RET (*decode_get_frame)(MppCtx ctx, MppFrame *frame); + /** + * @brief both send video frame to encoder and get encoded video stream from + * encoder at the same time + * @param ctx The context of mpp + * @param frame[in] The input video data + * @param packet[out] The output compressed data + * @return 0 for encode success, others for failure + */ + MPP_RET (*encode)(MppCtx ctx, MppFrame frame, MppPacket *packet); + /** + * @brief send video frame to encoder only, async interface + * @param ctx The context of mpp + * @param frame The input video data + * @return 0 for success, others for failure + */ + MPP_RET (*encode_put_frame)(MppCtx ctx, MppFrame frame); + /** + * @brief get encoded video packet from encoder only, async interface + * @param ctx The context of mpp + * @param packet The output compressed data + * @return 0 for success, others for failure + */ + MPP_RET (*encode_get_packet)(MppCtx ctx, MppPacket *packet); + + MPP_RET (*isp)(MppCtx ctx, MppFrame dst, MppFrame src); + MPP_RET (*isp_put_frame)(MppCtx ctx, MppFrame frame); + MPP_RET (*isp_get_frame)(MppCtx ctx, MppFrame *frame); + + // advance data flow interface + /** + * @brief poll port for dequeue + * @param ctx The context of mpp + * @param type input port or output port which are both for data transaction + * @return 0 for success there is valid task for dequeue, others for failure + */ + MPP_RET (*poll)(MppCtx ctx, MppPortType type, MppPollType timeout); + /** + * @brief dequeue MppTask + * @param ctx The context of mpp + * @param type input port or output port which are both for data transaction + * @param task MppTask which is sent to mpp for process + * @return 0 for success, others for failure + */ + MPP_RET (*dequeue)(MppCtx ctx, MppPortType type, MppTask *task); + /** + * @brief enqueue MppTask + * @param ctx The context of mpp + * @param type input port or output port which are both for data transaction + * @param task MppTask which is sent to mpp for process + * @return 0 for success, others for failure + */ + MPP_RET (*enqueue)(MppCtx ctx, MppPortType type, MppTask task); + + // control interface + /** + * @brief discard all packet and frame, reset all component, + * for both decoder and encoder + * @param ctx The context of mpp + */ + MPP_RET (*reset)(MppCtx ctx); + /** + * @brief control function for mpp property setting + * @param ctx The context of mpp + * @param cmd The mpi command + * @param param The mpi command parameter + * @return 0 for success, others for failure + */ + MPP_RET (*control)(MppCtx ctx, MpiCmd cmd, MppParam param); + + /** + * @brief The reserved segment + */ + RK_U32 reserv[16]; +} MppApi; + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup rk_mpi + * @brief Create empty context structure and mpi function pointers. + * Use functions in MppApi to access mpp services. + * @param ctx pointer of the mpp context + * @param mpi pointer of mpi function + */ +MPP_RET mpp_create(MppCtx *ctx, MppApi **mpi); +/** + * @ingroup rk_mpi + * @brief Call after mpp_create to setup mpp type and video format. + * This function will call internal context init function. + * @param ctx The context of mpp + * @param type MppCtxType, decoder or encoder + * @param coding video compression coding + */ +MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding); +/** + * @ingroup rk_mpi + * @brief Destroy mpp context and free both context and mpi structure + * @param ctx The context of mpp + */ +MPP_RET mpp_destroy(MppCtx ctx); + +// coding type format function +MPP_RET mpp_check_support_format(MppCtxType type, MppCodingType coding); +void mpp_show_support_format(void); +void mpp_show_color_format(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__RK_MPI_H__*/ diff --git a/mpp/inc/rk_mpi_cmd.h b/mpp/inc/rk_mpi_cmd.h new file mode 100755 index 0000000..a1416ab --- /dev/null +++ b/mpp/inc/rk_mpi_cmd.h @@ -0,0 +1,196 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RK_MPI_CMD_H__ +#define __RK_MPI_CMD_H__ + +/* + * Command id bit usage is defined as follows: + * bit 20 - 23 - module id + * bit 16 - 19 - contex id + * bit 0 - 15 - command id + */ +#define CMD_MODULE_ID_MASK (0x00F00000) +#define CMD_MODULE_OSAL (0x00100000) +#define CMD_MODULE_MPP (0x00200000) +#define CMD_MODULE_CODEC (0x00300000) +#define CMD_MODULE_HAL (0x00400000) + +#define CMD_CTX_ID_MASK (0x000F0000) +#define CMD_CTX_ID_DEC (0x00010000) +#define CMD_CTX_ID_ENC (0x00020000) +#define CMD_CTX_ID_ISP (0x00030000) + +/* separate encoder control command to different segment */ +#define CMD_CFG_ID_MASK (0x0000FF00) +#define CMD_ENC_CFG_ALL (0x00000000) +#define CMD_ENC_CFG_RC_API (0x00000100) +#define CMD_ENC_CFG_FRM (0x00000200) +#define CMD_ENC_CFG_PREP (0x00000300) +#define CMD_ENC_CFG_CODEC (0x00001000) +#define CMD_ENC_CFG_H264 (0x00001000) +#define CMD_ENC_CFG_H265 (0x00001800) +#define CMD_ENC_CFG_VP8 (0x00002000) +#define CMD_ENC_CFG_VP9 (0x00002800) +#define CMD_ENC_CFG_AV1 (0x00003000) +#define CMD_ENC_CFG_MJPEG (0x00004000) + +#define CMD_ENC_CFG_MISC (0x00008000) +#define CMD_ENC_CFG_SPLIT (0x00008100) +#define CMD_ENC_CFG_GOPREF (0x00008200) +#define CMD_ENC_CFG_ROI (0x00008300) +#define CMD_ENC_CFG_OSD (0x00008400) + +typedef enum { + MPP_OSAL_CMD_BASE = CMD_MODULE_OSAL, + MPP_OSAL_CMD_END, + + MPP_CMD_BASE = CMD_MODULE_MPP, + MPP_ENABLE_DEINTERLACE, + MPP_SET_INPUT_BLOCK, /* deprecated */ + MPP_SET_INTPUT_BLOCK_TIMEOUT, /* deprecated */ + MPP_SET_OUTPUT_BLOCK, /* deprecated */ + MPP_SET_OUTPUT_BLOCK_TIMEOUT, /* deprecated */ + /* + * timeout setup, refer to MPP_TIMEOUT_XXX + * zero - non block + * negative - block with no timeout + * positive - timeout in milisecond + */ + MPP_SET_INPUT_TIMEOUT, /* parameter type RK_S64 */ + MPP_SET_OUTPUT_TIMEOUT, /* parameter type RK_S64 */ + MPP_CMD_END, + + MPP_CODEC_CMD_BASE = CMD_MODULE_CODEC, + MPP_CODEC_GET_FRAME_INFO, + MPP_CODEC_CMD_END, + + MPP_DEC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_DEC, + MPP_DEC_SET_FRAME_INFO, /* vpu api legacy control for buffer slot dimension init */ + MPP_DEC_SET_EXT_BUF_GROUP, /* IMPORTANT: set external buffer group to mpp decoder */ + MPP_DEC_SET_INFO_CHANGE_READY, + MPP_DEC_SET_PRESENT_TIME_ORDER, /* use input time order for output */ + MPP_DEC_SET_PARSER_SPLIT_MODE, /* Need to setup before init */ + MPP_DEC_SET_PARSER_FAST_MODE, /* Need to setup before init */ + MPP_DEC_GET_STREAM_COUNT, + MPP_DEC_GET_VPUMEM_USED_COUNT, + MPP_DEC_SET_VC1_EXTRA_DATA, + MPP_DEC_SET_OUTPUT_FORMAT, + MPP_DEC_SET_DISABLE_ERROR, /* When set it will disable sw/hw error (H.264 / H.265) */ + MPP_DEC_SET_IMMEDIATE_OUT, + MPP_DEC_SET_ENABLE_DEINTERLACE, /* MPP enable deinterlace by default. Vpuapi can disable it */ + MPP_DEC_CMD_END, + + MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, + /* basic encoder setup control */ + MPP_ENC_SET_ALL_CFG, /* set MppEncCfgSet structure */ + MPP_ENC_GET_ALL_CFG, /* get MppEncCfgSet structure */ + MPP_ENC_SET_PREP_CFG, /* set MppEncPrepCfg structure */ + MPP_ENC_GET_PREP_CFG, /* get MppEncPrepCfg structure */ + MPP_ENC_SET_RC_CFG, /* set MppEncRcCfg structure */ + MPP_ENC_GET_RC_CFG, /* get MppEncRcCfg structure */ + MPP_ENC_SET_CODEC_CFG, /* set MppEncCodecCfg structure */ + MPP_ENC_GET_CODEC_CFG, /* get MppEncCodecCfg structure */ + /* runtime encoder setup control */ + MPP_ENC_SET_IDR_FRAME, /* next frame will be encoded as intra frame */ + MPP_ENC_SET_OSD_LEGACY_0, /* deprecated */ + MPP_ENC_SET_OSD_LEGACY_1, /* deprecated */ + MPP_ENC_SET_OSD_LEGACY_2, /* deprecated */ + MPP_ENC_GET_HDR_SYNC, /* get vps / sps / pps which has better sync behavior parameter is MppPacket */ + MPP_ENC_GET_EXTRA_INFO, /* deprecated */ + MPP_ENC_SET_SEI_CFG, /* SEI: Supplement Enhancemant Information, parameter is MppSeiMode */ + MPP_ENC_GET_SEI_DATA, /* SEI: Supplement Enhancemant Information, parameter is MppPacket */ + MPP_ENC_PRE_ALLOC_BUFF, /* allocate buffers before encoding */ + MPP_ENC_SET_QP_RANGE, /* used for adjusting qp range, the parameter can be 1 or 2 */ + MPP_ENC_SET_ROI_CFG, /* set MppEncROICfg structure */ + MPP_ENC_SET_CTU_QP, /* for H265 Encoder,set CTU's size and QP */ + + /* User define rate control stategy API control */ + MPP_ENC_CFG_RC_API = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_RC_API, + /* + * Get RcApiQueryAll structure + * Get all available rate control stategy string and count + */ + MPP_ENC_GET_RC_API_ALL = MPP_ENC_CFG_RC_API + 1, + /* + * Get RcApiQueryType structure + * Get available rate control stategy string with certain type + */ + MPP_ENC_GET_RC_API_BY_TYPE = MPP_ENC_CFG_RC_API + 2, + /* + * Set RcImplApi structure + * Add new or update rate control stategy function pointers + */ + MPP_ENC_SET_RC_API_CFG = MPP_ENC_CFG_RC_API + 3, + /* + * Get RcApiBrief structure + * Get current used rate control stategy brief information (type and name) + */ + MPP_ENC_GET_RC_API_CURRENT = MPP_ENC_CFG_RC_API + 4, + /* + * Set RcApiBrief structure + * Set current used rate control stategy brief information (type and name) + */ + MPP_ENC_SET_RC_API_CURRENT = MPP_ENC_CFG_RC_API + 5, + + MPP_ENC_CFG_FRM = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_FRM, + MPP_ENC_SET_FRM, /* set MppFrame structure */ + MPP_ENC_GET_FRM, /* get MppFrame structure */ + + + MPP_ENC_CFG_PREP = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_PREP, + MPP_ENC_SET_PREP, /* set MppEncPrepCfg structure */ + MPP_ENC_GET_PREP, /* get MppEncPrepCfg structure */ + + MPP_ENC_CFG_H264 = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_H264, + + MPP_ENC_CFG_H265 = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_H265, + + MPP_ENC_CFG_VP8 = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_VP8, + + MPP_ENC_CFG_MJPEG = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_MJPEG, + + MPP_ENC_CFG_MISC = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_MISC, + MPP_ENC_SET_HEADER_MODE, /* set MppEncHeaderMode */ + MPP_ENC_GET_HEADER_MODE, /* get MppEncHeaderMode */ + + MPP_ENC_CFG_SPLIT = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_SPLIT, + MPP_ENC_SET_SPLIT, /* set MppEncSliceSplit structure */ + MPP_ENC_GET_SPLIT, /* get MppEncSliceSplit structure */ + + MPP_ENC_CFG_GOPREF = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_GOPREF, + MPP_ENC_SET_GOPREF, /* set MppEncGopRef structure */ + + MPP_ENC_CFG_OSD = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_OSD, + MPP_ENC_SET_OSD_PLT_CFG, /* set OSD palette, parameter should be pointer to MppEncOSDPltCfg */ + MPP_ENC_GET_OSD_PLT_CFG, /* get OSD palette, parameter should be pointer to MppEncOSDPltCfg */ + MPP_ENC_SET_OSD_DATA_CFG, /* set OSD data with at most 8 regions, parameter should be pointer to MppEncOSDData */ + MPP_ENC_GET_OSD_DATA_CFG, /* get OSD data with at most 8 regions, parameter should be pointer to MppEncOSDData */ + + MPP_ENC_CMD_END, + + MPP_ISP_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ISP, + MPP_ISP_CMD_END, + + MPP_HAL_CMD_BASE = CMD_MODULE_HAL, + MPP_HAL_CMD_END, + + MPI_CMD_BUTT, +} MpiCmd; + +#include "rk_venc_cmd.h" + +#endif /*__RK_MPI_CMD_H__*/ diff --git a/mpp/inc/rk_type.h b/mpp/inc/rk_type.h new file mode 100755 index 0000000..6d131d0 --- /dev/null +++ b/mpp/inc/rk_type.h @@ -0,0 +1,137 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RK_TYPE_H__ +#define __RK_TYPE_H__ + +#include + +#if defined(_WIN32) && !defined(__MINGW32CE__) + +typedef unsigned char RK_U8; +typedef unsigned short RK_U16; +typedef unsigned int RK_U32; +typedef unsigned long RK_ULONG; +typedef unsigned __int64 RK_U64; + +typedef signed char RK_S8; +typedef signed short RK_S16; +typedef signed int RK_S32; +typedef signed long RK_LONG; +typedef signed __int64 RK_S64; + +#else + +typedef unsigned char RK_U8; +typedef unsigned short RK_U16; +typedef unsigned int RK_U32; +typedef unsigned long RK_ULONG; +typedef unsigned long long int RK_U64; + + +typedef signed char RK_S8; +typedef signed short RK_S16; +typedef signed int RK_S32; +typedef signed long RK_LONG; +typedef signed long long int RK_S64; + +#endif + +#ifndef MODULE_TAG +#define MODULE_TAG NULL +#endif + +/** + * @ingroup rk_mpi + * @brief The type of mpp context + */ +typedef enum { + MPP_CTX_DEC, /**< decoder */ + MPP_CTX_ENC, /**< encoder */ + MPP_CTX_ISP, /**< isp */ + MPP_CTX_BUTT, /**< undefined */ +} MppCtxType; + +/** + * @ingroup rk_mpi + * @brief Enumeration used to define the possible video compression codings. + * sync with the omx_video.h + * + * @note This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + */ +typedef enum { + MPP_VIDEO_CodingUnused, /**< Value when coding is N/A */ + MPP_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + MPP_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + MPP_VIDEO_CodingH263, /**< H.263 */ + MPP_VIDEO_CodingMPEG4, /**< MPEG-4 */ + MPP_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + MPP_VIDEO_CodingRV, /**< all versions of Real Video */ + MPP_VIDEO_CodingAVC, /**< H.264/AVC */ + MPP_VIDEO_CodingMJPEG, /**< Motion JPEG */ + MPP_VIDEO_CodingVP8, /**< VP8 */ + MPP_VIDEO_CodingVP9, /**< VP9 */ + MPP_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + MPP_VIDEO_CodingFLV1, /**< Sorenson H.263 */ + MPP_VIDEO_CodingDIVX3, /**< DIVX3 */ + MPP_VIDEO_CodingVP6, + MPP_VIDEO_CodingHEVC, /**< H.265/HEVC */ + MPP_VIDEO_CodingAVSPLUS, /**< AVS+ */ + MPP_VIDEO_CodingAVS, /**< AVS profile=0x20 */ + MPP_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + MPP_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + MPP_VIDEO_CodingMax = 0x7FFFFFFF +} MppCodingType; + +/* + * All external interface object list here. + * The interface object is defined as void * for expandability + * The cross include between these objects will introduce extra + * compiling difficulty. So we move them together in this header. + * + * Object interface header list: + * + * MppCtx - rk_mpi.h + * MppParam - rk_mpi.h + * + * MppFrame - mpp_frame.h + * MppPacket - mpp_packet.h + * + * MppBuffer - mpp_buffer.h + * MppBufferGroup - mpp_buffer.h + * + * MppTask - mpp_task.h + * MppMeta - mpp_meta.h + */ + +typedef void* MppCtx; +typedef void* MppParam; + +typedef void* MppFrame; +typedef void* MppPacket; + +typedef void* MppBuffer; +typedef void* MppBufferGroup; + +typedef void* MppTask; +typedef void* MppMeta; + +#endif /*__RK_TYPE_H__*/ diff --git a/mpp/inc/rk_venc_cmd.h b/mpp/inc/rk_venc_cmd.h new file mode 100755 index 0000000..725324d --- /dev/null +++ b/mpp/inc/rk_venc_cmd.h @@ -0,0 +1,1182 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RK_VENC_CMD_H__ +#define __RK_VENC_CMD_H__ + +#include "mpp_frame.h" + +/* + * Configure of encoder is very complicated. So we divide configures into + * four parts: + * + * 1. Rate control parameter + * This is quality and bitrate request from user. + * + * 2. Data source MppFrame parameter + * This is data source buffer information. + * Now it is PreP config + * PreP : Encoder Preprocess configuration + * + * 3. Video codec infomation + * This is user custormized stream information. + * including: + * H.264 / H.265 / vp8 / mjpeg + * + * 4. Misc parameter + * including: + * Split : Slice split configuration + * GopRef: Reference gop configuration + * ROI : Region Of Interest + * OSD : On Screen Display + * MD : Motion Detection + * + * The module transcation flow is as follows: + * + * + + + * User | Mpi/Mpp | EncImpl + * | | Hal + * | | + * +----------+ | +---------+ | +-----------+ + * | | | | +-----RcCfg-----> | + * | RcCfg +---------> | | | EncImpl | + * | | | | | +-Frame-----> | + * +----------+ | | | | | +--+-----^--+ + * | | | | | | | + * | | | | | | | + * +----------+ | | | | | syntax | + * | | | | | | | | | + * | MppFrame +---------> MppEnc +---+ | | result + * | | | | | | | | | + * +----------+ | | | | | | | + * | | | | | +--v-----+--+ + * | | | +-Frame-----> | + * +----------+ | | | | | | + * | | | | +---CodecCfg----> Hal | + * | CodecCfg +---------> | | | | + * | | | | <-----Extra-----> | + * +----------+ | +---------+ | +-----------+ + * | | + * | | + * + + + * + * The function call flow is shown below: + * + * mpi mpp_enc controller hal + * + + + + + * | | | | + * | | | | + * +----------init------------> | | + * | | | | + * | | | | + * | PrepCfg | | | + * +---------control----------> PrepCfg | | + * | +-----control-----> | + * | | | PrepCfg | + * | +--------------------------control--------> + * | | | allocate + * | | | buffer + * | | | | + * | RcCfg | | | + * +---------control----------> RcCfg | | + * | +-----control-----> | + * | | rc_init | + * | | | | + * | | | | + * | CodecCfg | | | + * +---------control----------> | CodecCfg | + * | +--------------------------control--------> + * | | | generate + * | | | sps/pps + * | | | Get extra info | + * | +--------------------------control--------> + * | Get extra info | | | + * +---------control----------> | | + * | | | | + * | | | | + * | ROICfg | | | + * +---------control----------> | ROICfg | + * | +--------------------------control--------> + * | | | | + * | OSDCfg | | | + * +---------control----------> | OSDCfg | + * | +--------------------------control--------> + * | | | | + * | MDCfg | | | + * +---------control----------> | MDCfg | + * | +--------------------------control--------> + * | | | | + * | Set extra info | | | + * +---------control----------> | Set extra info | + * | +--------------------------control--------> + * | | | | + * | task | | | + * +----------encode----------> task | | + * | +-----encode------> | + * | | encode | + * | | | syntax | + * | +--------------------------gen_reg--------> + * | | | | + * | | | | + * | +---------------------------start---------> + * | | | | + * | | | | + * | +---------------------------wait----------> + * | | | | + * | | callback | | + * | +-----------------> | + * +--OSD-MD--encode----------> | | + * | . | | | + * | . | | | + * | . | | | + * +--OSD-MD--encode----------> | | + * | | | | + * +----------deinit----------> | | + * + + + + + */ + +/* + * Rate control parameter + */ +typedef enum MppEncRcCfgChange_e { + MPP_ENC_RC_CFG_CHANGE_RC_MODE = (1 << 0), + MPP_ENC_RC_CFG_CHANGE_QUALITY = (1 << 1), + MPP_ENC_RC_CFG_CHANGE_BPS = (1 << 2), /* change on bps target / max / min */ + MPP_ENC_RC_CFG_CHANGE_FPS_IN = (1 << 5), /* change on fps in flex / numerator / denorminator */ + MPP_ENC_RC_CFG_CHANGE_FPS_OUT = (1 << 6), /* change on fps out flex / numerator / denorminator */ + MPP_ENC_RC_CFG_CHANGE_GOP = (1 << 7), + MPP_ENC_RC_CFG_CHANGE_SKIP_CNT = (1 << 8), + MPP_ENC_RC_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncRcCfgChange; + +typedef enum MppEncRcMode_t { + MPP_ENC_RC_MODE_VBR, + MPP_ENC_RC_MODE_CBR, + MPP_ENC_RC_MODE_FIXQP, + MPP_ENC_RC_MODE_BUTT +} MppEncRcMode; + +typedef enum MppEncRcQuality_t { + MPP_ENC_RC_QUALITY_WORST, + MPP_ENC_RC_QUALITY_WORSE, + MPP_ENC_RC_QUALITY_MEDIUM, + MPP_ENC_RC_QUALITY_BETTER, + MPP_ENC_RC_QUALITY_BEST, + MPP_ENC_RC_QUALITY_CQP, + MPP_ENC_RC_QUALITY_AQ_ONLY, + MPP_ENC_RC_QUALITY_BUTT +} MppEncRcQuality; + +typedef struct MppEncRcCfg_t { + RK_U32 change; + + /* + * rc_mode - rate control mode + * + * mpp provide two rate control mode: + * + * Constant Bit Rate (CBR) mode + * - paramter 'bps*' define target bps + * - paramter quality and qp will not take effect + * + * Variable Bit Rate (VBR) mode + * - paramter 'quality' define 5 quality levels + * - paramter 'bps*' is used as reference but not strict condition + * - special Constant QP (CQP) mode is under VBR mode + * CQP mode will work with qp in CodecCfg. But only use for test + * + * default: CBR + */ + MppEncRcMode rc_mode; + + /* + * quality - quality parameter, only takes effect in VBR mode + * + * Mpp does not give the direct parameter in different protocol. + * + * Mpp provide total 5 quality level: + * Worst - worse - Medium - better - best + * + * extra CQP level means special constant-qp (CQP) mode + * + * default value: Medium + */ + MppEncRcQuality quality; + + /* + * bit rate parameters + * mpp gives three bit rate control parameter for control + * bps_target - target bit rate, unit: bit per second + * bps_max - maximun bit rate, unit: bit per second + * bps_min - minimun bit rate, unit: bit per second + * if user need constant bit rate set parameters to the similar value + * if user need variable bit rate set parameters as they need + */ + RK_S32 bps_target; + RK_S32 bps_max; + RK_S32 bps_min; + + /* + * frame rate parameters have great effect on rate control + * + * fps_in_flex + * 0 - fix input frame rate + * 1 - variable input frame rate + * + * fps_in_num + * input frame rate numerator, if 0 then default 30 + * + * fps_in_denorm + * input frame rate denorminator, if 0 then default 1 + * + * fps_out_flex + * 0 - fix output frame rate + * 1 - variable output frame rate + * + * fps_out_num + * output frame rate numerator, if 0 then default 30 + * + * fps_out_denorm + * output frame rate denorminator, if 0 then default 1 + */ + RK_S32 fps_in_flex; + RK_S32 fps_in_num; + RK_S32 fps_in_denorm; + RK_S32 fps_out_flex; + RK_S32 fps_out_num; + RK_S32 fps_out_denorm; + + /* + * gop - group of picture, gap between Intra frame + * 0 for only 1 I frame the rest are all P frames + * 1 for all I frame + * 2 for I P I P I P + * 3 for I P P I P P + * etc... + */ + RK_S32 gop; + + /* + * skip_cnt - max continuous frame skip count + * 0 - frame skip is not allow + */ + RK_S32 skip_cnt; + + /* + * stat_times - the time of bitrate statistics + */ + RK_S32 stat_times; +} MppEncRcCfg; + +/* + * Mpp preprocess parameter + */ +typedef enum MppEncPrepCfgChange_e { + MPP_ENC_PREP_CFG_CHANGE_INPUT = (1 << 0), /* change on input config */ + MPP_ENC_PREP_CFG_CHANGE_FORMAT = (1 << 2), /* change on format */ + /* transform parameter */ + MPP_ENC_PREP_CFG_CHANGE_ROTATION = (1 << 4), /* change on ration */ + MPP_ENC_PREP_CFG_CHANGE_MIRRORING = (1 << 5), /* change on mirroring */ + /* enhancement parameter */ + MPP_ENC_PREP_CFG_CHANGE_DENOISE = (1 << 8), /* change on denoise */ + MPP_ENC_PREP_CFG_CHANGE_SHARPEN = (1 << 9), /* change on denoise */ + MPP_ENC_PREP_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncPrepCfgChange; + +/* + * Preprocess sharpen parameter + * + * 5x5 sharpen core + * + * enable_y - enable luma sharpen + * enable_uv - enable chroma sharpen + */ +typedef struct { + RK_U32 enable_y; + RK_U32 enable_uv; + RK_S32 coef[5]; + RK_S32 div; + RK_S32 threshold; +} MppEncPrepSharpenCfg; + +/* + * input frame rotation parameter + * 0 - disable rotation + * 1 - 90 degree + * 2 - 180 degree + * 3 - 270 degree + */ +typedef enum MppEncRotationCfg_t { + MPP_ENC_ROT_0, + MPP_ENC_ROT_90, + MPP_ENC_ROT_180, + MPP_ENC_ROT_270, + MPP_ENC_ROT_BUTT +} MppEncRotationCfg; + +typedef struct MppEncPrepCfg_t { + RK_U32 change; + + /* + * Mpp encoder input data dimension config + * + * width / height / hor_stride / ver_stride / format + * These information will be used for buffer allocation and rc config init + * The output format is always YUV420. So if input is RGB then color + * conversion will be done internally + */ + RK_S32 width; + RK_S32 height; + RK_S32 hor_stride; + RK_S32 ver_stride; + + /* + * Mpp encoder input data format config + */ + MppFrameFormat format; + MppFrameColorSpace color; + + MppEncRotationCfg rotation; + + /* + * input frame mirroring parameter + * 0 - disable mirroring + * 1 - horizontal mirroring + * 2 - vertical mirroring + */ + RK_S32 mirroring; + + /* + * TODO: + */ + RK_S32 denoise; + + MppEncPrepSharpenCfg sharpen; +} MppEncPrepCfg; + +/* + * Mpp Motion Detection parameter + * + * Mpp can output Motion Detection infomation for each frame. + * If user euqueue a encode task with KEY_MOTION_INFO by following function + * then encoder will output Motion Detection information to the buffer. + * + * mpp_task_meta_set_buffer(task, KEY_MOTION_INFO, buffer); + * + * Motion Detection information will be organized in this way: + * 1. Each 16x16 block will have a 32 bit block information which contains + * 15 bit SAD(Sum of Abstract Difference value + * 9 bit signed horizontal motion vector + * 8 bit signed vertical motion vector + * 2. The sequence of MD information in the buffer is corresponding to the + * block position in the frame, left-to right, top-to-bottom. + * 3. If the width of the frame is not a multiple of 256 pixels (16 macro + * blocks), DMA would extend the frame to a multiple of 256 pixels and + * the extended blocks' MD information are 32'h0000_0000. + * 4. Buffer must be ion buffer and 1024 byte aligned. + */ +typedef struct MppEncMDBlkInfo_t { + RK_U32 sad : 15; /* bit 0~14 - SAD */ + RK_S32 mvx : 9; /* bit 15~23 - signed horizontal mv */ + RK_S32 mvy : 8; /* bit 24~31 - signed vertical mv */ +} MppEncMDBlkInfo; + +typedef enum MppEncHeaderMode_t { + /* default mode: attach vps/sps/pps only on first frame */ + MPP_ENC_HEADER_MODE_DEFAULT, + /* IDR mode: attach vps/sps/pps on each IDR frame */ + MPP_ENC_HEADER_MODE_EACH_IDR, + MPP_ENC_HEADER_MODE_BUTT, +} MppEncHeaderMode; + +typedef enum MppEncSeiMode_t { + MPP_ENC_SEI_MODE_DISABLE, /* default mode, SEI writing is disabled */ + MPP_ENC_SEI_MODE_ONE_SEQ, /* one sequence has only one SEI */ + MPP_ENC_SEI_MODE_ONE_FRAME /* one frame may have one SEI, if SEI info has changed */ +} MppEncSeiMode; + +/* + * Mpp codec parameter + * parameter is defined from here + */ + +/* + * H.264 configurable parameter + */ +typedef struct MppEncH264VuiCfg_t { + RK_U32 change; + + RK_U32 b_vui; + + RK_S32 b_aspect_ratio_info_present; + RK_S32 i_sar_width; + RK_S32 i_sar_height; + + RK_S32 b_overscan_info_present; + RK_S32 b_overscan_info; + + RK_S32 b_signal_type_present; + RK_S32 i_vidformat; + RK_S32 b_fullrange; + RK_S32 b_color_description_present; + RK_S32 i_colorprim; + RK_S32 i_transfer; + RK_S32 i_colmatrix; + + RK_S32 b_chroma_loc_info_present; + RK_S32 i_chroma_loc_top; + RK_S32 i_chroma_loc_bottom; + + RK_S32 b_timing_info_present; + RK_U32 i_num_units_in_tick; + RK_U32 i_time_scale; + RK_S32 b_fixed_frame_rate; + + RK_S32 b_nal_hrd_parameters_present; + RK_S32 b_vcl_hrd_parameters_present; + + struct { + RK_S32 i_cpb_cnt; + RK_S32 i_bit_rate_scale; + RK_S32 i_cpb_size_scale; + RK_S32 i_bit_rate_value; + RK_S32 i_cpb_size_value; + RK_S32 i_bit_rate_unscaled; + RK_S32 i_cpb_size_unscaled; + RK_S32 b_cbr_hrd; + + RK_S32 i_initial_cpb_removal_delay_length; + RK_S32 i_cpb_removal_delay_length; + RK_S32 i_dpb_output_delay_length; + RK_S32 i_time_offset_length; + } hrd; + + RK_S32 b_pic_struct_present; + RK_S32 b_bitstream_restriction; + RK_S32 b_motion_vectors_over_pic_boundaries; + RK_S32 i_max_bytes_per_pic_denom; + RK_S32 i_max_bits_per_mb_denom; + RK_S32 i_log2_max_mv_length_horizontal; + RK_S32 i_log2_max_mv_length_vertical; + RK_S32 i_num_reorder_frames; + RK_S32 i_max_dec_frame_buffering; + + /* FIXME to complete */ +} MppEncH264VuiCfg; + +typedef struct MppEncH264RefCfg_t { + RK_S32 i_frame_reference; /* Maximum number of reference frames */ + RK_S32 i_ref_pos; + RK_S32 i_long_term_en; + RK_S32 i_long_term_internal; + RK_S32 hw_longterm_mode; + RK_S32 i_dpb_size; /* Force a DPB size larger than that implied by B-frames and reference frames. + * Useful in combination with interactive error resilience. */ +} MppEncH264RefCfg; + +typedef struct MppEncH264SeiCfg_t { + RK_U32 change; +} MppEncH264SeiCfg; + +typedef enum MppEncH264CfgChange_e { + /* change on stream type */ + MPP_ENC_H264_CFG_STREAM_TYPE = (1 << 0), + /* change on svc / profile / level */ + MPP_ENC_H264_CFG_CHANGE_PROFILE = (1 << 1), + /* change on entropy_coding_mode / cabac_init_idc */ + MPP_ENC_H264_CFG_CHANGE_ENTROPY = (1 << 2), + + /* change on transform8x8_mode */ + MPP_ENC_H264_CFG_CHANGE_TRANS_8x8 = (1 << 4), + /* change on constrained_intra_pred_mode */ + MPP_ENC_H264_CFG_CHANGE_CONST_INTRA = (1 << 5), + /* change on chroma_cb_qp_offset/ chroma_cr_qp_offset */ + MPP_ENC_H264_CFG_CHANGE_CHROMA_QP = (1 << 6), + /* change on deblock_disable / deblock_offset_alpha / deblock_offset_beta */ + MPP_ENC_H264_CFG_CHANGE_DEBLOCKING = (1 << 7), + /* change on use_longterm */ + MPP_ENC_H264_CFG_CHANGE_LONG_TERM = (1 << 8), + /* change on scaling_list_mode */ + MPP_ENC_H264_CFG_CHANGE_SCALING_LIST = (1 << 9), + + /* change on max_qp / min_qp / max_qp_step */ + MPP_ENC_H264_CFG_CHANGE_QP_LIMIT = (1 << 16), + /* change on intra_refresh_mode / intra_refresh_arg */ + MPP_ENC_H264_CFG_CHANGE_INTRA_REFRESH = (1 << 17), + /* change on slice_mode / slice_arg */ + MPP_ENC_H264_CFG_CHANGE_SLICE_MODE = (1 << 18), + + /* change on vui */ + MPP_ENC_H264_CFG_CHANGE_VUI = (1 << 28), + /* change on sei */ + MPP_ENC_H264_CFG_CHANGE_SEI = (1 << 29), + MPP_ENC_H264_CFG_CHANGE_REF = (1 << 30), + MPP_ENC_H264_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncH264CfgChange; + +typedef struct MppEncH264IntraPred_t { + RK_S32 constrained_intra_pred_mode; +} MppEncH264IntraPred; + +typedef struct MppEncH264InterPred_t { + RK_S32 reserve; +} MppEncH264InterPred; + +typedef struct MppEncH264Trans_t { + RK_S32 trans_mode; + RK_S32 scaling_list_enable; + RK_S8 inter_scaling_list_8x8[64]; + RK_S8 intra_scaling_list_8x8[64]; + RK_S8 chroma_qp_offset;; +} MppEncH264Trans; + +typedef struct MppEncH264Entropy_t { + RK_S32 entropy_coding_mode; + RK_S32 cabac_init_idc; +} MppEncH264Entropy; + +typedef struct MppEncH264Dblk_t { + RK_S32 deblock_disable; + RK_S32 deblock_offset_alpha; + RK_S32 deblock_offset_beta; +} MppEncH264Dblk; + +typedef struct MppEncH264Cfg_t { + RK_U32 change; + + /* + * H.264 stream format + * 0 - H.264 Annex B: NAL unit starts with '00 00 00 01' + * 1 - Plain NAL units without startcode + */ + RK_S32 stream_type; + + /* H.264 codec syntax config */ + RK_S32 svc; /* 0 - avc 1 - svc */ + + /* + * H.264 profile_idc parameter + * 66 - Baseline profile + * 77 - Main profile + * 100 - High profile + */ + RK_S32 profile; + + /* + * H.264 level_idc parameter + * 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps + * 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps + * 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps + * 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps + * 50 / 51 / 52 - 4K@30fps + */ + RK_S32 level; + + /* + * H.264 entropy coding method + * 0 - CAVLC + * 1 - CABAC + * When CABAC is select cabac_init_idc can be range 0~2 + */ + RK_S32 entropy_coding_mode; + RK_S32 cabac_init_idc; + + /* + * 8x8 intra prediction and 8x8 transform enable flag + * This flag can only be enable under High profile + * 0 : disable (BP/MP) + * 1 : enable (HP) + */ + RK_S32 transform8x8_mode; + + /* + * 0 : disable + * 1 : enable + */ + RK_S32 constrained_intra_pred_mode; + + /* + * 0 : flat scaling list + * 1 : default scaling list for all cases + * 2 : customized scaling list (not supported) + */ + RK_S32 scaling_list_mode; + + /* + * chroma qp offset (-12 - 12) + */ + RK_S32 chroma_cb_qp_offset; + RK_S32 chroma_cr_qp_offset; + + /* + * H.264 deblock filter mode flag + * 0 : enable + * 1 : disable + * 2 : disable deblocking filter at slice boundaries + * + * deblock filter offset alpha (-6 - 6) + * deblock filter offset beta (-6 - 6) + */ + RK_S32 deblock_disable; + RK_S32 deblock_offset_alpha; + RK_S32 deblock_offset_beta; + + /* + * H.264 long term reference picture enable flag + * 0 - disable + * 1 - enable + */ + RK_S32 use_longterm; + + /* + * quality config + * qp_max - 8 ~ 51 + * qp_min - 0 ~ 48 + * qp_max_step - max delta qp step between two frames + */ + RK_S32 qp_init; + RK_S32 qp_max; + RK_S32 qp_min; + RK_S32 qp_max_step; + + /* + * intra fresh config + * + * intra_refresh_mode + * 0 - no intra refresh + * 1 - intra refresh by MB row + * 2 - intra refresh by MB column + * 3 - intra refresh by MB gap + * + * intra_refresh_arg + * mode 0 - no effect + * mode 1 - refresh MB row number + * mode 2 - refresh MB colmn number + * mode 3 - refresh MB gap count + */ + RK_S32 intra_refresh_mode; + RK_S32 intra_refresh_arg; + + /* slice mode config */ + RK_S32 slice_mode; + RK_S32 slice_arg; + + /* extra info */ + MppEncH264VuiCfg vui; + MppEncH264SeiCfg sei; + MppEncH264RefCfg ref; +} MppEncH264Cfg; + + +#define H265E_MAX_ROI_NUMBER 64 +typedef struct H265eRect_t { + RK_S32 left; + RK_S32 right; + RK_S32 top; + RK_S32 bottom; +} H265eRect; + +typedef struct H265eRoi_Region_t { + RK_U8 level; + H265eRect rect; +} H265eRoiRegion; + +/* + * roi region only can be setting when rc_enable = 1 + */ +typedef struct MppEncH265RoiCfg_t { + /* + * the value is defined by H265eCtuMethod + */ + + RK_U8 method; + /* + * the number of roi,the value must less than H265E_MAX_ROI_NUMBER + */ + RK_S32 num; + + /* delat qp using in roi region*/ + RK_U32 delta_qp; + + /* roi region */ + H265eRoiRegion region[H265E_MAX_ROI_NUMBER]; +} MppEncH265RoiCfg; + +typedef struct H265eCtuQp_t { + /* the qp value using in ctu region */ + RK_U32 qp; + + /* + * define the ctu region + * method = H265E_METHOD_CUT_SIZE, the value of rect is in ctu size + * method = H264E_METHOD_COORDINATE,the value of rect is in coordinates + */ + H265eRect rect; +} H265eCtu; + +typedef struct H265eCtuRegion_t { + /* + * the value is defined by H265eCtuMethod + */ + RK_U8 method; + + /* + * the number of ctu,the value must less than H265E_MAX_ROI_NUMBER + */ + RK_S32 num; + + /* ctu region */ + H265eCtu ctu[H265E_MAX_ROI_NUMBER]; +} MppEncH265CtuCfg; + +/* + * define the method when set CTU/ROI parameters + * this value is using by method in H265eCtuRegion or H265eRoi struct + */ +typedef enum { + H265E_METHOD_CTU_SIZE, + H264E_METHOD_COORDINATE, +} H265eCtuMethod; + +/* + * H.265 configurable parameter + */ +typedef struct MppEncH265VuiCfg_t { + RK_U32 change; + RK_S32 vui_present; + RK_S32 vui_aspect_ratio; + RK_S32 vui_sar_size; + RK_S32 full_range; + RK_S32 time_scale; +} MppEncH265VuiCfg; + +typedef struct MppEncH265SeiCfg_t { + RK_U32 change; +} MppEncH265SeiCfg; + + +typedef enum MppEncH265CfgChange_e { + /* change on stream type */ + MPP_ENC_H265_CFG_PROFILE_LEVEL_TILER_CHANGE = (1 << 0), + MPP_ENC_H265_CFG_INTRA_QP_CHANGE = (1 << 1), + MPP_ENC_H265_CFG_FRAME_RATE_CHANGE = (1 << 2), + MPP_ENC_H265_CFG_BITRATE_CHANGE = (1 << 3), + MPP_ENC_H265_CFG_GOP_SIZE = (1 << 4), + MPP_ENC_H265_CFG_RC_QP_CHANGE = (1 << 5), + MPP_ENC_H265_CFG_INTRA_REFRESH_CHANGE = (1 << 6), + MPP_ENC_H265_CFG_INDEPEND_SLICE_CHANGE = (1 << 7), + MPP_ENC_H265_CFG_DEPEND_SLICE_CHANGE = (1 << 8), + MPP_ENC_H265_CFG_CTU_CHANGE = (1 << 9), + MPP_ENC_H265_CFG_ROI_CHANGE = (1 << 10), + MPP_ENC_H265_CFG_CU_CHANGE = (1 << 11), + MPP_ENC_H265_CFG_DBLK_CHANGE = (1 << 12), + MPP_ENC_H265_CFG_SAO_CHANGE = (1 << 13), + MPP_ENC_H265_CFG_TRANS_CHANGE = (1 << 14), + MPP_ENC_H265_CFG_SLICE_CHANGE = (1 << 15), + MPP_ENC_H265_CFG_ENTROPY_CHANGE = (1 << 16), + MPP_ENC_H265_CFG_MERGE_CHANGE = (1 << 17), + MPP_ENC_H265_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncH265CfgChange; + +typedef struct MppEncH265SliceCfg_t { + /* default value: 0, means no slice split*/ + RK_U32 split_enable; + + /* 0: by bits number; 1: by lcu line number*/ + RK_U32 split_mode; + + /* + * when splitmode is 0, this value presents bits number, + * when splitmode is 1, this value presents lcu line number + */ + RK_U32 slice_size; + RK_U32 loop_filter_across_slices_enabled_flag; +} MppEncH265SliceCfg; + +typedef struct MppEncH265CuCfg_t { + RK_U32 cu32x32_en; /*default: 1 */ + RK_U32 cu16x16_en; /*default: 1 */ + RK_U32 cu8x8_en; /*default: 1 */ + RK_U32 cu4x4_en; /*default: 1 */ + + // intra pred + RK_U32 constrained_intra_pred_flag; /*default: 0 */ + RK_U32 strong_intra_smoothing_enabled_flag; /*INTRA_SMOOTH*/ + RK_U32 pcm_enabled_flag; /*default: 0, enable ipcm*/ + RK_U32 pcm_loop_filter_disabled_flag; + +} MppEncH265CuCfg; + +typedef struct MppEncH265RefCfg_t { + RK_U32 num_lt_ref_pic; /*default: 0*/ +} MppEncH265RefCfg; + + +typedef struct MppEncH265DblkCfg_t { + RK_U32 slice_deblocking_filter_disabled_flag; /* default value: 0. {0,1} */ + RK_S32 slice_beta_offset_div2; /* default value: 0. [-6,+6] */ + RK_S32 slice_tc_offset_div2; /* default value: 0. [-6,+6] */ +} MppEncH265DblkCfg_t; + +typedef struct MppEncH265SaoCfg_t { + RK_U32 slice_sao_luma_flag; + RK_U32 slice_sao_chroma_flag; +} MppEncH265SaoCfg; + +typedef struct MppEncH265TransCfg_t { + RK_U32 transquant_bypass_enabled_flag; + RK_U32 transform_skip_enabled_flag; + RK_U32 defalut_ScalingList_enable; /* default: 0 */ + RK_U32 cb_qp_offset; + RK_U32 cr_qp_offset; +} MppEncH265TransCfg; + +typedef struct MppEncH265MergeCfg_t { + RK_U32 max_mrg_cnd; + RK_U32 merge_up_flag; + RK_U32 merge_left_flag; +} MppEncH265MergesCfg; + +typedef struct MppEncH265EntropyCfg_t { + RK_U32 cabac_init_flag; /* default: 0 */ +} MppEncH265EntropyCfg; + +typedef struct MppEncH265Cfg_t { + RK_U32 change; + + /* H.265 codec syntax config */ + RK_S32 profile; + RK_S32 level; + RK_S32 tier; + + /* constraint intra prediction flag */ + RK_S32 const_intra_pred; + RK_S32 ctu_size; + RK_S32 max_cu_size; + RK_S32 tmvp_enable; + RK_S32 amp_enable; + RK_S32 wpp_enable; + RK_S32 merge_range; + RK_S32 sao_enable; + RK_U32 num_ref; + + /* quality config */ + RK_S32 max_qp; + RK_S32 min_qp; + RK_S32 max_i_qp; + RK_S32 min_i_qp; + RK_S32 ip_qp_delta; + RK_S32 max_delta_qp; + RK_S32 intra_qp; + RK_S32 gop_delta_qp; + RK_S32 qp_init; + RK_S32 qp_max_step; + RK_S32 raw_dealt_qp; + RK_U8 qpmax_map[8]; + RK_U8 qpmin_map[8]; + RK_S32 qpmap_mode; + + /* intra fresh config */ + RK_S32 intra_refresh_mode; + RK_S32 intra_refresh_arg; + + /* slice mode config */ + RK_S32 independ_slice_mode; + RK_S32 independ_slice_arg; + RK_S32 depend_slice_mode; + RK_S32 depend_slice_arg; + + MppEncH265CuCfg cu_cfg; + MppEncH265SliceCfg slice_cfg; + MppEncH265EntropyCfg entropy_cfg; + MppEncH265TransCfg trans_cfg; + MppEncH265SaoCfg sao_cfg; + MppEncH265DblkCfg_t dblk_cfg; + MppEncH265RefCfg ref_cfg; + MppEncH265MergesCfg merge_cfg; + + /* extra info */ + MppEncH265VuiCfg vui; + MppEncH265SeiCfg sei; + + MppEncH265CtuCfg ctu; + MppEncH265RoiCfg roi; +} MppEncH265Cfg; + +/* + * motion jpeg configurable parameter + */ +typedef enum MppEncJpegCfgChange_e { + /* change on quant parameter */ + MPP_ENC_JPEG_CFG_CHANGE_QP = (1 << 0), + MPP_ENC_JPEG_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncJpegCfgChange; + +typedef struct MppEncJpegCfg_t { + RK_U32 change; + RK_S32 quant; +} MppEncJpegCfg; + +/* + * vp8 configurable parameter + */ +typedef struct MppEncVp8Cfg_t { + RK_U32 change; + RK_S32 quant; +} MppEncVp8Cfg; + +/* + * in decoder mode application need to specify the coding type first + * send a stream header to mpi ctx using parameter data / size + * and decoder will try to decode the input stream. + */ +typedef struct MppEncCodecCfg_t { + MppCodingType coding; + + union { + RK_U32 change; + MppEncH264Cfg h264; + MppEncH265Cfg h265; + MppEncJpegCfg jpeg; + MppEncVp8Cfg vp8; + }; +} MppEncCodecCfg; + +typedef enum MppEncSliceSplit_e { + /* change on quant parameter */ + MPP_ENC_SPLIT_CFG_CHANGE_MODE = (1 << 0), + MPP_ENC_SPLIT_CFG_CHANGE_ARG = (1 << 1), + MPP_ENC_SPLIT_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncSliceSplitChange; + +typedef enum MppEncSplitMode_e { + MPP_ENC_SPLIT_NONE, + MPP_ENC_SPLIT_BY_BYTE, + MPP_ENC_SPLIT_BY_CTU, +} MppEncSplitMode; + +typedef struct MppEncSliceSplit_t { + RK_U32 change; + + /* + * slice split mode + * + * MPP_ENC_SPLIT_NONE - No slice is split + * MPP_ENC_SPLIT_BY_BYTE - Slice is split by byte number + * MPP_ENC_SPLIT_BY_CTU - Slice is split by macroblock / ctu number + */ + RK_U32 split_mode; + + /* + * slice split size parameter + * + * When split by byte number this value is the max byte number for each + * slice. + * When split by macroblock / ctu number this value is the MB/CTU number + * for each slice. + */ + RK_U32 split_arg; +} MppEncSliceSplit; + +typedef enum MppEncRefMode_e { + GopRefModeRockchip, + GopRefModeHisilicon, + GopRefModeButt, +} MppEncRefMode; + +#define MAX_GOP_REF_LEN 16 +#define GOP_REF_SIZE (MAX_GOP_REF_LEN+1) +#define MAX_TEMPORAL_LAYER 4 + +typedef struct MppGopRefInfo_t { + RK_S32 temporal_id; + RK_S32 ref_idx; + RK_S32 is_non_ref; + RK_S32 is_lt_ref; + RK_S32 lt_idx; +} MppGopRefInfo; + +typedef enum MppEncGopRefChange_e { + /* change on gop_cfg_enable flag */ + MPP_ENC_GOPREF_ENABLE = (1 << 0), + /* change on lt_ref_interval and max_lt_ref_cnt for long-term reference loop */ + MPP_ENC_GOPREF_LT_LOOP = (1 << 1), + /* change on ref_gop_len and gop_info for short-term reference gop config */ + MPP_ENC_GOPREF_ST_GOP = (1 << 2), + /* change on layer_rc_enable and layer_weight for layer rate control config */ + MPP_ENC_GOPREF_LAYER_RC = (1 << 3), + + MPP_ENC_GOPREF_CHANGE_ALL = (0xFFFFFFFF), +} MppEncGopRefChange; + +typedef struct MppEncGopRef_t { + RK_U32 change; + + /* + * Enable flag for gop reference configuration + * 0 - Default reference mode I P P P ... + * 1 - Customized reference configuration + */ + RK_U32 gop_cfg_enable; + + /* + * Long-term reference frame interval is used for error recovery + * + * When lt_ref_interval is zero the long-term frame mode is indicated by + * gop_info configuration. + * When lt_ref_interval is non-zero (usually 2~3 second interval) then + * the long-term reference can be used for error recovery. + */ + RK_S32 lt_ref_interval; + + /* + * Max long-term reference frame index plus 1 indicated the max number of + * long-term reference frame. + * + * When zero there is no long-term refernce frame. + * When larger than zero the max long-term reference frame index is + * max_lt_ref_cnt - 1. + * The max long-term reference frame index should NOT larger than + * max_num_ref_frames in sps and should NOT over the limit in gop_info. + */ + RK_S32 max_lt_ref_cnt; + + /* Reference frame gop (vgop) config */ + RK_S32 ref_gop_len; + MppGopRefInfo gop_info[GOP_REF_SIZE]; + + /* temporal layer rate control config (max 4 layer) */ + RK_S32 layer_rc_enable; + RK_S32 layer_weight[MAX_TEMPORAL_LAYER]; +} MppEncGopRef; + + +/** + * @brief Mpp ROI parameter + * Region configure define a rectangle as ROI + * @note x, y, w, h are calculated in pixels, which had better be 16-pixel aligned. + * These parameters MUST retain in memory when encoder is running. + * Both absolute qp and relative qp are supported in vepu541. + * Only absolute qp is supported in rv1108 + */ +typedef struct MppEncROIRegion_t { + RK_U16 x; /**< horizontal position of top left corner */ + RK_U16 y; /**< vertical position of top left corner */ + RK_U16 w; /**< width of ROI rectangle */ + RK_U16 h; /**< height of ROI rectangle */ + RK_U16 intra; /**< flag of forced intra macroblock */ + RK_S16 quality; /**< absolute / relative qp of macroblock */ + RK_U16 qp_area_idx; /**< qp min max area select*/ + RK_U8 area_map_en; /**< enable area map */ + RK_U8 abs_qp_en; /**< absolute qp enable flag*/ +} MppEncROIRegion; + +/** + * @brief MPP encoder's ROI configuration + */ +typedef struct MppEncROICfg_t { + RK_U32 number; /**< ROI rectangle number */ + MppEncROIRegion *regions; /**< ROI parameters */ +} MppEncROICfg; + +/* + * Mpp OSD parameter + * + * Mpp OSD support total 8 regions + * Mpp OSD support 256-color palette two mode palette: + * 1. Configurable OSD palette + * When palette is set. + * 2. fixed OSD palette + * When palette is NULL. + * + * if MppEncOSDPlt.buf != NULL , palette includes maximun 256 levels, + * every level composed of 32 bits defined below: + * Y : 8 bits + * U : 8 bits + * V : 8 bits + * alpha : 8 bits + */ +#define MPP_ENC_OSD_PLT_WHITE ((255<<24)|(128<<16)|(128<<8)|235) +#define MPP_ENC_OSD_PLT_YELLOW ((255<<24)|(146<<16)|( 16<<8)|210) +#define MPP_ENC_OSD_PLT_CYAN ((255<<24)|( 16<<16)|(166<<8)|170) +#define MPP_ENC_OSD_PLT_GREEN ((255<<24)|( 34<<16)|( 54<<8)|145) +#define MPP_ENC_OSD_PLT_TRANS (( 0<<24)|(222<<16)|(202<<8)|106) +#define MPP_ENC_OSD_PLT_RED ((255<<24)|(240<<16)|( 90<<8)| 81) +#define MPP_ENC_OSD_PLT_BLUE ((255<<24)|(110<<16)|(240<<8)| 41) +#define MPP_ENC_OSD_PLT_BLACK ((255<<24)|(128<<16)|(128<<8)| 16) + +typedef enum MppEncOSDPltType_e { + MPP_ENC_OSD_PLT_TYPE_DEFAULT, + MPP_ENC_OSD_PLT_TYPE_USERDEF, + MPP_ENC_OSD_PLT_TYPE_BUTT, +} MppEncOSDPltType; + +/* OSD palette value define */ +typedef union MppEncOSDPltVal_u { + struct { + RK_U32 y : 8; + RK_U32 u : 8; + RK_U32 v : 8; + RK_U32 alpha : 8; + }; + RK_U32 val; +} MppEncOSDPltVal; + +typedef struct MppEncOSDPlt_t { + MppEncOSDPltVal data[256]; +} MppEncOSDPlt; + +typedef enum MppEncOSDPltCfgChange_e { + MPP_ENC_OSD_PLT_CFG_CHANGE_MODE = (1 << 0), /* change osd plt type */ + MPP_ENC_OSD_PLT_CFG_CHANGE_PLT_VAL = (1 << 1), /* change osd plt table value */ + MPP_ENC_OSD_PLT_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncOSDPltCfgChange; + +typedef struct MppEncOSDPltCfg_t { + RK_U32 change; + MppEncOSDPltType type; + MppEncOSDPlt *plt; +} MppEncOSDPltCfg; + +/* position info is unit in 16 pixels(one MB), and + * x-directon range in pixels = (rd_pos_x - lt_pos_x + 1) * 16; + * y-directon range in pixels = (rd_pos_y - lt_pos_y + 1) * 16; + */ +typedef struct MppEncOSDRegion_t { + RK_U32 enable; + RK_U32 inverse; + RK_U32 start_mb_x; + RK_U32 start_mb_y; + RK_U32 num_mb_x; + RK_U32 num_mb_y; + RK_U32 buf_offset; +} MppEncOSDRegion; + +/* if num_region > 0 && region==NULL + * use old osd data + */ +typedef struct MppEncOSDData_t { + MppBuffer buf; + RK_U32 num_region; + MppEncOSDRegion region[8]; +} MppEncOSDData; + +typedef struct MppEncUserData_t { + RK_U32 len; + void *pdata; +} MppEncUserData; + +#endif /*__RK_VENC_CMD_H__*/ diff --git a/mpp/inc/utils.h b/mpp/inc/utils.h new file mode 100755 index 0000000..3585b1d --- /dev/null +++ b/mpp/inc/utils.h @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include + +#include "mpp_frame.h" + +typedef struct OptionInfo_t { + const char* name; + const char* argname; + const char* help; +} OptionInfo; + +typedef struct data_crc_t { + RK_U32 len; + RK_U32 sum; + RK_U32 vor; // value of the xor +} DataCrc; + +typedef struct frame_crc_t { + DataCrc luma; + DataCrc chroma; +} FrmCrc; + + +#define show_options(opt) \ + do { \ + _show_options(sizeof(opt)/sizeof(OptionInfo), opt); \ + } while (0) + +#ifdef __cplusplus +extern "C" { +#endif + +void _show_options(int count, OptionInfo *options); +void dump_mpp_frame_to_file(MppFrame frame, FILE *fp); + +void calc_data_crc(RK_U8 *dat, RK_U32 len, DataCrc *crc); +void write_data_crc(FILE *fp, DataCrc *crc); +void read_data_crc(FILE *fp, DataCrc *crc); + +void calc_frm_crc(MppFrame frame, FrmCrc *crc); +void write_frm_crc(FILE *fp, FrmCrc *crc); +void read_frm_crc(FILE *fp, FrmCrc *crc); + +MPP_RET read_image(RK_U8 *buf, FILE *fp, RK_U32 width, RK_U32 height, + RK_U32 hor_stride, RK_U32 ver_stride, + MppFrameFormat fmt); +MPP_RET fill_image(RK_U8 *buf, RK_U32 width, RK_U32 height, + RK_U32 hor_stride, RK_U32 ver_stride, MppFrameFormat fmt, + RK_U32 frame_count); + +typedef struct OpsLine_t { + RK_U32 index; + char cmd[8]; + RK_U64 value1; + RK_U64 value2; +} OpsLine; + +RK_S32 parse_config_line(const char *str, OpsLine *info); + +MPP_RET name_to_frame_format(const char *name, MppFrameFormat *fmt); +MPP_RET name_to_coding_type(const char *name, MppCodingType *coding); + +#ifdef __cplusplus +} +#endif + +#endif /*__UTILS_H__*/ diff --git a/mpp/inc/vpu.h b/mpp/inc/vpu.h new file mode 100755 index 0000000..e415f4e --- /dev/null +++ b/mpp/inc/vpu.h @@ -0,0 +1,153 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VPU_H__ +#define __VPU_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rk_type.h" + +#define VPU_SUCCESS (0) +#define VPU_FAILURE (-1) + +#define VPU_HW_WAIT_OK VPU_SUCCESS +#define VPU_HW_WAIT_ERROR VPU_FAILURE +#define VPU_HW_WAIT_TIMEOUT 1 + +// vpu decoder 60 registers, size 240B +#define VPU_REG_NUM_DEC (60) +// vpu post processor 41 registers, size 164B +#define VPU_REG_NUM_PP (41) +// vpu decoder + post processor 101 registers, size 404B +#define VPU_REG_NUM_DEC_PP (VPU_REG_NUM_DEC+VPU_REG_NUM_PP) +// vpu encoder 96 registers, size 384B +#define VPU_REG_NUM_ENC (96) + +typedef enum { + VPU_ENC = 0x0, + VPU_DEC = 0x1, + VPU_PP = 0x2, + VPU_DEC_PP = 0x3, + VPU_DEC_HEVC = 0x4, + VPU_DEC_RKV = 0x5, + VPU_ENC_RKV = 0x6, + VPU_DEC_AVS = 0x7, + VPU_ENC_VEPU22 = 0x8, + VPU_TYPE_BUTT , +} VPU_CLIENT_TYPE; + +/* Hardware decoder configuration description */ + +typedef struct VPUHwDecConfig { + RK_U32 maxDecPicWidth; /* Maximum video decoding width supported */ + RK_U32 maxPpOutPicWidth; /* Maximum output width of Post-Processor */ + RK_U32 h264Support; /* HW supports h.264 */ + RK_U32 jpegSupport; /* HW supports JPEG */ + RK_U32 mpeg4Support; /* HW supports MPEG-4 */ + RK_U32 customMpeg4Support; /* HW supports custom MPEG-4 features */ + RK_U32 vc1Support; /* HW supports VC-1 Simple */ + RK_U32 mpeg2Support; /* HW supports MPEG-2 */ + RK_U32 ppSupport; /* HW supports post-processor */ + RK_U32 ppConfig; /* HW post-processor functions bitmask */ + RK_U32 sorensonSparkSupport; /* HW supports Sorenson Spark */ + RK_U32 refBufSupport; /* HW supports reference picture buffering */ + RK_U32 vp6Support; /* HW supports VP6 */ + RK_U32 vp7Support; /* HW supports VP7 */ + RK_U32 vp8Support; /* HW supports VP8 */ + RK_U32 avsSupport; /* HW supports AVS */ + RK_U32 jpegESupport; /* HW supports JPEG extensions */ + RK_U32 rvSupport; /* HW supports REAL */ + RK_U32 mvcSupport; /* HW supports H264 MVC extension */ +} VPUHwDecConfig_t; + +/* Hardware encoder configuration description */ + +typedef struct VPUHwEndConfig { + RK_U32 maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */ + RK_U32 h264Enabled; /* HW supports H.264 */ + RK_U32 jpegEnabled; /* HW supports JPEG */ + RK_U32 mpeg4Enabled; /* HW supports MPEG-4 */ + RK_U32 vsEnabled; /* HW supports video stabilization */ + RK_U32 rgbEnabled; /* HW supports RGB input */ + RK_U32 reg_size; /* HW bus type in use */ + RK_U32 reserv[2]; +} VPUHwEncConfig_t; + +typedef enum { + // common command + VPU_CMD_REGISTER , + VPU_CMD_REGISTER_ACK_OK , + VPU_CMD_REGISTER_ACK_FAIL , + VPU_CMD_UNREGISTER , + + VPU_SEND_CONFIG , + VPU_SEND_CONFIG_ACK_OK , + VPU_SEND_CONFIG_ACK_FAIL , + + VPU_GET_HW_INFO , + VPU_GET_HW_INFO_ACK_OK , + VPU_GET_HW_INFO_ACK_FAIL , + + VPU_CMD_BUTT , +} VPU_CMD_TYPE; + +typedef enum { + MPP_DEV_CMD_QUERY_BASE = 0, + MPP_DEV_CMD_PROBE_HW_SUPPORT = MPP_DEV_CMD_QUERY_BASE + 0, + MPP_DEV_CMD_PROBE_IOMMU_STATUS = MPP_DEV_CMD_QUERY_BASE + 1, + + MPP_DEV_CMD_INIT_BASE = 0x100, + MPP_DEV_CMD_INIT_CLIENT_TYPE = MPP_DEV_CMD_INIT_BASE + 0, + MPP_DEV_CMD_INIT_DRIVER_DATA = MPP_DEV_CMD_INIT_BASE + 1, + MPP_DEV_CMD_INIT_TRANS_TABLE = MPP_DEV_CMD_INIT_BASE + 2, + + MPP_DEV_CMD_SEND_BASE = 0x200, + MPP_DEV_CMD_SET_REG_WRITE = MPP_DEV_CMD_SEND_BASE + 0, + MPP_DEV_CMD_SET_REG_READ = MPP_DEV_CMD_SEND_BASE + 1, + MPP_DEV_CMD_SET_REG_ADDR_OFFSET = MPP_DEV_CMD_SEND_BASE + 2, + + MPP_DEV_CMD_POLL_BASE = 0x300, + MPP_DEV_CMD_POLL_HW_FINISH = MPP_DEV_CMD_POLL_BASE + 0, + + MPP_DEV_CMD_CONTROL_BASE = 0x400, + MPP_DEV_CMD_RESET_SESSION = MPP_DEV_CMD_CONTROL_BASE + 0, + MPP_DEV_CMD_TRANS_FD_TO_IOVA = MPP_DEV_CMD_CONTROL_BASE + 1, + MPP_DEV_CMD_RELEASE_FD = MPP_DEV_CMD_CONTROL_BASE + 2, + + MPP_DEV_CMD_BUTT, +} MPP_DEV_CMD_TYPE; + +int VPUClientInit(VPU_CLIENT_TYPE type); +RK_S32 VPUClientRelease(int socket); +RK_S32 VPUClientSendReg(int socket, RK_U32 *regs, RK_U32 nregs); +RK_S32 VPUClientSendReg2(RK_S32 socket, RK_S32 offset, RK_S32 size, void *param); +RK_S32 VPUClientWaitResult(int socket, RK_U32 *regs, RK_U32 nregs, VPU_CMD_TYPE *cmd, RK_S32 *len); +RK_S32 VPUClientGetHwCfg(int socket, RK_U32 *cfg, RK_U32 cfg_size); +RK_S32 VPUClientGetIOMMUStatus(); +RK_U32 VPUCheckSupportWidth(); + +#ifdef __cplusplus +} + +#endif + +#endif /* __VPU_H__ */ + + diff --git a/mpp/inc/vpu_api.h b/mpp/inc/vpu_api.h new file mode 100755 index 0000000..f012fa2 --- /dev/null +++ b/mpp/inc/vpu_api.h @@ -0,0 +1,459 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VPU_API_LEGACY_H__ +#define __VPU_API_LEGACY_H__ + +#include "rk_type.h" +#include "mpp_err.h" + +/** + * @brief rockchip media process interface + */ + +#define VPU_API_NOPTS_VALUE (0x8000000000000000LL) + +/* + * bit definition of ColorType in structure VPU_FRAME + */ +#define VPU_OUTPUT_FORMAT_TYPE_MASK (0x0000ffff) +#define VPU_OUTPUT_FORMAT_ARGB8888 (0x00000000) +#define VPU_OUTPUT_FORMAT_ABGR8888 (0x00000001) +#define VPU_OUTPUT_FORMAT_RGB888 (0x00000002) +#define VPU_OUTPUT_FORMAT_RGB565 (0x00000003) +#define VPU_OUTPUT_FORMAT_RGB555 (0x00000004) +#define VPU_OUTPUT_FORMAT_YUV420_SEMIPLANAR (0x00000005) +#define VPU_OUTPUT_FORMAT_YUV420_PLANAR (0x00000006) +#define VPU_OUTPUT_FORMAT_YUV422 (0x00000007) +#define VPU_OUTPUT_FORMAT_YUV444 (0x00000008) +#define VPU_OUTPUT_FORMAT_YCH420 (0x00000009) +#define VPU_OUTPUT_FORMAT_BIT_MASK (0x000f0000) +#define VPU_OUTPUT_FORMAT_BIT_8 (0x00000000) +#define VPU_OUTPUT_FORMAT_BIT_10 (0x00010000) +#define VPU_OUTPUT_FORMAT_BIT_12 (0x00020000) +#define VPU_OUTPUT_FORMAT_BIT_14 (0x00030000) +#define VPU_OUTPUT_FORMAT_BIT_16 (0x00040000) +#define VPU_OUTPUT_FORMAT_COLORSPACE_MASK (0x00f00000) +#define VPU_OUTPUT_FORMAT_COLORSPACE_BT709 (0x00100000) +#define VPU_OUTPUT_FORMAT_COLORSPACE_BT2020 (0x00200000) +#define VPU_OUTPUT_FORMAT_DYNCRANGE_MASK (0x0f000000) +#define VPU_OUTPUT_FORMAT_DYNCRANGE_SDR (0x00000000) +#define VPU_OUTPUT_FORMAT_DYNCRANGE_HDR10 (0x01000000) +#define VPU_OUTPUT_FORMAT_DYNCRANGE_HDR_HLG (0x02000000) +#define VPU_OUTPUT_FORMAT_DYNCRANGE_HDR_DOLBY (0x03000000) + +/** + * @brief input picture type + */ +typedef enum { + ENC_INPUT_YUV420_PLANAR = 0, /**< YYYY... UUUU... VVVV */ + ENC_INPUT_YUV420_SEMIPLANAR = 1, /**< YYYY... UVUVUV... */ + ENC_INPUT_YUV422_INTERLEAVED_YUYV = 2, /**< YUYVYUYV... */ + ENC_INPUT_YUV422_INTERLEAVED_UYVY = 3, /**< UYVYUYVY... */ + ENC_INPUT_RGB565 = 4, /**< 16-bit RGB */ + ENC_INPUT_BGR565 = 5, /**< 16-bit RGB */ + ENC_INPUT_RGB555 = 6, /**< 15-bit RGB */ + ENC_INPUT_BGR555 = 7, /**< 15-bit RGB */ + ENC_INPUT_RGB444 = 8, /**< 12-bit RGB */ + ENC_INPUT_BGR444 = 9, /**< 12-bit RGB */ + ENC_INPUT_RGB888 = 10, /**< 24-bit RGB */ + ENC_INPUT_BGR888 = 11, /**< 24-bit RGB */ + ENC_INPUT_RGB101010 = 12, /**< 30-bit RGB */ + ENC_INPUT_BGR101010 = 13 /**< 30-bit RGB */ +} EncInputPictureType; + +typedef enum VPU_API_CMD { + VPU_API_ENC_SETCFG, + VPU_API_ENC_GETCFG, + VPU_API_ENC_SETFORMAT, + VPU_API_ENC_SETIDRFRAME, + + VPU_API_ENABLE_DEINTERLACE, + VPU_API_SET_VPUMEM_CONTEXT, + VPU_API_USE_PRESENT_TIME_ORDER, + VPU_API_SET_DEFAULT_WIDTH_HEIGH, + VPU_API_SET_INFO_CHANGE, + VPU_API_USE_FAST_MODE, + VPU_API_DEC_GET_STREAM_COUNT, + VPU_API_GET_VPUMEM_USED_COUNT, + VPU_API_GET_FRAME_INFO, + VPU_API_SET_OUTPUT_BLOCK, + VPU_API_GET_EOS_STATUS, + + VPU_API_SET_IMMEDIATE_OUT = 0x1000, + VPU_API_ENC_VEPU22_START = 0x2000, + VPU_API_ENC_SET_VEPU22_CFG, + VPU_API_ENC_GET_VEPU22_CFG, + VPU_API_ENC_SET_VEPU22_CTU_QP, + VPU_API_ENC_SET_VEPU22_ROI, + +} VPU_API_CMD; + +typedef struct { + RK_U32 TimeLow; + RK_U32 TimeHigh; +} TIME_STAMP; + +typedef struct { + RK_U32 CodecType; + RK_U32 ImgWidth; + RK_U32 ImgHeight; + RK_U32 ImgHorStride; + RK_U32 ImgVerStride; + RK_U32 BufSize; +} VPU_GENERIC; + +typedef struct VPUMem { + RK_U32 phy_addr; + RK_U32 *vir_addr; + RK_U32 size; + RK_U32 *offset; +} VPUMemLinear_t; + +typedef struct tVPU_FRAME { + RK_U32 FrameBusAddr[2]; // 0: Y address; 1: UV address; + RK_U32 FrameWidth; // buffer horizontal stride + RK_U32 FrameHeight; // buffer vertical stride + RK_U32 OutputWidth; // deprecated + RK_U32 OutputHeight; // deprecated + RK_U32 DisplayWidth; // valid width for display + RK_U32 DisplayHeight; // valid height for display + RK_U32 CodingType; + RK_U32 FrameType; // frame; top_field_first; bot_field_first + RK_U32 ColorType; + RK_U32 DecodeFrmNum; + TIME_STAMP ShowTime; + RK_U32 ErrorInfo; // error information + RK_U32 employ_cnt; + VPUMemLinear_t vpumem; + struct tVPU_FRAME *next_frame; + union { + struct { + RK_U32 Res0[2]; + struct { + RK_U32 ColorPrimaries : 8; + RK_U32 ColorTransfer : 8; + RK_U32 ColorCoeffs : 8; + RK_U32 ColorRange : 1; + RK_U32 Res1 : 7; + }; + + RK_U32 Res2; + }; + + RK_U32 Res[4]; + }; +} VPU_FRAME; + +typedef struct VideoPacket { + RK_S64 pts; /* with unit of us*/ + RK_S64 dts; /* with unit of us*/ + RK_U8 *data; + RK_S32 size; + RK_U32 capability; + RK_U32 nFlags; +} VideoPacket_t; + +typedef struct DecoderOut { + RK_U8 *data; + RK_U32 size; + RK_S64 timeUs; + RK_S32 nFlags; +} DecoderOut_t; + +typedef struct ParserOut { + RK_U8 *data; + RK_U32 size; + RK_S64 timeUs; + RK_U32 nFlags; + RK_U32 width; + RK_U32 height; +} ParserOut_t; + +typedef struct EncInputStream { + RK_U8 *buf; + RK_S32 size; + RK_U32 bufPhyAddr; + RK_S64 timeUs; + RK_U32 nFlags; +} EncInputStream_t; + +typedef struct EncoderOut { + RK_U8 *data; + RK_S32 size; + RK_S64 timeUs; + RK_S32 keyFrame; + +} EncoderOut_t; + +/* + * @brief Enumeration used to define the possible video compression codings. + * @note This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + * + * sync with the omx_video.h + */ +typedef enum OMX_RK_VIDEO_CODINGTYPE { + OMX_RK_VIDEO_CodingUnused, /**< Value when coding is N/A */ + OMX_RK_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + OMX_RK_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + OMX_RK_VIDEO_CodingH263, /**< H.263 */ + OMX_RK_VIDEO_CodingMPEG4, /**< MPEG-4 */ + OMX_RK_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + OMX_RK_VIDEO_CodingRV, /**< all versions of Real Video */ + OMX_RK_VIDEO_CodingAVC, /**< H.264/AVC */ + OMX_RK_VIDEO_CodingMJPEG, /**< Motion JPEG */ + OMX_RK_VIDEO_CodingVP8, /**< VP8 */ + OMX_RK_VIDEO_CodingVP9, /**< VP9 */ + OMX_RK_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + OMX_RK_VIDEO_CodingFLV1, /**< Sorenson H.263 */ + OMX_RK_VIDEO_CodingDIVX3, /**< DIVX3 */ + OMX_RK_VIDEO_CodingVP6, + OMX_RK_VIDEO_CodingHEVC, /**< H.265/HEVC */ + OMX_RK_VIDEO_CodingAVS, /**< AVS+ */ + OMX_RK_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_RK_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_RK_VIDEO_CodingMax = 0x7FFFFFFF +} OMX_RK_VIDEO_CODINGTYPE; + +typedef enum CODEC_TYPE { + CODEC_NONE, + CODEC_DECODER, + CODEC_ENCODER, + CODEC_BUTT, +} CODEC_TYPE; + +typedef enum VPU_API_ERR { + VPU_API_OK = 0, + VPU_API_ERR_UNKNOW = -1, + VPU_API_ERR_BASE = -1000, + VPU_API_ERR_LIST_STREAM = VPU_API_ERR_BASE - 1, + VPU_API_ERR_INIT = VPU_API_ERR_BASE - 2, + VPU_API_ERR_VPU_CODEC_INIT = VPU_API_ERR_BASE - 3, + VPU_API_ERR_STREAM = VPU_API_ERR_BASE - 4, + VPU_API_ERR_FATAL_THREAD = VPU_API_ERR_BASE - 5, + VPU_API_EOS_STREAM_REACHED = VPU_API_ERR_BASE - 11, + + VPU_API_ERR_BUTT, +} VPU_API_ERR; + +typedef enum VPU_FRAME_ERR { + VPU_FRAME_ERR_UNKNOW = 0x0001, + VPU_FRAME_ERR_UNSUPPORT = 0x0002, + +} VPU_FRAME_ERR; + +typedef struct EncParameter { + RK_S32 width; + RK_S32 height; + RK_S32 rc_mode; /* 0 - CQP mode; 1 - CBR mode; */ + RK_S32 bitRate; /* target bitrate */ + RK_S32 framerate; + RK_S32 qp; + RK_S32 enableCabac; + RK_S32 cabacInitIdc; + RK_S32 format; + RK_S32 intraPicRate; + RK_S32 framerateout; + RK_S32 profileIdc; + RK_S32 levelIdc; + RK_S32 reserved[3]; +} EncParameter_t; + +typedef struct EXtraCfg { + RK_S32 vc1extra_size; + RK_S32 vp6codeid; + RK_S32 tsformat; + RK_U32 ori_vpu; /* use origin vpu framework */ + /* below used in decode */ + RK_U32 mpp_mode; /* use mpp framework */ + RK_U32 bit_depth; /* 8 or 10 bit */ + RK_U32 yuv_format; /* 0:420 1:422 2:444 */ + RK_U32 reserved[16]; +} EXtraCfg_t; + +/** + * @brief vpu function interface + */ +typedef struct VpuCodecContext { + void* vpuApiObj; + + CODEC_TYPE codecType; + OMX_RK_VIDEO_CODINGTYPE videoCoding; + + RK_U32 width; + RK_U32 height; + void *extradata; + RK_S32 extradata_size; + + RK_U8 enableparsing; + + RK_S32 no_thread; + EXtraCfg_t extra_cfg; + + void* private_data; + + /* + ** 1: error state(not working) 0: working + */ + RK_S32 decoder_err; + + + /** + * Allocate and initialize an VpuCodecContext. + * + * @param ctx The context of vpu api, allocated in this function. + * @param extraData The extra data of codec, some codecs need / can + * use extradata like Huffman tables, also live VC1 codec can + * use extradata to initialize itself. + * @param extra_size The size of extra data. + * + * @return 0 for init success, others for failure. + * @note check whether ctx has been allocated success after you do init. + */ + RK_S32 (*init)(struct VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size); + /** + * @brief both send video stream packet to decoder and get video frame from + * decoder at the same time + * @param ctx The context of vpu codec + * @param pkt[in] Stream to be decoded + * @param aDecOut[out] Decoding frame + * @return 0 for decode success, others for failure. + */ + RK_S32 (*decode)(struct VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut); + /** + * @brief both send video frame to encoder and get encoded video stream from + * encoder at the same time. + * @param ctx The context of vpu codec + * @param aEncInStrm[in] Frame to be encoded + * @param aEncOut[out] Encoding stream + * @return 0 for encode success, others for failure. + */ + RK_S32 (*encode)(struct VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut); + /** + * @brief flush codec while do fast forward playing. + * @param ctx The context of vpu codec + * @return 0 for flush success, others for failure. + */ + RK_S32 (*flush)(struct VpuCodecContext *ctx); + RK_S32 (*control)(struct VpuCodecContext *ctx, VPU_API_CMD cmdType, void* param); + /** + * @brief send video stream packet to decoder only, async interface + * @param ctx The context of vpu codec + * @param pkt Stream to be decoded + * @return 0 for success, others for failure. + */ + RK_S32 (*decode_sendstream)(struct VpuCodecContext *ctx, VideoPacket_t *pkt); + /** + * @brief get video frame from decoder only, async interface + * @param ctx The context of vpu codec + * @param aDecOut Decoding frame + * @return 0 for success, others for failure. + */ + RK_S32 (*decode_getframe)(struct VpuCodecContext *ctx, DecoderOut_t *aDecOut); + /** + * @brief send video frame to encoder only, async interface + * @param ctx The context of vpu codec + * @param aEncInStrm Frame to be encoded + * @return 0 for success, others for failure. + */ + RK_S32 (*encoder_sendframe)(struct VpuCodecContext *ctx, EncInputStream_t *aEncInStrm); + /** + * @brief get encoded video packet from encoder only, async interface + * @param ctx The context of vpu codec + * @param aEncOut Encoding stream + * @return 0 for success, others for failure. + */ + RK_S32 (*encoder_getstream)(struct VpuCodecContext *ctx, EncoderOut_t *aEncOut); +} VpuCodecContext_t; + +/* allocated vpu codec context */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief open context of vpu + * @param ctx pointer of vpu codec context + */ +RK_S32 vpu_open_context(struct VpuCodecContext **ctx); +/** + * @brief close context of vpu + * @param ctx pointer of vpu codec context + */ +RK_S32 vpu_close_context(struct VpuCodecContext **ctx); + +#ifdef __cplusplus +} +#endif + +/* + * vpu_mem api + */ +#define vpu_display_mem_pool_FIELDS \ + RK_S32 (*commit_hdl)(vpu_display_mem_pool *p, RK_S32 hdl, RK_S32 size); \ + void* (*get_free)(vpu_display_mem_pool *p); \ + RK_S32 (*inc_used)(vpu_display_mem_pool *p, void *hdl); \ + RK_S32 (*put_used)(vpu_display_mem_pool *p, void *hdl); \ + RK_S32 (*reset)(vpu_display_mem_pool *p); \ + RK_S32 (*get_unused_num)(vpu_display_mem_pool *p); \ + RK_S32 buff_size;\ + float version; \ + RK_S32 res[18]; + +typedef struct vpu_display_mem_pool vpu_display_mem_pool; + +struct vpu_display_mem_pool { + vpu_display_mem_pool_FIELDS +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * vpu memory handle interface + */ +RK_S32 VPUMemJudgeIommu(void); +RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size); +RK_S32 VPUFreeLinear(VPUMemLinear_t *p); +RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src); +RK_S32 VPUMemLink(VPUMemLinear_t *p); +RK_S32 VPUMemFlush(VPUMemLinear_t *p); +RK_S32 VPUMemClean(VPUMemLinear_t *p); +RK_S32 VPUMemInvalidate(VPUMemLinear_t *p); +RK_S32 VPUMemGetFD(VPUMemLinear_t *p); +RK_S32 VPUMallocLinearFromRender(VPUMemLinear_t *p, RK_U32 size, void *ctx); + +/* + * vpu memory allocator and manager interface + */ +vpu_display_mem_pool* open_vpu_memory_pool(void); +void close_vpu_memory_pool(vpu_display_mem_pool *p); +int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size); +void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool); + +#ifdef __cplusplus +} +#endif + +#endif /*__VPU_API_LEGACY_H__*/ diff --git a/mpp/lib/libhal_dummy.a b/mpp/lib/libhal_dummy.a new file mode 100755 index 0000000..b039118 Binary files /dev/null and b/mpp/lib/libhal_dummy.a differ diff --git a/mpp/lib/libosal.a b/mpp/lib/libosal.a new file mode 100755 index 0000000..f2b4c73 Binary files /dev/null and b/mpp/lib/libosal.a differ diff --git a/mpp/lib/librockchip_mpp.so b/mpp/lib/librockchip_mpp.so new file mode 100755 index 0000000..bb209cc Binary files /dev/null and b/mpp/lib/librockchip_mpp.so differ diff --git a/mpp/lib/librockchip_mpp.so.0 b/mpp/lib/librockchip_mpp.so.0 new file mode 100755 index 0000000..bb209cc Binary files /dev/null and b/mpp/lib/librockchip_mpp.so.0 differ diff --git a/mpp/lib/librockchip_mpp.so.1 b/mpp/lib/librockchip_mpp.so.1 new file mode 100755 index 0000000..bb209cc Binary files /dev/null and b/mpp/lib/librockchip_mpp.so.1 differ diff --git a/mpp/lib/librockchip_mpp_static.a b/mpp/lib/librockchip_mpp_static.a new file mode 100755 index 0000000..420ba81 Binary files /dev/null and b/mpp/lib/librockchip_mpp_static.a differ diff --git a/mpp/lib/librockchip_vpu.so b/mpp/lib/librockchip_vpu.so new file mode 100755 index 0000000..c8ebc15 Binary files /dev/null and b/mpp/lib/librockchip_vpu.so differ diff --git a/mpp/lib/librockchip_vpu.so.0 b/mpp/lib/librockchip_vpu.so.0 new file mode 100755 index 0000000..c8ebc15 Binary files /dev/null and b/mpp/lib/librockchip_vpu.so.0 differ diff --git a/mpp/lib/librockchip_vpu.so.1 b/mpp/lib/librockchip_vpu.so.1 new file mode 100755 index 0000000..c8ebc15 Binary files /dev/null and b/mpp/lib/librockchip_vpu.so.1 differ diff --git a/mpp/lib/librockchip_vpu_static.a b/mpp/lib/librockchip_vpu_static.a new file mode 100755 index 0000000..7594b8d Binary files /dev/null and b/mpp/lib/librockchip_vpu_static.a differ diff --git a/mpp/lib/libutils.a b/mpp/lib/libutils.a new file mode 100755 index 0000000..998837c Binary files /dev/null and b/mpp/lib/libutils.a differ diff --git a/myrga.cpp b/myrga.cpp new file mode 100644 index 0000000..dc7aaf3 --- /dev/null +++ b/myrga.cpp @@ -0,0 +1,250 @@ +#define LOG_NDEBUG 0 +#define LOG_TAG "rgaClip" + +#include "myrga.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/// +// #include "../drmrga.h" +#include +#include +#include +#include +#include +#include + +#include +#include +// #include +/// +rga_client_t rga_client; + +// const int SRCFMT = RK_FORMAT_YCrCb_420_SP; +const int SRCFMT = RK_FORMAT_YCbCr_420_SP; +const int DSTFMT = RK_FORMAT_RGB_888; + +// const int DSTWidth = 640; +// const int DSTHeight = 640; + +int rga_client_t::convert(unsigned char *src, int sw, int sh, int swstride, int shstride, char *out) +{ + RockchipRga &rga(RockchipRga::getInstance()); + int ret = 0; + char *buf = (char *)src; + // get_buf_from_file(buf, SRCFMT, sw, sh, 1); + // out should be 1280*720*3 + buf = out; + // get_buf_from_file(buf, DSTFMT, DSTWidth, DSTHeight, 0); + + while (1) + { + // ********** rga_info_t Init ********** + rga_info_t rgasrc; + rga_info_t rgadst; + + memset(&rgasrc, 0, sizeof(rga_info_t)); + rgasrc.fd = -1; + rgasrc.mmuFlag = 1; + rgasrc.virAddr = src; + + memset(&rgadst, 0, sizeof(rga_info_t)); + rgadst.fd = -1; + rgadst.mmuFlag = 1; + rgadst.virAddr = out; + + struct timeval tpend1, tpend2; + long usec1 = 0; + + gettimeofday(&tpend1, NULL); + + rgadst.color = 0xcccccc; + rga_set_rect(&rgadst.rect, 0, 0, DSTWidth, DSTHeight, DSTWidth, DSTHeight, DSTFMT); + rga.RkRgaCollorFill(&rgadst); + + float widthratio = 1.0 * swstride / DSTWidth; + float heightratio = 1.0 * shstride / DSTHeight; + + int TMPWIDTH = DSTWidth; + int TMPHEIGHT = DSTHeight; + int startwidth = 0; + int startheight = 0; + if (widthratio < heightratio) + { + TMPWIDTH = int(swstride / heightratio); + startwidth = int((DSTWidth - TMPWIDTH) / 2); + } + else + { + TMPHEIGHT = int(shstride / widthratio); + startheight = int((DSTHeight - TMPHEIGHT) / 2); + } + + // ********** set the rect_info ********** + rga_set_rect(&rgasrc.rect, 0, 0, sw, sh, + // stride + swstride, shstride, SRCFMT); + /* + rga_set_rect(&rgadst.rect, 0, 0, DSTWidth, DSTHeight, + // stride + DSTWidth, DSTHeight, + DSTFMT); + */ + rga_set_rect(&rgadst.rect, startwidth, startheight, TMPWIDTH, TMPHEIGHT, DSTWidth, DSTHeight, DSTFMT); + + // ************ set the rga_mod ,rotation\composition\scale\copy .... ********** + // rgasrc.blend = 0xff0105; + // rga_set_rect(&rgasrc.rect, 0, 0, sw, sh, swstride, shstride, SRCFMT); + // rga_set_rect(&rgadst.rect, 0, 0, DSTWidth, DSTHeight, DSTWidth, DSTHeight, DSTFMT); + + // ********** call rga_Interface ********** + ret = rga.RkRgaBlit(&rgasrc, &rgadst, NULL); + + gettimeofday(&tpend2, NULL); + usec1 = 1000 * (tpend2.tv_sec - tpend1.tv_sec) + (tpend2.tv_usec - tpend1.tv_usec) / 1000; + + printf("rga cost_time=%ld ms\n", usec1); + + if (ret) + { + printf("rgaFillColor error : %s\n", + strerror(errno)); + } + + { + // ********** output buf data to file ********* + /* + char* dstbuf = (char *)dst; + output_buf_data_to_file(dstbuf, dstFormat, dstWidth, dstHeight, 0); + */ + } + // printf("threadloop\n"); + usleep(5000); + break; + } + return 0; +} + +void initRkRga() +{ +} + +void deinitRkRga() +{ +} + +// using namespace android; + +/* +int main() { + int ret = 0; + int srcWidth,srcHeight,srcFormat; + int dstWidth,dstHeight,dstFormat; + + void *src = NULL; + void *dst = NULL; + + srcWidth = 1280; + srcHeight = 720; + // srcFormat = HAL_PIXEL_FORMAT_RGBA_8888; + srcFormat = RK_FORMAT_RGBA_8888; + + dstWidth = 1280; + dstHeight = 720; + //dstFormat = HAL_PIXEL_FORMAT_RGBA_8888; + dstFormat = RK_FORMAT_RGBA_8888; + + // ********** apply for buffer ********** + src = malloc(srcWidth * srcHeight * 4); + if (!src) + return -ENOMEM; + + //********** apply for buffer ********** + dst = malloc(dstWidth * dstHeight * 4); + if (!dst) { + free(src); + return -ENOMEM; + } + + RockchipRga& rkRga(RockchipRga::get()); + + // ********** get data to src_buffer or init buffer********** + char* buf = (char *)src; +#if 1 + get_buf_from_file(buf, srcFormat, srcWidth, srcHeight, 1); +#else + memset(buf,0x55,4*1280*720); +#endif + + // ********** get data to dst_buffer or init buffer ********** + buf = (char *)dst; +#if 1 + get_buf_from_file(buf, srcFormat, srcWidth, srcHeight, 0); +#else + memset(buf,0x00,4*1280*720); +#endif + + while(1) { + // ********** rga_info_t Init ********** + rga_info_t rgasrc; + rga_info_t rgadst; + + memset(&rgasrc, 0, sizeof(rga_info_t)); + rgasrc.fd = -1; + rgasrc.mmuFlag = 1; + rgasrc.virAddr = src; + + memset(&rgadst, 0, sizeof(rga_info_t)); + rgadst.fd = -1; + rgadst.mmuFlag = 1; + rgadst.virAddr = dst; + + // ********** set the rect_info ********** + rga_set_rect(&rgasrc.rect, 0,0,srcWidth,srcHeight, + // stride + srcWidth,srcHeight, + srcFormat); + rga_set_rect(&rgadst.rect, 0,0,dstWidth,dstHeight, + // stride + dstWidth,dstHeight, + dstFormat); + + // ************ set the rga_mod ,rotation\composition\scale\copy .... ********** + rgasrc.blend = 0xff0105; + + // ********** call rga_Interface ********** + struct timeval tpend1, tpend2; + long usec1 = 0; + gettimeofday(&tpend1, NULL); + ret = rkRga.RkRgaBlit(&rgasrc, &rgadst, NULL); + gettimeofday(&tpend2, NULL); + usec1 = 1000 * (tpend2.tv_sec - tpend1.tv_sec) + (tpend2.tv_usec - tpend1.tv_usec) / 1000; + printf("cost_time=%ld ms\n", usec1); + + if (ret) { + printf("rgaFillColor error : %s\n", + strerror(errno)); + } + + { + // ********** output buf data to file ********* + char* dstbuf = (char *)dst; + output_buf_data_to_file(dstbuf, dstFormat, dstWidth, dstHeight, 0); + } + printf("threadloop\n"); + usleep(500000); + break; + } + return 0; +} +*/ \ No newline at end of file diff --git a/myrga.h b/myrga.h new file mode 100644 index 0000000..21ee2e8 --- /dev/null +++ b/myrga.h @@ -0,0 +1,18 @@ +#ifndef _POSE_BODY_RGA_H_ +#define _POSE_BODY_RGA_H_ + +#define DSTWidth 640 +#define DSTHeight 640 + +class rga_client_t { + public: + rga_client_t() {}; + int convert(unsigned char *src, int sw, int sh, int swstride, int shstride, char *out); +}; + +extern rga_client_t rga_client; + +void initRkRga(); +void deinitRkRga(); + +#endif \ No newline at end of file diff --git a/pack.sh b/pack.sh new file mode 100755 index 0000000..79481ed --- /dev/null +++ b/pack.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +PWD=$(pwd) +DirName=efka-flow +BinName=efka_flow + +rm -rf ${DirName} +mkdir -p ${DirName} +cp build/mpp_test ${DirName}/${BinName} +cp .args.yaml ${DirName} +cd ${DirName} +md5sum ${BinName} > ${BinName}.md5 +tar -czvf ${BinName}_aarch.tgz ${BinName} ${BinName}.md5 .args.yaml diff --git a/pose_body.cpp b/pose_body.cpp new file mode 100644 index 0000000..ed59451 --- /dev/null +++ b/pose_body.cpp @@ -0,0 +1,13 @@ +#include "pose_body.h" +#include +#include +#include "cJSON.h" +#include "utils.h" +#include +#include "action.h" +#include "rknn.h" +#include "utils.h" + +#include + + diff --git a/pose_body.h b/pose_body.h new file mode 100644 index 0000000..ab65fa8 --- /dev/null +++ b/pose_body.h @@ -0,0 +1,11 @@ +#ifndef _POSE_BODY_H_ +#define _POSE_BODY_H_ + +#include "MppDecode.h" + +extern char *CameraID; +extern int TypeID; +extern int UploadPort; + + +#endif \ No newline at end of file diff --git a/postprocess.cc b/postprocess.cc new file mode 100644 index 0000000..e0c3258 --- /dev/null +++ b/postprocess.cc @@ -0,0 +1,657 @@ +// Copyright (c) 2021 by Rockchip Electronics Co., Ltd. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "yolov5.h" + +#include +#include +#include +#include +#include +#include + +#include "rknn.h" + +#include +#include +// #define LABEL_NALE_TXT_PATH "./model/coco_80_labels_list.txt" + +char *labels[OBJ_MAX_CLASS_NUM]; +int codes[OBJ_MAX_CLASS_NUM]; + +int OBJ_CLASS_REAL_NUM = 0; +int PROP_BOX_SIZE = 0; + +const int anchor[3][6] = {{10, 13, 16, 30, 33, 23}, + {30, 61, 62, 45, 59, 119}, + {116, 90, 156, 198, 373, 326}}; + +inline static int clamp(float val, int min, int max) { return val > min ? (val < max ? val : max) : min; } + + +static char *readLine(FILE *fp, char *buffer, int *len) +{ + int ch; + int i = 0; + size_t buff_len = 0; + + buffer = (char *)malloc(buff_len + 1); + if (!buffer) + return NULL; // Out of memory + + while ((ch = fgetc(fp)) != '\n' && ch != EOF) + { + buff_len++; + void *tmp = realloc(buffer, buff_len + 1); + if (tmp == NULL) + { + free(buffer); + return NULL; // Out of memory + } + buffer = (char *)tmp; + + buffer[i] = (char)ch; + i++; + } + buffer[i] = '\0'; + + *len = buff_len; + + // Detect end + if (ch == EOF && (i == 0 || ferror(fp))) + { + free(buffer); + return NULL; + } + return buffer; +} + +static int readLines(const char *fileName, char *lines[], int max_line) +{ + FILE *file = fopen(fileName, "r"); + char *s; + int i = 0; + int n = 0; + + if (file == NULL) + { + printf("Open %s fail!\n", fileName); + return -1; + } + + while ((s = readLine(file, s, &n)) != NULL) + { + printf("now is %s\n", s); + lines[i++] = s; + if (i >= max_line) + break; + } + OBJ_CLASS_REAL_NUM = i; + PROP_BOX_SIZE = (OBJ_CLASS_REAL_NUM + 5); + fclose(file); + return i; +} + +static int loadLabelName(const char *locationFilename, char *label[]) +{ + printf("load lable %s\n", locationFilename); + readLines(locationFilename, label, OBJ_MAX_CLASS_NUM); + for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++) { + printf("%d => %s\n", i, coco_cls_to_name(i)); + } + return 0; +} + +static float CalculateOverlap(float xmin0, float ymin0, float xmax0, float ymax0, float xmin1, float ymin1, float xmax1, + float ymax1) +{ + float w = fmax(0.f, fmin(xmax0, xmax1) - fmax(xmin0, xmin1) + 1.0); + float h = fmax(0.f, fmin(ymax0, ymax1) - fmax(ymin0, ymin1) + 1.0); + float i = w * h; + float u = (xmax0 - xmin0 + 1.0) * (ymax0 - ymin0 + 1.0) + (xmax1 - xmin1 + 1.0) * (ymax1 - ymin1 + 1.0) - i; + return u <= 0.f ? 0.f : (i / u); +} + +static int nms(int validCount, std::vector &outputLocations, std::vector classIds, std::vector &order, + int filterId, float threshold) +{ + for (int i = 0; i < validCount; ++i) + { + int n = order[i]; + if (n == -1 || classIds[n] != filterId) + { + continue; + } + for (int j = i + 1; j < validCount; ++j) + { + int m = order[j]; + if (m == -1 || classIds[m] != filterId) + { + continue; + } + float xmin0 = outputLocations[n * 4 + 0]; + float ymin0 = outputLocations[n * 4 + 1]; + float xmax0 = outputLocations[n * 4 + 0] + outputLocations[n * 4 + 2]; + float ymax0 = outputLocations[n * 4 + 1] + outputLocations[n * 4 + 3]; + + float xmin1 = outputLocations[m * 4 + 0]; + float ymin1 = outputLocations[m * 4 + 1]; + float xmax1 = outputLocations[m * 4 + 0] + outputLocations[m * 4 + 2]; + float ymax1 = outputLocations[m * 4 + 1] + outputLocations[m * 4 + 3]; + + float iou = CalculateOverlap(xmin0, ymin0, xmax0, ymax0, xmin1, ymin1, xmax1, ymax1); + + if (iou > threshold) + { + order[j] = -1; + } + } + } + return 0; +} + +static int quick_sort_indice_inverse(std::vector &input, int left, int right, std::vector &indices) +{ + float key; + int key_index; + int low = left; + int high = right; + if (left < right) + { + key_index = indices[left]; + key = input[left]; + while (low < high) + { + while (low < high && input[high] <= key) + { + high--; + } + input[low] = input[high]; + indices[low] = indices[high]; + while (low < high && input[low] >= key) + { + low++; + } + input[high] = input[low]; + indices[high] = indices[low]; + } + input[low] = key; + indices[low] = key_index; + quick_sort_indice_inverse(input, left, low - 1, indices); + quick_sort_indice_inverse(input, low + 1, right, indices); + } + return low; +} + +static float sigmoid(float x) { return 1.0 / (1.0 + expf(-x)); } + +static float unsigmoid(float y) { return -1.0 * logf((1.0 / y) - 1.0); } + +inline static int32_t __clip(float val, float min, float max) +{ + float f = val <= min ? min : (val >= max ? max : val); + return f; +} + +static int8_t qnt_f32_to_affine(float f32, int32_t zp, float scale) +{ + float dst_val = (f32 / scale) + zp; + int8_t res = (int8_t)__clip(dst_val, -128, 127); + return res; +} + +static uint8_t qnt_f32_to_affine_u8(float f32, int32_t zp, float scale) +{ + float dst_val = (f32 / scale) + zp; + uint8_t res = (uint8_t)__clip(dst_val, 0, 255); + return res; +} + +static float deqnt_affine_to_f32(int8_t qnt, int32_t zp, float scale) { return ((float)qnt - (float)zp) * scale; } +static float deqnt_affine_u8_to_f32(uint8_t qnt, int32_t zp, float scale) { return ((float)qnt - (float)zp) * scale; } + +static int process_u8(uint8_t *input, int *anchor, int grid_h, int grid_w, int height, int width, int stride, + std::vector &boxes, std::vector &objProbs, std::vector &classId, float threshold, + int32_t zp, float scale) +{ + int validCount = 0; + int grid_len = grid_h * grid_w; + uint8_t thres_u8 = qnt_f32_to_affine_u8(threshold, zp, scale); + for (int a = 0; a < 3; a++) + { + for (int i = 0; i < grid_h; i++) + { + for (int j = 0; j < grid_w; j++) + { + uint8_t box_confidence = input[(PROP_BOX_SIZE * a + 4) * grid_len + i * grid_w + j]; + if (box_confidence >= thres_u8) + { + int offset = (PROP_BOX_SIZE * a) * grid_len + i * grid_w + j; + uint8_t *in_ptr = input + offset; + float box_x = (deqnt_affine_u8_to_f32(*in_ptr, zp, scale)) * 2.0 - 0.5; + float box_y = (deqnt_affine_u8_to_f32(in_ptr[grid_len], zp, scale)) * 2.0 - 0.5; + float box_w = (deqnt_affine_u8_to_f32(in_ptr[2 * grid_len], zp, scale)) * 2.0; + float box_h = (deqnt_affine_u8_to_f32(in_ptr[3 * grid_len], zp, scale)) * 2.0; + box_x = (box_x + j) * (float)stride; + box_y = (box_y + i) * (float)stride; + box_w = box_w * box_w * (float)anchor[a * 2]; + box_h = box_h * box_h * (float)anchor[a * 2 + 1]; + box_x -= (box_w / 2.0); + box_y -= (box_h / 2.0); + + uint8_t maxClassProbs = in_ptr[5 * grid_len]; + int maxClassId = 0; + for (int k = 1; k < OBJ_CLASS_REAL_NUM; ++k) + { + uint8_t prob = in_ptr[(5 + k) * grid_len]; + if (prob > maxClassProbs) + { + maxClassId = k; + maxClassProbs = prob; + } + } + float limit_score = (deqnt_affine_u8_to_f32(maxClassProbs, zp, scale)) * (deqnt_affine_u8_to_f32(box_confidence, zp, scale)); + if (limit_score >= threshold) + { + objProbs.push_back(limit_score); + classId.push_back(maxClassId); + validCount++; + boxes.push_back(box_x); + boxes.push_back(box_y); + boxes.push_back(box_w); + boxes.push_back(box_h); + } + } + } + } + } + return validCount; +} + +static int process_i8(int8_t *input, int *anchor, int grid_h, int grid_w, int height, int width, int stride, + std::vector &boxes, std::vector &objProbs, std::vector &classId, float threshold, + int32_t zp, float scale) +{ + int validCount = 0; + int grid_len = grid_h * grid_w; + int8_t thres_i8 = qnt_f32_to_affine(threshold, zp, scale); + for (int a = 0; a < 3; a++) + { + for (int i = 0; i < grid_h; i++) + { + for (int j = 0; j < grid_w; j++) + { + int8_t box_confidence = input[(PROP_BOX_SIZE * a + 4) * grid_len + i * grid_w + j]; + if (box_confidence >= thres_i8) + { + int offset = (PROP_BOX_SIZE * a) * grid_len + i * grid_w + j; + int8_t *in_ptr = input + offset; + float box_x = (deqnt_affine_to_f32(*in_ptr, zp, scale)) * 2.0 - 0.5; + float box_y = (deqnt_affine_to_f32(in_ptr[grid_len], zp, scale)) * 2.0 - 0.5; + float box_w = (deqnt_affine_to_f32(in_ptr[2 * grid_len], zp, scale)) * 2.0; + float box_h = (deqnt_affine_to_f32(in_ptr[3 * grid_len], zp, scale)) * 2.0; + box_x = (box_x + j) * (float)stride; + box_y = (box_y + i) * (float)stride; + box_w = box_w * box_w * (float)anchor[a * 2]; + box_h = box_h * box_h * (float)anchor[a * 2 + 1]; + box_x -= (box_w / 2.0); + box_y -= (box_h / 2.0); + + int8_t maxClassProbs = in_ptr[5 * grid_len]; + int maxClassId = 0; + for (int k = 1; k < OBJ_CLASS_REAL_NUM; ++k) + { + int8_t prob = in_ptr[(5 + k) * grid_len]; + if (prob > maxClassProbs) + { + maxClassId = k; + maxClassProbs = prob; + } + } + float limit_score = (deqnt_affine_to_f32(maxClassProbs, zp, scale)) * (deqnt_affine_to_f32(box_confidence, zp, scale)); + if (limit_score >= threshold) + { + objProbs.push_back(limit_score); + classId.push_back(maxClassId); + validCount++; + boxes.push_back(box_x); + boxes.push_back(box_y); + boxes.push_back(box_w); + boxes.push_back(box_h); + } + } + } + } + } + return validCount; +} + +static int process_i8_rv1106(int8_t *input, int *anchor, int grid_h, int grid_w, int height, int width, int stride, + std::vector &boxes, std::vector &boxScores, std::vector &classId, float threshold, + int32_t zp, float scale) { + int validCount = 0; + int8_t thres_i8 = qnt_f32_to_affine(threshold, zp, scale); + + int anchor_per_branch = 3; + int align_c = PROP_BOX_SIZE * anchor_per_branch; + + for (int h = 0; h < grid_h; h++) { + for (int w = 0; w < grid_w; w++) { + for (int a = 0; a < anchor_per_branch; a++) { + int hw_offset = h * grid_w * align_c + w * align_c + a * PROP_BOX_SIZE; + int8_t *hw_ptr = input + hw_offset; + int8_t box_confidence = hw_ptr[4]; + + if (box_confidence >= thres_i8) { + int8_t maxClassProbs = hw_ptr[5]; + int maxClassId = 0; + for (int k = 1; k < OBJ_CLASS_REAL_NUM; ++k) { + int8_t prob = hw_ptr[5 + k]; + if (prob > maxClassProbs) { + maxClassId = k; + maxClassProbs = prob; + } + } + + float box_conf_f32 = deqnt_affine_to_f32(box_confidence, zp, scale); + float class_prob_f32 = deqnt_affine_to_f32(maxClassProbs, zp, scale); + float limit_score = box_conf_f32 * class_prob_f32; + + if (limit_score > threshold) { + float box_x, box_y, box_w, box_h; + + box_x = deqnt_affine_to_f32(hw_ptr[0], zp, scale) * 2.0 - 0.5; + box_y = deqnt_affine_to_f32(hw_ptr[1], zp, scale) * 2.0 - 0.5; + box_w = deqnt_affine_to_f32(hw_ptr[2], zp, scale) * 2.0; + box_h = deqnt_affine_to_f32(hw_ptr[3], zp, scale) * 2.0; + box_w = box_w * box_w; + box_h = box_h * box_h; + + + box_x = (box_x + w) * (float)stride; + box_y = (box_y + h) * (float)stride; + box_w *= (float)anchor[a * 2]; + box_h *= (float)anchor[a * 2 + 1]; + + box_x -= (box_w / 2.0); + box_y -= (box_h / 2.0); + + boxes.push_back(box_x); + boxes.push_back(box_y); + boxes.push_back(box_w); + boxes.push_back(box_h); + boxScores.push_back(limit_score); + classId.push_back(maxClassId); + validCount++; + } + } + } + } + } + return validCount; +} + +static int process_fp32(float *input, int *anchor, int grid_h, int grid_w, int height, int width, int stride, + std::vector &boxes, std::vector &objProbs, std::vector &classId, float threshold) +{ + int validCount = 0; + int grid_len = grid_h * grid_w; + + for (int a = 0; a < 3; a++) + { + for (int i = 0; i < grid_h; i++) + { + for (int j = 0; j < grid_w; j++) + { + float box_confidence = input[(PROP_BOX_SIZE * a + 4) * grid_len + i * grid_w + j]; + if (box_confidence >= threshold) + { + int offset = (PROP_BOX_SIZE * a) * grid_len + i * grid_w + j; + float *in_ptr = input + offset; + float box_x = *in_ptr * 2.0 - 0.5; + float box_y = in_ptr[grid_len] * 2.0 - 0.5; + float box_w = in_ptr[2 * grid_len] * 2.0; + float box_h = in_ptr[3 * grid_len] * 2.0; + box_x = (box_x + j) * (float)stride; + box_y = (box_y + i) * (float)stride; + box_w = box_w * box_w * (float)anchor[a * 2]; + box_h = box_h * box_h * (float)anchor[a * 2 + 1]; + box_x -= (box_w / 2.0); + box_y -= (box_h / 2.0); + + float maxClassProbs = in_ptr[5 * grid_len]; + int maxClassId = 0; + for (int k = 1; k < OBJ_CLASS_REAL_NUM; ++k) + { + float prob = in_ptr[(5 + k) * grid_len]; + if (prob > maxClassProbs) + { + maxClassId = k; + maxClassProbs = prob; + } + } + if (maxClassProbs > threshold) + { + objProbs.push_back(maxClassProbs * box_confidence); + classId.push_back(maxClassId); + validCount++; + boxes.push_back(box_x); + boxes.push_back(box_y); + boxes.push_back(box_w); + boxes.push_back(box_h); + } + } + } + } + } + return validCount; +} + +int readLinesCode(const char *fileName, int lines[], int max_line) +{ + FILE *file = fopen(fileName, "r"); + char *s; + int i = 0; + int n = 0; + int result = 0; + while ((s = readLine(file, s, &n)) != NULL) + { + result = atoi(s); + lines[i++] = result; + if (i >= max_line) + break; + } + return i; +} + +int loadCodes(const char *locationFilename, int label[]) +{ + for (int i = 0; i < OBJ_MAX_CLASS_NUM; i++) + { + codes[i] = i; + } + printf("load codes %s\n", locationFilename); + readLinesCode(locationFilename, label, OBJ_CLASS_REAL_NUM); + // PROP_BOX_SIZE = OBJ_CLASS_NUM + 5; + for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++) + { + printf("%d => %d\n", i, codes[i]); + } + return 0; +} + +int post_process(rknn_app_context_t *app_ctx, void *outputs, letterbox_t *letter_box, float conf_threshold, float nms_threshold, object_detect_result_list *od_results) +{ +#if defined(RV1106_1103) + rknn_tensor_mem **_outputs = (rknn_tensor_mem **)outputs; +#else + rknn_output *_outputs = (rknn_output *)outputs; +#endif + std::vector filterBoxes; + std::vector objProbs; + std::vector classId; + int validCount = 0; + int stride = 0; + int grid_h = 0; + int grid_w = 0; + int model_in_w = app_ctx->model_width; + int model_in_h = app_ctx->model_height; + + memset(od_results, 0, sizeof(object_detect_result_list)); + + for (int i = 0; i < 3; i++) + { + +#if defined(RV1106_1103) + grid_h = app_ctx->output_attrs[i].dims[2]; + grid_w = app_ctx->output_attrs[i].dims[3]; + stride = model_in_h / grid_h; + //RV1106 only support i8 + if (app_ctx->is_quant) { + validCount += process_i8((int8_t *)(_outputs[i]->virt_addr), (int *)anchor[i], grid_h, grid_w, model_in_h, model_in_w, stride, filterBoxes, objProbs, + classId, conf_threshold, app_ctx->output_attrs[i].zp, app_ctx->output_attrs[i].scale); + } +#elif defined(RKNPU1) + // NCHW reversed: WHCN + grid_h = app_ctx->output_attrs[i].dims[1]; + grid_w = app_ctx->output_attrs[i].dims[0]; + stride = model_in_h / grid_h; + /* + if (app_ctx->is_quant) + { + validCount += process_u8((uint8_t *)_outputs[i].buf, (int *)anchor[i], grid_h, grid_w, model_in_h, model_in_w, stride, filterBoxes, objProbs, + classId, conf_threshold, app_ctx->output_attrs[i].zp, app_ctx->output_attrs[i].scale); + } + else + { + validCount += process_fp32((float *)_outputs[i].buf, (int *)anchor[i], grid_h, grid_w, model_in_h, model_in_w, stride, filterBoxes, objProbs, + classId, conf_threshold); + } + */ + validCount += process_fp32((float *)_outputs[i].buf, (int *)anchor[i], grid_h, grid_w, model_in_h, model_in_w, stride, filterBoxes, objProbs, + classId, conf_threshold); +#else + grid_h = app_ctx->output_attrs[i].dims[2]; + grid_w = app_ctx->output_attrs[i].dims[3]; + stride = model_in_h / grid_h; + if (app_ctx->is_quant) + { + validCount += process_i8((int8_t *)_outputs[i].buf, (int *)anchor[i], grid_h, grid_w, model_in_h, model_in_w, stride, filterBoxes, objProbs, + classId, conf_threshold, app_ctx->output_attrs[i].zp, app_ctx->output_attrs[i].scale); + } + else + { + validCount += process_fp32((float *)_outputs[i].buf, (int *)anchor[i], grid_h, grid_w, model_in_h, model_in_w, stride, filterBoxes, objProbs, + classId, conf_threshold); + } +#endif + } + + // no object detect + if (validCount <= 0) + { + return 0; + } + std::vector indexArray; + for (int i = 0; i < validCount; ++i) + { + indexArray.push_back(i); + } + quick_sort_indice_inverse(objProbs, 0, validCount - 1, indexArray); + + std::set class_set(std::begin(classId), std::end(classId)); + + for (auto c : class_set) + { + nms(validCount, filterBoxes, classId, indexArray, c, nms_threshold); + } + + int last_count = 0; + od_results->count = 0; + + /* box valid detect target */ + for (int i = 0; i < validCount; ++i) + { + if (indexArray[i] == -1 || last_count >= OBJ_NUMB_MAX_SIZE) + { + continue; + } + int n = indexArray[i]; + + float x1 = filterBoxes[n * 4 + 0] - letter_box->x_pad; + float y1 = filterBoxes[n * 4 + 1] - letter_box->y_pad; + float x2 = x1 + filterBoxes[n * 4 + 2]; + float y2 = y1 + filterBoxes[n * 4 + 3]; + int id = classId[n]; + float obj_conf = objProbs[i]; + + od_results->results[last_count].box.left = (int)(clamp(x1, 0, model_in_w) / letter_box->scale); + od_results->results[last_count].box.top = (int)(clamp(y1, 0, model_in_h) / letter_box->scale); + od_results->results[last_count].box.right = (int)(clamp(x2, 0, model_in_w) / letter_box->scale); + od_results->results[last_count].box.bottom = (int)(clamp(y2, 0, model_in_h) / letter_box->scale); + od_results->results[last_count].prop = obj_conf; + od_results->results[last_count].cls_id = id; + last_count++; + } + od_results->count = last_count; + return 0; +} + +int init_post_process() +{ + + char txt_path[128]; + snprintf(txt_path, 127, "%s/%s.txt", MODELDIR, global_model); + + int ret = 0; + ret = loadLabelName(txt_path, labels); + if (ret < 0) + { + printf("Load %s failed!\n", txt_path); + return -1; + } + + snprintf(txt_path, 127, "%s/%s_code.txt", MODELDIR, global_model); + ret = loadCodes(txt_path, codes); + + return 0; +} + +const char *coco_cls_to_name(int cls_id) +{ + + if (cls_id >= OBJ_CLASS_REAL_NUM) + { + return "null"; + } + + if (labels[cls_id]) + { + return labels[cls_id]; + } + + return "null"; +} + +void deinit_post_process() +{ + for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++) + { + if (labels[i] != nullptr) + { + free(labels[i]); + labels[i] = nullptr; + } + } +} diff --git a/postprocess.h b/postprocess.h new file mode 100644 index 0000000..1ecc139 --- /dev/null +++ b/postprocess.h @@ -0,0 +1,33 @@ +#ifndef _RKNN_YOLOV5_DEMO_POSTPROCESS_H_ +#define _RKNN_YOLOV5_DEMO_POSTPROCESS_H_ + +#include +#include +#include "rknn_api.h" +#include "common.h" +#include "yolov5.h" + +#define RKNPU1 + +// #define PROP_BOX_SIZE (5 + OBJ_CLASS_NUM) + +extern int OBJ_CLASS_REAL_NUM; +extern int PROP_BOX_SIZE; + +extern char *labels[OBJ_MAX_CLASS_NUM]; +extern int codes[OBJ_MAX_CLASS_NUM]; + +// class rknn_app_context_t; +typedef struct { + int x_pad; + int y_pad; + float scale; +} letterbox_t; + +int init_post_process(); +void deinit_post_process(); +const char *coco_cls_to_name(int cls_id); +int post_process(rknn_app_context_t *app_ctx, void *outputs, letterbox_t *letter_box, float conf_threshold, float nms_threshold, object_detect_result_list *od_results); + +void deinitPostProcess(); +#endif //_RKNN_YOLOV5_DEMO_POSTPROCESS_H_ diff --git a/rga/inc/GrallocOps.h b/rga/inc/GrallocOps.h new file mode 100644 index 0000000..97e92d4 --- /dev/null +++ b/rga/inc/GrallocOps.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Authors: + * Zhiqin Wei + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _rk_graphic_buffer_h_ +#define _rk_graphic_buffer_h_ + +#ifdef ANDROID + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "drmrga.h" +#include "rga.h" + +// ------------------------------------------------------------------------------- +int RkRgaGetHandleFd(buffer_handle_t handle, int *fd); +int RkRgaGetHandleAttributes(buffer_handle_t handle, + std::vector *attrs); +int RkRgaGetHandleMapAddress(buffer_handle_t handle, + void **buf); +#endif //Android + +#endif //_rk_graphic_buffer_h_ diff --git a/rga/inc/RgaApi.h b/rga/inc/RgaApi.h new file mode 100644 index 0000000..b0049f7 --- /dev/null +++ b/rga/inc/RgaApi.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Authors: + * Zhiqin Wei + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _rockchip_rga_c_h_ +#define _rockchip_rga_c_h_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "drmrga.h" +#include "rga.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * Compatible with the old version of C interface.The new + * version of the C interface no longer requires users to + * initialize rga, so RgaInit and RgaDeInit are just for + * compatibility with the old C interface, so please do + * not use ctx, because it is usually a NULL. + */ +#define RgaInit(ctx) ({ \ + int ret = 0; \ + ret = c_RkRgaInit(); \ + c_RkRgaGetContext(ctx); \ + ret;\ +}) +#define RgaDeInit(ctx) { \ + (void)ctx; /* unused */ \ + c_RkRgaDeInit(); \ +} +#define RgaBlit(...) c_RkRgaBlit(__VA_ARGS__) +#define RgaCollorFill(...) c_RkRgaColorFill(__VA_ARGS__) +#define RgaFlush() c_RkRgaFlush() + +int c_RkRgaInit(); +void c_RkRgaDeInit(); +void c_RkRgaGetContext(void **ctx); +int c_RkRgaBlit(rga_info_t *src, rga_info_t *dst, rga_info_t *src1); +int c_RkRgaColorFill(rga_info_t *dst); +int c_RkRgaFlush(); + +#ifndef ANDROID /* linux */ +int c_RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp); +int c_RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp); +int c_RkRgaGetMmap(bo_t *bo_info); +int c_RkRgaUnmap(bo_t *bo_info); +int c_RkRgaFree(bo_t *bo_info); +int c_RkRgaGetBufferFd(bo_t *bo_info, int *fd); +#endif /* #ifndef ANDROID */ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef _rockchip_rga_c_h_ */ diff --git a/rga/inc/RgaMutex.h b/rga/inc/RgaMutex.h new file mode 100644 index 0000000..61909e2 --- /dev/null +++ b/rga/inc/RgaMutex.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd. + * Authors: + * PutinLee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef _LIBS_RGA_MUTEX_H +#define _LIBS_RGA_MUTEX_H + +#ifndef ANDROID +#include +#include +#include + +#include + + +// Enable thread safety attributes only with clang. +// The attributes can be safely erased when compiling with other compilers. +#if defined(__clang__) && (!defined(SWIG)) +#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) +#else +#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op +#endif + +#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) + +#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) + +#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) + +#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) + +#define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) + +#define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) + +#define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) + +#define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) + +#define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) + +#define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) + +#define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) + +#define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) + +#define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) + +#define TRY_ACQUIRE_SHARED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) + +#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) + +#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) + +#define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) + +#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) + +#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) + +class Condition; + +/* + * NOTE: This class is for code that builds on Win32. Its usage is + * deprecated for code which doesn't build for Win32. New code which + * doesn't build for Win32 should use std::mutex and std::lock_guard instead. + * + * Simple mutex class. The implementation is system-dependent. + * + * The mutex must be unlocked by the thread that locked it. They are not + * recursive, i.e. the same thread can't lock it multiple times. + */ +class CAPABILITY("mutex") Mutex { + public: + enum { + PRIVATE = 0, + SHARED = 1 + }; + + Mutex(); + explicit Mutex(const char* name); + explicit Mutex(int type, const char* name = nullptr); + ~Mutex(); + + // lock or unlock the mutex + int32_t lock() ACQUIRE(); + void unlock() RELEASE(); + + // lock if possible; returns 0 on success, error otherwise + int32_t tryLock() TRY_ACQUIRE(0); + + int32_t timedLock(int64_t timeoutNs) TRY_ACQUIRE(0); + + // Manages the mutex automatically. It'll be locked when Autolock is + // constructed and released when Autolock goes out of scope. + class SCOPED_CAPABILITY Autolock { + public: + inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) { + mLock.lock(); + } + inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) { + mLock.lock(); + } + inline ~Autolock() RELEASE() { + mLock.unlock(); + } + + private: + Mutex& mLock; + // Cannot be copied or moved - declarations only + Autolock(const Autolock&); + Autolock& operator=(const Autolock&); + }; + + private: + friend class Condition; + + // A mutex cannot be copied + Mutex(const Mutex&); + Mutex& operator=(const Mutex&); + + pthread_mutex_t mMutex; +}; + +// --------------------------------------------------------------------------- +inline Mutex::Mutex() { + pthread_mutex_init(&mMutex, nullptr); +} +inline Mutex::Mutex(__attribute__((unused)) const char* name) { + pthread_mutex_init(&mMutex, nullptr); +} +inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { + if (type == SHARED) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&mMutex, &attr); + pthread_mutexattr_destroy(&attr); + } else { + pthread_mutex_init(&mMutex, nullptr); + } +} +inline Mutex::~Mutex() { + pthread_mutex_destroy(&mMutex); +} +inline int32_t Mutex::lock() { + return -pthread_mutex_lock(&mMutex); +} +inline void Mutex::unlock() { + pthread_mutex_unlock(&mMutex); +} +inline int32_t Mutex::tryLock() { + return -pthread_mutex_trylock(&mMutex); +} +inline int32_t Mutex::timedLock(int64_t timeoutNs) { + timespec now; + clock_gettime(CLOCK_REALTIME, &now); + timeoutNs += now.tv_sec*1000000000 + now.tv_nsec; + const struct timespec ts = { + /* .tv_sec = */ static_cast(timeoutNs / 1000000000), + /* .tv_nsec = */ static_cast(timeoutNs % 1000000000), + }; + return -pthread_mutex_timedlock(&mMutex, &ts); +} + +// --------------------------------------------------------------------------- + +/* + * Automatic mutex. Declare one of these at the top of a function. + * When the function returns, it will go out of scope, and release the + * mutex. + */ + +typedef Mutex::Autolock AutoMutex; +#endif // __ANDROID_VNDK__ +#endif // _LIBS_RGA_MUTEX_H diff --git a/rga/inc/RgaSingleton.h b/rga/inc/RgaSingleton.h new file mode 100644 index 0000000..e87cf1c --- /dev/null +++ b/rga/inc/RgaSingleton.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Authors: + * Zhiqin Wei + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_RGA_SINGLETON_H +#define _LIBS_RGA_SINGLETON_H + +#ifndef ANDROID +#include "RgaMutex.h" + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-var-template" +#endif + +template +class Singleton { + public: + static TYPE& getInstance() { + Mutex::Autolock _l(sLock); + TYPE* instance = sInstance; + if (instance == nullptr) { + instance = new TYPE(); + sInstance = instance; + } + return *instance; + } + + static bool hasInstance() { + Mutex::Autolock _l(sLock); + return sInstance != nullptr; + } + + protected: + ~Singleton() { } + Singleton() { } + + private: + Singleton(const Singleton&); + Singleton& operator = (const Singleton&); + static Mutex sLock; + static TYPE* sInstance; +}; + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +#define RGA_SINGLETON_STATIC_INSTANCE(TYPE) \ + template<> ::Mutex \ + (::Singleton< TYPE >::sLock)(::Mutex::PRIVATE); \ + template<> TYPE* ::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \ + template class ::Singleton< TYPE >; + +#endif //ANDROID +#endif //_LIBS_RGA_SINGLETON_H diff --git a/rga/inc/RgaUtils.h b/rga/inc/RgaUtils.h new file mode 100644 index 0000000..217ecea --- /dev/null +++ b/rga/inc/RgaUtils.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Authors: + * Zhiqin Wei + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _rga_utils_h_ +#define _rga_utils_h_ + +// ------------------------------------------------------------------------------- +float get_bpp_from_format(int format); +int get_perPixel_stride_from_format(int format); +int get_buf_from_file(void *buf, int f, int sw, int sh, int index); +int output_buf_data_to_file(void *buf, int f, int sw, int sh, int index); +const char *translate_format_str(int format); +int get_buf_from_file_FBC(void *buf, int f, int sw, int sh, int index); +int output_buf_data_to_file_FBC(void *buf, int f, int sw, int sh, int index); +#endif + diff --git a/rga/inc/RockchipRga.h b/rga/inc/RockchipRga.h new file mode 100644 index 0000000..082f9e1 --- /dev/null +++ b/rga/inc/RockchipRga.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Authors: + * Zhiqin Wei + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _rockchip_rga_h_ +#define _rockchip_rga_h_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drmrga.h" +#include "GrallocOps.h" +#include "RgaUtils.h" +#include "rga.h" + +////////////////////////////////////////////////////////////////////////////////// +#ifndef ANDROID +#include "RgaSingleton.h" +#endif + +#ifdef ANDROID +#include +#include +#include + +namespace android { +#endif + + class RockchipRga :public Singleton { + public: + + static inline RockchipRga& get() { + return getInstance(); + } + + int RkRgaInit(); + void RkRgaDeInit(); + void RkRgaGetContext(void **ctx); +#ifndef ANDROID /* LINUX */ + int RkRgaAllocBuffer(int drm_fd /* input */, bo_t *bo_info, + int width, int height, int bpp, int flags); + int RkRgaFreeBuffer(int drm_fd /* input */, bo_t *bo_info); + int RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp); + int RkRgaGetAllocBufferExt(bo_t *bo_info, int width, int height, int bpp, int flags); + int RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp); + int RkRgaGetMmap(bo_t *bo_info); + int RkRgaUnmap(bo_t *bo_info); + int RkRgaFree(bo_t *bo_info); + int RkRgaGetBufferFd(bo_t *bo_info, int *fd); +#else + int RkRgaGetBufferFd(buffer_handle_t handle, int *fd); + int RkRgaGetHandleMapCpuAddress(buffer_handle_t handle, void **buf); +#endif + int RkRgaBlit(rga_info *src, rga_info *dst, rga_info *src1); + int RkRgaCollorFill(rga_info *dst); + int RkRgaCollorPalette(rga_info *src, rga_info *dst, rga_info *lut); + int RkRgaFlush(); + + + void RkRgaSetLogOnceFlag(int log) { + mLogOnce = log; + } + void RkRgaSetAlwaysLogFlag(bool log) { + mLogAlways = log; + } + void RkRgaLogOutRgaReq(struct rga_req rgaReg); + int RkRgaLogOutUserPara(rga_info *rgaInfo); + inline bool RkRgaIsReady() { + return mSupportRga; + } + + RockchipRga(); + ~RockchipRga(); + private: + bool mSupportRga; + int mLogOnce; + int mLogAlways; + void * mContext; + + friend class Singleton; + }; + +#ifdef ANDROID +}; // namespace android +#endif + +#endif + diff --git a/rga/inc/drmrga.h b/rga/inc/drmrga.h new file mode 100644 index 0000000..c089c6d --- /dev/null +++ b/rga/inc/drmrga.h @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Authors: + * Zhiqin Wei + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _rk_drm_rga_ +#define _rk_drm_rga_ + +#include +#include +#include + +#include "rga.h" + +#ifdef ANDROID +#define DRMRGA_HARDWARE_MODULE_ID "librga" + +#include +#include +#include +#include + +#ifdef ANDROID_12 +#include +#endif + +#endif + +#ifndef ANDROID /* LINUX */ +/* flip source image horizontally (around the vertical axis) */ +#define HAL_TRANSFORM_FLIP_H 0x01 +/* flip source image vertically (around the horizontal axis)*/ +#define HAL_TRANSFORM_FLIP_V 0x02 +/* rotate source image 90 degrees clockwise */ +#define HAL_TRANSFORM_ROT_90 0x04 +/* rotate source image 180 degrees */ +#define HAL_TRANSFORM_ROT_180 0x03 +/* rotate source image 270 degrees clockwise */ +#define HAL_TRANSFORM_ROT_270 0x07 +#endif + +#define HAL_TRANSFORM_FLIP_H_V 0x08 + +/*****************************************************************************/ + +/* for compatibility */ +#define DRM_RGA_MODULE_API_VERSION HWC_MODULE_API_VERSION_0_1 +#define DRM_RGA_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_0_1 +#define DRM_RGA_API_VERSION HWC_DEVICE_API_VERSION + +#define DRM_RGA_TRANSFORM_ROT_MASK 0x0000000F +#define DRM_RGA_TRANSFORM_ROT_0 0x00000000 +#define DRM_RGA_TRANSFORM_ROT_90 HAL_TRANSFORM_ROT_90 +#define DRM_RGA_TRANSFORM_ROT_180 HAL_TRANSFORM_ROT_180 +#define DRM_RGA_TRANSFORM_ROT_270 HAL_TRANSFORM_ROT_270 + +#define DRM_RGA_TRANSFORM_FLIP_MASK 0x00000003 +#define DRM_RGA_TRANSFORM_FLIP_H HAL_TRANSFORM_FLIP_H +#define DRM_RGA_TRANSFORM_FLIP_V HAL_TRANSFORM_FLIP_V + +enum { + AWIDTH = 0, + AHEIGHT, + ASTRIDE, + AFORMAT, + ASIZE, + ATYPE, +}; +/*****************************************************************************/ + +#ifndef ANDROID +/* memory type definitions. */ +enum drm_rockchip_gem_mem_type { + /* Physically Continuous memory and used as default. */ + ROCKCHIP_BO_CONTIG = 1 << 0, + /* cachable mapping. */ + ROCKCHIP_BO_CACHABLE = 1 << 1, + /* write-combine mapping. */ + ROCKCHIP_BO_WC = 1 << 2, + ROCKCHIP_BO_SECURE = 1 << 3, + ROCKCHIP_BO_MASK = ROCKCHIP_BO_CONTIG | ROCKCHIP_BO_CACHABLE | + ROCKCHIP_BO_WC | ROCKCHIP_BO_SECURE +}; + +typedef struct bo { + int fd; + void *ptr; + size_t size; + size_t offset; + size_t pitch; + unsigned handle; +} bo_t; +#endif + +/* + @value size: user not need care about.For avoid read/write out of memory + */ +typedef struct rga_rect { + int xoffset; + int yoffset; + int width; + int height; + int wstride; + int hstride; + int format; + int size; +} rga_rect_t; + +typedef struct rga_nn { + int nn_flag; + int scale_r; + int scale_g; + int scale_b; + int offset_r; + int offset_g; + int offset_b; +} rga_nn_t; + +typedef struct rga_dither { + int enable; + int mode; + int lut0_l; + int lut0_h; + int lut1_l; + int lut1_h; +} rga_dither_t; + +/* + @value fd: use fd to share memory, it can be ion shard fd,and dma fd. + @value virAddr:userspace address + @value phyAddr:use phy address + @value hnd: use buffer_handle_t + */ +typedef struct rga_info { + int fd; + void *virAddr; + void *phyAddr; +#ifndef ANDROID /* LINUX */ + unsigned hnd; +#else /* Android */ + buffer_handle_t hnd; +#endif + int format; + rga_rect_t rect; + unsigned int blend; + int bufferSize; + int rotation; + int color; + int testLog; + int mmuFlag; + int colorkey_en; + int colorkey_mode; + int colorkey_max; + int colorkey_min; + int scale_mode; + int color_space_mode; + int sync_mode; + rga_nn_t nn; + rga_dither_t dither; + int rop_code; + int rd_mode; + unsigned short is_10b_compact; + unsigned short is_10b_endian; + + int in_fence_fd; + int out_fence_fd; + + int core; + int priority; + + unsigned short enable; + + int handle; + + struct rga_mosaic_info mosaic_info; + + struct rga_osd_info osd_info; + + struct rga_pre_intr_info pre_intr; + + int mpi_mode; + int ctx_id; + + char reserve[402]; +} rga_info_t; + + +typedef struct drm_rga { + rga_rect_t src; + rga_rect_t dst; +} drm_rga_t; + +/* + @fun rga_set_rect:For use to set the rects esayly + + @param rect:The rect user want to set,like setting the src rect: + drm_rga_t rects; + rga_set_rect(rects.src,0,0,1920,1080,1920,NV12); + mean to set the src rect to the value. + */ +static inline int rga_set_rect(rga_rect_t *rect, + int x, int y, int w, int h, int sw, int sh, int f) { + if (!rect) + return -EINVAL; + + rect->xoffset = x; + rect->yoffset = y; + rect->width = w; + rect->height = h; + rect->wstride = sw; + rect->hstride = sh; + rect->format = f; + + return 0; +} + +#ifndef ANDROID /* LINUX */ +static inline void rga_set_rotation(rga_info_t *info, int angle) { + if (angle == 90) + info->rotation = HAL_TRANSFORM_ROT_90; + else if (angle == 180) + info->rotation = HAL_TRANSFORM_ROT_180; + else if (angle == 270) + info->rotation = HAL_TRANSFORM_ROT_270; +} +#endif +/*****************************************************************************/ + +#endif diff --git a/rga/inc/im2d.h b/rga/inc/im2d.h new file mode 100644 index 0000000..a2ca1ea --- /dev/null +++ b/rga/inc/im2d.h @@ -0,0 +1,763 @@ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd. + * Authors: + * PutinLee + * Cerf Yu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _im2d_h_ +#define _im2d_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "im2d_version.h" +#include "im2d_type.h" + +#ifndef IM_API +#define IM_API /* define API export as needed */ +#endif + +#define RGA_GET_MIN(n1, n2) ((n1) < (n2) ? (n1) : (n2)) + +/* + * @return error message string + */ +#define imStrError(...) \ + ({ \ + const char* im2d_api_err; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + im2d_api_err = imStrError_t(IM_STATUS_INVALID_PARAM); \ + } else if (__argc == 1){ \ + im2d_api_err = imStrError_t((IM_STATUS)__args[0]); \ + } else { \ + im2d_api_err = ("Fatal error, imStrError() too many parameters\n"); \ + printf("Fatal error, imStrError() too many parameters\n"); \ + } \ + im2d_api_err; \ + }) +IM_API const char* imStrError_t(IM_STATUS status); + +/* + * Import external buffers into RGA driver. + * + * @param fd/va/pa + * Select dma_fd/virtual_address/physical_address by buffer type + * @param param + * Configure buffer parameters + * + * @return rga_buffer_handle_t + */ +IM_API rga_buffer_handle_t importbuffer_fd(int fd, im_handle_param_t *param); +IM_API rga_buffer_handle_t importbuffer_virtualaddr(void *va, im_handle_param_t *param); +IM_API rga_buffer_handle_t importbuffer_physicaladdr(uint64_t pa, im_handle_param_t *param); + +/* + * Import external buffers into RGA driver. + * + * @param handle + * rga buffer handle + * + * @return success or else negative error code. + */ +IM_API IM_STATUS releasebuffer_handle(rga_buffer_handle_t handle); + +/* + * Wrap image Parameters. + * + * @param handle + * RGA buffer handle. + * @param width + * Width of image manipulation area. + * @param height + * Height of image manipulation area. + * @param wstride + * Width pixel stride, default (width = wstride). + * @param hstride + * Height pixel stride, default (height = hstride). + * @param format + * Image format. + * + * @return rga_buffer_t + */ +#define wrapbuffer_handle(handle, width, height, format, ...) \ + ({ \ + rga_buffer_t im2d_api_buffer; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + im2d_api_buffer = wrapbuffer_handle_t(handle, width, height, width, height, format); \ + } else if (__argc == 2){ \ + im2d_api_buffer = wrapbuffer_handle_t(handle, width, height, __args[0], __args[1], format); \ + } else { \ + printf("invalid parameter\n"); \ + } \ + im2d_api_buffer; \ + }) +IM_API rga_buffer_t wrapbuffer_handle_t(rga_buffer_handle_t handle, int width, int height, int wstride, int hstride, int format); + +/* For legarcy. */ +#define wrapbuffer_virtualaddr(vir_addr, width, height, format, ...) \ + ({ \ + rga_buffer_t im2d_api_buffer; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + im2d_api_buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, width, height, format); \ + } else if (__argc == 2){ \ + im2d_api_buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, __args[0], __args[1], format); \ + } else { \ + printf("invalid parameter\n"); \ + } \ + im2d_api_buffer; \ + }) + +#define wrapbuffer_physicaladdr(phy_addr, width, height, format, ...) \ + ({ \ + rga_buffer_t im2d_api_buffer; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + im2d_api_buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, width, height, format); \ + } else if (__argc == 2){ \ + im2d_api_buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, __args[0], __args[1], format); \ + } else { \ + printf("invalid parameter\n"); \ + } \ + im2d_api_buffer; \ + }) + +#define wrapbuffer_fd(fd, width, height, format, ...) \ + ({ \ + rga_buffer_t im2d_api_buffer; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + im2d_api_buffer = wrapbuffer_fd_t(fd, width, height, width, height, format); \ + } else if (__argc == 2){ \ + im2d_api_buffer = wrapbuffer_fd_t(fd, width, height, __args[0], __args[1], format); \ + } else { \ + printf("invalid parameter\n"); \ + } \ + im2d_api_buffer; \ + }) +IM_API rga_buffer_t wrapbuffer_virtualaddr_t(void* vir_addr, int width, int height, int wstride, int hstride, int format); +IM_API rga_buffer_t wrapbuffer_physicaladdr_t(void* phy_addr, int width, int height, int wstride, int hstride, int format); +IM_API rga_buffer_t wrapbuffer_fd_t(int fd, int width, int height, int wstride, int hstride, int format); + +/* + * Query RGA basic information, supported resolution, supported format, etc. + * + * @param name + * RGA_VENDOR + * RGA_VERSION + * RGA_MAX_INPUT + * RGA_MAX_OUTPUT + * RGA_INPUT_FORMAT + * RGA_OUTPUT_FORMAT + * RGA_EXPECTED + * RGA_ALL + * + * @returns a string describing properties of RGA. + */ +IM_API const char* querystring(int name); + +/* + * check RGA basic information, supported resolution, supported format, etc. + * + * @param src + * @param dst + * @param src_rect + * @param dst_rect + * @param mode_usage + * + * @returns no error or else negative error code. + */ +#define imcheck(src, dst, src_rect, dst_rect, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_NOERROR; \ + rga_buffer_t __pat; \ + im_rect __pat_rect; \ + memset(&__pat, 0, sizeof(rga_buffer_t)); \ + memset(&__pat_rect, 0, sizeof(im_rect)); \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&__pat), \ + (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&__pat_rect), 0); \ + __ret = imcheck_t(src, dst, __pat, src_rect, dst_rect, __pat_rect, 0); \ + } else if (__argc == 1){ \ + rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&__pat), \ + (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&__pat_rect), __args[0]); \ + __ret = imcheck_t(src, dst, __pat, src_rect, dst_rect, __pat_rect, __args[0]); \ + } else { \ + __ret = IM_STATUS_FAILED; \ + printf("check failed\n"); \ + } \ + __ret; \ + }) +#define imcheck_composite(src, dst, pat, src_rect, dst_rect, pat_rect, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_NOERROR; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&pat), \ + (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&pat_rect), 0); \ + __ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0); \ + } else if (__argc == 1){ \ + rga_check_perpare((rga_buffer_t *)(&src), (rga_buffer_t *)(&dst), (rga_buffer_t *)(&pat), \ + (im_rect *)(&src_rect), (im_rect *)(&dst_rect), (im_rect *)(&pat_rect), __args[0]); \ + __ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, __args[0]); \ + } else { \ + __ret = IM_STATUS_FAILED; \ + printf("check failed\n"); \ + } \ + __ret; \ + }) +IM_API void rga_check_perpare(rga_buffer_t *src, rga_buffer_t *dst, rga_buffer_t *pat, + im_rect *src_rect, im_rect *dst_rect, im_rect *pat_rect, int mode_usage); +IM_API IM_STATUS imcheck_t(const rga_buffer_t src, const rga_buffer_t dst, const rga_buffer_t pat, + const im_rect src_rect, const im_rect dst_rect, const im_rect pat_rect, const int mode_usage); + +/* + * Resize + * + * @param src + * @param dst + * @param fx + * @param fy + * @param interpolation + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imresize(src, dst, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + double __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(double); \ + if (__argc == 0) { \ + __ret = imresize_t(src, dst, 0, 0, INTER_LINEAR, 1); \ + } else if (__argc == 2){ \ + __ret = imresize_t(src, dst, __args[RGA_GET_MIN(__argc, 0)], __args[RGA_GET_MIN(__argc, 1)], INTER_LINEAR, 1); \ + } else if (__argc == 3){ \ + __ret = imresize_t(src, dst, __args[RGA_GET_MIN(__argc, 0)], __args[RGA_GET_MIN(__argc, 1)], (int)__args[RGA_GET_MIN(__argc, 2)], 1); \ + } else if (__argc == 4){ \ + __ret = imresize_t(src, dst, __args[RGA_GET_MIN(__argc, 0)], __args[RGA_GET_MIN(__argc, 1)], (int)__args[RGA_GET_MIN(__argc, 2)], (int)__args[RGA_GET_MIN(__argc, 3)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +#define impyramid(src, dst, direction) \ + imresize_t(src, \ + dst, \ + direction == IM_UP_SCALE ? 0.5 : 2, \ + direction == IM_UP_SCALE ? 0.5 : 2, \ + INTER_LINEAR, 1) + +IM_API IM_STATUS imresize_t(const rga_buffer_t src, rga_buffer_t dst, double fx, double fy, int interpolation, int sync); + +/* + * Crop + * + * @param src + * @param dst + * @param rect + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imcrop(src, dst, rect, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imcrop_t(src, dst, rect, 1); \ + } else if (__argc == 1){ \ + __ret = imcrop_t(src, dst, rect, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +IM_API IM_STATUS imcrop_t(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync); + +/* + * rotation + * + * @param src + * @param dst + * @param rotation + * IM_HAL_TRANSFORM_ROT_90 + * IM_HAL_TRANSFORM_ROT_180 + * IM_HAL_TRANSFORM_ROT_270 + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imrotate(src, dst, rotation, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imrotate_t(src, dst, rotation, 1); \ + } else if (__argc == 1){ \ + __ret = imrotate_t(src, dst, rotation, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +IM_API IM_STATUS imrotate_t(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync); + +/* + * flip + * + * @param src + * @param dst + * @param mode + * IM_HAL_TRANSFORM_FLIP_H + * IM_HAL_TRANSFORM_FLIP_V + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imflip(src, dst, mode, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imflip_t(src, dst, mode, 1); \ + } else if (__argc == 1){ \ + __ret = imflip_t(src, dst, mode, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +IM_API IM_STATUS imflip_t (const rga_buffer_t src, rga_buffer_t dst, int mode, int sync); + +/* + * fill/reset/draw + * + * @param src + * @param dst + * @param rect + * @param color + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imfill(buf, rect, color, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imfill_t(buf, rect, color, 1); \ + } else if (__argc == 1){ \ + __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +#define imreset(buf, rect, color, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imfill_t(buf, rect, color, 1); \ + } else if (__argc == 1){ \ + __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +#define imdraw(buf, rect, color, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imfill_t(buf, rect, color, 1); \ + } else if (__argc == 1){ \ + __ret = imfill_t(buf, rect, color, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) +IM_API IM_STATUS imfill_t(rga_buffer_t dst, im_rect rect, int color, int sync); + +/* + * palette + * + * @param src + * @param dst + * @param lut + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define impalette(src, dst, lut, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = impalette_t(src, dst, lut, 1); \ + } else if (__argc == 1){ \ + __ret = impalette_t(src, dst, lut, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) +IM_API IM_STATUS impalette_t(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t lut, int sync); + +/* + * translate + * + * @param src + * @param dst + * @param x + * @param y + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imtranslate(src, dst, x, y, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imtranslate_t(src, dst, x, y, 1); \ + } else if (__argc == 1){ \ + __ret = imtranslate_t(src, dst, x, y, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) +IM_API IM_STATUS imtranslate_t(const rga_buffer_t src, rga_buffer_t dst, int x, int y, int sync); + +/* + * copy + * + * @param src + * @param dst + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imcopy(src, dst, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imcopy_t(src, dst, 1); \ + } else if (__argc == 1){ \ + __ret = imcopy_t(src, dst, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +IM_API IM_STATUS imcopy_t(const rga_buffer_t src, rga_buffer_t dst, int sync); + +/* + * blend (SRC + DST -> DST or SRCA + SRCB -> DST) + * + * @param srcA + * @param srcB can be NULL. + * @param dst + * @param mode + * IM_ALPHA_BLEND_MODE + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imblend(srcA, dst, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + rga_buffer_t srcB; \ + memset(&srcB, 0x00, sizeof(rga_buffer_t)); \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \ + } else if (__argc == 1){ \ + __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \ + } else if (__argc == 2){ \ + __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) +#define imcomposite(srcA, srcB, dst, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \ + } else if (__argc == 1){ \ + __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \ + } else if (__argc == 2){ \ + __ret = imblend_t(srcA, srcB, dst, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) +IM_API IM_STATUS imblend_t(const rga_buffer_t srcA, const rga_buffer_t srcB, rga_buffer_t dst, int mode, int sync); + +/* + * color key + * + * @param src + * @param dst + * @param colorkey_range + * max color + * min color + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imcolorkey(src, dst, range, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imcolorkey_t(src, dst, range, IM_ALPHA_COLORKEY_NORMAL, 1); \ + } else if (__argc == 1){ \ + __ret = imcolorkey_t(src, dst, range, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \ + } else if (__argc == 2){ \ + __ret = imcolorkey_t(src, dst, range, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) +IM_API IM_STATUS imcolorkey_t(const rga_buffer_t src, rga_buffer_t dst, im_colorkey_range range, int mode, int sync); + +/* + * format convert + * + * @param src + * @param dst + * @param sfmt + * @param dfmt + * @param mode + * color space mode: IM_COLOR_SPACE_MODE + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imcvtcolor(src, dst, sfmt, dfmt, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imcvtcolor_t(src, dst, sfmt, dfmt, IM_COLOR_SPACE_DEFAULT, 1); \ + } else if (__argc == 1){ \ + __ret = imcvtcolor_t(src, dst, sfmt, dfmt, (int)__args[RGA_GET_MIN(__argc, 0)], 1); \ + } else if (__argc == 2){ \ + __ret = imcvtcolor_t(src, dst, sfmt, dfmt, (int)__args[RGA_GET_MIN(__argc, 0)], (int)__args[RGA_GET_MIN(__argc, 1)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +IM_API IM_STATUS imcvtcolor_t(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode, int sync); + +/* + * nn quantize + * + * @param src + * @param dst + * @param nninfo + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imquantize(src, dst, nn_info, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imquantize_t(src, dst, nn_info, 1); \ + } else if (__argc == 1){ \ + __ret = imquantize_t(src, dst, nn_info, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) + +IM_API IM_STATUS imquantize_t(const rga_buffer_t src, rga_buffer_t dst, im_nn_t nn_info, int sync); + +/* + * ROP + * + * @param src + * @param dst + * @param rop_code + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +#define imrop(src, dst, rop_code, ...) \ + ({ \ + IM_STATUS __ret = IM_STATUS_SUCCESS; \ + int __args[] = {__VA_ARGS__}; \ + int __argc = sizeof(__args)/sizeof(int); \ + if (__argc == 0) { \ + __ret = imrop_t(src, dst, rop_code, 1); \ + } else if (__argc == 1){ \ + __ret = imrop_t(src, dst, rop_code, (int)__args[RGA_GET_MIN(__argc, 0)]); \ + } else { \ + __ret = IM_STATUS_INVALID_PARAM; \ + printf("invalid parameter\n"); \ + } \ + __ret; \ + }) +IM_API IM_STATUS imrop_t(const rga_buffer_t src, rga_buffer_t dst, int rop_code, int sync); + +/* + * MOSAIC + * + * @param src + * @param dst + * @param mosaic_mode + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +IM_API IM_STATUS immosaic(const rga_buffer_t image, im_rect rect, int mosaic_mode, int sync); + +/* + * OSD + * + * @param osd + * osd block + * @param dst + * background image + * @param osd_rect + * @param osd_config + * osd mode config + * @param sync + * wait until operation complete + * + * @returns success or else negative error code. + */ +IM_API IM_STATUS imosd(const rga_buffer_t osd,const rga_buffer_t dst, + const im_rect osd_rect, im_osd_t *osd_config, int sync); + +/* + * process + * + * @param src + * @param dst + * @param usage + * @param ... + * wait until operation complete + * + * @returns success or else negative error code. + */ +IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat, + im_rect srect, im_rect drect, im_rect prect, int usage); + +/* + * block until all execution is complete + * + * @returns success or else negative error code. + */ +IM_API IM_STATUS imsync(int out_fence_fd); + +/* + * config + * + * @param name + * enum IM_CONFIG_NAME + * @param value + * + * @returns success or else negative error code. + */ +IM_API IM_STATUS imconfig(IM_CONFIG_NAME name, uint64_t value); + +IM_API im_ctx_id_t imbegin(uint32_t flags); + +IM_API IM_STATUS imcancel(im_ctx_id_t id); + +#ifdef __cplusplus +} +#endif +#endif /* _im2d_h_ */ + diff --git a/rga/inc/im2d_hardware.h b/rga/inc/im2d_hardware.h new file mode 100644 index 0000000..2bdfbd3 --- /dev/null +++ b/rga/inc/im2d_hardware.h @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2021 Rockchip Electronics Co., Ltd. + * Authors: + * Cerf Yu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _RGA_IM2D_HARDWARE_H_ +#define _RGA_IM2D_HARDWARE_H_ + +#include "rga.h" + +typedef enum { + IM_RGA_HW_VERSION_RGA_V_ERR_INDEX = 0x0, + IM_RGA_HW_VERSION_RGA_1_INDEX, + IM_RGA_HW_VERSION_RGA_1_PLUS_INDEX, + IM_RGA_HW_VERSION_RGA_2_INDEX, + IM_RGA_HW_VERSION_RGA_2_LITE0_INDEX, + IM_RGA_HW_VERSION_RGA_2_LITE1_INDEX, + IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX, + IM_RGA_HW_VERSION_RGA_3_INDEX, + IM_RGA_HW_VERSION_MASK_INDEX, +} IM_RGA_HW_VERSION_INDEX; + +typedef enum { + IM_RGA_HW_VERSION_RGA_V_ERR = 1 << IM_RGA_HW_VERSION_RGA_V_ERR_INDEX, + IM_RGA_HW_VERSION_RGA_1 = 1 << IM_RGA_HW_VERSION_RGA_1_INDEX, + IM_RGA_HW_VERSION_RGA_1_PLUS = 1 << IM_RGA_HW_VERSION_RGA_1_PLUS_INDEX, + IM_RGA_HW_VERSION_RGA_2 = 1 << IM_RGA_HW_VERSION_RGA_2_INDEX, + IM_RGA_HW_VERSION_RGA_2_LITE0 = 1 << IM_RGA_HW_VERSION_RGA_2_LITE0_INDEX, + IM_RGA_HW_VERSION_RGA_2_LITE1 = 1 << IM_RGA_HW_VERSION_RGA_2_LITE1_INDEX, + IM_RGA_HW_VERSION_RGA_2_ENHANCE = 1 << IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX, + IM_RGA_HW_VERSION_RGA_3 = 1 << IM_RGA_HW_VERSION_RGA_3_INDEX, + IM_RGA_HW_VERSION_MASK = ~((~(unsigned int)0x0 << IM_RGA_HW_VERSION_MASK_INDEX) | 1), +}IM_RGA_HW_VERSION; + +typedef enum { + IM_RGA_SUPPORT_FORMAT_ERROR_INDEX = 0, + IM_RGA_SUPPORT_FORMAT_RGB_INDEX, + IM_RGA_SUPPORT_FORMAT_RGB_OTHER_INDEX, + IM_RGA_SUPPORT_FORMAT_BPP_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUYV_420_INDEX, + IM_RGA_SUPPORT_FORMAT_YUYV_422_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_400_INDEX, + IM_RGA_SUPPORT_FORMAT_Y4_INDEX, + IM_RGA_SUPPORT_FORMAT_RGBA2BPP_INDEX, + IM_RGA_SUPPORT_FORMAT_MASK_INDEX, +} IM_RGA_SUPPORT_FORMAT_INDEX; + +typedef enum { + IM_RGA_SUPPORT_FORMAT_ERROR = 1 << IM_RGA_SUPPORT_FORMAT_ERROR_INDEX, + IM_RGA_SUPPORT_FORMAT_RGB = 1 << IM_RGA_SUPPORT_FORMAT_RGB_INDEX, + IM_RGA_SUPPORT_FORMAT_RGB_OTHER = 1 << IM_RGA_SUPPORT_FORMAT_RGB_OTHER_INDEX, + IM_RGA_SUPPORT_FORMAT_BPP = 1 << IM_RGA_SUPPORT_FORMAT_BPP_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_10_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_10_BIT = 1 << IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_10_BIT_INDEX, + IM_RGA_SUPPORT_FORMAT_YUYV_420 = 1 << IM_RGA_SUPPORT_FORMAT_YUYV_420_INDEX, + IM_RGA_SUPPORT_FORMAT_YUYV_422 = 1 << IM_RGA_SUPPORT_FORMAT_YUYV_422_INDEX, + IM_RGA_SUPPORT_FORMAT_YUV_400 = 1 << IM_RGA_SUPPORT_FORMAT_YUV_400_INDEX, + IM_RGA_SUPPORT_FORMAT_Y4 = 1 << IM_RGA_SUPPORT_FORMAT_Y4_INDEX, + IM_RGA_SUPPORT_FORMAT_RGBA2BPP = 1 << IM_RGA_SUPPORT_FORMAT_RGBA2BPP_INDEX, + IM_RGA_SUPPORT_FORMAT_MASK = ~((~(unsigned int)0x0 << IM_RGA_SUPPORT_FORMAT_MASK_INDEX) | 1), +} IM_RGA_SUPPORT_FORMAT; + +typedef enum { + IM_RGA_SUPPORT_FEATURE_ERROR_INDEX = 0, + IM_RGA_SUPPORT_FEATURE_COLOR_FILL_INDEX, + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE_INDEX, + IM_RGA_SUPPORT_FEATURE_ROP_INDEX, + IM_RGA_SUPPORT_FEATURE_QUANTIZE_INDEX, + IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC_INDEX, + IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC_INDEX, + IM_RGA_SUPPORT_FEATURE_FBC_INDEX, + IM_RGA_SUPPORT_FEATURE_BLEND_YUV_INDEX, + IM_RGA_SUPPORT_FEATURE_BT2020_INDEX, + IM_RGA_SUPPORT_FEATURE_MOSAIC_INDEX, + IM_RGA_SUPPORT_FEATURE_OSD_INDEX, + IM_RGA_SUPPORT_FEATURE_PRE_INTR_INDEX, + IM_RGA_SUPPORT_FEATURE_MASK_INDEX, +} IM_RGA_SUPPORT_FEATURE_INDEX; + +typedef enum { + IM_RGA_SUPPORT_FEATURE_ERROR = 1 << IM_RGA_SUPPORT_FEATURE_ERROR_INDEX, + IM_RGA_SUPPORT_FEATURE_COLOR_FILL = 1 << IM_RGA_SUPPORT_FEATURE_COLOR_FILL_INDEX, + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE = 1 << IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE_INDEX, + IM_RGA_SUPPORT_FEATURE_ROP = 1 << IM_RGA_SUPPORT_FEATURE_ROP_INDEX, + IM_RGA_SUPPORT_FEATURE_QUANTIZE = 1 << IM_RGA_SUPPORT_FEATURE_QUANTIZE_INDEX, + IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC = 1 << IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC_INDEX, + IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC = 1 << IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC_INDEX, + IM_RGA_SUPPORT_FEATURE_FBC = 1 << IM_RGA_SUPPORT_FEATURE_FBC_INDEX, + IM_RGA_SUPPORT_FEATURE_BLEND_YUV = 1 << IM_RGA_SUPPORT_FEATURE_BLEND_YUV_INDEX, + IM_RGA_SUPPORT_FEATURE_BT2020 = 1 << IM_RGA_SUPPORT_FEATURE_BT2020_INDEX, + IM_RGA_SUPPORT_FEATURE_MOSAIC = 1 << IM_RGA_SUPPORT_FEATURE_MOSAIC_INDEX, + IM_RGA_SUPPORT_FEATURE_OSD = 1 << IM_RGA_SUPPORT_FEATURE_OSD_INDEX, + IM_RGA_SUPPORT_FEATURE_PRE_INTR = 1 << IM_RGA_SUPPORT_FEATURE_PRE_INTR_INDEX, + IM_RGA_SUPPORT_FEATURE_MASK = ~((~(unsigned int)0x0 << IM_RGA_SUPPORT_FEATURE_MASK_INDEX) | 1), +} IM_RGA_SUPPORT_FEATURE; + +typedef struct { + unsigned int version; + unsigned int input_resolution; + unsigned int output_resolution; + unsigned int byte_stride; + unsigned int scale_limit; + unsigned int performance; + unsigned int input_format; + unsigned int output_format; + unsigned int feature; + char reserved[24]; +} rga_info_table_entry; + +typedef struct { + struct rga_version_t user; + struct rga_version_t driver; +} rga_dirver_bind_table_entry; + +const rga_info_table_entry hw_info_table[] = { + { IM_RGA_HW_VERSION_RGA_V_ERR , 0, 0, 0, 0, 0, 0, 0, 0, {0} }, + { IM_RGA_HW_VERSION_RGA_1 , 8192, 2048, 4, 8, 1, + /* input format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_BPP | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* output format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* feature */ + IM_RGA_SUPPORT_FEATURE_COLOR_FILL | + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE | + IM_RGA_SUPPORT_FEATURE_ROP, + /* reserved */ + {0} }, + { IM_RGA_HW_VERSION_RGA_1_PLUS , 8192, 2048, 4, 8, 1, + /* input format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_BPP | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* output format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* feature */ + IM_RGA_SUPPORT_FEATURE_COLOR_FILL | + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE, + /* reserved */ + {0} }, + { IM_RGA_HW_VERSION_RGA_2 , 8192, 4096, 4, 16, 2, + /* input format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* output format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* feature */ + IM_RGA_SUPPORT_FEATURE_COLOR_FILL | + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE | + IM_RGA_SUPPORT_FEATURE_ROP, + /* reserved */ + {0} }, + { IM_RGA_HW_VERSION_RGA_2_LITE0 , 8192, 4096, 4, 8, 2, + /* input format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* output format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* feature */ + IM_RGA_SUPPORT_FEATURE_COLOR_FILL | + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE | + IM_RGA_SUPPORT_FEATURE_ROP, + /* reserved */ + {0} }, + { IM_RGA_HW_VERSION_RGA_2_LITE1 , 8192, 4096, 4, 8, 2, + /* input format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_10_BIT, + /* output format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT, + /* feature */ + IM_RGA_SUPPORT_FEATURE_COLOR_FILL | + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE, + /* reserved */ + {0} }, + { IM_RGA_HW_VERSION_RGA_2_ENHANCE , 8192, 4096, 4, 16, 2, + /* input format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_10_BIT, + /* output format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_RGB_OTHER | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUYV_420 | + IM_RGA_SUPPORT_FORMAT_YUYV_422, + /* feature */ + IM_RGA_SUPPORT_FEATURE_COLOR_FILL | + IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE | + IM_RGA_SUPPORT_FEATURE_ROP, + /* reserved */ + {0} }, + { IM_RGA_HW_VERSION_RGA_3 , 8176, 8128, 16, 8, 4, + /* input format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUYV_422, + /* output format */ + IM_RGA_SUPPORT_FORMAT_RGB | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT | + IM_RGA_SUPPORT_FORMAT_YUYV_422, + /* feature */ + IM_RGA_SUPPORT_FEATURE_FBC | + IM_RGA_SUPPORT_FEATURE_BLEND_YUV | + IM_RGA_SUPPORT_FEATURE_BT2020, + /* reserved */ + {0} }, +}; + +/* The range of the version is [min, max), that is version >= min, version < max. */ +const rga_dirver_bind_table_entry driver_bind_table[] = { + { { 0, 0, 0, "0.0.0" }, {0, 0, 0, "0.0.0" } }, + { { 1, 0, 3, "1.0.3" }, {0, 0, 0, "0.0.0" } }, + { { 1, 6, 0, "1.6.0" }, {1, 1, 5, "1.1.5" } }, + { { 1, 7, 2, "1.7.2" }, {1, 2, 0, "1.2.0" } }, + { { 1, 7, 3, "1.7.3" }, {1, 2, 4, "1.2.4" } }, +}; + +#endif diff --git a/rga/inc/im2d_type.h b/rga/inc/im2d_type.h new file mode 100644 index 0000000..16e85b0 --- /dev/null +++ b/rga/inc/im2d_type.h @@ -0,0 +1,417 @@ +/* + * Copyright (C) 2022 Rockchip Electronics Co., Ltd. + * Authors: + * Cerf Yu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _RGA_IM2D_TYPE_H_ +#define _RGA_IM2D_TYPE_H_ + +#include + +typedef enum { + /* Rotation */ + IM_HAL_TRANSFORM_ROT_90 = 1 << 0, + IM_HAL_TRANSFORM_ROT_180 = 1 << 1, + IM_HAL_TRANSFORM_ROT_270 = 1 << 2, + IM_HAL_TRANSFORM_FLIP_H = 1 << 3, + IM_HAL_TRANSFORM_FLIP_V = 1 << 4, + IM_HAL_TRANSFORM_FLIP_H_V = 1 << 5, + IM_HAL_TRANSFORM_MASK = 0x3f, + + /* + * Blend + * Additional blend usage, can be used with both source and target configs. + * If none of the below is set, the default "SRC over DST" is applied. + */ + IM_ALPHA_BLEND_SRC_OVER = 1 << 6, /* Default, Porter-Duff "SRC over DST" */ + IM_ALPHA_BLEND_SRC = 1 << 7, /* Porter-Duff "SRC" */ + IM_ALPHA_BLEND_DST = 1 << 8, /* Porter-Duff "DST" */ + IM_ALPHA_BLEND_SRC_IN = 1 << 9, /* Porter-Duff "SRC in DST" */ + IM_ALPHA_BLEND_DST_IN = 1 << 10, /* Porter-Duff "DST in SRC" */ + IM_ALPHA_BLEND_SRC_OUT = 1 << 11, /* Porter-Duff "SRC out DST" */ + IM_ALPHA_BLEND_DST_OUT = 1 << 12, /* Porter-Duff "DST out SRC" */ + IM_ALPHA_BLEND_DST_OVER = 1 << 13, /* Porter-Duff "DST over SRC" */ + IM_ALPHA_BLEND_SRC_ATOP = 1 << 14, /* Porter-Duff "SRC ATOP" */ + IM_ALPHA_BLEND_DST_ATOP = 1 << 15, /* Porter-Duff "DST ATOP" */ + IM_ALPHA_BLEND_XOR = 1 << 16, /* Xor */ + IM_ALPHA_BLEND_MASK = 0x1ffc0, + + IM_ALPHA_COLORKEY_NORMAL = 1 << 17, + IM_ALPHA_COLORKEY_INVERTED = 1 << 18, + IM_ALPHA_COLORKEY_MASK = 0x60000, + + IM_SYNC = 1 << 19, + IM_CROP = 1 << 20, /* Unused */ + IM_COLOR_FILL = 1 << 21, + IM_COLOR_PALETTE = 1 << 22, + IM_NN_QUANTIZE = 1 << 23, + IM_ROP = 1 << 24, + IM_ALPHA_BLEND_PRE_MUL = 1 << 25, + IM_ASYNC = 1 << 26, + IM_MOSAIC = 1 << 27, + IM_OSD = 1 << 28, + IM_PRE_INTR = 1 << 29, +} IM_USAGE; + +typedef enum { + IM_RASTER_MODE = 1 << 0, + IM_FBC_MODE = 1 << 1, + IM_TILE_MODE = 1 << 2, +} IM_RD_MODE; + +typedef enum { + IM_SCHEDULER_RGA3_CORE0 = 1 << 0, + IM_SCHEDULER_RGA3_CORE1 = 1 << 1, + IM_SCHEDULER_RGA2_CORE0 = 1 << 2, + IM_SCHEDULER_RGA3_DEFAULT = IM_SCHEDULER_RGA3_CORE0, + IM_SCHEDULER_RGA2_DEFAULT = IM_SCHEDULER_RGA2_CORE0, + IM_SCHEDULER_MASK = 0x7, + IM_SCHEDULER_DEFAULT = 0, +} IM_SCHEDULER_CORE; + +typedef enum { + IM_ROP_AND = 0x88, + IM_ROP_OR = 0xee, + IM_ROP_NOT_DST = 0x55, + IM_ROP_NOT_SRC = 0x33, + IM_ROP_XOR = 0xf6, + IM_ROP_NOT_XOR = 0xf9, +} IM_ROP_CODE; + +typedef enum { + IM_MOSAIC_8 = 0x0, + IM_MOSAIC_16 = 0x1, + IM_MOSAIC_32 = 0x2, + IM_MOSAIC_64 = 0x3, + IM_MOSAIC_128 = 0x4, +} IM_MOSAIC_MODE; + +/* Status codes, returned by any blit function */ +typedef enum { + IM_YUV_TO_RGB_BT601_LIMIT = 1 << 0, + IM_YUV_TO_RGB_BT601_FULL = 2 << 0, + IM_YUV_TO_RGB_BT709_LIMIT = 3 << 0, + IM_YUV_TO_RGB_MASK = 3 << 0, + IM_RGB_TO_YUV_BT601_FULL = 1 << 2, + IM_RGB_TO_YUV_BT601_LIMIT = 2 << 2, + IM_RGB_TO_YUV_BT709_LIMIT = 3 << 2, + IM_RGB_TO_YUV_MASK = 3 << 2, + IM_RGB_TO_Y4 = 1 << 4, + IM_RGB_TO_Y4_DITHER = 2 << 4, + IM_RGB_TO_Y1_DITHER = 3 << 4, + IM_Y4_MASK = 3 << 4, + IM_RGB_FULL = 1 << 8, + IM_RGB_CLIP = 2 << 8, + IM_YUV_BT601_LIMIT_RANGE = 3 << 8, + IM_YUV_BT601_FULL_RANGE = 4 << 8, + IM_YUV_BT709_LIMIT_RANGE = 5 << 8, + IM_YUV_BT709_FULL_RANGE = 6 << 8, + IM_FULL_CSC_MASK = 0xf << 8, + IM_COLOR_SPACE_DEFAULT = 0, +} IM_COLOR_SPACE_MODE; + +typedef enum { + IM_UP_SCALE, + IM_DOWN_SCALE, +} IM_SCALE; + +typedef enum { + INTER_NEAREST, + INTER_LINEAR, + INTER_CUBIC, +} IM_SCALE_MODE; + +typedef enum { + IM_CONFIG_SCHEDULER_CORE, + IM_CONFIG_PRIORITY, + IM_CONFIG_CHECK, +} IM_CONFIG_NAME; + +typedef enum { + IM_OSD_MODE_STATISTICS = 0x1 << 0, + IM_OSD_MODE_AUTO_INVERT = 0x1 << 1, +} IM_OSD_MODE; + +typedef enum { + IM_OSD_INVERT_CHANNEL_NONE = 0x0, + IM_OSD_INVERT_CHANNEL_Y_G = 0x1 << 0, + IM_OSD_INVERT_CHANNEL_C_RB = 0x1 << 1, + IM_OSD_INVERT_CHANNEL_ALPHA = 0x1 << 2, + IM_OSD_INVERT_CHANNEL_COLOR = IM_OSD_INVERT_CHANNEL_Y_G | + IM_OSD_INVERT_CHANNEL_C_RB, + IM_OSD_INVERT_CHANNEL_BOTH = IM_OSD_INVERT_CHANNEL_COLOR | + IM_OSD_INVERT_CHANNEL_ALPHA, +} IM_OSD_INVERT_CHANNEL; + +typedef enum { + IM_OSD_FLAGS_INTERNAL = 0, + IM_OSD_FLAGS_EXTERNAL, +} IM_OSD_FLAGS_MODE; + +typedef enum { + IM_OSD_INVERT_USE_FACTOR, + IM_OSD_INVERT_USE_SWAP, +} IM_OSD_INVERT_MODE; + +typedef enum { + IM_OSD_BACKGROUND_DEFAULT_BRIGHT = 0, + IM_OSD_BACKGROUND_DEFAULT_DARK, +} IM_OSD_BACKGROUND_DEFAULT; + +typedef enum { + IM_OSD_BLOCK_MODE_NORMAL = 0, + IM_OSD_BLOCK_MODE_DIFFERENT, +} IM_OSD_BLOCK_WIDTH_MODE; + +typedef enum { + IM_OSD_MODE_HORIZONTAL, + IM_OSD_MODE_VERTICAL, +} IM_OSD_DIRECTION; + +typedef enum { + IM_OSD_COLOR_PIXEL, + IM_OSD_COLOR_EXTERNAL, +} IM_OSD_COLOR_MODE; + +typedef enum { + IM_INTR_READ_INTR = 1 << 0, + IM_INTR_READ_HOLD = 1 << 1, + IM_INTR_WRITE_INTR = 1 << 2, +} IM_PRE_INTR_FLAGS; + +typedef enum { + IM_CONTEXT_NONE = 0x0, + IM_CONTEXT_SRC_FIX_ENABLE = 0x1 << 0, // Enable kernel to modify the image parameters of the channel. + IM_CONTEXT_SRC_CACHE_INFO = 0x1 << 1, // It will replace the parameters in ctx with the modified parameters. + IM_CONTEXT_SRC1_FIX_ENABLE = 0x1 << 2, + IM_CONTEXT_SRC1_CACHE_INFO = 0x1 << 3, + IM_CONTEXT_DST_FIX_ENABLE = 0x1 << 4, + IM_CONTEXT_DST_CACHE_INFO = 0x1 << 5, +} IM_CONTEXT_FLAGS; + +/* Get RGA basic information index */ +typedef enum { + RGA_VENDOR = 0, + RGA_VERSION, + RGA_MAX_INPUT, + RGA_MAX_OUTPUT, + RGA_BYTE_STRIDE, + RGA_SCALE_LIMIT, + RGA_INPUT_FORMAT, + RGA_OUTPUT_FORMAT, + RGA_FEATURE, + RGA_EXPECTED, + RGA_ALL, +} IM_INFORMATION; + +/* Status codes, returned by any blit function */ +typedef enum { + IM_STATUS_NOERROR = 2, + IM_STATUS_SUCCESS = 1, + IM_STATUS_NOT_SUPPORTED = -1, + IM_STATUS_OUT_OF_MEMORY = -2, + IM_STATUS_INVALID_PARAM = -3, + IM_STATUS_ILLEGAL_PARAM = -4, + IM_STATUS_ERROR_VERSION = -5, + IM_STATUS_FAILED = 0, +} IM_STATUS; + +typedef uint32_t im_api_version_t; +typedef uint32_t im_ctx_id_t; +typedef uint32_t rga_buffer_handle_t; + +/* Rectangle definition */ +typedef struct { + int x; /* upper-left x */ + int y; /* upper-left y */ + int width; /* width */ + int height; /* height */ +} im_rect; + +typedef struct { + int max; /* The Maximum value of the color key */ + int min; /* The minimum value of the color key */ +} im_colorkey_range; + + +typedef struct im_nn { + int scale_r; /* scaling factor on R channal */ + int scale_g; /* scaling factor on G channal */ + int scale_b; /* scaling factor on B channal */ + int offset_r; /* offset on R channal */ + int offset_g; /* offset on G channal */ + int offset_b; /* offset on B channal */ +} im_nn_t; + +/* im_info definition */ +typedef struct { + void* vir_addr; /* virtual address */ + void* phy_addr; /* physical address */ + int fd; /* shared fd */ + + int width; /* width */ + int height; /* height */ + int wstride; /* wstride */ + int hstride; /* hstride */ + int format; /* format */ + + int color_space_mode; /* color_space_mode */ + int global_alpha; /* global_alpha */ + int rd_mode; + + /* legarcy */ + int color; /* color, used by color fill */ + im_colorkey_range colorkey_range; /* range value of color key */ + im_nn_t nn; + int rop_code; + + rga_buffer_handle_t handle; /* buffer handle */ +} rga_buffer_t; + +typedef struct im_color { + union { + struct { + uint8_t red; + uint8_t green; + uint8_t blue; + uint8_t alpha; + }; + uint32_t value; + }; +} im_color_t; + +typedef struct im_osd_invert_factor { + uint8_t alpha_max; + uint8_t alpha_min; + uint8_t yg_max; + uint8_t yg_min; + uint8_t crb_max; + uint8_t crb_min; +} im_osd_invert_factor_t; + +typedef struct im_osd_bpp2 { + uint8_t ac_swap; // ac swap flag + // 0: CA + // 1: AC + uint8_t endian_swap; // rgba2bpp endian swap + // 0: Big endian + // 1: Little endian + im_color_t color0; + im_color_t color1; +} im_osd_bpp2_t; + +typedef struct im_osd_block { + int width_mode; // normal or different + // IM_OSD_BLOCK_MODE_NORMAL + // IM_OSD_BLOCK_MODE_DIFFERENT + union { + int width; // normal_mode block width + int width_index; // different_mode block width index in RAM + }; + + int block_count; // block count + + int background_config; // background config is bright or dark + // IM_OSD_BACKGROUND_DEFAULT_BRIGHT + // IM_OSD_BACKGROUND_DEFAULT_DARK + + int direction; // osd block direction + // IM_OSD_MODE_HORIZONTAL + // IM_OSD_MODE_VERTICAL + + int color_mode; // using src1 color or config color + // IM_OSD_COLOR_PIXEL + // IM_OSD_COLOR_EXTERNAL + im_color_t normal_color; // config color: normal + im_color_t invert_color; // config color: invert +} im_osd_block_t; + +typedef struct im_osd_invert { + int invert_channel; // invert channel config: + // IM_OSD_INVERT_CHANNEL_NONE + // IM_OSD_INVERT_CHANNEL_Y_G + // IM_OSD_INVERT_CHANNEL_C_RB + // IM_OSD_INVERT_CHANNEL_ALPHA + // IM_OSD_INVERT_CHANNEL_COLOR + // IM_OSD_INVERT_CHANNEL_BOTH + int flags_mode; // use external or inertnal RAM invert flags + // IM_OSD_FLAGS_EXTERNAL + // IM_OSD_FLAGS_INTERNAL + int flags_index; // flags index when using internal RAM invert flags + + uint64_t invert_flags; // external invert flags + uint64_t current_flags; // current flags + + int invert_mode; // invert use swap or factor + // IM_OSD_INVERT_USE_FACTOR + // IM_OSD_INVERT_USE_SWAP + im_osd_invert_factor_t factor; + + int threash; +} im_osd_invert_t; + +typedef struct im_osd { + int osd_mode; // osd mode: statistics or auto_invert + // IM_OSD_MODE_STATISTICS + // IM_OSD_MODE_AUTO_INVERT + im_osd_block_t block_parm; // osd block info config + + im_osd_invert_t invert_config; + + im_osd_bpp2_t bpp2_info; +} im_osd_t; + +typedef struct im_intr_config { + uint32_t flags; + + int read_threshold; + int write_start; + int write_step; +} im_intr_config_t; + +typedef struct im_opt { + im_api_version_t version; + + int color; /* color, used by color fill */ + im_colorkey_range colorkey_range; /* range value of color key */ + im_nn_t nn; + int rop_code; + + int priority; + int core; + + int mosaic_mode; + + im_osd_t osd_config; + + im_intr_config_t intr_config; + + char reserve[128]; +} im_opt_t; + +typedef struct im_context { + int priority; + IM_SCHEDULER_CORE core; + int check_mode; +} im_context_t; + +typedef struct im_handle_param { + uint32_t width; + uint32_t height; + uint32_t format; +}im_handle_param_t; + +#endif /* _RGA_IM2D_TYPE_H_ */ diff --git a/rga/inc/im2d_version.h b/rga/inc/im2d_version.h new file mode 100644 index 0000000..997008a --- /dev/null +++ b/rga/inc/im2d_version.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2022 Rockchip Electronics Co., Ltd. + * Authors: + * Cerf Yu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _RGA_IM2D_VERSION_H_ +#define _RGA_IM2D_VERSION_H_ + +#define RGA_VERSION_STR_HELPER(x) #x +#define RGA_VERSION_STR(x) RGA_VERSION_STR_HELPER(x) + +/* RGA im2d api verison */ +#define RGA_API_MAJOR_VERSION 1 +#define RGA_API_MINOR_VERSION 8 +#define RGA_API_REVISION_VERSION 0 +#define RGA_API_BUILD_VERSION 0 + +#define RGA_API_VERSION \ + RGA_VERSION_STR(RGA_API_MAJOR_VERSION) "." \ + RGA_VERSION_STR(RGA_API_MINOR_VERSION) "." \ + RGA_VERSION_STR(RGA_API_REVISION_VERSION) "_[" \ + RGA_VERSION_STR(RGA_API_BUILD_VERSION) "]" +#define RGA_API_FULL_VERSION "rga_api version " RGA_API_VERSION + +#define RGA_SET_CURRENT_API_VERISON (\ + (RGA_API_MAJOR_VERSION & 0xff) << 24 | \ + (RGA_API_MINOR_VERSION & 0xff) << 16 | \ + (RGA_API_REVISION_VERSION & 0xff) << 8 | \ + (RGA_API_BUILD_VERSION & 0xff)\ + ) + +#endif /* _RGA_IM2D_VERSION_H_ */ diff --git a/rga/inc/rga.h b/rga/inc/rga.h new file mode 100644 index 0000000..4dc3689 --- /dev/null +++ b/rga/inc/rga.h @@ -0,0 +1,589 @@ +/* + * Copyright (C) 2016 Rockchip Electronics Co., Ltd. + * Authors: + * Zhiqin Wei + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _RGA_DRIVER_H_ +#define _RGA_DRIVER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Use 'r' as magic number */ +#define RGA_IOC_MAGIC 'r' +#define RGA_IOW(nr, type) _IOW(RGA_IOC_MAGIC, nr, type) +#define RGA_IOR(nr, type) _IOR(RGA_IOC_MAGIC, nr, type) +#define RGA_IOWR(nr, type) _IOWR(RGA_IOC_MAGIC, nr, type) + +#define RGA_IOC_GET_DRVIER_VERSION RGA_IOR(0x1, struct rga_version_t) +#define RGA_IOC_GET_HW_VERSION RGA_IOR(0x2, struct rga_hw_versions_t) +#define RGA_IOC_IMPORT_BUFFER RGA_IOWR(0x3, struct rga_buffer_pool) +#define RGA_IOC_RELEASE_BUFFER RGA_IOW(0x4, struct rga_buffer_pool) +#define RGA_START_CONFIG RGA_IOR(0x5, uint32_t) +#define RGA_END_CONFIG RGA_IOWR(0x6, struct rga_user_ctx_t) +#define RGA_CMD_CONFIG RGA_IOWR(0x7, struct rga_user_ctx_t) +#define RGA_CANCEL_CONFIG RGA_IOWR(0x8, uint32_t) + +#define RGA_BLIT_SYNC 0x5017 +#define RGA_BLIT_ASYNC 0x5018 +#define RGA_FLUSH 0x5019 +#define RGA_GET_RESULT 0x501a +#define RGA_GET_VERSION 0x501b + +#define RGA2_BLIT_SYNC 0x6017 +#define RGA2_BLIT_ASYNC 0x6018 +#define RGA2_FLUSH 0x6019 +#define RGA2_GET_RESULT 0x601a +#define RGA2_GET_VERSION 0x601b + +#define RGA_REG_CTRL_LEN 0x8 /* 8 */ +#define RGA_REG_CMD_LEN 0x1c /* 28 */ +#define RGA_CMD_BUF_SIZE 0x700 /* 16*28*4 */ + +#ifndef ENABLE +#define ENABLE 1 +#endif + +#ifndef DISABLE +#define DISABLE 0 +#endif + +enum rga_memory_type { + RGA_DMA_BUFFER = 0, + RGA_VIRTUAL_ADDRESS, + RGA_PHYSICAL_ADDRESS +}; + +/* RGA process mode enum */ +enum { + bitblt_mode = 0x0, + color_palette_mode = 0x1, + color_fill_mode = 0x2, + line_point_drawing_mode = 0x3, + blur_sharp_filter_mode = 0x4, + pre_scaling_mode = 0x5, + update_palette_table_mode = 0x6, + update_patten_buff_mode = 0x7, +}; + + +enum { + rop_enable_mask = 0x2, + dither_enable_mask = 0x8, + fading_enable_mask = 0x10, + PD_enbale_mask = 0x20, +}; + +enum { + yuv2rgb_mode0 = 0x0, /* BT.601 MPEG */ + yuv2rgb_mode1 = 0x1, /* BT.601 JPEG */ + yuv2rgb_mode2 = 0x2, /* BT.709 */ + + rgb2yuv_601_full = 0x1 << 8, + rgb2yuv_709_full = 0x2 << 8, + yuv2yuv_601_limit_2_709_limit = 0x3 << 8, + yuv2yuv_601_limit_2_709_full = 0x4 << 8, + yuv2yuv_709_limit_2_601_limit = 0x5 << 8, + yuv2yuv_709_limit_2_601_full = 0x6 << 8, //not support + yuv2yuv_601_full_2_709_limit = 0x7 << 8, + yuv2yuv_601_full_2_709_full = 0x8 << 8, //not support + yuv2yuv_709_full_2_601_limit = 0x9 << 8, //not support + yuv2yuv_709_full_2_601_full = 0xa << 8, //not support + full_csc_mask = 0xf00, +}; + +/* RGA rotate mode */ +enum { + rotate_mode0 = 0x0, /* no rotate */ + rotate_mode1 = 0x1, /* rotate */ + rotate_mode2 = 0x2, /* x_mirror */ + rotate_mode3 = 0x3, /* y_mirror */ +}; + +enum { + color_palette_mode0 = 0x0, /* 1K */ + color_palette_mode1 = 0x1, /* 2K */ + color_palette_mode2 = 0x2, /* 4K */ + color_palette_mode3 = 0x3, /* 8K */ +}; + +enum { + BB_BYPASS = 0x0, /* no rotate */ + BB_ROTATE = 0x1, /* rotate */ + BB_X_MIRROR = 0x2, /* x_mirror */ + BB_Y_MIRROR = 0x3 /* y_mirror */ +}; + +enum { + nearby = 0x0, /* no rotate */ + bilinear = 0x1, /* rotate */ + bicubic = 0x2, /* x_mirror */ +}; + +#define RGA_SCHED_PRIORITY_DEFAULT 0 +#define RGA_SCHED_PRIORITY_MAX 6 + +enum { + RGA3_SCHEDULER_CORE0 = 1 << 0, + RGA3_SCHEDULER_CORE1 = 1 << 1, + RGA2_SCHEDULER_CORE0 = 1 << 2, +}; + +/* +// Alpha Red Green Blue +{ 4, 32, {{32,24, 8, 0, 16, 8, 24,16 }}, GGL_RGBA }, // RK_FORMAT_RGBA_8888 +{ 4, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGBX_8888 +{ 3, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGB_888 +{ 4, 32, {{32,24, 24,16, 16, 8, 8, 0 }}, GGL_BGRA }, // RK_FORMAT_BGRA_8888 +{ 2, 16, {{ 0, 0, 16,11, 11, 5, 5, 0 }}, GGL_RGB }, // RK_FORMAT_RGB_565 +{ 2, 16, {{ 1, 0, 16,11, 11, 6, 6, 1 }}, GGL_RGBA }, // RK_FORMAT_RGBA_5551 +{ 2, 16, {{ 4, 0, 16,12, 12, 8, 8, 4 }}, GGL_RGBA }, // RK_FORMAT_RGBA_4444 +{ 3, 24, {{ 0, 0, 24,16, 16, 8, 8, 0 }}, GGL_BGR }, // RK_FORMAT_BGB_888 + +*/ +/* In order to be compatible with RK_FORMAT_XX and HAL_PIXEL_FORMAT_XX, + * RK_FORMAT_XX is shifted to the left by 8 bits to distinguish. */ +typedef enum _Rga_SURF_FORMAT { + RK_FORMAT_RGBA_8888 = 0x0 << 8, + RK_FORMAT_RGBX_8888 = 0x1 << 8, + RK_FORMAT_RGB_888 = 0x2 << 8, + RK_FORMAT_BGRA_8888 = 0x3 << 8, + RK_FORMAT_RGB_565 = 0x4 << 8, + RK_FORMAT_RGBA_5551 = 0x5 << 8, + RK_FORMAT_RGBA_4444 = 0x6 << 8, + RK_FORMAT_BGR_888 = 0x7 << 8, + + RK_FORMAT_YCbCr_422_SP = 0x8 << 8, + RK_FORMAT_YCbCr_422_P = 0x9 << 8, + RK_FORMAT_YCbCr_420_SP = 0xa << 8, + RK_FORMAT_YCbCr_420_P = 0xb << 8, + + RK_FORMAT_YCrCb_422_SP = 0xc << 8, + RK_FORMAT_YCrCb_422_P = 0xd << 8, + RK_FORMAT_YCrCb_420_SP = 0xe << 8, + RK_FORMAT_YCrCb_420_P = 0xf << 8, + + RK_FORMAT_BPP1 = 0x10 << 8, + RK_FORMAT_BPP2 = 0x11 << 8, + RK_FORMAT_BPP4 = 0x12 << 8, + RK_FORMAT_BPP8 = 0x13 << 8, + + RK_FORMAT_Y4 = 0x14 << 8, + RK_FORMAT_YCbCr_400 = 0x15 << 8, + + RK_FORMAT_BGRX_8888 = 0x16 << 8, + + RK_FORMAT_YVYU_422 = 0x18 << 8, + RK_FORMAT_YVYU_420 = 0x19 << 8, + RK_FORMAT_VYUY_422 = 0x1a << 8, + RK_FORMAT_VYUY_420 = 0x1b << 8, + RK_FORMAT_YUYV_422 = 0x1c << 8, + RK_FORMAT_YUYV_420 = 0x1d << 8, + RK_FORMAT_UYVY_422 = 0x1e << 8, + RK_FORMAT_UYVY_420 = 0x1f << 8, + + RK_FORMAT_YCbCr_420_SP_10B = 0x20 << 8, + RK_FORMAT_YCrCb_420_SP_10B = 0x21 << 8, + RK_FORMAT_YCbCr_422_SP_10B = 0x22 << 8, + RK_FORMAT_YCrCb_422_SP_10B = 0x23 << 8, + /* For compatibility with misspellings */ + RK_FORMAT_YCbCr_422_10b_SP = RK_FORMAT_YCbCr_422_SP_10B, + RK_FORMAT_YCrCb_422_10b_SP = RK_FORMAT_YCrCb_422_SP_10B, + + RK_FORMAT_BGR_565 = 0x24 << 8, + RK_FORMAT_BGRA_5551 = 0x25 << 8, + RK_FORMAT_BGRA_4444 = 0x26 << 8, + + RK_FORMAT_ARGB_8888 = 0x28 << 8, + RK_FORMAT_XRGB_8888 = 0x29 << 8, + RK_FORMAT_ARGB_5551 = 0x2a << 8, + RK_FORMAT_ARGB_4444 = 0x2b << 8, + RK_FORMAT_ABGR_8888 = 0x2c << 8, + RK_FORMAT_XBGR_8888 = 0x2d << 8, + RK_FORMAT_ABGR_5551 = 0x2e << 8, + RK_FORMAT_ABGR_4444 = 0x2f << 8, + + RK_FORMAT_RGBA2BPP = 0x30 << 8, + + RK_FORMAT_UNKNOWN = 0x100 << 8, +} RgaSURF_FORMAT; + +/* RGA3 rd_mode */ +enum +{ + raster_mode = 0x1 << 0, + fbc_mode = 0x1 << 1, + tile_mode = 0x1 << 2, +}; + +typedef struct rga_img_info_t { + uint64_t yrgb_addr; /* yrgb mem addr */ + uint64_t uv_addr; /* cb/cr mem addr */ + uint64_t v_addr; /* cr mem addr */ + + uint32_t format; //definition by RK_FORMAT + uint16_t act_w; + uint16_t act_h; + uint16_t x_offset; + uint16_t y_offset; + + uint16_t vir_w; + uint16_t vir_h; + + uint16_t endian_mode; //for BPP + uint16_t alpha_swap; + + //used by RGA3 + uint16_t rotate_mode; + uint16_t rd_mode; + + uint16_t is_10b_compact; + uint16_t is_10b_endian; + + uint16_t enable; +} +rga_img_info_t; + +typedef struct POINT { + uint16_t x; + uint16_t y; +} +POINT; + +typedef struct RECT { + uint16_t xmin; + uint16_t xmax; // width - 1 + uint16_t ymin; + uint16_t ymax; // height - 1 +} RECT; + +typedef struct MMU { + uint8_t mmu_en; + uint64_t base_addr; + uint32_t mmu_flag; /* [0] mmu enable [1] src_flush [2] dst_flush [3] CMD_flush [4~5] page size*/ +} MMU; + +typedef struct COLOR_FILL { + int16_t gr_x_a; + int16_t gr_y_a; + int16_t gr_x_b; + int16_t gr_y_b; + int16_t gr_x_g; + int16_t gr_y_g; + int16_t gr_x_r; + int16_t gr_y_r; + //u8 cp_gr_saturation; +} +COLOR_FILL; + +typedef struct FADING { + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t res; +} +FADING; + +typedef struct line_draw_t { + POINT start_point; /* LineDraw_start_point */ + POINT end_point; /* LineDraw_end_point */ + uint32_t color; /* LineDraw_color */ + uint32_t flag; /* (enum) LineDrawing mode sel */ + uint32_t line_width; /* range 1~16 */ +} +line_draw_t; + +/* color space convert coefficient. */ +typedef struct csc_coe_t { + int16_t r_v; + int16_t g_y; + int16_t b_u; + int32_t off; +} csc_coe_t; + +typedef struct full_csc_t { + uint8_t flag; + csc_coe_t coe_y; + csc_coe_t coe_u; + csc_coe_t coe_v; +} full_csc_t; + +struct rga_mosaic_info { + uint8_t enable; + uint8_t mode; +}; + +struct rga_pre_intr_info { + uint8_t enable; + + uint8_t read_intr_en; + uint8_t write_intr_en; + uint8_t read_hold_en; + uint32_t read_threshold; + uint32_t write_start; + uint32_t write_step; +}; + +/* MAX(min, (max - channel_value)) */ +struct rga_osd_invert_factor { + uint8_t alpha_max; + uint8_t alpha_min; + uint8_t yg_max; + uint8_t yg_min; + uint8_t crb_max; + uint8_t crb_min; +}; + +struct rga_color { + union { + struct { + uint8_t red; + uint8_t green; + uint8_t blue; + uint8_t alpha; + }; + uint32_t value; + }; +}; + +struct rga_osd_bpp2 { + uint8_t ac_swap; // ac swap flag + // 0: CA + // 1: AC + uint8_t endian_swap; // rgba2bpp endian swap + // 0: Big endian + // 1: Little endian + struct rga_color color0; + struct rga_color color1; +}; + +struct rga_osd_mode_ctrl { + uint8_t mode; // OSD cal mode: + // 0b'1: statistics mode + // 1b'1: auto inversion overlap mode + uint8_t direction_mode; // horizontal or vertical + // 0: horizontal + // 1: vertical + uint8_t width_mode; // using @fix_width or LUT width + // 0: fix width + // 1: LUT width + uint16_t block_fix_width; // OSD block fixed width + // real width = (fix_width + 1) * 2 + uint8_t block_num; // OSD block num + uint16_t flags_index; // auto invert flags index + + /* invertion config */ + uint8_t color_mode; // selete color + // 0: src1 color + // 1: config data color + uint8_t invert_flags_mode; // invert flag selete + // 0: use RAM flag + // 1: usr last result + uint8_t default_color_sel; // default color mode + // 0: default is bright + // 1: default is dark + uint8_t invert_enable; // invert channel enable + // 1 << 0: aplha enable + // 1 << 1: Y/G disable + // 1 << 2: C/RB disable + uint8_t invert_mode; // invert cal mode + // 0: normal(max-data) + // 1: swap + uint8_t invert_thresh; // if luma > thresh, osd_flag to be 1 + uint8_t unfix_index; // OSD width config index +}; + +struct rga_osd_info { + uint8_t enable; + + struct rga_osd_mode_ctrl mode_ctrl; + struct rga_osd_invert_factor cal_factor; + struct rga_osd_bpp2 bpp2_info; + + union { + struct { + uint32_t last_flags1; + uint32_t last_flags0; + }; + uint64_t last_flags; + }; + + union { + struct { + uint32_t cur_flags1; + uint32_t cur_flags0; + }; + uint64_t cur_flags; + }; +}; + +#define RGA_VERSION_SIZE 16 +#define RGA_HW_SIZE 5 + +struct rga_version_t { + uint32_t major; + uint32_t minor; + uint32_t revision; + uint8_t str[RGA_VERSION_SIZE]; +}; + +struct rga_hw_versions_t { + struct rga_version_t version[RGA_HW_SIZE]; + uint32_t size; +}; + +struct rga_memory_parm { + uint32_t width; + uint32_t height; + uint32_t format; + + uint32_t size; +}; + +struct rga_external_buffer { + uint64_t memory; + uint32_t type; + + uint32_t handle; + struct rga_memory_parm memory_info; + + uint8_t reserve[252]; +}; + +struct rga_buffer_pool { + uint64_t buffers; + uint32_t size; +}; + +struct rga_req { + uint8_t render_mode; /* (enum) process mode sel */ + + rga_img_info_t src; /* src image info */ + rga_img_info_t dst; /* dst image info */ + rga_img_info_t pat; /* patten image info */ + + uint64_t rop_mask_addr; /* rop4 mask addr */ + uint64_t LUT_addr; /* LUT addr */ + + RECT clip; /* dst clip window default value is dst_vir */ + /* value from [0, w-1] / [0, h-1]*/ + + int32_t sina; /* dst angle default value 0 16.16 scan from table */ + int32_t cosa; /* dst angle default value 0 16.16 scan from table */ + + uint16_t alpha_rop_flag; /* alpha rop process flag */ + /* ([0] = 1 alpha_rop_enable) */ + /* ([1] = 1 rop enable) */ + /* ([2] = 1 fading_enable) */ + /* ([3] = 1 PD_enable) */ + /* ([4] = 1 alpha cal_mode_sel) */ + /* ([5] = 1 dither_enable) */ + /* ([6] = 1 gradient fill mode sel) */ + /* ([7] = 1 AA_enable) */ + /* ([8] = 1 nn_quantize) */ + /* ([9] = 1 Real color mode) */ + + uint8_t scale_mode; /* 0 nearst / 1 bilnear / 2 bicubic */ + + uint32_t color_key_max; /* color key max */ + uint32_t color_key_min; /* color key min */ + + uint32_t fg_color; /* foreground color */ + uint32_t bg_color; /* background color */ + + COLOR_FILL gr_color; /* color fill use gradient */ + + line_draw_t line_draw_info; + + FADING fading; + + uint8_t PD_mode; /* porter duff alpha mode sel */ + + uint8_t alpha_global_value; /* global alpha value */ + + uint16_t rop_code; /* rop2/3/4 code scan from rop code table*/ + + uint8_t bsfilter_flag; /* [2] 0 blur 1 sharp / [1:0] filter_type*/ + + uint8_t palette_mode; /* (enum) color palatte 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/ + + uint8_t yuv2rgb_mode; /* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */ + + uint8_t endian_mode; /* 0/big endian 1/little endian*/ + + uint8_t rotate_mode; /* (enum) rotate mode */ + /* 0x0, no rotate */ + /* 0x1, rotate */ + /* 0x2, x_mirror */ + /* 0x3, y_mirror */ + + uint8_t color_fill_mode; /* 0 solid color / 1 patten color */ + + MMU mmu_info; /* mmu information */ + + uint8_t alpha_rop_mode; /* ([0~1] alpha mode) */ + /* ([2~3] rop mode) */ + /* ([4] zero mode en) */ + /* ([5] dst alpha mode) (RGA1) */ + + uint8_t src_trans_mode; + + uint8_t dither_mode; + + full_csc_t full_csc; /* full color space convert */ + + int32_t in_fence_fd; + uint8_t core; + uint8_t priority; + int32_t out_fence_fd; + + uint8_t handle_flag; + + /* RGA2 1106 add */ + struct rga_mosaic_info mosaic_info; + + uint8_t uvhds_mode; + uint8_t uvvds_mode; + + struct rga_osd_info osd_info; + + struct rga_pre_intr_info pre_intr_info; + + uint8_t reservr[59]; +}; + +struct rga_user_ctx_t { + uint64_t cmd_ptr; + uint32_t cmd_num; + uint32_t id; + uint32_t sync_mode; + uint32_t out_fence_fd; + + uint32_t mpi_config_flags; + + uint8_t reservr[124]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /*_RK29_IPP_DRIVER_H_*/ diff --git a/rga/lib/libdrm.so.2 b/rga/lib/libdrm.so.2 new file mode 100755 index 0000000..a807bf7 Binary files /dev/null and b/rga/lib/libdrm.so.2 differ diff --git a/rga/lib/librga.so b/rga/lib/librga.so new file mode 100755 index 0000000..c895014 Binary files /dev/null and b/rga/lib/librga.so differ diff --git a/rga/lib/librga.so.bak b/rga/lib/librga.so.bak new file mode 100644 index 0000000..69e1ba9 Binary files /dev/null and b/rga/lib/librga.so.bak differ diff --git a/rknn.cpp b/rknn.cpp new file mode 100644 index 0000000..88d14c6 --- /dev/null +++ b/rknn.cpp @@ -0,0 +1,246 @@ +#include "rknn.h" +#include +#include +#include "rknn_api.h" +#include +#include +#include +#include +#include +#include +#include "MppDecode.h" +#include "cJSON.h" +#include "pose_body.h" +#include "yolov5.h" +#include "common.h" +#include "postprocess.h" +#include "vertix.h" + + +void *upload_info(void *arg); + +// #define LABEL_NALE_TXT_PATH "./model/coco_80_labels_list.txt" +static int pre_change_frames[OBJ_CLASS_MAX] = {0}; +// static int last_objects[OBJ_NUMB_MAX_SIZE] = {0}; +static int pre_change_objects[OBJ_CLASS_MAX] = {0}; +static int size_of_last_objects = 0; +static int size_of_pre_changed = 0; + +char *CameraID = NULL; +int TypeID = 0; +int UploadPort = 0; + +static char is_uploading = 0; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +// rknn_t *rk = NULL; +char *global_model = NULL; + +float conf_threshold; +const float nms_threshold = 0.4; + +static int init = -1; + +#ifdef DUMP_FIRST_FRAME +#include "rga.h" +volatile char save_flag = 1; +#endif + +int process_a_frame(char *buf, int sw, int sh) +{ + // pthread_mutex_lock(&frame_mutex); + // int ret = pose_body(buf, sw, sh, 0); + struct timeval tpend1, tpend2; + long usec1 = 0; + gettimeofday(&tpend1, NULL); + int ret; + + if (pthread_mutex_trylock(&mutex) == 0) + { + image_buffer_t src_img = {0}; + src_img.format = IMAGE_FORMAT_RGB888; + src_img.height = sh; + src_img.width = sw; + src_img.height_stride = 0; + src_img.width_stride = 0; + src_img.virt_addr = (unsigned char *)buf; + src_img.size = sw * sh * 3; + + object_detect_result_list od_results; + memset(&od_results, 0, sizeof(object_detect_result_list)); + + ret = inference_yolov5_model(&rknn_app_ctx, &src_img, &od_results); + + if (rknn_app_ctx.callback != NULL) { + rknn_app_ctx.callback(&rknn_app_ctx, &od_results, (unsigned char*)buf); + } else { + free(buf); + } + // printf("detect result: %d, %s\n", od_results.count, coco_cls_to_name(0)); + /* + for (int i = 0; i < od_results.count; i++) { + object_detect_result *det_result = &(od_results.results[i]); + printf("(%d)[%s] @ (%d %d %d %d) %.3f\n", det_result->cls_id, coco_cls_to_name(det_result->cls_id), + det_result->box.left, det_result->box.top, + det_result->box.right, det_result->box.bottom, + det_result->prop); + } + */ + pthread_mutex_unlock(&mutex); + } + else + { + ret = -1; + free(buf); + printf("skipped judge\n"); + } + + // free(buf); + gettimeofday(&tpend2, NULL); + usec1 = 1000 * (tpend2.tv_sec - tpend1.tv_sec) + (tpend2.tv_usec - tpend1.tv_usec) / 1000; + printf("rknn cost_time=%ld ms\n", usec1); + + pthread_mutex_unlock(&frame_mutex); + return ret; +} + +int print_object_detect_result(rknn_app_context_t *rknn, object_detect_result_list *group, unsigned char *buff) +{ + int need_upload_info[OBJ_CLASS_MAX] = {-1}; + + int current_objects[OBJ_CLASS_MAX] = {0}; + char need_upload = 0; + + for (int i = 0; i < group->count; i++) + { + if (group->results[i].cls_id >= OBJ_CLASS_REAL_NUM) + { + printf("skip clsid > OBJ_CLASS_NUM: %d\n", group->results[i].cls_id); + continue; + } + char *label = labels[group->results[i].cls_id]; + if (group->results[i].prop < conf_threshold) { + printf("skip prop = %f for class %s\n", group->results[i].prop, label); + continue; + } + int left = group->results[i].box.left; + int top = group->results[i].box.top; + int right = group->results[i].box.right; + int bottom = group->results[i].box.bottom; + if (is_point_in_workspace(left, top, right, bottom)) + { + printf("in "); + current_objects[group->results[i].cls_id] += 1; + } + else + { + printf("not in "); + } + // char *label = labels[group->results[i].cls_id]; + printf("result %2d: (%3d %3d %3d %3d) %f, %s\n", i, group->results[i].box.left, group->results[i].box.top, + group->results[i].box.right, group->results[i].box.bottom, group->results[i].prop, label); + // current_objects[group->results[i].cls_id] += 1; + } + for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++) + { + if (current_objects[i] != pre_change_objects[i]) + { + pre_change_frames[i] = 1; + pre_change_objects[i] = current_objects[i]; + } + // 个数相同, 并且在数帧数 + else if (pre_change_frames[i] != 0) + { + pre_change_frames[i] += 1; + if (pre_change_frames[i] >= 3) + { + need_upload = 1; + pre_change_frames[i] = 0; + // last_objects[i] = pre_change_objects[i]; + need_upload_info[i] = pre_change_objects[i]; + + // change to current, need upload + } + } + } + + if (need_upload && is_uploading == 0) + { + int *need_upload_copy = (int *)malloc(sizeof(int) * OBJ_CLASS_REAL_NUM); + for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++) + { + need_upload_copy[i] = need_upload_info[i]; + } + pthread_t uploadth; + pthread_create(&uploadth, NULL, upload_info, (void *)need_upload_copy); + pthread_detach(uploadth); + } + + free(buff); +} + +void *upload_info(void *arg) +{ + int *need_upload_info = (int *)arg; + if (is_uploading != 0) + { + free(need_upload_info); + return NULL; + } + is_uploading = 1; + + char need_uploading = 0; + + cJSON *array = cJSON_CreateArray(); + for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++) + { + if ((need_upload_info[i] != -1) && codes[i] != 0) + { + need_uploading = 1; + int total_number = need_upload_info[i]; + for (int j = i+1; j < OBJ_CLASS_REAL_NUM; j++) { + if (codes[i] == codes[j]) { + printf("merge %s(No: %d) to %s", labels[j], need_upload_info[j], labels[i]); + total_number += need_upload_info[j]; + need_upload_info[j] = 0; + } + } + + printf("xxxxxxx class idx = %d\n", codes[i]); + cJSON *obj = cJSON_CreateObject(); + // 事件编码,外部事件编码 + cJSON_AddNumberToObject(obj, "class_idx", codes[i]); + cJSON_AddStringToObject(obj, "name", labels[i]); + cJSON_AddNumberToObject(obj, "number", total_number); + cJSON_AddItemToArray(array, obj); + // do upload + } + } + + if (!need_uploading) + { + cJSON_Delete(array); + free(need_upload_info); + is_uploading = 0; + printf("no need to upload\n"); + return NULL; + } + cJSON *uploadinfo = cJSON_CreateObject(); + cJSON_AddStringToObject(uploadinfo, "serial", CameraID); + // 内部事件编码,因为没法表示多个,所以,即将废弃 + cJSON_AddNumberToObject(uploadinfo, "type", TypeID); + cJSON_AddNumberToObject(uploadinfo, "at", current_time_stamp()); + cJSON_AddItemToObject(uploadinfo, "params", array); + + time_t now; + now = time(NULL); + + post_json("127.0.0.1", UploadPort, "localhost", "/video/post", uploadinfo); + cJSON_Delete(uploadinfo); + free(need_upload_info); + + // int resgap = now % TIMEGAP; + // printf("sleep for %d seconds", (2 * TIMEGAP - resgap)); + // sleep(2 * (TIMEGAP - resgap)); + is_uploading = 0; +} \ No newline at end of file diff --git a/rknn.h b/rknn.h new file mode 100644 index 0000000..e37a2f9 --- /dev/null +++ b/rknn.h @@ -0,0 +1,77 @@ +#ifndef _RKNN_H_ +#define _RKNN_H_ + +#include "rknn_api.h" +#include +#include "yolov5.h" + + +#define MODELDIR "." + +#define DEFAULT_CONF_THRESHOLD 0.6 +extern float conf_threshold; + +extern char *CameraID; +extern int TypeID; +extern int UploadPort; + +/* +typedef struct _BOX_RECT +{ + int left, right, top, bottom; +} BOX_RECT; + +typedef struct __detect_result_t +{ + char name[OBJ_NAME_MAX_SIZE]; + int class_index; + BOX_RECT box; + float prop; +} detect_result_t; + +typedef struct _detect_result_groupt_t +{ + int id; + int count; + detect_result_t results[OBJ_NUMB_MAX_SIZE]; +} detect_result_group_t; + +typedef struct rknn +{ + rknn_context ctx; + unsigned char *model; + int num_input; + int num_output; + + int model_width; + int model_height; + + rknn_tensor_attr *out_attrs; + + int (*do_judge)(struct rknn *rk, char *rgb_hwc, int width, int height, + int (*callback)(struct rknn *rk, detect_result_group_t *result_group)); + int (*deinit)(struct rknn *rk); +} rknn_t; +*/ + +extern char *global_model; + +/* +rknn_t *get_rknn(); +rknn_t *do_init_model(); +rknn_t *reload_rknn(char *model_path); +*/ +int process_a_frame(char *buf, int sw, int sh); + +/* +int post_process_u8(uint8_t *input0, uint8_t *input1, uint8_t *input2, int model_in_h, int model_in_w, + int h_offset, int w_offset, float resize_w_scale, float resize_h_scale, float conf_threshold, float nms_threshold, + std::vector &qnt_zps, std::vector &qnt_scales, + detect_result_group_t *group, char *origin_buf); +*/ + +int print_object_detect_result(rknn_app_context_t* rknn, object_detect_result_list *group, unsigned char *buff); + +// #define DUMP_FIRST_FRAME + +#endif \ No newline at end of file diff --git a/rknn/inc/rknn_api.h b/rknn/inc/rknn_api.h new file mode 100644 index 0000000..4c8a650 --- /dev/null +++ b/rknn/inc/rknn_api.h @@ -0,0 +1,490 @@ +/**************************************************************************** +* +* Copyright (c) 2017 - 2018 by Rockchip Corp. All rights reserved. +* +* The material in this file is confidential and contains trade secrets +* of Rockchip Corporation. This is proprietary information owned by +* Rockchip Corporation. No part of this work may be disclosed, +* reproduced, copied, transmitted, or used in any way for any purpose, +* without the express written permission of Rockchip Corporation. +* +*****************************************************************************/ + + +#ifndef _RKNN_API_H +#define _RKNN_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + Definition of extended flag for rknn_init. +*/ +/* set high priority context. */ +#define RKNN_FLAG_PRIOR_HIGH 0x00000000 + +/* set medium priority context */ +#define RKNN_FLAG_PRIOR_MEDIUM 0x00000001 + +/* set low priority context. */ +#define RKNN_FLAG_PRIOR_LOW 0x00000002 + +/* asynchronous mode. + when enable, rknn_outputs_get will not block for too long because it directly retrieves the result of + the previous frame which can increase the frame rate on single-threaded mode, but at the cost of + rknn_outputs_get not retrieves the result of the current frame. + in multi-threaded mode you do not need to turn this mode on. */ +#define RKNN_FLAG_ASYNC_MASK 0x00000004 + +/* collect performance mode. + when enable, you can get detailed performance reports via rknn_query(ctx, RKNN_QUERY_PERF_DETAIL, ...), + but it will reduce the frame rate. */ +#define RKNN_FLAG_COLLECT_PERF_MASK 0x00000008 + +/* + Error code returned by the RKNN API. +*/ +#define RKNN_SUCC 0 /* execute succeed. */ +#define RKNN_ERR_FAIL -1 /* execute failed. */ +#define RKNN_ERR_TIMEOUT -2 /* execute timeout. */ +#define RKNN_ERR_DEVICE_UNAVAILABLE -3 /* device is unavailable. */ +#define RKNN_ERR_MALLOC_FAIL -4 /* memory malloc fail. */ +#define RKNN_ERR_PARAM_INVALID -5 /* parameter is invalid. */ +#define RKNN_ERR_MODEL_INVALID -6 /* model is invalid. */ +#define RKNN_ERR_CTX_INVALID -7 /* context is invalid. */ +#define RKNN_ERR_INPUT_INVALID -8 /* input is invalid. */ +#define RKNN_ERR_OUTPUT_INVALID -9 /* output is invalid. */ +#define RKNN_ERR_DEVICE_UNMATCH -10 /* the device is unmatch, please update rknn sdk + and npu driver/firmware. */ +#define RKNN_ERR_INCOMPATILE_PRE_COMPILE_MODEL -11 /* This RKNN model use pre_compile mode, but not compatible with current driver. */ +#define RKNN_ERR_INCOMPATILE_OPTIMIZATION_LEVEL_VERSION -12 /* This RKNN model set optimization level, but not compatible with current driver. */ +#define RKNN_ERR_TARGET_PLATFORM_UNMATCH -13 /* This RKNN model set target platform, but not compatible with current platform. */ +#define RKNN_ERR_NON_PRE_COMPILED_MODEL_ON_MINI_DRIVER -14 /* This RKNN model is not a pre-compiled model, but the npu driver is mini driver. */ + +/* + Definition for tensor +*/ +#define RKNN_MAX_DIMS 16 /* maximum dimension of tensor. */ +#define RKNN_MAX_NAME_LEN 256 /* maximum name lenth of tensor. */ + + +#ifdef __arm__ +typedef uint32_t rknn_context; +#else +typedef uint64_t rknn_context; +#endif + + +/* + The query command for rknn_query +*/ +typedef enum _rknn_query_cmd { + RKNN_QUERY_IN_OUT_NUM = 0, /* query the number of input & output tensor. */ + RKNN_QUERY_INPUT_ATTR, /* query the attribute of input tensor. */ + RKNN_QUERY_OUTPUT_ATTR, /* query the attribute of output tensor. */ + RKNN_QUERY_PERF_DETAIL, /* query the detail performance, need set + RKNN_FLAG_COLLECT_PERF_MASK when call rknn_init, + this query needs to be valid after rknn_outputs_get. */ + RKNN_QUERY_PERF_RUN, /* query the time of run, + this query needs to be valid after rknn_outputs_get. */ + RKNN_QUERY_SDK_VERSION, /* query the sdk & driver version */ + + RKNN_QUERY_CMD_MAX +} rknn_query_cmd; + +/* + the tensor data type. +*/ +typedef enum _rknn_tensor_type { + RKNN_TENSOR_FLOAT32 = 0, /* data type is float32. */ + RKNN_TENSOR_FLOAT16, /* data type is float16. */ + RKNN_TENSOR_INT8, /* data type is int8. */ + RKNN_TENSOR_UINT8, /* data type is uint8. */ + RKNN_TENSOR_INT16, /* data type is int16. */ + + RKNN_TENSOR_TYPE_MAX +} rknn_tensor_type; + +/* + the quantitative type. +*/ +typedef enum _rknn_tensor_qnt_type { + RKNN_TENSOR_QNT_NONE = 0, /* none. */ + RKNN_TENSOR_QNT_DFP, /* dynamic fixed point. */ + RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC, /* asymmetric affine. */ + + RKNN_TENSOR_QNT_MAX +} rknn_tensor_qnt_type; + +/* + the tensor data format. +*/ +typedef enum _rknn_tensor_format { + RKNN_TENSOR_NCHW = 0, /* data format is NCHW. */ + RKNN_TENSOR_NHWC, /* data format is NHWC. */ + + RKNN_TENSOR_FORMAT_MAX +} rknn_tensor_format; + +inline static const char *get_format_string(rknn_tensor_format fmt) +{ + switch (fmt) + { + case RKNN_TENSOR_NCHW: + return "NCHW"; + case RKNN_TENSOR_NHWC: + return "NHWC"; + default: + return "UNKNOW"; + } +} + +inline static const char *get_qnt_type_string(rknn_tensor_qnt_type type) +{ + switch (type) + { + case RKNN_TENSOR_QNT_NONE: + return "NONE"; + case RKNN_TENSOR_QNT_DFP: + return "DFP"; + case RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC: + return "AFFINE"; + default: + return "UNKNOW"; + } +} + +inline static const char *get_type_string(rknn_tensor_type type) +{ + switch (type) + { + case RKNN_TENSOR_FLOAT32: + return "FP32"; + case RKNN_TENSOR_FLOAT16: + return "FP16"; + case RKNN_TENSOR_INT8: + return "INT8"; + case RKNN_TENSOR_UINT8: + return "UINT8"; + case RKNN_TENSOR_INT16: + return "INT16"; + default: + return "UNKNOW"; + } +} +/* + the information for RKNN_QUERY_IN_OUT_NUM. +*/ +typedef struct _rknn_input_output_num { + uint32_t n_input; /* the number of input. */ + uint32_t n_output; /* the number of output. */ +} rknn_input_output_num; + +/* + the information for RKNN_QUERY_INPUT_ATTR / RKNN_QUERY_OUTPUT_ATTR. +*/ +typedef struct _rknn_tensor_attr { + uint32_t index; /* input parameter, the index of input/output tensor, + need set before call rknn_query. */ + + uint32_t n_dims; /* the number of dimensions. */ + uint32_t dims[RKNN_MAX_DIMS]; /* the dimensions array. */ + char name[RKNN_MAX_NAME_LEN]; /* the name of tensor. */ + + uint32_t n_elems; /* the number of elements. */ + uint32_t size; /* the bytes size of tensor. */ + + rknn_tensor_format fmt; /* the data format of tensor. */ + rknn_tensor_type type; /* the data type of tensor. */ + rknn_tensor_qnt_type qnt_type; /* the quantitative type of tensor. */ + int8_t fl; /* fractional length for RKNN_TENSOR_QNT_DFP. */ + uint32_t zp; /* zero point for RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC. */ + float scale; /* scale for RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC. */ +} rknn_tensor_attr; + +/* + the information for RKNN_QUERY_PERF_DETAIL. +*/ +typedef struct _rknn_perf_detail { + char* perf_data; /* the string pointer of perf detail. don't need free it by user. */ + uint64_t data_len; /* the string length. */ +} rknn_perf_detail; + +/* + the information for RKNN_QUERY_PERF_RUN. +*/ +typedef struct _rknn_perf_run { + int64_t run_duration; /* real inference time (us) */ +} rknn_perf_run; + +/* + the information for RKNN_QUERY_SDK_VERSION. +*/ +typedef struct _rknn_sdk_version { + char api_version[256]; /* the version of rknn api. */ + char drv_version[256]; /* the version of rknn driver. */ +} rknn_sdk_version; + +/* + the memory information of tensor. +*/ +typedef struct _rknn_tensor_memory { + void* logical_addr; /* the virtual address of tensor buffer. */ + uint64_t physical_addr; /* the physical address of tensor buffer. */ + int32_t fd; /* the fd of tensor buffer. */ + uint32_t size; /* the size of tensor buffer. */ + uint32_t handle; /* the handle tensor buffer. */ + void * priv_data; /* the data which is reserved. */ + uint64_t reserved_flag; /* the flag which is reserved */ +} rknn_tensor_mem; + +/* + the input information for rknn_input_set. +*/ +typedef struct _rknn_input { + uint32_t index; /* the input index. */ + void* buf; /* the input buf for index. */ + uint32_t size; /* the size of input buf. */ + uint8_t pass_through; /* pass through mode. + if TRUE, the buf data is passed directly to the input node of the rknn model + without any conversion. the following variables do not need to be set. + if FALSE, the buf data is converted into an input consistent with the model + according to the following type and fmt. so the following variables + need to be set.*/ + rknn_tensor_type type; /* the data type of input buf. */ + rknn_tensor_format fmt; /* the data format of input buf. + currently the internal input format of NPU is NCHW by default. + so entering NCHW data can avoid the format conversion in the driver. */ +} rknn_input; + +/* + the output information for rknn_outputs_get. +*/ +typedef struct _rknn_output { + uint8_t want_float; /* want transfer output data to float */ + uint8_t is_prealloc; /* whether buf is pre-allocated. + if true, the following variables need to be set. + if false, The following variables do not need to be set. */ + uint32_t index; /* the output index. */ + void* buf; /* the output buf for index. + when is_prealloc = FALSE and rknn_outputs_release called, + this buf pointer will be free and don't use it anymore. */ + uint32_t size; /* the size of output buf. */ +} rknn_output; + +/* + the extend information for rknn_run. +*/ +typedef struct _rknn_run_extend { + uint64_t frame_id; /* output parameter, indicate current frame id of run. */ +} rknn_run_extend; + +/* + the extend information for rknn_outputs_get. +*/ +typedef struct _rknn_output_extend { + uint64_t frame_id; /* output parameter, indicate the frame id of outputs, corresponds to + struct rknn_run_extend.frame_id.*/ +} rknn_output_extend; + + +/* rknn_init + + initial the context and load the rknn model. + + input: + rknn_context* context the pointer of context handle. + void* model pointer to the rknn model. + uint32_t size the size of rknn model. + uint32_t flag extend flag, see the define of RKNN_FLAG_XXX_XXX. + return: + int error code. +*/ +int rknn_init(rknn_context* context, void* model, uint32_t size, uint32_t flag); + + +/* rknn_destroy + + unload the rknn model and destroy the context. + + input: + rknn_context context the handle of context. + return: + int error code. +*/ +int rknn_destroy(rknn_context context); + + +/* rknn_query + + query the information about model or others. see rknn_query_cmd. + + input: + rknn_context context the handle of context. + rknn_query_cmd cmd the command of query. + void* info the buffer point of information. + uint32_t size the size of information. + return: + int error code. +*/ +int rknn_query(rknn_context context, rknn_query_cmd cmd, void* info, uint32_t size); + + +/* rknn_inputs_set + + set inputs information by input index of rknn model. + inputs information see rknn_input. + + input: + rknn_context context the handle of context. + uint32_t n_inputs the number of inputs. + rknn_input inputs[] the arrays of inputs information, see rknn_input. + return: + int error code +*/ +int rknn_inputs_set(rknn_context context, uint32_t n_inputs, rknn_input inputs[]); + + +/* rknn_inputs_map + + map inputs tensor memory information by input index of rknn model. + inputs information see rknn_input. + + input: + rknn_context context the handle of context. + uint32_t n_inputs the number of inputs. + rknn_tensor_mem mem[] the array of tensor memory information + return: + int error code +*/ +int rknn_inputs_map(rknn_context context, uint32_t n_inputs, rknn_tensor_mem mem[]); + + +/* rknn_inputs_sync + + synchronize inputs tensor buffer by input index of rknn model. + + input: + rknn_context context the handle of context. + uint32_t n_inputs the number of inputs. + rknn_tensor_mem mem[] the array of tensor memory information + return: + int error code +*/ +int rknn_inputs_sync(rknn_context context, uint32_t n_inputs, rknn_tensor_mem mem[]); + + +/* rknn_inputs_unmap + + unmap inputs tensor memory information by input index of rknn model. + inputs information see rknn_input. + + input: + rknn_context context the handle of context. + uint32_t n_inputs the number of inputs. + rknn_tensor_mem mem[] the array of tensor memory information + return: + int error code +*/ +int rknn_inputs_unmap(rknn_context context, uint32_t n_inputs, rknn_tensor_mem mem[]); + + +/* rknn_run + + run the model to execute inference. + Note: On RK3399Pro, this function does not block normally, but it blocks when more than 3 inferences + are not obtained by rknn_outputs_get. + + input: + rknn_context context the handle of context. + rknn_run_extend* extend the extend information of run. + return: + int error code. +*/ +int rknn_run(rknn_context context, rknn_run_extend* extend); + + +/* rknn_outputs_get + + wait the inference to finish and get the outputs. + this function will block until inference finish. + the results will set to outputs[]. + + input: + rknn_context context the handle of context. + uint32_t n_outputs the number of outputs. + rknn_output outputs[] the arrays of output, see rknn_output. + rknn_output_extend* the extend information of output. + return: + int error code. +*/ +int rknn_outputs_get(rknn_context context, uint32_t n_outputs, rknn_output outputs[], rknn_output_extend* extend); + + +/* rknn_outputs_release + + release the outputs that get by rknn_outputs_get. + after called, the rknn_output[x].buf get from rknn_outputs_get will + also be free when rknn_output[x].is_prealloc = FALSE. + + input: + rknn_context context the handle of context. + uint32_t n_ouputs the number of outputs. + rknn_output outputs[] the arrays of output. + return: + int error code +*/ +int rknn_outputs_release(rknn_context context, uint32_t n_ouputs, rknn_output outputs[]); + + +/* rknn_outputs_map + + map the model output tensors memory information. + The difference between this function and "rknn_outputs_get" is + that it directly maps the model output tensor memory location to the user. + + input: + rknn_context context the handle of context. + uint32_t n_outputs the number of outputs. + rknn_tensor_mem mem[] the array of tensor memory information + return: + int error code. +*/ +int rknn_outputs_map(rknn_context context, uint32_t n_outputs, rknn_tensor_mem mem[]); + + +/* rknn_outputs_sync + + synchronize the output tensors buffer to ensure cache cohenrency, wait the inference to finish. + + input: + rknn_context context the handle of context. + uint32_t n_outputs the number of outputs. + rknn_tensor_mem mem[] the array of tensor memory information + return: + int error code. +*/ +int rknn_outputs_sync(rknn_context context, uint32_t n_outputs, rknn_tensor_mem mem[]); + + +/* rknn_outputs_unmap + + unmap the outputs memory information that get by rknn_outputs_map. + + input: + rknn_context context the handle of context. + uint32_t n_ouputs the number of outputs. + rknn_tensor_mem mem[] the array of tensor memory information + return: + int error code +*/ +int rknn_outputs_unmap(rknn_context context, uint32_t n_ouputs, rknn_tensor_mem mem[]); + +#ifdef __cplusplus +} //extern "C" +#endif + +#endif //_RKNN_API_H diff --git a/rknn/lib/librknn_api.so b/rknn/lib/librknn_api.so new file mode 100644 index 0000000..3c2fb02 Binary files /dev/null and b/rknn/lib/librknn_api.so differ diff --git a/utils.cpp b/utils.cpp new file mode 100644 index 0000000..6f4ea5c --- /dev/null +++ b/utils.cpp @@ -0,0 +1,279 @@ +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" +#include + +char header[1024] = {0}; +char send_request[1024] = {0}; +char send_end[1024] = {0}; +char http_boundary[64] = {0}; + +unsigned long get_file_size(const char *path) // 获取文件大小 +{ + unsigned long filesize = -1; + struct stat statbuff; + if (stat(path, &statbuff) < 0) + { + return filesize; + } + else + { + filesize = statbuff.st_size; + } + return filesize; +} + +int create_socket(const char *ip, const unsigned int port) +{ + int cfd = -1; + struct sockaddr_in s_addr, c_addr; + cfd = socket(AF_INET, SOCK_STREAM, 0); + if (-1 == cfd) + { + printf("socket create fail\n"); + return -1; + } + + bzero(&s_addr, sizeof(struct sockaddr_in)); + s_addr.sin_family = AF_INET; + s_addr.sin_addr.s_addr = inet_addr(ip); + s_addr.sin_port = htons(port); + + if (-1 == connect(cfd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr))) + { + printf("conect failed\n"); + return -1; + } + return cfd; +} + +void close_socket(int sockfd) +{ + if (sockfd < 0) + { + return; + } + close(sockfd); +} + +int post_json(const char *ip, const unsigned int port, const char *host, const char *uri, cJSON *data) +{ + int cfd = -1, recbytes = -1; + struct sockaddr_in s_addr, c_addr; + char buffer[1024 * 10] = {0}; + + cfd = create_socket(ip, port); + if (cfd < 0) + { + printf("create sockfd failed\n"); + return -1; + } + + char *strs = cJSON_Print(data); + + int totalsize = strlen(strs); + unsigned long head_len = snprintf(header, 1024, HTTP_HEAD, uri, host, "Content-Type: application/json", totalsize); // 头信息 + totalsize += head_len; + + char *request = (char *)malloc(totalsize); // 申请内存用于存放要发送的数据 + if (request == NULL) + { + printf("malloc request fail !\r\n"); + close_socket(cfd); + return -1; + } + request[0] = '\0'; + strcat(request, header); // http头信息 + strcat(request, strs); // json数据 + free(strs); + + if (-1 == write(cfd, request, totalsize)) + { + printf("send http package fail!\r\n"); + close_socket(cfd); + return -1; + } + + if (-1 == (recbytes = read(cfd, buffer, 10240))) + { + printf("read http ACK fail !\r\n"); + close_socket(cfd); + return -1; + } + buffer[recbytes] = '\0'; + + printf("got response %s\n", buffer); + + free(request); + close_socket(cfd); + return 0; +} + +int post_data(const char *ip, const unsigned int port, char *host, char *uri, const char *filepath) +{ + int cfd = -1, recbytes = -1; + struct sockaddr_in s_addr, c_addr; + char buffer[1024 * 10] = {0}; + + /* + cfd = socket(AF_INET, SOCK_STREAM, 0); + if (-1 == cfd) { + printf("socket create fail\n"); + return -1; + } + + bzero(&s_addr, sizeof(struct sockaddr_in)); + s_addr.sin_family = AF_INET; + s_addr.sin_addr.s_addr = inet_addr(ip); + s_addr.sin_port = htons(port); + + if (-1 == connect(cfd, (struct sockaddr*)&s_addr, sizeof(struct sockaddr))) { + printf("conect failed\n"); + return -1; + } + */ + + cfd = create_socket(ip, port); + if (cfd < 0) + { + printf("create sockfd failed\n"); + return -1; + } + + long long int timestamp; + struct timeval tv; + gettimeofday(&tv, NULL); + timestamp = (long long int)tv.tv_sec * 1000 + tv.tv_usec; + snprintf(http_boundary, 64, "---------------------------%lld", timestamp); + + unsigned long totalsize = 0; + unsigned long filesize = get_file_size(filepath); // 文件大小 + unsigned long request_len = snprintf(send_request, 1024, UPLOAD_REQUEST, http_boundary, filepath); // 请求信息 + unsigned long end_len = snprintf(send_end, 1024, "\r\n--%s--\r\n", http_boundary); // 结束信息 + totalsize = filesize + request_len + end_len; + + char application[128] = {0}; + snprintf(application, 128, "multipart/form-data; boundary=%s", http_boundary); + unsigned long head_len = snprintf(header, 1024, HTTP_HEAD, uri, host, application, totalsize); // 头信息 + totalsize += head_len; + + char *request = (char *)malloc(totalsize); // 申请内存用于存放要发送的数据 + if (request == NULL) + { + printf("malloc request fail !\r\n"); + close_socket(cfd); + return -1; + } + request[0] = '\0'; + + strcat(request, header); // http头信息 + strcat(request, send_request); // 文件图片请求信息 + FILE *fp = fopen(filepath, "rb+"); // 打开要上传的图片 + if (fp == NULL) + { + printf("open file fail!\r\n"); + close_socket(cfd); + return -1; + } + int readbyte = fread(request + head_len + request_len, 1, filesize, fp); // 读取上传的图片信息 + if (readbyte < 1024) // 小于1024个字节 则认为图片有问题 + { + printf("Read picture data fail!\r\n"); + close_socket(cfd); + return -1; + } + memcpy(request + head_len + request_len + filesize, send_end, end_len); // http结束信息 + + /********* 发送http 请求 ***********/ + if (-1 == write(cfd, request, totalsize)) + { + printf("send http package fail!\r\n"); + close_socket(cfd); + return -1; + } + + if (-1 == (recbytes = read(cfd, buffer, 10240))) + { + printf("read http ACK fail !\r\n"); + close_socket(cfd); + return -1; + } + buffer[recbytes] = '\0'; + + printf("got response %s\n", buffer); + + free(request); + fclose(fp); + close_socket(cfd); + return 0; +} + +// outbuf should be larger than 15 digits 20060102150405\0, +// 返回这个时间片里,还剩下多少秒时间 +int get_current_time_gap(current_time_gap_t *gap) +{ + time_t now; + + now = time(NULL); + int resgap = now % TIMEGAP; + + gap->now = now; + gap->now_gap = now - resgap; + gap->gap_remaining = TIMEGAP - resgap; + gap->next_gap = now - resgap + TIMEGAP; + return 0; +} + +double current_time_stamp() +{ + time_t now; + now = time(NULL); + return double(now); +} + +uint64_t convert_time_to_name(time_t now) +{ + struct tm now_time; + localtime_r(&now, &now_time); + + uint64_t res = ((uint64_t)(1900 + now_time.tm_year)) * 1e10 + ((uint64_t)(1 + now_time.tm_mon)) * 1e8 + + ((uint64_t)now_time.tm_mday) * 1e6 + ((uint64_t)now_time.tm_hour) * 1e4 + + ((uint64_t)now_time.tm_min) * 1e2 + (uint64_t)now_time.tm_sec; + + return res; +} + + +int read_data_from_file(const char *path, char **out_data) +{ + FILE *fp = fopen(path, "rb"); + if(fp == NULL) { + printf("fopen %s fail!\n", path); + return -1; + } + fseek(fp, 0, SEEK_END); + int file_size = ftell(fp); + char *data = (char *)malloc(file_size+1); + data[file_size] = 0; + fseek(fp, 0, SEEK_SET); + if(file_size != fread(data, 1, file_size, fp)) { + printf("fread %s fail!\n", path); + free(data); + fclose(fp); + return -1; + } + if(fp) { + fclose(fp); + } + *out_data = data; + return file_size; +} \ No newline at end of file diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..4fd46e8 --- /dev/null +++ b/utils.h @@ -0,0 +1,56 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#define TIMEGAP 10 +#define SERVER_URL "test.com" +#include +#include "cJSON.h" + +typedef unsigned long uint64_t; + +typedef struct _current_time_gap +{ + // 当前时间,用20060102150405表示 + time_t now; + // now gap time + time_t now_gap; + // 距离下一个gap还差多少秒 + int gap_remaining; + // next_gap time; + time_t next_gap; +} current_time_gap_t; + +// Content-Type: multipart/form-data; boundary=%s +// Content-Type: application/json + +#define HTTP_HEAD "POST %s HTTP/1.1\r\n" \ + "Host: %s\r\n" \ + "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:59.0) Gecko/20100101 Firefox/59.0\r\n" \ + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" \ + "Accept-Language: en-US,en;q=0.5\r\n" \ + "Accept-Encoding: gzip, deflate\r\n" \ + "Content-Type: %s\r\n" \ + "Content-Length: %ld\r\n" \ + "Connection: close\r\n" \ + "Upgrade-Insecure-Requests: 1\r\n" \ + "DNT: 1\r\n\r\n" + +#define UPLOAD_REQUEST "--%s\r\n" \ + "Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n" \ + "Content-Type: application/octet-stream\r\n\r\n" + +// #define SERVER_PATH "/h264/upload" + +// HOST: domain name, like git.asxalex.pw +// URI: uri path, like /h264/upload +int post_data(const char *ip, const unsigned int port, char *host, char *URI, const char *filepath); + +int get_current_time_gap(current_time_gap_t *); +uint64_t convert_time_to_name(time_t now); +double current_time_stamp(); + +int read_data_from_file(const char *path, char **out_data); + +int post_json(const char *ip, const unsigned int port, const char *host, const char *uri, cJSON *data); + +#endif \ No newline at end of file diff --git a/vertix.cpp b/vertix.cpp new file mode 100644 index 0000000..d47a079 --- /dev/null +++ b/vertix.cpp @@ -0,0 +1,137 @@ +#include "vertix.h" +#include +#include "pose_body.h" + +Polygon workspace; + +void dump_polygon_to_file(char *filename) { + FILE *fp = fopen(filename, "w+"); + if (fp == NULL) + { + printf("failed to open fp\n"); + return; + } + + char s[100]; + snprintf(s, 100, "rect: ["); + fwrite(s, strlen(s), 1, fp); + for (int i = 0; i < workspace.numVertix; i++) + { + if (i != workspace.numVertix - 1) + { + snprintf(s, 100, "(%f, %f), ", workspace.vertix[i].x, workspace.vertix[i].y); + } + else + { + snprintf(s, 100, "(%f, %f)", workspace.vertix[i].x, workspace.vertix[i].y); + } + fwrite(s, strlen(s), 1, fp); + } + const char *suffix = "]\n"; + fwrite(suffix, strlen(suffix), 1, fp); + fclose(fp); + +} + +void init_polygon(float *datas, int point_size) +{ + if (point_size == 0) + { + workspace.numVertix = 0; +#ifdef DUMP_POLYGON_INFO + char filename[128]; + snprintf(filename, 128, "/usr/data/camera/%s/dump_rect.txt", CameraID); + dump_polygon_to_file(filename); +#endif + return; + } + if (point_size % 2 != 0) + { + printf("point size error"); + exit(0); + } + workspace.numVertix = point_size / 2; + workspace.vertix = (Point *)malloc(sizeof(Point) * point_size); + for (int i = 0; i < point_size / 2; i++) + { + workspace.vertix[i] = Point{ + x : datas[i * 2], + y : datas[i * 2 + 1], + }; + } + +#ifdef DUMP_POLYGON_INFO + char filename[128]; + snprintf(filename, 128, "/usr/data/camera/%s/dump_rect.txt", CameraID); + dump_polygon_to_file(filename); +#endif +} + +void dump_box_info(bool is_in, int left, int top, int right, int bottom) +{ + char filename[128]; + snprintf(filename, 128, "/usr/data/camera/%s/dump_rect.txt", CameraID); + FILE *fp = fopen(filename, "a+"); + if (fp == NULL) + { + printf("failed to open fp\n"); + return; + } + + float y = (top + bottom) / 2.0; + float x = (left + right) / 2.0; + char s[] = {0}; + if (is_in) + { + snprintf(s, 1024, "in: [%d, %d, %d, %d](%f, %f)\n", + left, top, right, bottom, x, y); + } + else + { + snprintf(s, 1024, "not in: [%d, %d, %d, %d](%f, %f)\n", + left, top, right, bottom, x, y); + } + fwrite(s, strlen(s), 1, fp); + fclose(fp); +} + +bool is_point_in_workspace(int left, int top, int right, int bottom) +{ + + float y = (top + bottom) / 2.0; + float x = (left + right) / 2.0; + int n = workspace.numVertix; + if (n == 0) + { + // all area +#ifdef DUMP_POLYGON_INFO + dump_box_info(true, left, top, right, bottom); +#endif + printf("all workspace\n"); + return true; + } + + int i, j; + bool inside = false; + + for (i = 0, j = n - 1; i < n; j = i++) + { + if ((workspace.vertix[i].y > y) != (workspace.vertix[j].y > y)) + { + // this point is between the Point[j] and Point[i] in y axis + float deltax = (workspace.vertix[j].x - workspace.vertix[i].x); + float deltay = (workspace.vertix[j].y - workspace.vertix[i].y); + float ratio = deltax / deltay; + + if (x < (ratio * (y - workspace.vertix[i].y) + workspace.vertix[i].x)) + { + inside = !inside; + } + } + } + +#ifdef DUMP_POLYGON_INFO + dump_box_info(inside, left, top, right, bottom); +#endif + return inside; +} \ No newline at end of file diff --git a/vertix.h b/vertix.h new file mode 100644 index 0000000..12bc8cf --- /dev/null +++ b/vertix.h @@ -0,0 +1,24 @@ +#ifndef __MY_VERTIX_H__ +#define __MY_VERTIX_H__ + +typedef struct +{ + float x; + float y; +} Point; + +typedef struct +{ + int numVertix; + Point *vertix; +} Polygon; + +extern Polygon workspace; + +#define DUMP_POLYGON_INFO + +void init_polygon(float *datas, int size); + +bool is_point_in_workspace(int left, int top, int right, int bottom); + +#endif \ No newline at end of file diff --git a/yolov5.cc b/yolov5.cc new file mode 100644 index 0000000..fee21f6 --- /dev/null +++ b/yolov5.cc @@ -0,0 +1,283 @@ +// Copyright (c) 2023 by Rockchip Electronics Co., Ltd. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include + +#include "yolov5.h" +#include "common.h" +#include "utils.h" +// #include "file_utils.h" +// #include "image_utils.h" + + +rknn_app_context_t rknn_app_ctx; + +static void dump_tensor_attr(rknn_tensor_attr *attr) +{ + printf(" index=%d, name=%s, n_dims=%d, dims=[%d, %d, %d, %d], n_elems=%d, size=%d, fmt=%s, type=%s, qnt_type=%s, " + "zp=%d, scale=%f\n", + attr->index, attr->name, attr->n_dims, attr->dims[3], attr->dims[2], attr->dims[1], attr->dims[0], + attr->n_elems, attr->size, get_format_string(attr->fmt), get_type_string(attr->type), + get_qnt_type_string(attr->qnt_type), attr->zp, attr->scale); +} + +int init_yolov5_model(const char *model_path, rknn_app_context_t *app_ctx,int(*callback)(rknn_app_context_t *rk, object_detect_result_list *result_group, unsigned char *buff)) +{ + int ret; + int model_len = 0; + char *model; + rknn_context ctx = 0; + + + // Load RKNN Model + model_len = read_data_from_file(model_path, &model); + if (model == NULL) + { + printf("load_model fail!\n"); + return -1; + } + + ret = rknn_init(&ctx, model, model_len, 0); + free(model); + if (ret < 0) + { + printf("rknn_init fail! ret=%d\n", ret); + return -1; + } + + // Get Model Input Output Number + rknn_input_output_num io_num; + ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num)); + if (ret != RKNN_SUCC) + { + printf("rknn_query fail! ret=%d\n", ret); + return -1; + } + printf("model input num: %d, output num: %d\n", io_num.n_input, io_num.n_output); + + // Get Model Input Info + printf("input tensors:\n"); + rknn_tensor_attr input_attrs[io_num.n_input]; + memset(input_attrs, 0, sizeof(input_attrs)); + for (int i = 0; i < io_num.n_input; i++) + { + input_attrs[i].index = i; + ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]), sizeof(rknn_tensor_attr)); + if (ret != RKNN_SUCC) + { + printf("rknn_query fail! ret=%d\n", ret); + return -1; + } + dump_tensor_attr(&(input_attrs[i])); + } + + // Get Model Output Info + printf("output tensors:\n"); + rknn_tensor_attr output_attrs[io_num.n_output]; + memset(output_attrs, 0, sizeof(output_attrs)); + for (int i = 0; i < io_num.n_output; i++) + { + output_attrs[i].index = i; + ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]), sizeof(rknn_tensor_attr)); + if (ret != RKNN_SUCC) + { + printf("rknn_query fail! ret=%d\n", ret); + return -1; + } + dump_tensor_attr(&(output_attrs[i])); + } + + // Set to context + app_ctx->rknn_ctx = ctx; + + + app_ctx->callback = callback; + + // TODO + if (output_attrs[0].qnt_type == RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC && output_attrs[0].type != RKNN_TENSOR_FLOAT16) + { + app_ctx->is_quant = true; + } + else + { + app_ctx->is_quant = false; + } + + app_ctx->io_num = io_num; + app_ctx->input_attrs = (rknn_tensor_attr *)malloc(io_num.n_input * sizeof(rknn_tensor_attr)); + memcpy(app_ctx->input_attrs, input_attrs, io_num.n_input * sizeof(rknn_tensor_attr)); + app_ctx->output_attrs = (rknn_tensor_attr *)malloc(io_num.n_output * sizeof(rknn_tensor_attr)); + memcpy(app_ctx->output_attrs, output_attrs, io_num.n_output * sizeof(rknn_tensor_attr)); + + if (input_attrs[0].fmt == RKNN_TENSOR_NCHW) + { + printf("model is NCHW input fmt\n"); + app_ctx->model_channel = input_attrs[0].dims[2]; + app_ctx->model_height = input_attrs[0].dims[1]; + app_ctx->model_width = input_attrs[0].dims[0]; + } + else + { + printf("model is NHWC input fmt\n"); + app_ctx->model_height = input_attrs[0].dims[2]; + app_ctx->model_width = input_attrs[0].dims[1]; + app_ctx->model_channel = input_attrs[0].dims[0]; + } + printf("model input height=%d, width=%d, channel=%d\n", + app_ctx->model_height, app_ctx->model_width, app_ctx->model_channel); + + return 0; +} + +int release_yolov5_model(rknn_app_context_t *app_ctx) +{ + if (app_ctx->input_attrs != NULL) + { + free(app_ctx->input_attrs); + app_ctx->input_attrs = NULL; + } + if (app_ctx->output_attrs != NULL) + { + free(app_ctx->output_attrs); + app_ctx->output_attrs = NULL; + } + if (app_ctx->rknn_ctx != 0) + { + rknn_destroy(app_ctx->rknn_ctx); + app_ctx->rknn_ctx = 0; + } + return 0; +} + +int inference_yolov5_model(rknn_app_context_t *app_ctx, image_buffer_t *img, object_detect_result_list *od_results) +{ + int ret; + struct timeval tpend1, tpend2; + long usec1 = 0; + + + + image_buffer_t dst_img; + letterbox_t letter_box; + rknn_input inputs[app_ctx->io_num.n_input]; + rknn_output outputs[app_ctx->io_num.n_output]; + const float nms_threshold = NMS_THRESH; // Default NMS threshold + const float box_conf_threshold = BOX_THRESH; // Default box threshold + int bg_color = 114; + + if ((!app_ctx) || !(img) || (!od_results)) + { + return -1; + } + + memset(od_results, 0x00, sizeof(*od_results)); + memset(&letter_box, 0, sizeof(letterbox_t)); + memset(&dst_img, 0, sizeof(image_buffer_t)); + memset(inputs, 0, sizeof(inputs)); + memset(outputs, 0, sizeof(outputs)); + + // Pre Process + dst_img.width = app_ctx->model_width; + dst_img.height = app_ctx->model_height; + dst_img.format = IMAGE_FORMAT_RGB888; + // dst_img.size = dst_img.width * + // dst_img.size = get_image_size(&dst_img); + // dst_img.virt_addr = (unsigned char *)malloc(dst_img.size); + dst_img.virt_addr = (unsigned char *)img->virt_addr; + if (dst_img.virt_addr == NULL) + { + printf("malloc buffer size:%d fail!\n", dst_img.size); + return -1; + } + + letter_box.scale = 1.0; + letter_box.x_pad = 0; + letter_box.y_pad = 0; + + // letterbox + /* + ret = convert_image_with_letterbox(img, &dst_img, &letter_box, bg_color); + if (ret < 0) + { + printf("convert_image_with_letterbox fail! ret=%d\n", ret); + return -1; + } + */ + + // Set Input Data + inputs[0].index = 0; + inputs[0].type = RKNN_TENSOR_UINT8; + inputs[0].fmt = RKNN_TENSOR_NHWC; + inputs[0].size = app_ctx->model_width * app_ctx->model_height * app_ctx->model_channel; + inputs[0].buf = dst_img.virt_addr; + // inputs[0].buf = img->virt_addr; + + ret = rknn_inputs_set(app_ctx->rknn_ctx, app_ctx->io_num.n_input, inputs); + if (ret < 0) + { + printf("rknn_input_set fail! ret=%d\n", ret); + return -1; + } + + // Run + printf("rknn_run\n"); + + gettimeofday(&tpend1, NULL); + ret = rknn_run(app_ctx->rknn_ctx, nullptr); + if (ret < 0) + { + printf("rknn_run fail! ret=%d\n", ret); + return -1; + } + + // Get Output + memset(outputs, 0, sizeof(outputs)); + for (int i = 0; i < app_ctx->io_num.n_output; i++) + { + outputs[i].index = i; + // outputs[i].want_float = (!app_ctx->is_quant); + outputs[i].want_float = 1; + } + ret = rknn_outputs_get(app_ctx->rknn_ctx, app_ctx->io_num.n_output, outputs, NULL); + if (ret < 0) + { + printf("rknn_outputs_get fail! ret=%d\n", ret); + goto out; + } + + + gettimeofday(&tpend2, NULL); + usec1 =1000 * (tpend2.tv_sec - tpend1.tv_sec) + (tpend2.tv_usec - tpend1.tv_usec) / 1000; + printf("rknn inference_time =%ld ms\n", usec1); + + // Post Process + post_process(app_ctx, outputs, &letter_box, box_conf_threshold, nms_threshold, od_results); + + // Remeber to release rknn output + rknn_outputs_release(app_ctx->rknn_ctx, app_ctx->io_num.n_output, outputs); +out: + + /* + if (dst_img.virt_addr != NULL) + { + free(dst_img.virt_addr); + } + */ + + return ret; +} \ No newline at end of file diff --git a/yolov5.h b/yolov5.h new file mode 100644 index 0000000..003cc90 --- /dev/null +++ b/yolov5.h @@ -0,0 +1,52 @@ +#ifndef _RKNN_DEMO_YOLOV5_H_ +#define _RKNN_DEMO_YOLOV5_H_ + +#include "rknn_api.h" +#include "common.h" + +#define OBJ_NAME_MAX_SIZE 64 +#define OBJ_NUMB_MAX_SIZE 128 +#define OBJ_MAX_CLASS_NUM 80 +#define OBJ_CLASS_MAX 80 + +#define NMS_THRESH 0.45 +#define BOX_THRESH 0.25 + +typedef struct { + image_rect_t box; + float prop; + int cls_id; +} object_detect_result; + +typedef struct { + int id; + int count; + object_detect_result results[OBJ_NUMB_MAX_SIZE]; +} object_detect_result_list; + +typedef struct _rknn_app_context{ + rknn_context rknn_ctx; + rknn_input_output_num io_num; + rknn_tensor_attr* input_attrs; + rknn_tensor_attr* output_attrs; + + int (*callback)(struct _rknn_app_context *rk, object_detect_result_list *result_group, unsigned char *buff); + + int model_channel; + int model_width; + int model_height; + bool is_quant; +} rknn_app_context_t; + +extern rknn_app_context_t rknn_app_ctx; + + +#include "postprocess.h" + +int init_yolov5_model(const char* model_path, rknn_app_context_t* app_ctx, int(*callback)(rknn_app_context_t *rk, object_detect_result_list *result_group, unsigned char *buff)); + +int release_yolov5_model(rknn_app_context_t* app_ctx); + +int inference_yolov5_model(rknn_app_context_t* app_ctx, image_buffer_t* img, object_detect_result_list* od_results); + +#endif \ No newline at end of file