diff --git a/mpp/codec/CMakeLists.txt b/mpp/codec/CMakeLists.txt index 5fa52165..e47d7f18 100644 --- a/mpp/codec/CMakeLists.txt +++ b/mpp/codec/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(mpp_codec codec_avsd codec_m2vd codec_mpg4d + codec_vp8d codec_dummy_enc codec_dummy_dec mpp_base) diff --git a/mpp/codec/dec/CMakeLists.txt b/mpp/codec/dec/CMakeLists.txt index 35835795..2a9a0ab4 100644 --- a/mpp/codec/dec/CMakeLists.txt +++ b/mpp/codec/dec/CMakeLists.txt @@ -13,3 +13,5 @@ add_subdirectory(avs) add_subdirectory(m2v) add_subdirectory(mpg4) + +add_subdirectory(vp8) diff --git a/mpp/codec/dec/vp8/CMakeLists.txt b/mpp/codec/dec/vp8/CMakeLists.txt new file mode 100644 index 00000000..d58ef1ce --- /dev/null +++ b/mpp/codec/dec/vp8/CMakeLists.txt @@ -0,0 +1,29 @@ +# vim: syntax=cmake +include_directories(.) + +#vp8 decoder api +set(VP8D_API + ../../inc/vp8d_api.h + ) + +#vp8 decoder header +set(VP8D_HDR + vp8d_parser.h + vp8d_codec.h + ) + +#vp8 decoder source +set(VP8D_SRC + vp8d_api.c + vp8d_parser.c +) + +add_library(codec_vp8d STATIC + ${VP8D_API} + ${VP8D_HDR} + ${VP8D_SRC} + ) + +target_link_libraries(codec_vp8d mpp_base) +set_target_properties(codec_vp8d PROPERTIES FOLDER "mpp/codec") + diff --git a/mpp/codec/dec/vp8/CMakeLists.txt.bak b/mpp/codec/dec/vp8/CMakeLists.txt.bak new file mode 100644 index 00000000..8f1b497b --- /dev/null +++ b/mpp/codec/dec/vp8/CMakeLists.txt.bak @@ -0,0 +1,36 @@ +# vim: syntax=cmake +include_directories(.) + +# m2v decoder api +set(M2VD_API + ../../inc/m2vd_api.h + ) +set(M2VD_COMMON + ) + +# m2v decoder header +set(M2VD_HDR + m2vd_parser.h + m2vd_codec.h + m2vd_com.h + ) + +# m2v decoder source +set(M2VD_SRC + m2vd_api.c + m2vd_parser.c +) + + +add_library(codec_m2vd STATIC + ${M2VD_API} + ${M2VD_COMMON} + ${M2VD_HDR} + ${M2VD_SRC} + ) +target_link_libraries(codec_m2vd + mpp + mpp_legacy + ) +set_target_properties(codec_m2vd PROPERTIES FOLDER "mpp/codec") + diff --git a/mpp/codec/dec/vp8/vp8d_api.c b/mpp/codec/dec/vp8/vp8d_api.c new file mode 100644 index 00000000..6ea0c548 --- /dev/null +++ b/mpp/codec/dec/vp8/vp8d_api.c @@ -0,0 +1,44 @@ +/* +* +* 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. +*/ + +#define MODULE_TAG "vp8d_api" + +#include +#include "vpu_api.h" +#include "mpp_env.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_mem.h" +#include "mpp_log.h" +#include "vp8d_api.h" +#include "vp8d_parser.h" +#include "vp8d_codec.h" + +const ParserApi api_vp8d_parser = { + "vp8d_parse", + MPP_VIDEO_CodingVP8, + sizeof(VP8DContext), + 0, + vp8d_parser_init, + vp8d_parser_deinit, + vp8d_parser_prepare, + vp8d_parser_parse, + vp8d_parser_reset, + vp8d_parser_flush, + vp8d_parser_control, + vp8d_parser_callback, +}; diff --git a/mpp/codec/dec/vp8/vp8d_codec.h b/mpp/codec/dec/vp8/vp8d_codec.h new file mode 100644 index 00000000..996d9896 --- /dev/null +++ b/mpp/codec/dec/vp8/vp8d_codec.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 __VP8D_CODEC_H__ +#define __VP8D_CODEC_H__ + +#include "rk_type.h" +#include "mpp_common.h" +#include "vpu_api.h" +#include "mpp_frame.h" +#include "mpp_dec.h" +#include "mpp_packet.h" + + +typedef struct VP8DContext_t { + void *parse_ctx; + +} VP8DContext; + +#endif diff --git a/mpp/codec/dec/vp8/vp8d_data.h b/mpp/codec/dec/vp8/vp8d_data.h new file mode 100644 index 00000000..09f473f6 --- /dev/null +++ b/mpp/codec/dec/vp8/vp8d_data.h @@ -0,0 +1,407 @@ +/* + * + * 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. + */ + +#include +#include "rk_type.h" + +#ifndef __VP8D_DATA_H__ +#define __VP8D_DATA_H__ + +#define VP7_MV_PROBS_PER_COMPONENT (17) +#define VP8_MV_PROBS_PER_COMPONENT (19) + + +#define swap32bit(x) ((x>>24)|((x>>8)&0xff00)|((x<<8)&0xff0000)|(x<<24)) + +static const RK_U8 MvUpdateProbs[2][VP8_MV_PROBS_PER_COMPONENT] = { + { + 237, 246, 253, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 + }, + { + 231, 243, 245, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 + } +}; + +static const RK_U8 Vp8DefaultMvProbs[2][VP8_MV_PROBS_PER_COMPONENT] = { + { + 162, 128, 225, 146, 172, 147, 214, 39, 156, + 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 + }, + { + 164, 128, 204, 170, 119, 235, 140, 230, 228, + 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 + } +}; + +static const RK_U8 Vp7DefaultMvProbs[2][VP7_MV_PROBS_PER_COMPONENT] = { + { + 162, 128, 225, 146, 172, 147, 214, 39, 156, + 247, 210, 135, 68, 138, 220, 239, 246 + }, + { + 164, 128, 204, 170, 119, 235, 140, 230, 228, + 244, 184, 201, 44, 173, 221, 239, 253 + } +}; + +static const RK_U8 CoeffUpdateProbs[4][8][3][11] = { + { + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, + {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, + {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255, }, + {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, + { + { + {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255, }, + {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255, }, + }, + { + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, + { + { + {186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255, }, + {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255, }, + {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255, }, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, + { + { + {248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255, }, + {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, + {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, +}; + + +static const RK_U8 DefaultCoeffProbs [4][8][3][11] = { + { + { + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128}, + { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128}, + { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128} + }, + { + { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128}, + { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128}, + { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128} + }, + { + { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128}, + { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128}, + { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128} + }, + { + { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128}, + { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128}, + { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128} + }, + { + { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128}, + { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128}, + { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128} + }, + { + { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128}, + { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128}, + { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128} + }, + { + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { + { + { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62}, + { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1}, + { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128} + }, + { + { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128}, + { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128}, + { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128} + }, + { + { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128}, + { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128}, + { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128} + }, + { + { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128}, + { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128}, + { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128} + }, + { + { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128}, + { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128}, + { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128} + }, + { + { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128}, + { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128}, + { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128} + }, + { + { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128}, + { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128}, + { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128} + }, + { + { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128}, + { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128} + } + }, + { + { + { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128}, + { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128}, + { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128} + }, + { + { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128}, + { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128}, + { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128} + }, + { + { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128}, + { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128}, + { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128} + }, + { + { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128}, + { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128}, + { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128}, + { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128}, + { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128}, + { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { + { + { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255}, + { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128}, + { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128} + }, + { + { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128}, + { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128}, + { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128} + }, + { + { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128}, + { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128}, + { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128} + }, + { + { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128}, + { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128}, + { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128} + }, + { + { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128}, + { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128}, + { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128} + }, + { + { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128}, + { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128}, + { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128} + }, + { + { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128}, + { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128}, + { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128} + }, + { + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + } + } +}; + + +#endif diff --git a/mpp/codec/dec/vp8/vp8d_parser.c b/mpp/codec/dec/vp8/vp8d_parser.c new file mode 100644 index 00000000..d35fcae5 --- /dev/null +++ b/mpp/codec/dec/vp8/vp8d_parser.c @@ -0,0 +1,1198 @@ +/* + * + * 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. + */ + +#define MODULE_TAG "vp8d_parser" +#include + +#include "vp8d_parser.h" +#include "vp8d_codec.h" +#include "mpp_frame.h" +#include "mpp_env.h" + +RK_U32 vp8d_debug = 0x0; + +#define FUN_T(tag) \ + do {\ + if (VP8D_DBG_FUNCTION & vp8d_debug)\ + { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ + } while (0) + + +void vp8hwdBoolStart(vpBoolCoder_t *bit_ctx, RK_U8 *buffer, RK_U32 len) +{ + FUN_T("FUN_IN"); + bit_ctx->lowvalue = 0; + bit_ctx->range = 255; + bit_ctx->count = 8; + bit_ctx->buffer = buffer; + bit_ctx->pos = 0; + + bit_ctx->value = (bit_ctx->buffer[0] << 24) + (bit_ctx->buffer[1] << 16) + (bit_ctx->buffer[2] << 8) + (bit_ctx->buffer[3]); + + bit_ctx->pos += 4; + + bit_ctx->streamEndPos = len; + bit_ctx->strmError = bit_ctx->pos > bit_ctx->streamEndPos; + + FUN_T("FUN_OUT"); +} + +RK_U32 vp8hwdDecodeBool(vpBoolCoder_t *bit_ctx, RK_S32 probability) +{ + RK_U32 bit = 0; + RK_U32 split; + RK_U32 bigsplit; + RK_U32 count = bit_ctx->count; + RK_U32 range = bit_ctx->range; + RK_U32 value = bit_ctx->value; + + FUN_T("FUN_IN"); + split = 1 + (((range - 1) * probability) >> 8); + bigsplit = (split << 24); + range = split; + + if (value >= bigsplit) { + range = bit_ctx->range - split; + value = value - bigsplit; + bit = 1; + } + + if (range >= 0x80) { + bit_ctx->value = value; + bit_ctx->range = range; + return bit; + } else { + do { + range += range; + value += value; + + if (!--count) { + /* no more stream to read? */ + if (bit_ctx->pos >= bit_ctx->streamEndPos) { + bit_ctx->strmError = 1; + mpp_log("vp8hwdDecodeBool read end"); + break; + } + count = 8; + value |= bit_ctx->buffer[bit_ctx->pos]; + bit_ctx->pos++; + } + } while (range < 0x80); + } + + + bit_ctx->count = count; + bit_ctx->value = value; + bit_ctx->range = range; + + FUN_T("FUN_OUT"); + return bit; +} + +RK_U32 vp8hwdDecodeBool128(vpBoolCoder_t *bit_ctx) +{ + RK_U32 bit = 0; + RK_U32 split; + RK_U32 bigsplit; + RK_U32 count = bit_ctx->count; + RK_U32 range = bit_ctx->range; + RK_U32 value = bit_ctx->value; + + FUN_T("FUN_IN"); + split = (range + 1) >> 1; + bigsplit = (split << 24); + range = split; + + if (value >= bigsplit) { + range = (bit_ctx->range - split); + value = (value - bigsplit); + bit = 1; + } + + if (range >= 0x80) { + bit_ctx->value = value; + bit_ctx->range = range; + + FUN_T("FUN_OUT"); + return bit; + } else { + range <<= 1; + value <<= 1; + + if (!--count) { + /* no more stream to read? */ + if (bit_ctx->pos >= bit_ctx->streamEndPos) { + bit_ctx->strmError = 1; + mpp_log("vp8hwdDecodeBool128 read end"); + return 0; /* any value, not valid */ + } + count = 8; + value |= bit_ctx->buffer[bit_ctx->pos]; + bit_ctx->pos++; + } + } + + bit_ctx->count = count; + bit_ctx->value = value; + bit_ctx->range = range; + + FUN_T("FUN_OUT"); + return bit; +} + +RK_U32 vp8hwdReadBits(vpBoolCoder_t *bit_ctx, RK_S32 bits) +{ + RK_U32 z = 0; + RK_S32 bit; + + FUN_T("FUN_IN"); + for (bit = bits - 1; bit >= 0; bit--) { + z |= (vp8hwdDecodeBool128(bit_ctx) << bit); + } + + FUN_T("FUN_OUT"); + return z; +} + +RK_U32 ScaleDimension( RK_U32 orig, RK_U32 scale ) +{ + + FUN_T("FUN_IN"); + switch (scale) { + case 0: + return orig; + break; + case 1: /* 5/4 */ + return (5 * orig) / 4; + break; + case 2: /* 5/3 */ + return (5 * orig) / 3; + break; + case 3: /* 2 */ + return 2 * orig; + break; + } + + FUN_T("FUN_OUT"); + return orig; +} + +RK_S32 DecodeQuantizerDelta(vpBoolCoder_t *bit_ctx) +{ + RK_S32 result = 0; + + FUN_T("FUN_IN"); + if (vp8hwdDecodeBool128(bit_ctx)) { + result = vp8hwdReadBits(bit_ctx, 4); + if (vp8hwdDecodeBool128(bit_ctx)) + result = -result; + } + + FUN_T("FUN_OUT"); + return result; +} + +MPP_RET vp8d_parser_init(void *ctx, ParserCfg *parser_cfg) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + + FUN_T("FUN_IN"); + if (p == NULL) { + p = (VP8DParserContext_t*)mpp_calloc(VP8DParserContext_t, 1); + if (NULL == p) { + mpp_err("vp8d malloc VP8DParserContext_t fail"); + FUN_T("FUN_OUT"); + return MPP_ERR_NOMEM; + } + c->parse_ctx = p; + } + p->packet_slots = parser_cfg->packet_slots; + p->frame_slots = parser_cfg->frame_slots; + p->notify_cb = parser_cfg->notify_cb; + + mpp_buf_slot_setup(p->frame_slots, 15); + + p->dxva_ctx = mpp_calloc(DXVA_PicParams_VP8, 1); + + if (NULL == p->dxva_ctx) { + mpp_err("vp8d malloc dxva_ctx fail"); + FUN_T("FUN_OUT"); + return MPP_ERR_NOMEM; + } + p->decMode = VP8HWD_VP8; + p->bitstream_sw_buf = mpp_malloc(RK_U8, VP8D_BUF_SIZE_BITMEM); + mpp_packet_init(&p->input_packet, p->bitstream_sw_buf, VP8D_BUF_SIZE_BITMEM); + p->max_stream_size = VP8D_BUF_SIZE_BITMEM; + + FUN_T("FUN_OUT"); + return ret; +} + +void vp8d_unref_frame(VP8DParserContext_t *p, VP8Frame *frame) +{ + + FUN_T("FUN_IN"); + if (NULL == frame || frame->ref_count <= 0 + || frame->slot_index >= 0x7f) { + mpp_err("ref count alreay is zero"); + FUN_T("FUN_OUT"); + return; + } + frame->ref_count--; + if (!frame->ref_count && frame->slot_index < 0x7f) { + mpp_buf_slot_clr_flag(p->frame_slots, frame->slot_index, SLOT_CODEC_USE); + frame->slot_index = 0xff; + mpp_free(frame->f); + mpp_free(frame); + frame = NULL; + } + + FUN_T("FUN_OUT"); + return; +} + +void vp8d_unref_allframe(VP8DParserContext_t *p) +{ + + FUN_T("FUN_IN"); + if (NULL != p->frame_out) { + vp8d_unref_frame(p, p->frame_out); + p->frame_out = NULL; + } + + if (NULL != p->frame_ref) { + vp8d_unref_frame(p, p->frame_ref); + p->frame_ref = NULL; + } + + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + + FUN_T("FUN_OUT"); + return; +} + +MPP_RET vp8d_parser_deinit(void *ctx) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + + FUN_T("FUN_IN"); + + if (NULL != p->bitstream_sw_buf) { + mpp_free(p->bitstream_sw_buf); + p->bitstream_sw_buf = NULL; + } + + if (NULL != p->dxva_ctx) { + mpp_free(p->dxva_ctx); + p->dxva_ctx = NULL; + } + + vp8d_unref_allframe(p); + + if ( NULL != p) { + mpp_free(p); + } + FUN_T("FUN_OUT"); + return ret; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +MPP_RET vp8d_parser_reset(void *ctx) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + + FUN_T("FUN_IN"); + vp8d_unref_allframe(p); + p->needKeyFrame = 0; + FUN_T("FUN_OUT"); + return ret; +} + +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +MPP_RET vp8d_parser_flush(void *ctx) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void) ctx; + FUN_T("FUN_OUT"); + return ret; +} + +/*! +*********************************************************************** +* \brief +* control/perform +*********************************************************************** +*/ +MPP_RET vp8d_parser_control(void *ctx, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)ctx; + (void)cmd_type; + (void)param; + + FUN_T("FUN_OUT"); + return ret; +} + + +/*! +*********************************************************************** +* \brief +* prepare +*********************************************************************** +*/ + +MPP_RET vp8d_parser_split_frame(RK_U8 *src, RK_U32 src_size, RK_U8 *dst, RK_U32 *dst_size) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + memcpy(dst, src, src_size);; + *dst_size = src_size; + + (void)dst; + + FUN_T("FUN_OUT"); + return ret; +} + + +MPP_RET vp8d_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task) +{ + MPP_RET ret = MPP_OK; + RK_U32 out_size = 0; + RK_U8 * pos = NULL; + RK_U8 *buf = NULL; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + MppPacket input_packet = p->input_packet; + + FUN_T("FUN_IN"); + task->valid = 0; + + + buf = pos = mpp_packet_get_pos(pkt); + p->pts = mpp_packet_get_pts(pkt); + + vp8d_parser_split_frame(buf, + mpp_packet_get_length(pkt), + p->bitstream_sw_buf, + &out_size); + pos += out_size; + mpp_packet_set_pos(pkt, pos); + + if (out_size > p->max_stream_size) { + mpp_free(p->bitstream_sw_buf); + p->bitstream_sw_buf = mpp_malloc(RK_U8, out_size + 1024); + if (NULL == p->bitstream_sw_buf) { + mpp_err("vp8d_parser realloc fail"); + return MPP_ERR_NOMEM; + } + p->max_stream_size = out_size + 1024; + } + + mpp_log("p->bitstream_sw_buf = 0x%x", p->bitstream_sw_buf); + mpp_log("out_size = 0x%x", out_size); + mpp_packet_set_data(input_packet, p->bitstream_sw_buf); + mpp_packet_set_size(input_packet, p->max_stream_size); + mpp_packet_set_length(input_packet, out_size); + p->stream_size = out_size; + task->input_packet = input_packet; + task->valid = 1; + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET vp8d_convert_to_syntx( VP8DParserContext_t *p, HalDecTask *in_task) +{ + MPP_RET ret = MPP_OK; + RK_U32 i, tmp; + RK_U32 byteOffset = 0, extraBytesPacked = 0; + DXVA_PicParams_VP8 *pic_param = p->dxva_ctx; + + FUN_T("FUN_IN"); + tmp = (p->bitstr.pos) * 8 + (8 - p->bitstr.count); + + if (p->frameTagSize == 4) + tmp += 8; + + if (p->decMode == VP8HWD_VP8 && p->keyFrame) + extraBytesPacked += 7; + + tmp += extraBytesPacked * 8; + byteOffset = tmp / 8; + pic_param->stream_start_bit = (byteOffset & 0x07U) * 8; + byteOffset &= (~0x07U); /* align the base */ + pic_param->stream_start_offset = byteOffset; + + pic_param->stream_start_bit += (tmp & 0x7); + + pic_param->frame_type = !p->keyFrame; + pic_param->stVP8Segments.segmentation_enabled = p->segmentationEnabled; + pic_param->stVP8Segments.update_mb_segmentation_map = p->segmentationMapUpdate; + pic_param->mode_ref_lf_delta_enabled = p->modeRefLfEnabled; + pic_param->mb_no_coeff_skip = p->coeffSkipMode; + pic_param->width = p->width; + pic_param->height = p->height; + pic_param->decMode = p->decMode; + pic_param->filter_type = p->loopFilterType; + pic_param->sharpness = p->loopFilterSharpness; + pic_param->filter_level = p->loopFilterLevel; + pic_param->stVP8Segments.update_mb_segmentation_data = p->segmentFeatureMode; + pic_param->version = p->vpVersion; + pic_param->bool_value = ((p->bitstr.value >> 24) & (0xFFU)); + pic_param->bool_range = (p->bitstr.range & (0xFFU)); + pic_param->frameTagSize = p->frameTagSize; + pic_param->streamEndPos = p->bitstr.streamEndPos; + pic_param->log2_nbr_of_dct_partitions = p->nbrDctPartitions; + pic_param->offsetToDctParts = p->offsetToDctParts; + + pic_param->y1ac_delta_q = p->qpYAc; + pic_param->y1dc_delta_q = p->qpYDc; + pic_param->y2ac_delta_q = p->qpY2Ac; + pic_param->y2dc_delta_q = p->qpY2Dc; + pic_param->uvac_delta_q = p->qpChAc; + pic_param->uvdc_delta_q = p->qpChDc; + pic_param->probe_skip_false = p->probMbSkipFalse; + pic_param->prob_intra = p->probIntra; + pic_param->prob_last = p->probRefLast; + pic_param->prob_golden = p->probRefGolden; + + memcpy(pic_param->vp8_coef_update_probs, p->entropy.probCoeffs, sizeof(pic_param->vp8_coef_update_probs)); + memcpy(pic_param->vp8_mv_update_probs, p->entropy.probMvContext, sizeof(pic_param->vp8_mv_update_probs)); + + for ( i = 0; i < 3; i++) { + pic_param->intra_chroma_prob[i] = p->entropy.probChromaPredMode[i]; + pic_param->stVP8Segments.mb_segment_tree_probs[i] = p->probSegment[i]; + } + + pic_param->ref_frame_sign_bias_golden = p->refFrameSignBias[0]; + pic_param->ref_frame_sign_bias_altref = p->refFrameSignBias[1]; + + + for (i = 0; i < 4; i++) { + pic_param->stVP8Segments.segment_feature_data[0][i] = p->segmentQp[i]; + pic_param->ref_lf_deltas[i] = p->mbRefLfDelta[i]; + pic_param->mode_lf_deltas[i] = p->mbModeLfDelta[i]; + pic_param->stVP8Segments.segment_feature_data[1][i] = p->segmentLoopfilter[i]; + pic_param->intra_16x16_prob[i] = p->entropy.probLuma16x16PredMode[i]; + } + + p->dxva_ctx->CurrPic.Index7Bits = p->frame_out->slot_index; + memset(in_task->refer, -1, sizeof(in_task->refer)); + + if (p->frame_ref != NULL) { + pic_param->lst_fb_idx.Index7Bits = p->frame_ref->slot_index; + mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref->slot_index, SLOT_HAL_INPUT); + in_task->refer[0] = p->frame_ref->slot_index; + } else { + pic_param->lst_fb_idx.Index7Bits = 0x7f; + } + + if (p->frame_golden != NULL) { + pic_param->gld_fb_idx.Index7Bits = p->frame_golden->slot_index; + mpp_buf_slot_set_flag(p->frame_slots, p->frame_golden->slot_index, SLOT_HAL_INPUT); + in_task->refer[1] = p->frame_golden->slot_index; + } else { + pic_param->gld_fb_idx.Index7Bits = 0x7f; + } + + if (p->frame_alternate != NULL) { + pic_param->alt_fb_idx.Index7Bits = p->frame_alternate->slot_index; + mpp_buf_slot_set_flag(p->frame_slots, p->frame_alternate->slot_index, SLOT_HAL_INPUT); + in_task->refer[2] = p->frame_alternate->slot_index; + } else { + pic_param->alt_fb_idx.Index7Bits = 0x7f; + } + + memcpy(pic_param->dctPartitionOffsets, p->dctPartitionOffsets, sizeof(p->dctPartitionOffsets)); + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET vp8d_alloc_frame(VP8DParserContext_t *p) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + if (NULL == p->frame_out) { + p->frame_out = mpp_calloc(VP8Frame, 1); + if (NULL == p->frame_out) { + mpp_err("alloc vp8 frame fail"); + return MPP_ERR_NOMEM; + } + + if (NULL == p->frame_out->f) { + mpp_frame_init(&p->frame_out->f); + if (NULL == p->frame_out->f) { + mpp_err("alloc vp8 mpp frame fail"); + return MPP_ERR_NOMEM; + } + } + p->frame_out->slot_index = 0xff; + } + + if (p->frame_out->slot_index == 0xff) { + mpp_frame_set_width(p->frame_out->f, p->width); + mpp_frame_set_height(p->frame_out->f, p->height); + mpp_frame_set_hor_stride(p->frame_out->f, p->width); + mpp_frame_set_ver_stride(p->frame_out->f, p->height); + mpp_frame_set_errinfo(p->frame_out->f, 0); + mpp_frame_set_pts(p->frame_out->f, p->pts); + ret = mpp_buf_slot_get_unused(p->frame_slots, &p->frame_out->slot_index); + if (MPP_OK != ret) { + mpp_err("vp8 buf_slot_get_unused get fail"); + return ret; + } + mpp_buf_slot_set_prop(p->frame_slots, p->frame_out->slot_index, SLOT_FRAME, p->frame_out->f); + mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_CODEC_USE); + mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_HAL_OUTPUT); + mpp_frame_set_mode(p->frame_out->f, 0); + + if (p->showFrame) { + mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p->frame_slots, p->frame_out->slot_index, QUEUE_DISPLAY); + } + p->frame_out->ref_count++; + } + + FUN_T("FUN_OUT"); + return ret; +} + +void vp8d_ref_frame(VP8Frame *frame) +{ + + FUN_T("FUN_IN"); + if ((NULL == frame) || (frame->slot_index >= 0x7f)) { + mpp_err("frame is null or slot_index is no valid"); + return; + } + frame->ref_count++; + + FUN_T("FUN_OUT"); +} + + +MPP_RET vp8d_ref_update(VP8DParserContext_t *p) +{ + + FUN_T("FUN_IN"); + if (p->decMode != VP8HWD_WEBP) { + if (p->copyBufferToAlternate == 1) { + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + p->frame_alternate = p->frame_ref; + vp8d_ref_frame(p->frame_alternate); + } else if (p->copyBufferToAlternate == 2) { + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + p->frame_alternate = p->frame_golden; + vp8d_ref_frame(p->frame_alternate); + } + + if (p->copyBufferToGolden == 1) { + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + p->frame_golden = p->frame_ref; + vp8d_ref_frame(p->frame_golden); + } else if (p->copyBufferToGolden == 2) { + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + p->frame_golden = p->frame_alternate; + vp8d_ref_frame(p->frame_golden); + } + + if (p->refreshGolden) { + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + p->frame_golden = p->frame_out; + vp8d_ref_frame(p->frame_golden); + } + + if (p->refreshAlternate) { + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + p->frame_alternate = p->frame_out; + vp8d_ref_frame(p->frame_out); + } + + if (p->refreshLast) { + if (NULL != p->frame_ref) { + vp8d_unref_frame(p, p->frame_ref); + p->frame_ref = NULL; + } + p->frame_ref = p->frame_out; + vp8d_ref_frame(p->frame_ref); + } + vp8d_unref_frame(p, p->frame_out); + p->frame_out = NULL; + } + + FUN_T("FUN_OUT"); + return 0; +} + +void vp8hwdResetProbs(VP8DParserContext_t *p) +{ + RK_U32 i, j, k, l; + static const RK_U32 Vp7DefaultScan[] = { + 0, 1, 4, 8, 5, 2, 3, 6, + 9, 12, 13, 10, 7, 11, 14, 15, + }; + + FUN_T("FUN_IN"); + for ( i = 0 ; i < 16 ; ++i ) + p->vp7ScanOrder[i] = Vp7DefaultScan[i]; + + + /* Intra-prediction modes */ + p->entropy.probLuma16x16PredMode[0] = 112; + p->entropy.probLuma16x16PredMode[1] = 86; + p->entropy.probLuma16x16PredMode[2] = 140; + p->entropy.probLuma16x16PredMode[3] = 37; + p->entropy.probChromaPredMode[0] = 162; + p->entropy.probChromaPredMode[1] = 101; + p->entropy.probChromaPredMode[2] = 204; + + for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++) + p->mbRefLfDelta[i] = 0; + + for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++) + p->mbModeLfDelta[i] = 0; + + /* MV context */ + k = 0; + if (p->decMode == VP8HWD_VP8) { + for ( i = 0 ; i < 2 ; ++i ) + for ( j = 0 ; j < VP8_MV_PROBS_PER_COMPONENT ; ++j, ++k ) + p->entropy.probMvContext[i][j] = Vp8DefaultMvProbs[i][j]; + } else { + for ( i = 0 ; i < 2 ; ++i ) + for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j, ++k ) + p->entropy.probMvContext[i][j] = Vp7DefaultMvProbs[i][j]; + } + + /* Coefficients */ + for ( i = 0 ; i < 4 ; ++i ) + for ( j = 0 ; j < 8 ; ++j ) + for ( k = 0 ; k < 3 ; ++k ) + for ( l = 0 ; l < 11 ; ++l ) + p->entropy.probCoeffs[i][j][k][l] = DefaultCoeffProbs[i][j][k][l]; + + FUN_T("FUN_OUT"); +} + +void vp8hwdDecodeCoeffUpdate(VP8DParserContext_t *p) +{ + RK_U32 i, j, k, l; + + FUN_T("FUN_IN"); + for ( i = 0; i < 4; i++ ) { + for ( j = 0; j < 8; j++ ) { + for ( k = 0; k < 3; k++ ) { + for ( l = 0; l < 11; l++ ) { + if (vp8hwdDecodeBool(&p->bitstr, CoeffUpdateProbs[i][j][k][l])) + p->entropy.probCoeffs[i][j][k][l] = vp8hwdReadBits(&p->bitstr, 8); + } + } + } + } + FUN_T("FUN_OUT"); +} + +MPP_RET vp8_header_parser(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) +{ + RK_U32 tmp; + int i, j; + vpBoolCoder_t *bit_ctx = &p->bitstr; + + FUN_T("FUN_IN"); + if (p->keyFrame) { + tmp = (pbase[0] << 16) | (pbase[1] << 8) | (pbase[2] << 0); + if (tmp != VP8_KEY_FRAME_START_CODE) + return MPP_ERR_PROTOL; + tmp = (pbase[3] << 0) | (pbase[4] << 8); + p->width = tmp & 0x3fff; + p->scaledWidth = ScaleDimension(p->width, tmp >> 14); + tmp = (pbase[5] << 0) | (pbase[6] << 8); + p->height = tmp & 0x3fff; + p->scaledHeight = ScaleDimension(p->height, tmp >> 14); + pbase += 7; + size -= 7; + } + vp8hwdBoolStart(bit_ctx, pbase, size); + if (p->keyFrame) { + p->colorSpace = (vpColorSpace_e)vp8hwdDecodeBool128(bit_ctx); + p->clamping = vp8hwdDecodeBool128(bit_ctx); + } + p->segmentationEnabled = vp8hwdDecodeBool128(bit_ctx); + p->segmentationMapUpdate = 0; + if (p->segmentationEnabled) { + p->segmentationMapUpdate = vp8hwdDecodeBool128(bit_ctx); + if (vp8hwdDecodeBool128(bit_ctx)) { /* Segmentation map update */ + p->segmentFeatureMode = vp8hwdDecodeBool128(bit_ctx); + memset(&p->segmentQp[0], 0, MAX_NBR_OF_SEGMENTS * sizeof(RK_S32)); + memset(&p->segmentLoopfilter[0], 0, MAX_NBR_OF_SEGMENTS * sizeof(RK_S32)); + for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->segmentQp[i] = vp8hwdReadBits(bit_ctx, 7); + if (vp8hwdDecodeBool128(bit_ctx)) + p->segmentQp[i] = -p->segmentQp[i]; + } + } + for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->segmentLoopfilter[i] = vp8hwdReadBits(bit_ctx, 6); + if (vp8hwdDecodeBool128(bit_ctx)) + p->segmentLoopfilter[i] = -p->segmentLoopfilter[i]; + } + } + } + if (p->segmentationMapUpdate) { + p->probSegment[0] = 255; + p->probSegment[1] = 255; + p->probSegment[2] = 255; + for (i = 0; i < 3; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->probSegment[i] = vp8hwdReadBits(bit_ctx, 8); + } + } + } + if (bit_ctx->strmError) { + mpp_err_f("paser header stream no enough"); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + } + p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); + p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6); + p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3); + p->modeRefLfEnabled = vp8hwdDecodeBool128(bit_ctx); + if (p->modeRefLfEnabled) { + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->mbRefLfDelta[i] = vp8hwdReadBits(bit_ctx, 6); + if (vp8hwdDecodeBool128(bit_ctx)) + p->mbRefLfDelta[i] = -p->mbRefLfDelta[i]; + } + } + for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++) { + if (vp8hwdDecodeBool128(&p->bitstr)) { + p->mbModeLfDelta[i] = vp8hwdReadBits(bit_ctx, 6); + if (vp8hwdDecodeBool128(bit_ctx)) + p->mbModeLfDelta[i] = -p->mbModeLfDelta[i]; + } + } + } + } + if (bit_ctx->strmError) { + mpp_err_f("paser header stream no enough"); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + p->nbrDctPartitions = vp8hwdReadBits(bit_ctx, 2); + p->qpYAc = vp8hwdReadBits(bit_ctx, 7); + p->qpYDc = DecodeQuantizerDelta(bit_ctx); + p->qpY2Dc = DecodeQuantizerDelta(bit_ctx); + p->qpY2Ac = DecodeQuantizerDelta(bit_ctx); + p->qpChDc = DecodeQuantizerDelta(bit_ctx); + p->qpChAc = DecodeQuantizerDelta(bit_ctx); + if (p->keyFrame) { + p->refreshGolden = 1; + p->refreshAlternate = 1; + p->copyBufferToGolden = 0; + p->copyBufferToAlternate = 0; + + /* Refresh entropy probs */ + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + + p->refFrameSignBias[0] = 0; + p->refFrameSignBias[1] = 0; + p->refreshLast = 1; + } else { + /* Refresh golden */ + p->refreshGolden = vp8hwdDecodeBool128(bit_ctx); + /* Refresh alternate */ + p->refreshAlternate = vp8hwdDecodeBool128(bit_ctx); + if ( p->refreshGolden == 0 ) { + /* Copy to golden */ + p->copyBufferToGolden = vp8hwdReadBits(bit_ctx, 2); + } else + p->copyBufferToGolden = 0; + + if ( p->refreshAlternate == 0 ) { + /* Copy to alternate */ + p->copyBufferToAlternate = vp8hwdReadBits(bit_ctx, 2); + } else + p->copyBufferToAlternate = 0; + + /* Sign bias for golden frame */ + p->refFrameSignBias[0] = vp8hwdDecodeBool128(bit_ctx); + /* Sign bias for alternate frame */ + p->refFrameSignBias[1] = vp8hwdDecodeBool128(bit_ctx); + /* Refresh entropy probs */ + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + /* Refresh last */ + p->refreshLast = vp8hwdDecodeBool128(bit_ctx); + } + + /* Make a "backup" of current entropy probabilities if refresh is not set */ + if (p->refreshEntropyProbs == 0) { + memcpy((void*)&p->entropyLast, (void*)&p->entropy, (unsigned long)sizeof(vp8EntropyProbs_t)); + memcpy( (void*)p->vp7PrevScanOrder, (void*)p->vp7ScanOrder, (unsigned long)sizeof(p->vp7ScanOrder)); + } + + vp8hwdDecodeCoeffUpdate(p); + p->coeffSkipMode = vp8hwdDecodeBool128(bit_ctx); + if (!p->keyFrame) { + RK_U32 mvProbs; + + p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8); + p->probIntra = vp8hwdReadBits(bit_ctx, 8); + p->probRefLast = vp8hwdReadBits(bit_ctx, 8); + p->probRefGolden = vp8hwdReadBits(bit_ctx, 8); + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 4; i++) + p->entropy.probLuma16x16PredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 3; i++) + p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + mvProbs = VP8_MV_PROBS_PER_COMPONENT; + for ( i = 0 ; i < 2 ; ++i ) { + for ( j = 0 ; j < (RK_S32)mvProbs ; ++j ) { + if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j]) == 1) { + tmp = vp8hwdReadBits(bit_ctx, 7); + if ( tmp ) + tmp = tmp << 1; + else + tmp = 1; + p->entropy.probMvContext[i][j] = tmp; + } + } + } + } else { + p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8); + } + if (bit_ctx->strmError) { + mpp_err_f("paser header stream no enough"); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET vp7_header_parser(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) +{ + RK_U32 tmp; + int i, j; + + FUN_T("FUN_IN"); + vpBoolCoder_t *bit_ctx = &p->bitstr; + vp8hwdBoolStart(bit_ctx, pbase, size); + + if (p->keyFrame) { + p->width = vp8hwdReadBits(bit_ctx, 12); + p->height = vp8hwdReadBits(bit_ctx, 12); + tmp = vp8hwdReadBits(bit_ctx, 2); + p->scaledWidth = ScaleDimension(p->width, tmp); + tmp = vp8hwdReadBits(bit_ctx, 2); + p->scaledHeight = ScaleDimension(p->height, tmp); + } + { + const RK_U32 vp70FeatureBits[4] = { 7, 6, 0, 8 }; + const RK_U32 vp71FeatureBits[4] = { 7, 6, 0, 5 }; + const RK_U32 *featureBits; + if (p->vpVersion == 0) + featureBits = vp70FeatureBits; + else + featureBits = vp71FeatureBits; + for (i = 0; i < MAX_NBR_OF_VP7_MB_FEATURES; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + tmp = vp8hwdReadBits(bit_ctx, 8); + for (j = 0; j < 3; j++) { + if (vp8hwdDecodeBool128(bit_ctx)) + tmp = vp8hwdReadBits(bit_ctx, 8); + } + if (featureBits[i]) { + for (j = 0; j < 4; j++) { + if (vp8hwdDecodeBool128(bit_ctx)) + tmp = vp8hwdReadBits(bit_ctx, featureBits[i]); + } + } + FUN_T("FUN_OUT"); + return MPP_ERR_PROTOL; + } + + } + p->nbrDctPartitions = 0; + } + p->qpYAc = (RK_S32)vp8hwdReadBits(bit_ctx, 7 ); + p->qpYDc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpY2Dc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpY2Ac = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpChDc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpChAc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + if (!p->keyFrame) { + p->refreshGolden = vp8hwdDecodeBool128(bit_ctx); + if (p->vpVersion >= 1) { + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + p->refreshLast = vp8hwdDecodeBool128(bit_ctx); + } else { + p->refreshEntropyProbs = 1; + p->refreshLast = 1; + } + } else { + p->refreshGolden = 1; + p->refreshAlternate = 1; + p->copyBufferToGolden = 0; + p->copyBufferToAlternate = 0; + if (p->vpVersion >= 1) + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + else + p->refreshEntropyProbs = 1; + p->refFrameSignBias[0] = 0; + p->refFrameSignBias[1] = 0; + p->refreshLast = 1; + } + + if (!p->refreshEntropyProbs) { + memcpy(&p->entropyLast, &p->entropy, (unsigned long)sizeof(vp8EntropyProbs_t)); + memcpy(p->vp7PrevScanOrder, p->vp7ScanOrder, (unsigned long)sizeof(p->vp7ScanOrder)); + } + if (p->refreshLast) { + if (vp8hwdDecodeBool128(bit_ctx)) { + tmp = vp8hwdReadBits(bit_ctx, 8); + tmp = vp8hwdReadBits(bit_ctx, 8); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + } + if (p->vpVersion == 0) { + p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); + } + if (vp8hwdDecodeBool128(bit_ctx)) { + static const RK_U32 Vp7DefaultScan[] = { + 0, 1, 4, 8, 5, 2, 3, 6, + 9, 12, 13, 10, 7, 11, 14, 15, + }; + p->vp7ScanOrder[0] = 0; + for (i = 1; i < 16; i++) + p->vp7ScanOrder[i] = Vp7DefaultScan[vp8hwdReadBits(bit_ctx, 4)]; + } + if (p->vpVersion >= 1) + p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); + p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6); + p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3); + vp8hwdDecodeCoeffUpdate(p); + if (!p->keyFrame) { + p->probIntra = vp8hwdReadBits(bit_ctx, 8); + p->probRefLast = vp8hwdReadBits(bit_ctx, 8); + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 4; i++) + p->entropy.probLuma16x16PredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 3; i++) + p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + for ( i = 0 ; i < 2 ; ++i ) { + for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j ) { + if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j])) { + tmp = vp8hwdReadBits(bit_ctx, 7); + if ( tmp ) + tmp = tmp << 1; + else + tmp = 1; + p->entropy.probMvContext[i][j] = tmp; + } + } + } + } + if (bit_ctx->strmError) { + FUN_T("FUN_OUT"); + return MPP_ERR_PROTOL; + } + + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET vp8hwdSetPartitionOffsets(VP8DParserContext_t *p, RK_U8 *stream, RK_U32 len) +{ + RK_U32 i = 0; + RK_U32 offset = 0; + RK_U32 baseOffset; + RK_U32 extraBytesPacked = 0; + + FUN_T("FUN_IN"); + if (p->decMode == VP8HWD_VP8 && p->keyFrame) + extraBytesPacked += 7; + + stream += p->frameTagSize; + + baseOffset = p->frameTagSize + p->offsetToDctParts + 3 * ( (1 << p->nbrDctPartitions) - 1); + + stream += p->offsetToDctParts + extraBytesPacked; + for ( i = 0 ; i < (RK_U32)(1 << p->nbrDctPartitions) - 1 ; ++i ) { + RK_U32 tmp; + + p->dctPartitionOffsets[i] = baseOffset + offset; + tmp = stream[0] | (stream[1] << 8) | (stream[2] << 16); + offset += tmp; + stream += 3; + } + p->dctPartitionOffsets[i] = baseOffset + offset; + + return (p->dctPartitionOffsets[i] < len ? MPP_OK : MPP_ERR_STREAM); +} + + + +MPP_RET decoder_frame_header(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) +{ + MPP_RET ret; + + FUN_T("FUN_IN"); + p->keyFrame = !(pbase[0] & 1); + p->vpVersion = (pbase[0] >> 1) & 7; + p->showFrame = 1; + if (p->keyFrame && !p->needKeyFrame) { + p->needKeyFrame = 1; + } else { + if (!p->needKeyFrame) { + mpp_err("no found key frame"); + return MPP_NOK; + } + } + if (p->decMode == VP8HWD_VP7) { + p->offsetToDctParts = (pbase[0] >> 4) | (pbase[1] << 4) | (pbase[2] << 12); + p->frameTagSize = p->vpVersion >= 1 ? 3 : 4; + } else { + p->offsetToDctParts = (pbase[0] >> 5) | (pbase[1] << 3) | (pbase[2] << 11); + mpp_log("offsetToDctParts %d pbase[0] = 0x%x pbase[1] = 0x%x pbase[2] = 0x%x ", p->offsetToDctParts, pbase[0], + pbase[1], pbase[2]); + p->showFrame = (pbase[0] >> 4) & 1; + p->frameTagSize = 3; + } + pbase += p->frameTagSize; + size -= p->frameTagSize; + if (p->keyFrame) + vp8hwdResetProbs(p); + mpp_log_f("p->decMode = %d", p->decMode); + if (p->decMode == VP8HWD_VP8) { + ret = vp8_header_parser(p, pbase, size); + } else { + ret = vp7_header_parser(p, pbase, size); + } + if (ret != MPP_OK) { + return ret; + } + return MPP_OK; +} + + +MPP_RET vp8d_parser_parse(void *ctx, HalDecTask *in_task) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + FUN_T("FUN_IN"); + + ret = decoder_frame_header(p, p->bitstream_sw_buf, p->stream_size); + + if (MPP_OK != ret) { + mpp_err("decoder_frame_header err ret %d", ret); + FUN_T("FUN_OUT"); + return ret; + } + + vp8hwdSetPartitionOffsets(p, p->bitstream_sw_buf, p->stream_size); + + ret = vp8d_alloc_frame(p); + if (MPP_OK != ret) { + mpp_err("vp8d_alloc_frame err ret %d", ret); + FUN_T("FUN_OUT"); + return ret; + } + + vp8d_convert_to_syntx(p, in_task); + in_task->syntax.data = (void *)p->dxva_ctx; + in_task->syntax.number = 1; + in_task->output = p->frame_out->slot_index; + + in_task->valid = 1; + vp8d_ref_update(p); + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET vp8d_parser_callback(void *ctx, void *hal_info) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_IN"); + (void)ctx; + (void)hal_info; + FUN_T("FUN_OUT"); + return ret; +} diff --git a/mpp/codec/dec/vp8/vp8d_parser.h b/mpp/codec/dec/vp8/vp8d_parser.h new file mode 100644 index 00000000..79f21880 --- /dev/null +++ b/mpp/codec/dec/vp8/vp8d_parser.h @@ -0,0 +1,200 @@ +/* + * + * 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 __VP8D_PARSER_H__ +#define __VP8D_PARSER_H__ + +#include "mpp_bitread.h" +#include "mpp_common.h" +#include "mpp_frame.h" +#include "mpp_mem.h" +#include "mpp_dec.h" +#include "mpp_packet.h" + +#include "vp8d_syntax.h" +#include "vp8d_data.h" + +#define VP8HWD_VP7 1 +#define VP8HWD_VP8 2 +#define VP8HWD_WEBP 3 + +#define DEC_MODE_VP7 9 +#define DEC_MODE_VP8 10 + +#define MAX_NBR_OF_SEGMENTS (4) +#define MAX_NBR_OF_MB_REF_LF_DELTAS (4) +#define MAX_NBR_OF_MB_MODE_LF_DELTAS (4) + +#define MAX_NBR_OF_DCT_PARTITIONS (8) + +#define MAX_NBR_OF_VP7_MB_FEATURES (4) + +#define VP8D_BUF_SIZE_BITMEM (512 * 1024) +#define VP8D_PROB_TABLE_SIZE (1<<16) /* TODO */ +#define VP8D_MAX_SEGMAP_SIZE (2048 + 1024) //1920*1080 /* TODO */ +#define VP8_KEY_FRAME_START_CODE 0x9d012a + +#define VP8D_DBG_FUNCTION (0x00000001) +#define VP8D_DBG_WARNNING (0x00000004) +#define VP8D_DBG_LOG (0x00000008) +#define VP8D_DBG_SEC_HEADER (0x00000010) + + +typedef enum { + VP8_YCbCr_BT601, + VP8_CUSTOM +} vpColorSpace_e; + +typedef struct { + RK_U32 lowvalue; + RK_U32 range; + RK_U32 value; + RK_S32 count; + RK_U32 pos; + RK_U8 *buffer; + RK_U32 BitCounter; + RK_U32 streamEndPos; + RK_U32 strmError; +} vpBoolCoder_t; + +typedef struct { + RK_U8 probLuma16x16PredMode[4]; + RK_U8 probChromaPredMode[3]; + RK_U8 probMvContext[2][VP8_MV_PROBS_PER_COMPONENT]; + RK_U8 probCoeffs[4][8][3][11]; +} vp8EntropyProbs_t; + +typedef struct VP8Frame { + MppFrame f; + RK_S32 slot_index; + RK_S8 ref_count; +} VP8Frame; + + +typedef struct VP8DParserContext { + DXVA_PicParams_VP8 *dxva_ctx; + RK_U8 *bitstream_sw_buf; + RK_U32 max_stream_size; + RK_U32 stream_size; + + VP8Frame *frame_out; + VP8Frame *frame_ref; + VP8Frame *frame_golden; + VP8Frame *frame_alternate; + + vpBoolCoder_t bitstr; + + RK_U32 decMode; + + /* Current frame dimensions */ + RK_U32 width; + RK_U32 height; + RK_U32 scaledWidth; + RK_U32 scaledHeight; + + RK_U8 vpVersion; + RK_U32 vpProfile; + + RK_U32 keyFrame; + + RK_U8 coeffSkipMode; + + /* DCT coefficient partitions */ + RK_U32 offsetToDctParts; + RK_U32 nbrDctPartitions; + RK_U32 dctPartitionOffsets[MAX_NBR_OF_DCT_PARTITIONS]; + + vpColorSpace_e colorSpace; + RK_U32 clamping; + RK_U32 showFrame; + + + RK_U32 refreshGolden; + RK_U32 refreshAlternate; + RK_U32 refreshLast; + RK_U32 refreshEntropyProbs; + RK_U32 copyBufferToGolden; + RK_U32 copyBufferToAlternate; + + RK_U32 refFrameSignBias[2]; + RK_U32 useAsReference; + RK_U32 loopFilterType; + RK_U32 loopFilterLevel; + RK_U32 loopFilterSharpness; + + /* Quantization parameters */ + RK_S8 qpYAc, qpYDc, qpY2Ac, qpY2Dc, qpChAc, qpChDc; + + /* From here down, frame-to-frame persisting stuff */ + RK_U32 vp7ScanOrder[16]; + RK_U32 vp7PrevScanOrder[16]; + + /* Probabilities */ + RK_U32 probIntra; + RK_U32 probRefLast; + RK_U32 probRefGolden; + RK_U32 probMbSkipFalse; + RK_U32 probSegment[3]; + vp8EntropyProbs_t entropy, entropyLast; + + /* Segment and macroblock specific values */ + RK_U32 segmentationEnabled; + RK_U32 segmentationMapUpdate; + RK_U32 segmentFeatureMode; /* delta/abs */ + RK_S32 segmentQp[MAX_NBR_OF_SEGMENTS]; + RK_S32 segmentLoopfilter[MAX_NBR_OF_SEGMENTS]; + RK_U32 modeRefLfEnabled; + RK_S32 mbRefLfDelta[MAX_NBR_OF_MB_REF_LF_DELTAS]; + RK_S32 mbModeLfDelta[MAX_NBR_OF_MB_MODE_LF_DELTAS]; + + RK_U32 frameTagSize; + + /* Value to remember last frames prediction for hits into most + * probable reference frame */ + RK_U32 refbuPredHits; + + + RK_S32 dcPred[2]; + RK_S32 dcMatch[2]; + + RK_U32 frame_cnt; + RK_U64 pts; + + RK_U32 needKeyFrame; + MppPacket input_packet; + RK_U32 eos; + + MppBufSlots packet_slots; + MppBufSlots frame_slots; + + IOInterruptCB notify_cb; + + // FILE *fp_dbg_file[VP8D_DBG_FILE_NUM]; + FILE *fp_dbg_yuv; +} VP8DParserContext_t; + +MPP_RET vp8d_parser_init (void *ctx, ParserCfg *cfg); +MPP_RET vp8d_parser_deinit (void *ctx); +MPP_RET vp8d_parser_reset (void *ctx); +MPP_RET vp8d_parser_flush (void *ctx); +MPP_RET vp8d_parser_control(void *ctx, RK_S32 cmd_type, void *param); +MPP_RET vp8d_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task); +MPP_RET vp8d_parser_parse (void *ctx, HalDecTask *task); +MPP_RET vp8d_parser_callback(void *ctx, void *hal_info); + +#endif + diff --git a/mpp/codec/inc/vp8d_api.h b/mpp/codec/inc/vp8d_api.h index 3f514ee8..c2c5a045 100644 --- a/mpp/codec/inc/vp8d_api.h +++ b/mpp/codec/inc/vp8d_api.h @@ -17,6 +17,12 @@ #ifndef __VP8D_API_H__ #define __VP8D_API_H__ - - +#include "parser_api.h" +#ifdef __cplusplus +extern "C" { +#endif +extern const ParserApi api_vp8d_parser; +#ifdef __cplusplus +} +#endif #endif /*__VP8D_API_H__*/ \ No newline at end of file diff --git a/mpp/codec/mpp_parser.cpp b/mpp/codec/mpp_parser.cpp index 04477152..97b4a2f5 100644 --- a/mpp/codec/mpp_parser.cpp +++ b/mpp/codec/mpp_parser.cpp @@ -30,7 +30,7 @@ #include "avsd_api.h" #include "m2vd_api.h" #include "mpg4d_api.h" - +#include "vp8d_api.h" // for test and demo #include "dummy_dec_api.h" @@ -44,6 +44,7 @@ static const ParserApi *parsers[] = { &api_avsd_parser, &api_m2vd_parser, &api_mpg4d_parser, + &api_vp8d_parser, &dummy_dec_parser, }; diff --git a/mpp/common/vp8d_syntax.h b/mpp/common/vp8d_syntax.h new file mode 100644 index 00000000..25fc1bea --- /dev/null +++ b/mpp/common/vp8d_syntax.h @@ -0,0 +1,170 @@ +/* + * + * 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 __VP8D_SYNTAX_H__ +#define __VP8D_SYNTAX_H__ + +#include "rk_type.h" + +typedef struct _DXVA_PicEntry_VP8 { + union { + struct { + RK_U8 Index7Bits : 7; + RK_U8 AssociatedFlag : 1; + }; + RK_U8 bPicEntry; + }; +} DXVA_PicEntry_VP8; +typedef struct _segmentation_Vp8 { + union { + struct { + RK_U8 segmentation_enabled : 1; + RK_U8 update_mb_segmentation_map : 1; + RK_U8 update_mb_segmentation_data : 1; + RK_U8 mb_segement_abs_delta : 1; + RK_U8 ReservedSegmentFlags4Bits : 4; + }; + RK_U8 wSegmentFlags; + }; + RK_S8 segment_feature_data[2][4]; + RK_U8 mb_segment_tree_probs[3]; +} DXVA_segmentation_VP8; + +typedef struct VP8DDxvaParam_t { + RK_U32 first_part_size; + RK_U32 width; + RK_U32 height; + DXVA_PicEntry_VP8 CurrPic; + union { + struct { + RK_U8 frame_type : 1; + RK_U8 version : 3; + RK_U8 show_frame : 1; + RK_U8 clamp_type : 1; + RK_U8 ReservedFrameTag2Bits: 2; + }; + RK_U8 wFrameTagFlags; + }; + DXVA_segmentation_VP8 stVP8Segments; + RK_U8 filter_type; + RK_U8 filter_level; + RK_U8 sharpness; + RK_U8 mode_ref_lf_delta_enabled; + RK_U8 mode_ref_lf_delta_update; + RK_S8 ref_lf_deltas[4]; + RK_S8 mode_lf_deltas[4]; + RK_U8 log2_nbr_of_dct_partitions; + RK_U8 base_qindex; + RK_S8 y1dc_delta_q; + RK_S8 y1ac_delta_q; + RK_S8 y2dc_delta_q; + RK_S8 y2ac_delta_q; + RK_S8 uvdc_delta_q; + RK_S8 uvac_delta_q; + + DXVA_PicEntry_VP8 alt_fb_idx; + DXVA_PicEntry_VP8 gld_fb_idx; + DXVA_PicEntry_VP8 lst_fb_idx; + + RK_U8 ref_frame_sign_bias_golden; + RK_U8 ref_frame_sign_bias_altref; + RK_U8 refresh_entropy_probs; + + RK_U8 vp8_coef_update_probs[4][8][3][11]; + RK_U8 probe_skip_false; + RK_U8 mb_no_coeff_skip; + RK_U8 prob_intra; + RK_U8 prob_last; + RK_U8 prob_golden; + RK_U8 intra_16x16_prob[4]; + RK_U8 intra_chroma_prob[3]; + RK_U8 vp8_mv_update_probs[2][19]; + + RK_U32 decMode; + RK_U32 bool_value; + RK_U32 bool_range; + RK_U32 stream_start_offset; + RK_U32 dctPartitionOffsets[8]; + RK_U32 bitstream_length; + RK_U32 stream_start_bit; + RK_U32 frameTagSize; + RK_U32 streamEndPos; + RK_U32 offsetToDctParts; +} DXVA_PicParams_VP8; + +#if 0 +typedef struct VP8DDxvaParam_t { + RK_U32 first_part_size; + RK_U32 width; + RK_U32 height; + DXVA_PicEntry_VP8 CurrPic; + union { + struct { + RK_U8 key_frame : 1; + RK_U8 segmentationEnabled : 1; + RK_U8 segmentationMapUpdate : 1; + RK_U8 modeRefLfEnabled : 1; + RK_U8 coeffSkipMode: 1; + RK_U8 reservedFormatInfo: 3; + }; + RK_U8 wFormatAndPictureInfoFlags; + }; + RK_U32 decMode; + RK_U32 loopFilterType; + RK_U32 loopFilterSharpness; + RK_U32 loopFilterLevel; + RK_U32 segmentFeatureMode; + RK_U32 vpVersion; + RK_U32 bool_value; + RK_U32 bool_range; + RK_U32 stream_start_offset; + RK_U32 stream_start_bit; + RK_U32 frameTagSize; + RK_U32 streamEndPos; + RK_U32 nbrDctPartitions; + RK_U32 offsetToDctParts; + + RK_S8 qpYAc; + RK_S8 qpYDc; + RK_S8 qpY2Ac; + RK_S8 qpY2Dc; + RK_S8 qpChAc; + RK_S8 qpChDc; + RK_U8 vp8_coef_update_probs[4][8][3][11]; + RK_U8 probe_skip_false; + RK_U8 prob_intra; + RK_U8 prob_last; + RK_U8 prob_golden; + RK_U8 intra_16x16_prob[4]; + RK_U8 intra_chroma_prob[3]; + RK_U8 vp8_mv_update_probs[2][19]; + RK_U8 vp8_segment_prob[3]; + + RK_U32 refFrameSignBias[2]; + RK_S32 dcPred[2]; + RK_S32 dcMatch[2]; + RK_S32 segmentQp[4]; + RK_S32 mbRefLfDelta[4]; + RK_S32 mbModeLfDelta[4]; + RK_U32 vp7ScanOrder[16]; + RK_S32 segmentLoopfilter[4]; + RK_U32 dctPartitionOffsets[8]; + RK_U32 bitstream_length; + DXVA_PicEntry_VP8 frame_refs[3]; +} DXVA_PicParams_VP8; +#endif +#endif diff --git a/mpp/hal/CMakeLists.txt b/mpp/hal/CMakeLists.txt index 499e596b..3e3de881 100644 --- a/mpp/hal/CMakeLists.txt +++ b/mpp/hal/CMakeLists.txt @@ -26,6 +26,8 @@ add_subdirectory(vpu/m2vd) add_subdirectory(vpu/mpg4d) +add_subdirectory(vpu/vp8d) + # ---------------------------------------------------------------------------- # add hardware worker implement # ---------------------------------------------------------------------------- @@ -44,6 +46,7 @@ target_link_libraries(mpp_hal hal_avsd hal_m2vd hal_mpg4d + hal_vp8d hal_dummy ${RKPLAT_VPU} ) diff --git a/mpp/hal/inc/hal_vp8d_api.h b/mpp/hal/inc/hal_vp8d_api.h new file mode 100644 index 00000000..7cacad60 --- /dev/null +++ b/mpp/hal/inc/hal_vp8d_api.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 __HAL_VP8D_API_H__ +#define __HAL_VP8D_API_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_vp8d; + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_VP8D_API_H__*/ diff --git a/mpp/hal/mpp_hal.cpp b/mpp/hal/mpp_hal.cpp index 4edfd8b2..b4985c92 100644 --- a/mpp/hal/mpp_hal.cpp +++ b/mpp/hal/mpp_hal.cpp @@ -31,6 +31,7 @@ #include "hal_avsd_api.h" #include "hal_m2vd_api.h" #include "hal_mpg4d_api.h" +#include "hal_vp8d_api.h" // for test and demo #include "hal_dummy_dec_api.h" @@ -46,6 +47,7 @@ static const MppHalApi *hw_apis[] = { &hal_api_avsd, &hal_api_m2vd, &hal_api_mpg4d, + &hal_api_vp8d, &hal_api_dummy_dec, &hal_api_dummy_enc, }; diff --git a/mpp/hal/vpu/m2vd/CMakeLists.txt b/mpp/hal/vpu/m2vd/CMakeLists.txt index 14c2dd0a..a9f925ea 100644 --- a/mpp/hal/vpu/m2vd/CMakeLists.txt +++ b/mpp/hal/vpu/m2vd/CMakeLists.txt @@ -24,13 +24,9 @@ add_library(hal_m2vd STATIC ${HAL_M2VD_HDR} ${HAL_M2VD_SRC} ) -if(ANDROID) - target_link_libraries(hal_m2vd vpu osal) -else() - target_link_libraries(hal_m2vd osal) -endif() -target_link_libraries(hal_m2vd - mpp_base - ) + + +target_link_libraries(hal_m2vd mpp_base) + set_target_properties(hal_m2vd PROPERTIES FOLDER "mpp/hal") diff --git a/mpp/hal/vpu/vp8d/CMakeLists.txt b/mpp/hal/vpu/vp8d/CMakeLists.txt new file mode 100644 index 00000000..5c54bb60 --- /dev/null +++ b/mpp/hal/vpu/vp8d/CMakeLists.txt @@ -0,0 +1,29 @@ +# vim: syntax=cmake +include_directories(.) + +# hal vp8 decoder api +set(HAL_VP8D_API + ../../inc/hal_vp8d_api.h + ../../../common/vp8d_syntax.h + ) + + +# hal vp8 header +set(HAL_VP8D_HDR + hal_vp8d_reg.h + ) + +# hal vp8 decoder sourse +set(HAL_VP8D_SRC + hal_vp8d_api.c + hal_vp8d_reg.c + ) + +add_library(hal_vp8d STATIC + ${HAL_VP8D_API} + ${HAL_VP8D_HDR} + ${HAL_VP8D_SRC} + ) +target_link_libraries(hal_vp8d mpp_base) +set_target_properties(hal_vp8d PROPERTIES FOLDER "mpp/hal") + diff --git a/mpp/hal/vpu/vp8d/hal_vp8d_api.c b/mpp/hal/vpu/vp8d/hal_vp8d_api.c new file mode 100644 index 00000000..bb1c890c --- /dev/null +++ b/mpp/hal/vpu/vp8d/hal_vp8d_api.c @@ -0,0 +1,43 @@ +/* +* +* 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. +*/ +#define MODULE_TAG "hal_vp8d_api" + +#include + +#include "mpp_hal.h" +#include "hal_vp8d_reg.h" + +const MppHalApi hal_api_vp8d = { + "vp8d_rkdec", + MPP_CTX_DEC, + MPP_VIDEO_CodingVP8, + sizeof(VP8DHalContext_t), + 0, + hal_vp8d_init, + hal_vp8d_deinit, + hal_vp8d_gen_regs, + hal_vp8d_start, + hal_vp8d_wait, + hal_vp8d_reset, + hal_vp8d_flush, + hal_vp8d_control, +}; + + + + + diff --git a/mpp/hal/vpu/vp8d/hal_vp8d_reg.c b/mpp/hal/vpu/vp8d/hal_vp8d_reg.c new file mode 100644 index 00000000..2b024353 --- /dev/null +++ b/mpp/hal/vpu/vp8d/hal_vp8d_reg.c @@ -0,0 +1,816 @@ +/* + * 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. + */ + +#define MODULE_TAG "hal_vp8d_reg" +#include + +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_mem.h" + +#include "vpu.h" +#include "hal_vp8d_reg.h" + + +RK_U32 vp8h_debug = 0; + +#define VP8HWD_VP7 1 +#define VP8HWD_VP8 2 +#define VP8HWD_WEBP 3 + +#define DEC_MODE_VP7 9 +#define DEC_MODE_VP8 10 + +#define VP8D_PROB_TABLE_SIZE (1<<16) /* TODO */ +#define VP8D_MAX_SEGMAP_SIZE (2048 + 1024) //1920*1080 /* TODO */ +#define FUN_T(tag) \ + do {\ + if (VP8H_DBG_FUNCTION & vp8h_debug)\ + { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ + } while (0) + +/* VP7 QP LUTs */ +static const RK_U16 YDcQLookup[128] = { + 4, 4, 5, 6, 6, 7, 8, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 33, 34, 35, 36, 36, 37, + 38, 39, 39, 40, 41, 41, 42, 43, + 43, 44, 45, 45, 46, 47, 48, 48, + 49, 50, 51, 52, 53, 53, 54, 56, + 57, 58, 59, 60, 62, 63, 65, 66, + 68, 70, 72, 74, 76, 79, 81, 84, + 87, 90, 93, 96, 100, 104, 108, 112, + 116, 121, 126, 131, 136, 142, 148, 154, + 160, 167, 174, 182, 189, 198, 206, 215, + 224, 234, 244, 254, 265, 277, 288, 301, + 313, 327, 340, 355, 370, 385, 401, 417, + 434, 452, 470, 489, 509, 529, 550, 572 +}; + +static const RK_U16 YAcQLookup[128] = { + 4, 4, 5, 5, 6, 6, 7, 8, + 9, 10, 11, 12, 13, 15, 16, 17, + 19, 20, 22, 23, 25, 26, 28, 29, + 31, 32, 34, 35, 37, 38, 40, 41, + 42, 44, 45, 46, 48, 49, 50, 51, + 53, 54, 55, 56, 57, 58, 59, 61, + 62, 63, 64, 65, 67, 68, 69, 70, + 72, 73, 75, 76, 78, 80, 82, 84, + 86, 88, 91, 93, 96, 99, 102, 105, + 109, 112, 116, 121, 125, 130, 135, 140, + 146, 152, 158, 165, 172, 180, 188, 196, + 205, 214, 224, 234, 245, 256, 268, 281, + 294, 308, 322, 337, 353, 369, 386, 404, + 423, 443, 463, 484, 506, 529, 553, 578, + 604, 631, 659, 688, 718, 749, 781, 814, + 849, 885, 922, 960, 1000, 1041, 1083, 1127 + +}; + +static const RK_U16 Y2DcQLookup[128] = { + 7, 9, 11, 13, 15, 17, 19, 21, + 23, 26, 28, 30, 33, 35, 37, 39, + 42, 44, 46, 48, 51, 53, 55, 57, + 59, 61, 63, 65, 67, 69, 70, 72, + 74, 75, 77, 78, 80, 81, 83, 84, + 85, 87, 88, 89, 90, 92, 93, 94, + 95, 96, 97, 99, 100, 101, 102, 104, + 105, 106, 108, 109, 111, 113, 114, 116, + 118, 120, 123, 125, 128, 131, 134, 137, + 140, 144, 148, 152, 156, 161, 166, 171, + 176, 182, 188, 195, 202, 209, 217, 225, + 234, 243, 253, 263, 274, 285, 297, 309, + 322, 336, 350, 365, 381, 397, 414, 432, + 450, 470, 490, 511, 533, 556, 579, 604, + 630, 656, 684, 713, 742, 773, 805, 838, + 873, 908, 945, 983, 1022, 1063, 1105, 1148 +}; + +static const RK_U16 Y2AcQLookup[128] = { + 7, 9, 11, 13, 16, 18, 21, 24, + 26, 29, 32, 35, 38, 41, 43, 46, + 49, 52, 55, 58, 61, 64, 66, 69, + 72, 74, 77, 79, 82, 84, 86, 88, + 91, 93, 95, 97, 98, 100, 102, 104, + 105, 107, 109, 110, 112, 113, 115, 116, + 117, 119, 120, 122, 123, 125, 127, 128, + 130, 132, 134, 136, 138, 141, 143, 146, + 149, 152, 155, 158, 162, 166, 171, 175, + 180, 185, 191, 197, 204, 210, 218, 226, + 234, 243, 252, 262, 273, 284, 295, 308, + 321, 335, 350, 365, 381, 398, 416, 435, + 455, 476, 497, 520, 544, 569, 595, 622, + 650, 680, 711, 743, 776, 811, 848, 885, + 925, 965, 1008, 1052, 1097, 1144, 1193, 1244, + 1297, 1351, 1407, 1466, 1526, 1588, 1652, 1719 +}; + +static const RK_U16 UvDcQLookup[128] = { + 4, 4, 5, 6, 6, 7, 8, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 33, 34, 35, 36, 36, 37, + 38, 39, 39, 40, 41, 41, 42, 43, + 43, 44, 45, 45, 46, 47, 48, 48, + 49, 50, 51, 52, 53, 53, 54, 56, + 57, 58, 59, 60, 62, 63, 65, 66, + 68, 70, 72, 74, 76, 79, 81, 84, + 87, 90, 93, 96, 100, 104, 108, 112, + 116, 121, 126, 131, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132 +}; + + +static const RK_U16 UvAcQLookup[128] = { + 4, 4, 5, 5, 6, 6, 7, 8, + 9, 10, 11, 12, 13, 15, 16, 17, + 19, 20, 22, 23, 25, 26, 28, 29, + 31, 32, 34, 35, 37, 38, 40, 41, + 42, 44, 45, 46, 48, 49, 50, 51, + 53, 54, 55, 56, 57, 58, 59, 61, + 62, 63, 64, 65, 67, 68, 69, 70, + 72, 73, 75, 76, 78, 80, 82, 84, + 86, 88, 91, 93, 96, 99, 102, 105, + 109, 112, 116, 121, 125, 130, 135, 140, + 146, 152, 158, 165, 172, 180, 188, 196, + 205, 214, 224, 234, 245, 256, 268, 281, + 294, 308, 322, 337, 353, 369, 386, 404, + 423, 443, 463, 484, 506, 529, 553, 578, + 604, 631, 659, 688, 718, 749, 781, 814, + 849, 885, 922, 960, 1000, 1041, 1083, 1127 +}; + +#define CLIP3(l, h, v) ((v) < (l) ? (l) : ((v) > (h) ? (h) : (v))) + +static const RK_U32 mcFilter[8][6] = { + { 0, 0, 128, 0, 0, 0 }, + { 0, -6, 123, 12, -1, 0 }, + { 2, -11, 108, 36, -8, 1 }, + { 0, -9, 93, 50, -6, 0 }, + { 3, -16, 77, 77, -16, 3 }, + { 0, -6, 50, 93, -9, 0 }, + { 1, -8, 36, 108, -11, 2 }, + { 0, -1, 12, 123, -6, 0 } +}; + +MPP_RET hal_vp8d_init(void *hal, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_OK; + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + + FUN_T("FUN_IN"); + //configure + ctx->packet_slots = cfg->packet_slots; + ctx->frame_slots = cfg->frame_slots; + + mpp_env_get_u32("vp8h_debug", &vp8h_debug, 0); + //get vpu socket +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + ctx->vpu_socket = VPUClientInit(VPU_DEC); + if (ctx->vpu_socket <= 0) { + mpp_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); + + FUN_T("FUN_OUT"); + return MPP_ERR_UNKNOW; + } else { + mpp_log("get vpu_socket(%d), success. \n", ctx->vpu_socket); + } + } +#endif + if (NULL == ctx->regs) { + ctx->regs = mpp_calloc_size(void, sizeof(VP8DRegSet_t)); + if (NULL == ctx->regs) { + mpp_err("hal_vp8 reg alloc failed\n"); + + FUN_T("FUN_OUT"); + return MPP_ERR_NOMEM; + } + } + + if (NULL == ctx->group) { +#ifdef RKPLATFORM + mpp_err("mpp_buffer_group_get_internal used ion in"); + ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION); +#else + ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_NORMAL); +#endif + if (MPP_OK != ret) { + mpp_err("hal_vp8 mpp_buffer_group_get failed\n"); + + FUN_T("FUN_OUT"); + return ret; + } + } + ret = mpp_buffer_get(ctx->group, &ctx->probe_table, VP8D_PROB_TABLE_SIZE); + if (MPP_OK != ret) { + mpp_err("hal_vp8 probe_table get buffer failed\n"); + + FUN_T("FUN_OUT"); + return ret; + } + + ret = mpp_buffer_get(ctx->group, &ctx->seg_map, VP8D_MAX_SEGMAP_SIZE); + + if (MPP_OK != ret) { + mpp_err("hal_vp8 seg_map get buffer failed\n"); + FUN_T("FUN_OUT"); + return ret; + } + + return ret; +} + +MPP_RET hal_vp8d_deinit(void *hal) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + if (ctx->probe_table) { + ret = mpp_buffer_put(ctx->probe_table); + if (MPP_OK != ret) { + mpp_err("hal_vp8 probe table put buffer failed\n"); + } + } + + if (ctx->seg_map) { + ret = mpp_buffer_put(ctx->seg_map); + if (MPP_OK != ret) { + mpp_err("hal_vp8 seg map put buffer failed\n"); + } + } + + if (ctx->group) { + ret = mpp_buffer_group_put(ctx->group); + if (MPP_OK != ret) { + mpp_err("hal_vp8 group free buffer failed\n"); + } + } + + if (ctx->regs) { + mpp_free(ctx->regs); + ctx->regs = NULL; + } + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8_init_hwcfg(VP8DHalContext_t *ctx) +{ + + VP8DRegSet_t *reg = (VP8DRegSet_t *)ctx->regs; + + FUN_T("FUN_IN"); + memset(reg, 0, sizeof(VP8DRegSet_t)); + reg->reg50_dec_ctrl.sw_dec_out_tiled_e = 0; + reg->reg50_dec_ctrl.sw_dec_scmd_dis = 0; + reg->reg50_dec_ctrl.sw_dec_adv_pre_dis = 0; + reg->reg50_dec_ctrl.sw_dec_latency = 0; + + reg->reg53_dec_mode = DEC_MODE_VP8; + + reg->reg54_endian.sw_dec_in_endian = 1; + reg->reg54_endian.sw_dec_out_endian = 1; + reg->reg54_endian.sw_dec_inswap32_e = 1; + reg->reg54_endian.sw_dec_outswap32_e = 1; + reg->reg54_endian.sw_dec_strswap32_e = 1; + reg->reg54_endian.sw_dec_strendian_e = 1; + + reg->reg55_Interrupt.sw_dec_irq = 0; + + reg->reg56_axi_ctrl.sw_dec_axi_rn_id = 0; + reg->reg56_axi_ctrl.sw_dec_axi_wr_id = 0; + + reg->reg56_axi_ctrl.sw_dec_data_disc_e = 0; + reg->reg56_axi_ctrl.sw_dec_max_burst = 16; + reg->reg57_enable_ctrl.sw_dec_timeout_e = 1; + reg->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; + reg->reg57_enable_ctrl.sw_dec_out_dis = 0; + +#ifdef RKPLATFORM + reg->reg149_segment_map_base = mpp_buffer_get_fd(ctx->seg_map); + reg->reg61_qtable_base = mpp_buffer_get_fd(ctx->probe_table); +#endif + + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET hal_vp8d_pre_filter_tap_set(VP8DHalContext_t *ctx) +{ + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + + FUN_T("FUN_IN"); + regs->reg59.sw_pred_bc_tap_0_0 = mcFilter[0][1]; + regs->reg59.sw_pred_bc_tap_0_1 = mcFilter[0][2]; + regs->reg59.sw_pred_bc_tap_0_2 = mcFilter[0][3]; + regs->reg153.sw_pred_bc_tap_0_3 = mcFilter[0][4]; + regs->reg153.sw_pred_bc_tap_1_0 = mcFilter[1][1]; + regs->reg153.sw_pred_bc_tap_1_1 = mcFilter[1][2]; + regs->reg154.sw_pred_bc_tap_1_2 = mcFilter[1][3]; + regs->reg154.sw_pred_bc_tap_1_3 = mcFilter[1][4]; + regs->reg154.sw_pred_bc_tap_2_0 = mcFilter[2][1]; + regs->reg155.sw_pred_bc_tap_2_1 = mcFilter[2][2]; + regs->reg155.sw_pred_bc_tap_2_2 = mcFilter[2][3]; + regs->reg155.sw_pred_bc_tap_2_3 = mcFilter[2][4]; + + regs->reg156.sw_pred_bc_tap_3_0 = mcFilter[3][1]; + regs->reg156.sw_pred_bc_tap_3_1 = mcFilter[3][2]; + regs->reg156.sw_pred_bc_tap_3_2 = mcFilter[3][3]; + regs->reg157.sw_pred_bc_tap_3_3 = mcFilter[3][4]; + regs->reg157.sw_pred_bc_tap_4_0 = mcFilter[4][1]; + regs->reg157.sw_pred_bc_tap_4_1 = mcFilter[4][2]; + regs->reg158.sw_pred_bc_tap_4_2 = mcFilter[4][3]; + regs->reg158.sw_pred_bc_tap_4_3 = mcFilter[4][4]; + regs->reg158.sw_pred_bc_tap_5_0 = mcFilter[5][1]; + + regs->reg125.sw_pred_bc_tap_5_1 = mcFilter[5][2]; + + regs->reg125.sw_pred_bc_tap_5_2 = mcFilter[5][3]; + + regs->reg125.sw_pred_bc_tap_5_3 = mcFilter[5][4]; + regs->reg126.sw_pred_bc_tap_6_0 = mcFilter[6][1]; + regs->reg126.sw_pred_bc_tap_6_1 = mcFilter[6][2]; + regs->reg126.sw_pred_bc_tap_6_2 = mcFilter[6][3]; + regs->reg127.sw_pred_bc_tap_6_3 = mcFilter[6][4]; + regs->reg127.sw_pred_bc_tap_7_0 = mcFilter[7][1]; + regs->reg127.sw_pred_bc_tap_7_1 = mcFilter[7][2]; + regs->reg128.sw_pred_bc_tap_7_2 = mcFilter[7][3]; + regs->reg128.sw_pred_bc_tap_7_3 = mcFilter[7][4]; + + regs->reg128.sw_pred_tap_2_M1 = mcFilter[2][0]; + regs->reg128.sw_pred_tap_2_4 = mcFilter[2][5]; + regs->reg128.sw_pred_tap_4_M1 = mcFilter[4][0]; + regs->reg128.sw_pred_tap_4_4 = mcFilter[4][5]; + regs->reg128.sw_pred_tap_6_M1 = mcFilter[6][0]; + regs->reg128.sw_pred_tap_6_4 = mcFilter[6][5]; + + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET hal_vp8d_dct_partition_cfg(VP8DHalContext_t *ctx, HalTaskInfo *task) +{ + RK_U32 i = 0, len = 0, len1 = 0; + RK_U32 extraBytesPacked = 0; + RK_U32 addr = 0, byte_offset = 0; +#ifdef RKPLATFORM + RK_U32 fd = 0; + MppBuffer streambuf = NULL; +#endif + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + DXVA_PicParams_VP8 *pic_param = (DXVA_PicParams_VP8 *)task->dec.syntax.data; + + + FUN_T("FUN_IN"); +#ifdef RKPLATFORM + mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); + fd = mpp_buffer_get_fd(streambuf); + regs->reg145_bitpl_ctrl_base = fd; + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg145_bitpl_ctrl_base |= (pic_param->stream_start_offset << 10); + } else { + regs->reg145_bitpl_ctrl_base += pic_param->stream_start_offset; + } + regs->reg122.sw_strm1_start_bit = pic_param->stream_start_bit; +#endif + /* calculate dct partition length here instead */ + if (pic_param->decMode == VP8HWD_VP8 && !pic_param->frame_type) + extraBytesPacked += 7; + len = pic_param->streamEndPos + pic_param->frameTagSize - pic_param->dctPartitionOffsets[0]; + len += ( (1 << pic_param->log2_nbr_of_dct_partitions) - 1) * 3; + len1 = extraBytesPacked + pic_param->dctPartitionOffsets[0]; + len += (len1 & 0x7); + regs->reg51_stream_info.sw_stream_len = len; + + //mpp_log("offsetToDctParts = %d pic_param->frameTagSize %d pic_param->stream_start_offset = %d extraBytesPacked = %d", + // pic_param->offsetToDctParts,pic_param->frameTagSize , + // pic_param->stream_start_offset,extraBytesPacked); + + len = pic_param->offsetToDctParts + pic_param->frameTagSize - + (pic_param->stream_start_offset - extraBytesPacked); + if (pic_param->decMode == VP8HWD_VP7) /* give extra byte for VP7 to pass test cases */ + len ++; + + regs->reg124.sw_stream1_len = len; + regs->reg124.sw_coeffs_part_am = (1 << pic_param->log2_nbr_of_dct_partitions) - 1; + for (i = 0; i < (RK_U32)(1 << pic_param->log2_nbr_of_dct_partitions); i++) { + addr = extraBytesPacked + pic_param->dctPartitionOffsets[i]; + byte_offset = addr & 0x7; + addr = addr & 0xFFFFFFF8; +#ifdef RKPLATFORM + if ( i == 0) { + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg64_input_stream_base = fd | (addr << 10); + } else { + regs->reg_dct_strm_base[i] = fd + addr; + } + } else if ( i <= 5) { + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg_dct_strm_base[i] = fd | (addr << 10); + } else { + regs->reg_dct_strm_base[i] = fd + addr; + } + } else { + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg_dct_strm1_base[i - 6] = fd | (addr << 10); + } else { + regs->reg_dct_strm_base[i - 6] = fd + addr; + } + } +#endif + switch (i) { + case 0: + regs->reg122.sw_strm_start_bit = byte_offset * 8; + break; + case 1: + regs->reg121.sw_dct1_start_bit = byte_offset * 8; + break; + case 2: + regs->reg121.sw_dct2_start_bit = byte_offset * 8; + break; + case 3: + regs->reg150.sw_dct_start_bit_3 = byte_offset * 8; + break; + case 4: + regs->reg150.sw_dct_start_bit_4 = byte_offset * 8; + break; + case 5: + regs->reg150.sw_dct_start_bit_5 = byte_offset * 8; + break; + case 6: + regs->reg150.sw_dct_start_bit_6 = byte_offset * 8; + break; + case 7: + regs->reg150.sw_dct_start_bit_6 = byte_offset * 8; + break; + default: + break; + } + } + + FUN_T("FUN_OUT"); + return MPP_OK; +} +void hal_vp8hw_asic_probe_update(DXVA_PicParams_VP8 *p, RK_U8 *probTbl) +{ + RK_U8 *dst; + RK_U32 i, j, k; + + FUN_T("FUN_IN"); + /* first probs */ + dst = probTbl; + + dst[0] = p->probe_skip_false; + dst[1] = p->prob_intra; + dst[2] = p->prob_last; + dst[3] = p->prob_golden; + dst[4] = p->stVP8Segments.mb_segment_tree_probs[0]; + dst[5] = p->stVP8Segments.mb_segment_tree_probs[1]; + dst[6] = p->stVP8Segments.mb_segment_tree_probs[2]; + dst[7] = 0; /*unused*/ + + dst += 8; + dst[0] = p->intra_16x16_prob[0]; + dst[1] = p->intra_16x16_prob[1]; + dst[2] = p->intra_16x16_prob[2]; + dst[3] = p->intra_16x16_prob[3]; + dst[4] = p->intra_chroma_prob[0]; + dst[5] = p->intra_chroma_prob[1]; + dst[6] = p->intra_chroma_prob[2]; + dst[7] = 0; /*unused*/ + + /* mv probs */ + dst += 8; + dst[0] = p->vp8_mv_update_probs[0][0]; /* is short */ + dst[1] = p->vp8_mv_update_probs[1][0]; + dst[2] = p->vp8_mv_update_probs[0][1]; /* sign */ + dst[3] = p->vp8_mv_update_probs[1][1]; + dst[4] = p->vp8_mv_update_probs[0][8 + 9]; + dst[5] = p->vp8_mv_update_probs[0][9 + 9]; + dst[6] = p->vp8_mv_update_probs[1][8 + 9]; + dst[7] = p->vp8_mv_update_probs[1][9 + 9]; + dst += 8; + for ( i = 0 ; i < 2 ; ++i ) { + for ( j = 0 ; j < 8 ; j += 4 ) { + dst[0] = p->vp8_mv_update_probs[i][j + 9 + 0]; + dst[1] = p->vp8_mv_update_probs[i][j + 9 + 1]; + dst[2] = p->vp8_mv_update_probs[i][j + 9 + 2]; + dst[3] = p->vp8_mv_update_probs[i][j + 9 + 3]; + dst += 4; + } + } + for ( i = 0 ; i < 2 ; ++i ) { + dst[0] = p->vp8_mv_update_probs[i][0 + 2]; + dst[1] = p->vp8_mv_update_probs[i][1 + 2]; + dst[2] = p->vp8_mv_update_probs[i][2 + 2]; + dst[3] = p->vp8_mv_update_probs[i][3 + 2]; + dst[4] = p->vp8_mv_update_probs[i][4 + 2]; + dst[5] = p->vp8_mv_update_probs[i][5 + 2]; + dst[6] = p->vp8_mv_update_probs[i][6 + 2]; + dst[7] = 0; /*unused*/ + dst += 8; + } + + /* coeff probs (header part) */ + dst = (RK_U8*)probTbl; + dst += (8 * 7); + for ( i = 0 ; i < 4 ; ++i ) { + for ( j = 0 ; j < 8 ; ++j ) { + for ( k = 0 ; k < 3 ; ++k ) { + dst[0] = p->vp8_coef_update_probs[i][j][k][0]; + dst[1] = p->vp8_coef_update_probs[i][j][k][1]; + dst[2] = p->vp8_coef_update_probs[i][j][k][2]; + dst[3] = p->vp8_coef_update_probs[i][j][k][3]; + dst += 4; + } + } + } + + /* coeff probs (footer part) */ + dst = (RK_U8*)probTbl; + dst += (8 * 55); + for ( i = 0 ; i < 4 ; ++i ) { + for ( j = 0 ; j < 8 ; ++j ) { + for ( k = 0 ; k < 3 ; ++k ) { + dst[0] = p->vp8_coef_update_probs[i][j][k][4]; + dst[1] = p->vp8_coef_update_probs[i][j][k][5]; + dst[2] = p->vp8_coef_update_probs[i][j][k][6]; + dst[3] = p->vp8_coef_update_probs[i][j][k][7]; + dst[4] = p->vp8_coef_update_probs[i][j][k][8]; + dst[5] = p->vp8_coef_update_probs[i][j][k][9]; + dst[6] = p->vp8_coef_update_probs[i][j][k][10]; + dst[7] = 0; /*unused*/ + dst += 8; + } + } + } + FUN_T("FUN_OUT"); + return ; +} +MPP_RET hal_vp8d_gen_regs(void* hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + RK_U32 mb_width = 0, mb_height = 0; +#ifdef RKPLATFORM + MppBuffer framebuf = NULL; + RK_U8 *segmap_ptr = NULL; + RK_U8 *probe_ptr = NULL; +#endif + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + DXVA_PicParams_VP8 *pic_param = (DXVA_PicParams_VP8 *)task->dec.syntax.data; + + FUN_T("FUN_IN"); + hal_vp8_init_hwcfg(ctx); + mb_width = (pic_param->width + 15) >> 4; + mb_height = (pic_param->height + 15) >> 4; + mpp_log("mb_width = %d mb_height = %d", mb_width, mb_height); + regs->reg120.sw_pic_mb_width = mb_width & 0x1FF; + regs->reg120.sw_pic_mb_hight_p = mb_height & 0xFF; + regs->reg120.sw_pic_mb_w_ext = mb_width >> 9; + regs->reg120.sw_pic_mb_h_ext = mb_height >> 8; + +#ifdef RKPLATFORM + if (!pic_param->frame_type) { + segmap_ptr = mpp_buffer_get_ptr(ctx->seg_map); + if (NULL != segmap_ptr) { + memset(segmap_ptr, 0, VP8D_MAX_SEGMAP_SIZE); + } + } + + probe_ptr = mpp_buffer_get_ptr(ctx->probe_table); + if (NULL != probe_ptr) { + hal_vp8hw_asic_probe_update(pic_param, probe_ptr); + } + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg63_cur_pic_base = mpp_buffer_get_fd(framebuf); + if (!pic_param->frame_type) { //key frame + if ((mb_width * mb_height) << 8 > 0x400000) { + mpp_log("mb_width*mb_height is big then 0x400000,iommu err"); + } + regs->reg131_ref0_base = regs->reg63_cur_pic_base | ((mb_width * mb_height) << 18); + } else if (pic_param->lst_fb_idx.Index7Bits < 0x7f) { //config ref0 base + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->lst_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg131_ref0_base = mpp_buffer_get_fd(framebuf); + } else { + regs->reg131_ref0_base = regs->reg63_cur_pic_base; + } + + /* golden reference */ + if (pic_param->gld_fb_idx.Index7Bits < 0x7f) { + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->gld_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg136_golden_ref_base = mpp_buffer_get_fd(framebuf); + } else { + regs->reg136_golden_ref_base = regs->reg63_cur_pic_base; + } + + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg136_golden_ref_base = regs->reg136_golden_ref_base | (pic_param->ref_frame_sign_bias_golden << 10); + } else { + regs->reg136_golden_ref_base = regs->reg136_golden_ref_base + pic_param->ref_frame_sign_bias_golden; + } + + /* alternate reference */ + if (pic_param->alt_fb_idx.Index7Bits < 0x7f) { + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->alt_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg137.alternate_ref_base = mpp_buffer_get_fd(framebuf); + } else { + regs->reg137.alternate_ref_base = regs->reg63_cur_pic_base; + } + + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg137.alternate_ref_base = regs->reg137.alternate_ref_base | (pic_param->ref_frame_sign_bias_altref << 10); + } else { + regs->reg137.alternate_ref_base = regs->reg137.alternate_ref_base + pic_param->ref_frame_sign_bias_altref; + } + + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg149_segment_map_base = regs->reg149_segment_map_base | + ((pic_param->stVP8Segments.segmentation_enabled + (pic_param->stVP8Segments.update_mb_segmentation_map << 1)) << 10); + } else { + regs->reg149_segment_map_base = regs->reg149_segment_map_base + + (pic_param->stVP8Segments.segmentation_enabled + (pic_param->stVP8Segments.update_mb_segmentation_map << 1)); + } + +#endif + regs->reg57_enable_ctrl.sw_pic_inter_e = pic_param->frame_type; + regs->reg50_dec_ctrl.sw_skip_mode = !pic_param->mb_no_coeff_skip; + + if (!pic_param->stVP8Segments.segmentation_enabled) { + regs->reg129.sw_filt_level_0 = pic_param->filter_level; + } else if (pic_param->stVP8Segments.update_mb_segmentation_data) { + regs->reg129.sw_filt_level_0 = pic_param->stVP8Segments.segment_feature_data[1][0]; + regs->reg129.sw_filt_level_1 = pic_param->stVP8Segments.segment_feature_data[1][1]; + regs->reg129.sw_filt_level_2 = pic_param->stVP8Segments.segment_feature_data[1][2]; + regs->reg129.sw_filt_level_3 = pic_param->stVP8Segments.segment_feature_data[1][3]; + } else { + regs->reg129.sw_filt_level_0 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][0]); + regs->reg129.sw_filt_level_1 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][1]); + regs->reg129.sw_filt_level_2 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][2]); + regs->reg129.sw_filt_level_3 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][3]); + } + + regs->reg132.sw_filt_type = pic_param->filter_type; + regs->reg132.sw_filt_sharpness = pic_param->sharpness; + + if (pic_param->filter_level == 0) { + regs->reg50_dec_ctrl.sw_filtering_dis = 1; + } + + if (pic_param->version != 3) { + regs->reg121.sw_romain_mv = 1; + } + + if (pic_param->decMode == VP8HWD_VP8 && (pic_param->version & 0x3)) { + regs->reg121.sw_eable_bilinear = 1; + } + regs->reg122.sw_boolean_value = pic_param->bool_value; + regs->reg122.sw_boolean_range = pic_param->bool_range; + + { + if (!pic_param->stVP8Segments.segmentation_enabled) + regs->reg130.sw_quant_0 = pic_param->y1ac_delta_q; + else if (pic_param->stVP8Segments.update_mb_segmentation_data) { /* absolute mode */ + regs->reg130.sw_quant_0 = pic_param->stVP8Segments.segment_feature_data[0][0]; + regs->reg130.sw_quant_1 = pic_param->stVP8Segments.segment_feature_data[0][1]; + regs->reg151.sw_quant_2 = pic_param->stVP8Segments.segment_feature_data[0][2]; + regs->reg151.sw_quant_3 = pic_param->stVP8Segments.segment_feature_data[0][3]; + } else { /* delta mode */ + regs->reg130.sw_quant_0 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][0]); + regs->reg130.sw_quant_1 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][1]); + regs->reg151.sw_quant_2 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][2]); + regs->reg151.sw_quant_3 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][3]); + } + + regs->reg130.sw_quant_delta_0 = pic_param->y1dc_delta_q; + regs->reg130.sw_quant_delta_1 = pic_param->y2dc_delta_q; + regs->reg151.sw_quant_delta_2 = pic_param->y2ac_delta_q; + regs->reg151.sw_quant_delta_3 = pic_param->uvdc_delta_q; + regs->reg152.sw_quant_delta_4 = pic_param->uvac_delta_q; + + if (pic_param->mode_ref_lf_delta_enabled) { + regs->reg133.sw_filt_ref_adj_0 = pic_param->ref_lf_deltas[0]; + regs->reg133.sw_filt_ref_adj_1 = pic_param->ref_lf_deltas[1]; + regs->reg133.sw_filt_ref_adj_2 = pic_param->ref_lf_deltas[2]; + regs->reg133.sw_filt_ref_adj_3 = pic_param->ref_lf_deltas[3]; + regs->reg132.sw_filt_mb_adj_0 = pic_param->mode_lf_deltas[0]; + regs->reg132.sw_filt_mb_adj_1 = pic_param->mode_lf_deltas[1]; + regs->reg132.sw_filt_mb_adj_2 = pic_param->mode_lf_deltas[2]; + regs->reg132.sw_filt_mb_adj_3 = pic_param->mode_lf_deltas[3]; + } + + } + + if ((pic_param->version & 0x3) == 0) + hal_vp8d_pre_filter_tap_set(ctx); + + hal_vp8d_dct_partition_cfg(ctx, task); + regs->reg57_enable_ctrl.sw_dec_e = 1; + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8d_start(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + +#ifdef RKPLATFORM + RK_U32 i = 0; + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + RK_U8 *p = ctx->regs; + + + FUN_T("FUN_IN"); + + for (i = 0; i < 159; i++) { + vp8h_dbg(VP8H_DBG_REG, "vp8d: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + // mpp_log("vp8d: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + p += 4; + } + ret = VPUClientSendReg(ctx->vpu_socket, (RK_U32 *)regs, VP8D_REG_NUM); + if (ret != 0) { + mpp_err("VPUClientSendReg Failed!!!\n"); + return MPP_ERR_VPUHW; + } + + FUN_T("FUN_OUT"); +#endif + (void)task; + (void)hal; + return ret; +} + +MPP_RET hal_vp8d_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; +#ifdef RKPLATFORM + VP8DRegSet_t reg_out; + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + FUN_T("FUN_IN"); + memset(®_out, 0, sizeof(VP8DRegSet_t)); + ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)®_out, + VP8D_REG_NUM, &cmd, &length); + FUN_T("FUN_OUT"); +#endif + (void)hal; + (void)task; + return ret; +} + +MPP_RET hal_vp8d_reset(void *hal) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)hal; + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8d_flush(void *hal) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)hal; + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8d_control(void *hal, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)hal; + (void)cmd_type; + (void)param; + FUN_T("FUN_OUT"); + return ret; +} diff --git a/mpp/hal/vpu/vp8d/hal_vp8d_reg.h b/mpp/hal/vpu/vp8d/hal_vp8d_reg.h new file mode 100644 index 00000000..3cf8baf7 --- /dev/null +++ b/mpp/hal/vpu/vp8d/hal_vp8d_reg.h @@ -0,0 +1,439 @@ +/* + * 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 __HAL_VP8D_REG_H__ +#define __HAL_VP8D_REG_H__ +#include + +#include "mpp_hal.h" +#include "mpp_buf_slot.h" + +#include "vp8d_syntax.h" +#include "hal_task.h" + +extern RK_U32 vp8h_debug; +#define VP8H_DBG_FUNCTION (0x00000001) +#define VP8H_DBG_REG (0x00000002) +#define VP8H_DBG_DUMP_REG (0x00000004) +#define VP8H_DBG_IRQ (0x00000008) + +#define VP8D_REG_NUM 159 +#define vp8h_dbg(flag, fmt, ...) _mpp_dbg_f(vp8h_debug, flag, fmt, ## __VA_ARGS__) + +typedef struct { + unsigned long ppReg[50]; + struct { + RK_U32 sw_dec_out_tiled_e : 1; + RK_U32 sw_dec_latency : 6; + RK_U32 sw_pic_fixed_quant : 1; + RK_U32 sw_filtering_dis : 1; + RK_U32 sw_skip_mode : 1; + RK_U32 sw_dec_scmd_dis : 1; + RK_U32 sw_dec_adv_pre_dis : 1; + RK_U32 sw_priority_mode : 1; + RK_U32 sw_refbu2_thr : 12; + RK_U32 sw_refbu2_picid : 5; + RK_U32 reserve1 : 2; + } reg50_dec_ctrl; + + struct { + RK_U32 sw_stream_len : 24; + RK_U32 reserve1 : 1; + RK_U32 sw_init_qp : 6; + RK_U32 reserve2 : 1; + } reg51_stream_info; + + struct { + RK_U32 sw_startmb_y : 8; + RK_U32 sw_startmb_x : 9; + RK_U32 sw_apf_threshold : 14; + RK_U32 sw_reserve : 1; + } reg52_error_concealment; + + RK_U32 reg53_dec_mode; + + struct { + RK_U32 sw_dec_in_endian : 1; + RK_U32 sw_dec_out_endian : 1; + RK_U32 sw_dec_inswap32_e : 1; + RK_U32 sw_dec_outswap32_e : 1; + RK_U32 sw_dec_strswap32_e : 1; + RK_U32 sw_dec_strendian_e : 1; + RK_U32 reserve3 : 26; + } reg54_endian; + + struct { + RK_U32 sw_dec_irq : 1; + RK_U32 sw_dec_irq_dis : 1; + RK_U32 reserve0 : 2; + RK_U32 sw_dec_rdy_int : 1; + RK_U32 sw_dec_bus_int : 1; + RK_U32 sw_dec_buffer_int : 1; + RK_U32 reserve1 : 1; + RK_U32 sw_dec_aso_int : 1; + RK_U32 sw_dec_slice_int : 1; + RK_U32 sw_dec_pic_inf : 1; + RK_U32 reserve2 : 1; + RK_U32 sw_dec_error_int: 1; + RK_U32 sw_dec_timeout : 1; + RK_U32 reserve3 : 18; + } reg55_Interrupt; + + struct { + RK_U32 sw_dec_axi_rn_id : 8; + RK_U32 sw_dec_axi_wr_id : 8; + RK_U32 sw_dec_max_burst : 5; + RK_U32 resever : 1; + RK_U32 sw_dec_data_disc_e : 1; + RK_U32 resever1 : 9; + } reg56_axi_ctrl; + + struct { + RK_U32 sw_dec_e : 1; + RK_U32 sw_refbu2_buf_e : 1; + RK_U32 sw_dec_out_dis : 1; + RK_U32 resever : 1; + RK_U32 sw_dec_clk_gate_e : 1; + RK_U32 sw_dec_timeout_e : 1; + RK_U32 sw_picord_count_e : 1; + RK_U32 sw_seq_mbaff_e : 1; + RK_U32 sw_reftopfirst_e : 1; + RK_U32 sw_ref_topfield_e : 1; + RK_U32 sw_write_mvs_e : 1; + RK_U32 sw_sorenson_e : 1; + RK_U32 sw_fwd_interlace_e : 1; + RK_U32 sw_pic_topfield_e : 1 ; + RK_U32 sw_pic_inter_e : 1; + RK_U32 sw_pic_b_e : 1; + RK_U32 sw_pic_fieldmode_e : 1; + RK_U32 sw_pic_interlace_e : 1; + RK_U32 sw_pjpeg_e : 1; + RK_U32 sw_divx3_e : 1; + RK_U32 sw_rlc_mode_e : 1; + RK_U32 sw_ch_8pix_ileav_e : 1; + RK_U32 sw_start_code_e : 1; + RK_U32 resever1 : 8; + RK_U32 sw_dec_ahb_hlock_e : 1; + + } reg57_enable_ctrl; + + RK_U32 reg58_soft_rest; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_0_2 : 10; + RK_U32 sw_pred_bc_tap_0_1 : 10; + RK_U32 sw_pred_bc_tap_0_0 : 10; + } reg59; + + RK_U32 reg60_addit_ch_st_base; + RK_U32 reg61_qtable_base; + RK_U32 reg62_directmv_base; + RK_U32 reg63_cur_pic_base; + RK_U32 reg64_input_stream_base; + + struct { + RK_U32 sw_refbu_y_offset : 9; + RK_U32 sw_reserve : 3; + RK_U32 sw_refbu_fparmod_e : 1; + RK_U32 sw_refbu_eval_e : 1; + RK_U32 sw_refbu_picid : 5; + RK_U32 sw_refbu_thr : 12; + RK_U32 sw_refbu_e : 1; + } reg65_refpicbuf_ctrl; + + struct { + RK_U32 build_version : 3; + RK_U32 product_IDen : 1; + RK_U32 minor_version : 8; + RK_U32 major_version : 4; + RK_U32 product_numer : 16; + } reg66_id; + + struct { + RK_U32 sw_reserve : 25; + RK_U32 sw_dec_rtl_rom : 1; + RK_U32 sw_dec_rv_prof : 2; + RK_U32 sw_ref_buff2_exist : 1; + RK_U32 sw_dec_divx_prof : 1; + RK_U32 sw_dec_refbu_ilace : 1; + RK_U32 sw_dec_jpeg_exten : 1; + } reg67_synthesis_cfg; + + struct { + RK_U32 sw_refbu_top_sum : 16; + RK_U32 sw_refbu_bot_sum : 16; + } reg68_sum_of_partitions; + + struct { + RK_U32 sw_refbu_intra_sum : 16; + RK_U32 sw_refbu_hit_sum : 16; + } reg69_sum_inf; + + struct { + RK_U32 sw_refbu_mv_sum : 22; + RK_U32 sw_reserve : 10; + } reg70_sum_mv; + + RK_U32 reg71_119_reserve[49]; + + struct { + RK_U32 sw_pic_mb_h_ext : 3; + RK_U32 sw_pic_mb_w_ext : 3; + RK_U32 sw_alt_scan_e : 1; + RK_U32 sw_mb_height_off : 4; + RK_U32 sw_pic_mb_hight_p : 8; + RK_U32 sw_mb_width_off : 4; + RK_U32 sw_pic_mb_width : 9; + } reg120; + + struct { + RK_U32 sw_resever : 5; + RK_U32 sw_vp7_version : 1; + RK_U32 sw_dc_match0 : 3; + RK_U32 sw_dc_match1 : 3; + RK_U32 sw_eable_bilinear : 1; + RK_U32 sw_romain_mv : 1; + RK_U32 sw_resever1 : 6; + RK_U32 sw_dct2_start_bit : 6; + RK_U32 sw_dct1_start_bit : 6; + } reg121; + + struct { + RK_U32 sw_boolean_range : 8; + RK_U32 sw_boolean_value : 8; + RK_U32 sw_multistream_e : 1; + RK_U32 sw_huffman_e : 1; + RK_U32 sw_strm1_start_bit : 6; + RK_U32 sw_resever : 2; + RK_U32 sw_strm_start_bit : 6; + } reg122; + + struct { + RK_U32 sw_dc_comp1 : 16; + RK_U32 sw_dc_comp0 : 16; + } reg123; + + struct { + RK_U32 sw_stream1_len : 24; + RK_U32 sw_coeffs_part_am : 4; + RK_U32 sw_resever : 4; + } reg124; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_5_3 : 10; + RK_U32 sw_pred_bc_tap_5_2 : 10; + RK_U32 sw_pred_bc_tap_5_1 : 10; + } reg125; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_6_2 : 10; + RK_U32 sw_pred_bc_tap_6_1 : 10; + RK_U32 sw_pred_bc_tap_6_0 : 10; + } reg126; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_7_1 : 10; + RK_U32 sw_pred_bc_tap_7_0 : 10; + RK_U32 sw_pred_bc_tap_6_3 : 10; + } reg127; + + struct { + RK_U32 sw_pred_tap_6_4 : 2; + RK_U32 sw_pred_tap_6_M1 : 2; + RK_U32 sw_pred_tap_4_4 : 2; + RK_U32 sw_pred_tap_4_M1 : 2; + RK_U32 sw_pred_tap_2_4 : 2; + RK_U32 sw_pred_tap_2_M1 : 2; + RK_U32 sw_pred_bc_tap_7_3 : 10; + RK_U32 sw_pred_bc_tap_7_2 : 10; + } reg128; + + struct { + RK_U32 sw_filt_level_3 : 6; + RK_U32 sw_filt_level_2 : 6; + RK_U32 sw_filt_level_1 : 6; + RK_U32 sw_filt_level_0 : 6; + RK_U32 resever : 8; + } reg129; + + struct { + RK_U32 sw_quant_1 : 11; + RK_U32 sw_quant_0 : 11; + RK_U32 sw_quant_delta_1 : 5; + RK_U32 sw_quant_delta_0 : 5; + } reg130; + + + RK_U32 reg131_ref0_base; + + struct { + RK_U32 sw_filt_mb_adj_3 : 7; + RK_U32 sw_filt_mb_adj_2 : 7; + RK_U32 sw_filt_mb_adj_1 : 7; + RK_U32 sw_filt_mb_adj_0 : 7; + RK_U32 sw_filt_sharpness : 3; + RK_U32 sw_filt_type : 1; + } reg132; + + + struct { + RK_U32 sw_filt_ref_adj_3 : 7; + RK_U32 sw_filt_ref_adj_2 : 7; + RK_U32 sw_filt_ref_adj_1 : 7; + RK_U32 sw_filt_ref_adj_0 : 7; + RK_U32 sw_resver : 4; + } reg133; + + RK_U32 reg134; + RK_U32 reg135; + + RK_U32 reg136_golden_ref_base; + + union { + RK_U32 alternate_ref_base; + struct { + RK_U32 sw_scan_map_5 : 6; + RK_U32 sw_scan_map_4 : 6; + RK_U32 sw_scan_map_3 : 6; + RK_U32 sw_scan_map_2 : 6; + RK_U32 sw_scan_map_1 : 6; + RK_U32 sw_resver : 2; + }; + } reg137; + + struct { + RK_U32 sw_scan_map_10 : 6; + RK_U32 sw_scan_map_9 : 6; + RK_U32 sw_scan_map_8 : 6; + RK_U32 sw_scan_map_7 : 6; + RK_U32 sw_scan_map_6 : 6; + RK_U32 sw_resver : 2; + } reg138; + + struct { + RK_U32 sw_scan_map_15 : 6; + RK_U32 sw_scan_map_14 : 6; + RK_U32 sw_scan_map_13 : 6; + RK_U32 sw_scan_map_12 : 6; + RK_U32 sw_scan_map_11 : 6; + RK_U32 sw_resver : 2; + } reg139; + + RK_U32 reg_dct_strm_base[5]; + RK_U32 reg145_bitpl_ctrl_base; + RK_U32 reg_dct_strm1_base[2]; + + struct { + RK_U32 sw_slice_h : 8; + RK_U32 sw_resver : 24; + } reg148; + + RK_U32 reg149_segment_map_base; + + + struct { + RK_U32 sw_dct_start_bit_7 : 6; + RK_U32 sw_dct_start_bit_6 : 6; + RK_U32 sw_dct_start_bit_5 : 6; + RK_U32 sw_dct_start_bit_4 : 6; + RK_U32 sw_dct_start_bit_3 : 6; + RK_U32 sw_resver : 2; + } reg150; + + struct { + RK_U32 sw_quant_3 : 11; + RK_U32 sw_quant_2 : 11; + RK_U32 sw_quant_delta_3 : 5; + RK_U32 sw_quant_delta_2 : 5; + } reg151; + + struct { + RK_U32 sw_quant_5 : 11; + RK_U32 sw_quant_4 : 11; + RK_U32 sw_quant_delta_4 : 5; + RK_U32 sw_resver : 5; + } reg152; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_1_1 : 10; + RK_U32 sw_pred_bc_tap_1_0 : 10; + RK_U32 sw_pred_bc_tap_0_3 : 10; + } reg153; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_2_0 : 10; + RK_U32 sw_pred_bc_tap_1_3 : 10; + RK_U32 sw_pred_bc_tap_1_2 : 10; + } reg154; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_2_3 : 10; + RK_U32 sw_pred_bc_tap_2_2 : 10; + RK_U32 sw_pred_bc_tap_2_1 : 10; + } reg155; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_3_2 : 10; + RK_U32 sw_pred_bc_tap_3_1 : 10; + RK_U32 sw_pred_bc_tap_3_0 : 10; + } reg156; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_4_1 : 10; + RK_U32 sw_pred_bc_tap_4_0 : 10; + RK_U32 sw_pred_bc_tap_3_3 : 10; + } reg157; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_5_0 : 10; + RK_U32 sw_pred_bc_tap_4_3 : 10; + RK_U32 sw_pred_bc_tap_4_2 : 10; + } reg158; +} VP8DRegSet_t; + +typedef struct VP8DHalContext { + MppBufSlots packet_slots; + MppBufSlots frame_slots; + RK_S32 vpu_socket; + void *regs; + RK_U8 reg_size; + MppBufferGroup group; + MppBuffer probe_table; + MppBuffer seg_map; + RK_U32 dec_frame_cnt; + FILE *fp_reg_in; + FILE *fp_reg_out; +} VP8DHalContext_t; + +MPP_RET hal_vp8d_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_vp8d_deinit (void *hal); +MPP_RET hal_vp8d_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_vp8d_start (void *hal, HalTaskInfo *task); +MPP_RET hal_vp8d_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_vp8d_reset (void *hal); +MPP_RET hal_vp8d_flush (void *hal); +MPP_RET hal_vp8d_control (void *hal, RK_S32 cmd_type, void *param); + +#endif diff --git a/mpp/mpi.cpp b/mpp/mpi.cpp index 9be66d9a..41ffa64f 100644 --- a/mpp/mpi.cpp +++ b/mpp/mpi.cpp @@ -35,6 +35,7 @@ typedef struct { } MppCodingTypeInfo; static MppCodingTypeInfo support_list[] = { + { MPP_CTX_DEC, MPP_VIDEO_CodingVP8, "dec", "vp8", }, { MPP_CTX_DEC, MPP_VIDEO_CodingMPEG2, "dec", "mpeg2", }, { MPP_CTX_DEC, MPP_VIDEO_CodingAVC, "dec", "h.264/AVC", }, { MPP_CTX_DEC, MPP_VIDEO_CodingHEVC, "dec", "h.265/HEVC", },