📄 slice.c
字号:
/*COPYRIGHT, LICENSE AND WARRANTY INFORMATIONThis software module has been originally developed by Nokia Corporation. Provided that a person, entity or a company willing to use the Software (hereinafter Licensee) comply with all the terms and conditions of this Statement and subject to the limitations set forth in this Statement Nokia grants to such Licensee a non-exclusive, sub-licensable, worldwide, limited license under copyrights owned by Nokia to use the Software for the sole purpose of creating, manufacturing, selling, marketing, or distributing (including the right to make modifications to the Software) a fully compliant decoder implementation (hereinafter "Decoder") of ITU-T Recommendation H.264 / ISO/IEC International Standard 14496-10 and an encoder implementation producing output that is decodable with the Decoder.Nokia retains the ownership of copyrights to the Software. There is no patent nor other intellectual property right of Nokia licensed under this Statement (except the copyright license above). Licensee hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if patent licenses are required, it is their responsibility to acquire the license before utilizing the Software.The license by Nokia is subject to that the Licensee grants to Nokia the non-exclusive, worldwide, royalty-free, perpetual and irrevocable covenant that the Licensee(s) shall not bring a suit before any court or administrative agency or otherwise assert a claim for infringement under the Licensee intellectual property rights that, but for a license, would be infringed by the Software against (a) Nokia or Nokia's Affiliate; or (b) other recipient of a license and covenant not to sue with respect to the Software from Nokia; or (c) contractor, customer or distributor of a party listed above in a or b, which suit or claim is related to the Software or use thereof.The Licensee(s) further agrees to grant a reciprocal license to Nokia (as granted by Nokia to the Licensee(s) on the modifications made by Licensee(s) to the Software. THE SOFTWARE IS PROVIDED "AS IS" AND THE ORIGINAL DEVELOPER DISCLAIMS ANY AND ALL WARRANTIES WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. THOSE INTENDING TO USE THE SOFTWARE ARE EXPRESSLY ADVISED THAT ITS USE MAY INFRINGE EXISTING PATENTS AND BE SUBJECT TO ROYALTY PAYMENTS TO PATENT OWNERS. ANYONE USING THE SOFTWARE ON THE BASIS OF THIS LICENSE AGREES TO OBTAIN THE NECESSARY PERMISSIONS FROM ANY AND ALL APPLICABLE PATENT OWNERS FOR SUCH USE.IN NO EVENT SHALL THE ORIGINAL DEVELOPER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.This copyright, license and warranty information notice must be retained in all copies and derivative works of the Software or substantial portions thereof.*/#include <string.h>#include "nccglob.h"#include "globals.h"#include "debug.h"#include "bitbuffer.h"#include "vld.h"#include "macroblock.h"#include "loopfilter.h"#include "parameterset.h"#include "framebuffer.h"#include "dpb.h"#include "slice.h"#ifdef ERROR_CONCEALMENT#include "errorconcealment.h"#endif#define MIN_ALPHA_BETA_OFFSET -6#define MAX_ALPHA_BETA_OFFSET 6/* * AVC syntax functions as specified in specification *//* * Static functions */static int getRefPicListReorderingCmds(slice_s *slice, unsigned int numRefFrames, bitbuffer_s *bitbuf);static int getDecRefPicMarkingCmds(slice_s *slice, unsigned int numRefFrames, bitbuffer_s *bitbuf);static int refPicListReordering(slice_s *slice, dpb_s *dpb, frmBuf_s *refPicList[], int numRefPicActive, sliceRefPicListReorderCmd_s reorderCmdList[]);/* * AVC syntax functions as specified in specification *//* Return fixed length code */static int u_n(bitbuffer_s *bitbuf, int len, unsigned int *val){ *val = vldGetFLC(bitbuf, len); if (bibGetStatus(bitbuf) < 0) return SLICE_ERROR; return SLICE_OK;}/* Return unsigned UVLC code */static int ue_v(bitbuffer_s *bitbuf, unsigned int *val, unsigned int maxVal){ *val = vldGetUVLC(bitbuf); if (bibGetStatus(bitbuf) < 0) return SLICE_ERROR; if (*val > maxVal) return SLICE_ERR_ILLEGAL_VALUE; return SLICE_OK;}/* Return signed UVLC code */static int se_v(bitbuffer_s *bitbuf, int *val, int minVal, int maxVal){ *val = vldGetSignedUVLC(bitbuf); if (bibGetStatus(bitbuf) < 0) return SLICE_ERROR; if (*val < minVal || *val > maxVal) return SLICE_ERR_ILLEGAL_VALUE; return SLICE_OK;}/* Return long signed UVLC code */static int se_v_long(bitbuffer_s *bitbuf, int32 *val){ *val = vldGetSignedUVLClong(bitbuf); if (bibGetStatus(bitbuf) < 0) return SLICE_ERROR; return SLICE_OK;}/* * * sliceOpen: * * Parameters: * * Function: * Allocate and initialize a slice. * * Returns: * Pointer to slice * */slice_s *sliceOpen(){ slice_s *slice; slice = (slice_s *)nccMalloc(sizeof(slice_s)); if (slice != NULL) memset(slice, 0, sizeof(slice_s)); return slice;}/* * * sliceClose: * * Parameters: * slice Slice object * * Function: * Deallocate slice * * Returns: * Nothing * */void sliceClose(slice_s *slice){ nccFree(slice);}/* * * getSliceHeader: * * Parameters: * slice Slice object * spsList Sequence Parameter Set list * ppsList Picture Parameter Set list * bitbuf Bitbuffer object * * Function: * Parses slice header syntax. * * Returns: * SLICE_OK for no error and neagtive value for error. * */int sliceGetHeader(slice_s *slice, seq_parameter_set_s *spsList[], pic_parameter_set_s *ppsList[], bitbuffer_s *bitbuf){ seq_parameter_set_s *sps; pic_parameter_set_s *pps; unsigned int picSizeInMapUnits; unsigned int temp, temp2; int sliceQp, len1; int retCode; slice->picHasMMCO5 = 0; /* first_mb_in_slice */ if ((retCode = ue_v(bitbuf, &slice->first_mb_in_slice, 65535)) < 0) return retCode; /* slice_type */ if ((retCode = ue_v(bitbuf, &slice->slice_type, SLICE_MAX)) < 0) return retCode; /* pps id */ if ((retCode = ue_v(bitbuf, &slice->pic_parameter_set_id, PS_MAX_NUM_OF_PPS-1)) < 0) return retCode; pps = ppsList[slice->pic_parameter_set_id]; if (pps == NULL) { deb0f(stderr, "Error: referring to non-existing PPS.\n"); return SLICE_ERR_NON_EXISTING_PPS; } sps = spsList[pps->seq_parameter_set_id]; if (sps == NULL) { deb0f(stderr, "Error: referring to non-existing SPS.\n"); return SLICE_ERR_NON_EXISTING_SPS; } picSizeInMapUnits = (sps->pic_width_in_mbs_minus1+1) * (sps->pic_height_in_map_units_minus1+1); if (slice->first_mb_in_slice >= picSizeInMapUnits) return SLICE_ERR_ILLEGAL_VALUE; /* frame_num */ slice->maxFrameNum = 1 << (sps->log2_max_frame_num_minus4+4); if ((retCode = u_n(bitbuf, (int)sps->log2_max_frame_num_minus4+4, &slice->frame_num)) < 0) return retCode; /* IDR pic ID */ if (slice->isIDR) { if ((retCode = ue_v(bitbuf, &slice->idr_pic_id, 65535)) < 0) return retCode; } /* POC parameters */ if (sps->pic_order_cnt_type == 0) { /* read pocLsb and deltaPOCLsb*/ if ((retCode = u_n(bitbuf, (int)sps->log2_max_pic_order_cnt_lsb_minus4+4, &slice->pic_order_cnt_lsb)) < 0) return retCode; slice->delta_pic_order_cnt_bottom = 0; if (pps->pic_order_present_flag) { /* && !field_pic_flag */ if ((retCode = se_v_long(bitbuf, &slice->delta_pic_order_cnt_bottom)) < 0) return retCode; } } else if (sps->pic_order_cnt_type == 1) { slice->delta_pic_order_cnt_0 = 0; slice->delta_pic_order_cnt_1 = 0; /* read delta_pic_order_cnt[ 0 ] and delta_pic_order_cnt[ 1 ]*/ if (!sps->delta_pic_order_always_zero_flag) { /* delta_pic_order_cnt[ 0 ] */ if ((retCode = se_v_long(bitbuf, &slice->delta_pic_order_cnt_0)) < 0) return retCode; if (pps->pic_order_present_flag) { /* && !field_pic_flag */ if ((retCode = se_v_long(bitbuf, &slice->delta_pic_order_cnt_1)) < 0) return retCode; } } } /* redundant pic cnt*/ if (pps->redundant_pic_cnt_present_flag) { if ((retCode = ue_v(bitbuf, &slice->redundant_pic_cnt, 127)) < 0) return retCode; } else slice->redundant_pic_cnt = 0; /* reference picture management */ if (IS_SLICE_P(slice->slice_type)) { if ((retCode = u_n(bitbuf, 1, &slice->num_ref_idx_active_override_flag)) < 0) return retCode; if (slice->num_ref_idx_active_override_flag) { if ((retCode = ue_v(bitbuf, &slice->num_ref_idx_l0_active_minus1, DPB_MAX_SIZE-1)) < 0) return retCode; } } /* reordering the ref picture list */ retCode = getRefPicListReorderingCmds(slice, sps->num_ref_frames, bitbuf); if (retCode < 0) return retCode; /* get the MMCO commands, but not do the operations until all the slices in current picture is decoded */ if (slice->nalRefIdc) { retCode = getDecRefPicMarkingCmds(slice, sps->num_ref_frames, bitbuf); if (retCode < 0) return retCode; } /* Slice quant */ if ((retCode = se_v(bitbuf, &slice->slice_qp_delta, -MAX_QP, MAX_QP)) < 0) return retCode; sliceQp = pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta; if (sliceQp < MIN_QP || sliceQp > MAX_QP) { deb0f(stderr, "Error: illegal slice quant.\n"); return SLICE_ERR_ILLEGAL_VALUE; } slice->qp = sliceQp; /* deblocking filter */ slice->disable_deblocking_filter_idc = 0; slice->slice_alpha_c0_offset_div2 = 0; slice->slice_beta_offset_div2 = 0; if (pps->deblocking_filter_parameters_present_flag == 1) { if ((retCode = ue_v(bitbuf, &slice->disable_deblocking_filter_idc, 2)) < 0) return retCode; if (slice->disable_deblocking_filter_idc != 1) { if ((retCode = se_v(bitbuf, &slice->slice_alpha_c0_offset_div2, MIN_ALPHA_BETA_OFFSET, MAX_ALPHA_BETA_OFFSET)) < 0) return retCode; if ((retCode = se_v(bitbuf, &slice->slice_beta_offset_div2, MIN_ALPHA_BETA_OFFSET, MAX_ALPHA_BETA_OFFSET)) < 0) return retCode; } } /* read slice_group_change_cycle */ if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) { /* len = Ceil( Log2( PicSizeInMapUnits / SliceGroupChangeRate + 1 ) ) */ /* PicSizeInMapUnits / SliceGroupChangeRate */ temp = picSizeInMapUnits / (pps->slice_group_change_rate_minus1+1); /* Calculate Log2 */ temp2 = (temp + 1) >> 1; for (len1 = 0; len1 < 16 && temp2 != 0; len1++) temp2 >>= 1; /* Calculate Ceil */ if ( (((unsigned)1) << len1) < (temp + 1) ) len1++; if ((retCode = u_n(bitbuf, len1, &slice->slice_group_change_cycle)) < 0) return retCode; /* Ceil( PicSizeInMapUnits/SliceGroupChangeRate ) */ if (temp * (pps->slice_group_change_rate_minus1+1) != picSizeInMapUnits) temp++; /* The value of slice_group_change_cycle shall be in the range of */ /* 0 to Ceil( PicSizeInMapUnits/SliceGroupChangeRate ), inclusive. */ if (slice->slice_group_change_cycle > temp) return SLICE_ERR_ILLEGAL_VALUE; } return SLICE_OK;}/* * getRefPicListReorderingCmds: * * Parameters: * slice Slice object * bitbuf Bitbuffer object * numRefFrames Number of reference frames in used * * Function: * Parse and store the ref pic reordering commands * * Return: * The number of bits being parsed */static int getRefPicListReorderingCmds(slice_s *slice, unsigned int numRefFrames, bitbuffer_s *bitbuf){ int i; unsigned int reordering_of_pic_nums_idc; int retCode; if (!IS_SLICE_I(slice->slice_type)) { if ((retCode = u_n(bitbuf, 1, &slice->ref_pic_list_reordering_flag0)) < 0) return retCode; if (slice->ref_pic_list_reordering_flag0) { i = 0; do { /* Get command */ if ((retCode = ue_v(bitbuf, &reordering_of_pic_nums_idc, 3)) < 0) return retCode; slice->reorderCmdList[i].reordering_of_pic_nums_idc = reordering_of_pic_nums_idc; /* Get command parameters */ if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) { unsigned int maxDiff = slice->maxFrameNum/2-1; if (reordering_of_pic_nums_idc == 1) maxDiff = maxDiff - 1; if ((retCode = ue_v(bitbuf, &slice->reorderCmdList[i].abs_diff_pic_num_minus1, maxDiff)) < 0) return retCode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -