--- a/videoeditorengine/avcedit/src/parameterset.cpp Fri Jan 29 14:08:33 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2403 +0,0 @@
-/*
-* Copyright (c) 2010 Ixonos Plc.
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - Initial contribution
-*
-* Contributors:
-* Ixonos Plc
-*
-* Description:
-*
-*/
-
-
-#include <string.h>
-#include "globals.h"
-#include "vld.h"
-#include "parameterset.h"
-
-
-#define MIN_CHROMA_QP_INDEX -12
-#define MAX_CHROMA_QP_INDEX 12
-#define NUM_LEVELS 16 /* The number of AVC levels */
-#define MAX_PIC_SIZE_IN_MBS 36864
-#define MAX_PIC_WIDTH_IN_MBS 543 /* Sqrt( MAX_PIC_SIZE_IN_MBS * 8 ) */
-#define MAX_PIC_HEIGHT_IN_MBS 543 /* Sqrt( MAX_PIC_SIZE_IN_MBS * 8 ) */
-
-
-/* These fields are defined in Annex A of the standard */
-typedef struct _level_s
-{
- int8 levelNumber;
- int8 constraintSet3flag;
- int32 maxMBPS;
- int32 maxFS;
- int32 maxDPB;
- int32 maxBR;
- int32 maxCPB;
- int16 maxVmvR;
- int8 minCR;
- int8 maxMvsPer2Mb;
-} level_s;
-
-/* Parameters for all levels */
-static const level_s levelArray[NUM_LEVELS] = {
- {10, 0, 1485, 99, 152064, 64, 175, 64, 2, 32},
- {11, 1, 1485, 99, 152064, 128, 350, 64, 2, 32}, /* level 1b */
- {11, 0, 3000, 396, 345600, 192, 500, 128, 2, 32},
- {12, 0, 6000, 396, 912384, 384, 1000, 128, 2, 32},
- {13, 0, 11880, 396, 912384, 768, 2000, 128, 2, 32},
- {20, 0, 11880, 396, 912384, 2000, 2000, 128, 2, 32},
- {21, 0, 19800, 792, 1824768, 4000, 4000, 256, 2, 32},
- {22, 0, 20250, 1620, 3110400, 4000, 4000, 256, 2, 32},
- {30, 0, 40500, 1620, 3110400, 10000, 10000, 256, 2, 32},
- {31, 0, 108000, 3600, 6912000, 14000, 14000, 512, 4, 16},
- {32, 0, 216000, 5120, 7864320, 20000, 20000, 512, 4, 16},
- {40, 0, 245760, 8192, 12582912, 20000, 25000, 512, 4, 16},
- {41, 0, 245760, 8192, 12582912, 50000, 62500, 512, 2, 16},
- {42, 0, 491520, 8192, 12582912, 50000, 62500, 512, 2, 16},
- {50, 0, 589824, 22080, 42393600, 135000, 135000, 512, 2, 16},
- {51, 0, 983040, 36864, 70778880, 240000, 240000, 512, 2, 16}
-};
-
-#ifdef VIDEOEDITORENGINE_AVC_EDITING
-
-struct aspectRatio_s
-{
- int width;
- int height;
-};
-
-static const struct aspectRatio_s aspectRatioArr[13] =
-{
- { 1, 1},
- { 12, 11},
- { 10, 11},
- { 16, 11},
- { 40, 33},
- { 24, 11},
- { 20, 11},
- { 32, 11},
- { 80, 33},
- { 18, 11},
- { 15, 11},
- { 64, 33},
- {160, 99}
-};
-#endif // VIDEOEDITORENGINE_AVC_EDITING
-
-/*
- * 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 PS_ERROR;
-
- return PS_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 PS_ERROR;
-
- if (*val > maxVal)
- return PS_ERR_ILLEGAL_VALUE;
-
- return PS_OK;
-}
-
-/* Return long signed UVLC code */
-static int se_v_long(bitbuffer_s *bitbuf, int32 *val)
-{
- *val = vldGetSignedUVLClong(bitbuf);
-
- if (bibGetStatus(bitbuf) < 0)
- return PS_ERROR;
-
- return PS_OK;
-}
-
-/* Return long unsigned UVLC code */
-static int ue_v_long(bitbuffer_s *bitbuf, u_int32 *val, u_int32 maxVal)
-{
- *val = vldGetUVLClong(bitbuf);
-
- if (bibGetStatus(bitbuf) < 0)
- return PS_ERROR;
-
- if (*val > maxVal)
- return PS_ERR_ILLEGAL_VALUE;
-
- return PS_OK;
-}
-
-#ifdef VIDEOEDITORENGINE_AVC_EDITING
-
-/* 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 PS_ERROR;
-
- if (*val < minVal || *val > maxVal)
- return PS_ERR_ILLEGAL_VALUE;
-
- return PS_OK;
-}
-
-#endif // VIDEOEDITORENGINE_AVC_EDITING
-
-
-/*
- * getLevel:
- *
- * Parameters:
- * levelNumber
- * constraintSet3flag
- *
- * Function:
- * Return parameters for level based on level number.
- *
- * Return:
- * Pointer to level or 0 if level does not exist
- */
-static const level_s *getLevel(int levelNumber, int constraintSet3flag)
-{
- int i;
-
- for (i = 0; i < NUM_LEVELS; i++) {
- if (levelArray[i].levelNumber == levelNumber &&
- levelArray[i].constraintSet3flag == constraintSet3flag)
- return &levelArray[i];
- }
-
- PRINT((_L("Unknown level: %i.\n"), levelNumber));
- return 0;
-}
-
-/*
- *
- * getHrdParameters:
- *
- * Parameters:
- * bitbuf The bitbuffer object
- * hrd the pointer for returning HRD parameters
- *
- * Function:
- * decode the HRD Parameters
- *
- * Returns:
- * PS_OK: Hrd parameters decoded succesfully
- * <0: Fail
- */
-static int getHrdParameters(bitbuffer_s *bitbuf, hrd_parameters_s *hrd)
-{
- unsigned int i;
- int retCode;
-
- if ((retCode = ue_v(bitbuf, &hrd->cpb_cnt_minus1, 31)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 4, &hrd->bit_rate_scale)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 4, &hrd->cpb_size_scale)) < 0)
- return retCode;
-
- for (i = 0; i <= hrd->cpb_cnt_minus1; i++) {
- /* bit_rate_value_minus1 must be in range of 0 to 2^32-2 */
- if ((retCode = ue_v_long(bitbuf, &hrd->bit_rate_value_minus1[i], (u_int32)4294967294U)) < 0)
- return retCode;
-
- /* cpb_size_value_minus1 must be in range of 0 to 2^32-2 */
- if ((retCode = ue_v_long(bitbuf, &hrd->cpb_size_value_minus1[i], (u_int32)4294967294U)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &hrd->cbr_flag[i])) < 0)
- return retCode;
- }
-
- if ((retCode = u_n(bitbuf, 5, &hrd->initial_cpb_removal_delay_length_minus1)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 5, &hrd->cpb_removal_delay_length_minus1)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 5, &hrd->dpb_output_delay_length_minus1)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 5, &hrd->time_offset_length)) < 0)
- return retCode;
-
- return PS_OK;
-}
-
-
-
-/*
- *
- * getVUI:
- *
- * Parameters:
- * bitbuf The bitbuffer object
- * vui the pointer for returning VUI parameters
- *
- * Function:
- * decode the VUI Parameters
- *
- * Returns:
- * PS_OK: VUI parameters decoded succesfully
- * <0: Fail
- */
-static int getVUI(bitbuffer_s *bitbuf, vui_parameters_s *vui)
-{
- unsigned tempWordHi, tempWordLo;
- int retCode;
-
- if ((retCode = u_n(bitbuf, 1, &vui->aspect_ratio_info_present_flag)) < 0)
- return retCode;
-
- if (vui->aspect_ratio_info_present_flag) {
- if ((retCode = u_n(bitbuf, 8, &vui->aspect_ratio_idc)) < 0)
- return retCode;
- if (vui->aspect_ratio_idc == PS_EXTENDED_SAR) {
- if ((retCode = u_n(bitbuf, 16, &vui->sar_width)) < 0)
- return retCode;
- if ((retCode = u_n(bitbuf, 16, &vui->sar_height)) < 0)
- return retCode;
- }
- }
-
- if ((retCode = u_n(bitbuf, 1, &vui->overscan_info_present_flag)) < 0)
- return retCode;
-
- if (vui->overscan_info_present_flag) {
- if ((retCode = u_n(bitbuf, 1, &vui->overscan_appropriate_flag)) < 0)
- return retCode;
- }
-
- if ((retCode = u_n(bitbuf, 1, &vui->video_signal_type_present_flag)) < 0)
- return retCode;
-
- if (vui->video_signal_type_present_flag) {
- if ((retCode = u_n(bitbuf, 3, &vui->video_format)) < 0)
- return retCode;
- if ((retCode = u_n(bitbuf, 1, &vui->video_full_range_flag)) < 0)
- return retCode;
- if ((retCode = u_n(bitbuf, 1, &vui->colour_description_present_flag)) < 0)
- return retCode;
- if (vui->colour_description_present_flag) {
- if ((retCode = u_n(bitbuf, 8, &vui->colour_primaries)) < 0)
- return retCode;
- if ((retCode = u_n(bitbuf, 8, &vui->transfer_characteristics)) < 0)
- return retCode;
- if ((retCode = u_n(bitbuf, 8, &vui->matrix_coefficients)) < 0)
- return retCode;
- }
- }
-
- if ((retCode = u_n(bitbuf, 1, &vui->chroma_loc_info_present_flag)) < 0)
- return retCode;
-
- if (vui->chroma_loc_info_present_flag) {
- if ((retCode = ue_v(bitbuf, &vui->chroma_sample_loc_type_top_field, 5)) < 0)
- return retCode;
- if ((retCode = ue_v(bitbuf, &vui->chroma_sample_loc_type_bottom_field, 5)) < 0)
- return retCode;
- }
-
- if ((retCode = u_n(bitbuf, 1, &vui->timing_info_present_flag)) < 0)
- return retCode;
-
- if (vui->timing_info_present_flag) {
- if ((retCode = u_n(bitbuf, 16, &tempWordHi)) < 0)
- return retCode;
- if ((retCode = u_n(bitbuf, 16, &tempWordLo)) < 0)
- return retCode;
- vui->num_units_in_tick = (((u_int32)tempWordHi) << 16) | ((u_int32)tempWordLo);
-
- if ((retCode = u_n(bitbuf, 16, &tempWordHi)) < 0)
- return retCode;
- if ((retCode = u_n(bitbuf, 16, &tempWordLo)) < 0)
- return retCode;
- vui->time_scale = (((u_int32)tempWordHi) << 16) | ((u_int32)tempWordLo);
-
- if ((retCode = u_n(bitbuf, 1, &vui->fixed_frame_rate_flag)) < 0)
- return retCode;
- }
-
- if ((retCode = u_n(bitbuf, 1, &vui->nal_hrd_parameters_present_flag)) < 0)
- return retCode;
-
- if (vui->nal_hrd_parameters_present_flag) {
- if ((retCode = getHrdParameters(bitbuf, &vui->nal_hrd_parameters)) < 0)
- return retCode;
- }
-
- if ((retCode = u_n(bitbuf, 1, &vui->vcl_hrd_parameters_present_flag)) < 0)
- return retCode;
-
- if (vui->vcl_hrd_parameters_present_flag) {
- if ((retCode = getHrdParameters(bitbuf, &vui->vcl_hrd_parameters)) < 0)
- return retCode;
- }
-
- if (vui->nal_hrd_parameters_present_flag || vui->vcl_hrd_parameters_present_flag) {
- if ((retCode = u_n(bitbuf, 1, &vui->low_delay_hrd_flag)) < 0)
- return retCode;
- }
-
- if ((retCode = u_n(bitbuf, 1, &vui->pic_struct_present_flag)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &vui->bitstream_restriction_flag)) < 0)
- return retCode;
-
- if (vui->bitstream_restriction_flag) {
- if ((retCode = u_n(bitbuf, 1, &vui->motion_vectors_over_pic_boundaries_flag)) < 0)
- return retCode;
- if ((retCode = ue_v(bitbuf, &vui->max_bytes_per_pic_denom, 16)) < 0)
- return retCode;
- if ((retCode = ue_v(bitbuf, &vui->max_bits_per_mb_denom, 16)) < 0)
- return retCode;
- if ((retCode = ue_v(bitbuf, &vui->log2_max_mv_length_horizontal, 16)) < 0)
- return retCode;
- if ((retCode = ue_v(bitbuf, &vui->log2_max_mv_length_vertical, 16)) < 0)
- return retCode;
- if ((retCode = ue_v(bitbuf, &vui->num_reorder_frames, 16)) < 0)
- return retCode;
- if ((retCode = ue_v(bitbuf, &vui->max_dec_frame_buffering, 16)) < 0)
- return retCode;
- }
-
- return PS_OK;
-}
-
-
-/*
- *
- * setVUIdefaults:
- *
- * Parameters:
- * vui Pointer to VUI parameters
- *
- * Function:
- * Set VUI parameters to their default values when default value is non-zero.
- *
- * Returns:
- * -
- */
-static void setVUIdefaults(seq_parameter_set_s *sps)
-{
- vui_parameters_s *vui;
- const level_s *level;
- int MaxDpbSize;
-
- vui = &sps->vui_parameters;
-
- vui->video_format = 5;
- vui->colour_primaries = 2;
- vui->transfer_characteristics = 2;
- vui->matrix_coefficients = 2;
- vui->motion_vectors_over_pic_boundaries_flag = 1;
- vui->max_bytes_per_pic_denom = 2;
- vui->max_bits_per_mb_denom = 1;
- vui->log2_max_mv_length_horizontal = 16;
- vui->log2_max_mv_length_vertical = 16;
-
- level = getLevel(sps->level_idc, sps->constraint_set3_flag);
- MaxDpbSize = level->maxDPB /
- ((sps->pic_width_in_mbs_minus1+1) * (sps->pic_height_in_map_units_minus1+1) * 384);
- MaxDpbSize = clip(1, 16, MaxDpbSize);
-
- vui->max_dec_frame_buffering = MaxDpbSize;
- vui->num_reorder_frames = vui->max_dec_frame_buffering;
-}
-
-/*
- *
- * psDecodeSPS:
- *
- * Parameters:
- * bitbuf Bitbuffer object
- * spsList The list for SPS's, the newly decoded SPS will be stored into the list
- *
- * Function:
- * Decode the SPS, and store it into the SPS list
- *
- * Returns:
- * PS_OK: SPS decoded succesfully
- * <0: Fail
- */
-int psDecodeSPS( bitbuffer_s *bitbuf, seq_parameter_set_s **spsList,
- TInt& aWidth, TInt& aHeight )
-{
- seq_parameter_set_s *sps;
- unsigned int i;
- int retCode;
-
- unsigned profile_idc; // u(8)
- Boolean constraint_set0_flag; // u(1)
- Boolean constraint_set1_flag; // u(1)
- Boolean constraint_set2_flag; // u(1)
- Boolean constraint_set3_flag; // u(1)
- Boolean reserved_zero_4bits; // u(4)
- unsigned level_idc; // u(8)
- unsigned seq_parameter_set_id; // ue(v)
-
-
- /*
- * Parse sequence parameter set syntax until sps id
- */
-
- if ((retCode = u_n(bitbuf, 8, &profile_idc)) < 0)
- return retCode;
-
- /* If constraint_set0_flag == 1, stream is Baseline Profile compliant */
- if ((retCode = u_n(bitbuf, 1, &constraint_set0_flag)) < 0)
- return retCode;
-
- /* If constraint_set1_flag == 1, stream is Main Profile compliant */
- if ((retCode = u_n(bitbuf, 1, &constraint_set1_flag)) < 0)
- return retCode;
-
- /* If constraint_set2_flag == 1, stream is Extended Profile compliant */
- if ((retCode = u_n(bitbuf, 1, &constraint_set2_flag)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &constraint_set3_flag)) < 0)
- return retCode;
-
- /* If CABAC is not defined we support only baseline compliant streams */
-#ifndef ENABLE_CABAC
- if (profile_idc != PS_BASELINE_PROFILE_IDC && constraint_set0_flag == 0)
- return PS_ERR_UNSUPPORTED_PROFILE;
-#else
- if (profile_idc != PS_BASELINE_PROFILE_IDC && constraint_set0_flag == 0 &&
- profile_idc != PS_MAIN_PROFILE_IDC && constraint_set1_flag == 0)
- return PS_ERR_UNSUPPORTED_PROFILE;
-#endif
-
- /* We don't care what is in these bits */
- if ((retCode = u_n(bitbuf, 4, &reserved_zero_4bits)) < 0)
- return retCode;
-
- /* Fetch level */
- if ((retCode = u_n(bitbuf, 8, &level_idc)) < 0)
- return retCode;
-
- /* Find level in the list of legal levels */
- for (i = 0; i < NUM_LEVELS; i++) {
- if ((int)level_idc == levelArray[i].levelNumber)
- break;
- }
-
- /* If level was not found in the list, return with error */
- if (i == NUM_LEVELS)
- return PS_ERR_ILLEGAL_VALUE;
-
- /* Get sequence parameter set id */
- if ((retCode = ue_v(bitbuf, &seq_parameter_set_id, PS_MAX_NUM_OF_SPS-1)) < 0)
- return retCode;
-
-
- /*
- * Allocate memory for SPS
- */
-
- /* Pointer to sequence parameter set structure */
- sps = spsList[seq_parameter_set_id];
-
- /* allocate mem for SPS, if it has not been allocated already */
- if (!sps) {
- sps = (seq_parameter_set_s *) User::Alloc(sizeof(seq_parameter_set_s));
- if (sps == 0) {
- return PS_ERR_MEM_ALLOC;
- }
- memset( sps, 0, sizeof(seq_parameter_set_s));
- spsList[seq_parameter_set_id] = sps;
- }
-
-
- /* Copy temporary variables to sequence parameter set structure */
- sps->profile_idc = profile_idc;
- sps->constraint_set0_flag = constraint_set0_flag;
- sps->constraint_set1_flag = constraint_set1_flag;
- sps->constraint_set2_flag = constraint_set2_flag;
- sps->constraint_set3_flag = constraint_set3_flag;
- sps->reserved_zero_4bits = reserved_zero_4bits;
- sps->level_idc = level_idc;
- sps->seq_parameter_set_id = seq_parameter_set_id;
-
-
- /*
- * Parse rest of the sequence parameter set syntax
- */
-
- /* This defines how many bits there are in frame_num syntax element */
- if ((retCode = ue_v(bitbuf, &sps->log2_max_frame_num_minus4, 12)) < 0)
- return retCode;
-
- /* Fetch POC type */
- if ((retCode = ue_v(bitbuf, &sps->pic_order_cnt_type, 2)) < 0)
- return retCode;
-
- if (sps->pic_order_cnt_type == 0) {
- if ((retCode = ue_v(bitbuf, &sps->log2_max_pic_order_cnt_lsb_minus4, 12)) < 0)
- return retCode;
- }
- else if (sps->pic_order_cnt_type == 1) {
- if ((retCode = u_n(bitbuf, 1, &sps->delta_pic_order_always_zero_flag)) < 0)
- return retCode;
-
- if ((retCode = se_v_long(bitbuf, &sps->offset_for_non_ref_pic)) < 0)
- return retCode;
-
- if ((retCode = se_v_long(bitbuf, &sps->offset_for_top_to_bottom_field)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->num_ref_frames_in_pic_order_cnt_cycle, 255)) < 0)
- return retCode;
-
- for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++) {
- if ((retCode = se_v_long(bitbuf, &sps->offset_for_ref_frame[i])) < 0)
- return retCode;
- }
- }
-
- if ((retCode = ue_v(bitbuf, &sps->num_ref_frames, 16)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &sps->gaps_in_frame_num_value_allowed_flag)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->pic_width_in_mbs_minus1, MAX_PIC_WIDTH_IN_MBS-1)) < 0)
- return retCode;
-
- aWidth = (sps->pic_width_in_mbs_minus1 + 1) * 16;
-
- if ((retCode = ue_v(bitbuf, &sps->pic_height_in_map_units_minus1, MAX_PIC_WIDTH_IN_MBS-1)) < 0)
- return retCode;
-
- aHeight = (sps->pic_height_in_map_units_minus1 + 1) * 16;
-
- if ((retCode = u_n(bitbuf, 1, &sps->frame_mbs_only_flag)) < 0)
- return retCode;
-
- if (!sps->frame_mbs_only_flag) {
- // u_n(bitbuf, 1, &sps->mb_adaptive_frame_field_flag);
- return PS_ERR_UNSUPPORTED_FEATURE;
- }
-
- if ((retCode = u_n(bitbuf, 1, &sps->direct_8x8_inference_flag)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &sps->frame_cropping_flag)) < 0)
- return retCode;
-
- /* Fetch cropping window */
- if (sps->frame_cropping_flag) {
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_left_offset, 8*(sps->pic_width_in_mbs_minus1+1)-1)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_right_offset, 8*(sps->pic_width_in_mbs_minus1+1)-sps->frame_crop_left_offset-1)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_top_offset, 8*(sps->pic_height_in_map_units_minus1+1)-1)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_bottom_offset, 8*(sps->pic_height_in_map_units_minus1+1)-sps->frame_crop_top_offset-1)) < 0)
- return retCode;
-
- TInt cropUnitX = 2;
- TInt cropUnitY = 2 * ( 2 - sps->frame_mbs_only_flag );
-
- TInt leftBorder = cropUnitX * sps->frame_crop_left_offset;
- TInt rightBorder = aWidth - ( cropUnitX * sps->frame_crop_right_offset );
-
- aWidth = rightBorder - leftBorder;
-
- TInt topBorder = cropUnitY * sps->frame_crop_top_offset;
- TInt bottomBorder = ( 16 * (sps->pic_height_in_map_units_minus1 + 1) ) -
- cropUnitY * sps->frame_crop_bottom_offset;
-
- aHeight = bottomBorder - topBorder;
-
- }
-
- if ((retCode = u_n(bitbuf, 1, &sps->vui_parameters_present_flag)) < 0)
- return retCode;
-
- setVUIdefaults(sps);
-
- if (sps->vui_parameters_present_flag) {
- if ((retCode = getVUI(bitbuf, &sps->vui_parameters)) < 0)
- return retCode;
- }
-
- if (bibSkipTrailingBits(bitbuf) < 0)
- return PS_ERROR;
-
- return PS_OK;
-}
-
-/*
- *
- * psCloseParametersSets:
- *
- * Parameters:
- * spsList The sequence parameter set list
- * ppsList The picture parameter set list
- *
- * Fucntion:
- * Free all parameter sets
- *
- * Returns:
- * -
- */
-void psCloseParametersSets(seq_parameter_set_s **spsList,
- pic_parameter_set_s **ppsList)
-{
- int i;
-
- for (i = 0; i < PS_MAX_NUM_OF_SPS; i++) {
- psCloseSPS(spsList[i]);
- spsList[i] = 0;
- }
-
- for (i = 0; i < PS_MAX_NUM_OF_PPS; i++) {
- psClosePPS(ppsList[i]);
- ppsList[i] = 0;
- }
-}
-
-/*
- *
- * psClosePPS:
- *
- * Parameters:
- * pps the picture parameter set to be freed
- *
- * Function:
- * free the picture parameter set
- *
- * Returns:
- * -
- */
-void psClosePPS( pic_parameter_set_s *pps )
-{
- if (pps == 0)
- return;
-
- // [KW]: Added
- if (pps->codedPPSBuffer)
- User::Free(pps->codedPPSBuffer);
-
-
- if (pps->slice_group_id)
- User::Free(pps->slice_group_id);
-// nccFree(pps->slice_group_id);
-
-// nccFree(pps);
- User::Free(pps);
-}
-
-
-/*
- *
- * psCloseSPS:
- *
- * Parameters:
- * sps the sequence parameter set to be freed
- *
- * Fucntion:
- * free the sequence parameter set
- *
- * Returns:
- * -
- */
-void psCloseSPS( seq_parameter_set_s *sps )
-{
- if (sps == 0)
- return;
-
- // [KW]: Added
- if (sps->codedSPSBuffer)
- User::Free(sps->codedSPSBuffer);
-
-// nccFree(sps);
- User::Free(sps);
-}
-
-
-// psParseLevelFromSPS
-// Returns the baseline profile level from SPS
-TInt psParseLevelFromSPS( bitbuffer_s *bitbuf, TInt& aLevel )
-{
- TInt retCode;
- TUint profile_idc; // u(8)
- Boolean constraint_set0_flag; // u(1)
- Boolean constraint_set1_flag; // u(1)
- Boolean constraint_set2_flag; // u(1)
- Boolean constraint_set3_flag; // u(1)
- Boolean reserved_zero_4bits; // u(4)
- TUint level_idc; // u(8)
-
- // Parse sequence parameter set syntax until sps id
- if ((retCode = u_n(bitbuf, 8, &profile_idc)) < 0)
- return retCode;
-
- // If constraint_set0_flag == 1, stream is Baseline Profile compliant
- if ((retCode = u_n(bitbuf, 1, &constraint_set0_flag)) < 0)
- return retCode;
-
- // If constraint_set1_flag == 1, stream is Main Profile compliant
- if ((retCode = u_n(bitbuf, 1, &constraint_set1_flag)) < 0)
- return retCode;
-
- // If constraint_set2_flag == 1, stream is Extended Profile compliant
- if ((retCode = u_n(bitbuf, 1, &constraint_set2_flag)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &constraint_set3_flag)) < 0)
- return retCode;
-
- // If CABAC is not defined we support only baseline compliant streams
- if (profile_idc != PS_BASELINE_PROFILE_IDC && constraint_set0_flag == 0)
- return PS_ERR_UNSUPPORTED_PROFILE;
-
- // We don't care what is in these bits
- if ((retCode = u_n(bitbuf, 4, &reserved_zero_4bits)) < 0)
- return retCode;
-
- // Fetch level
- if ((retCode = u_n(bitbuf, 8, &level_idc)) < 0)
- return retCode;
-
- aLevel = level_idc;
-
- if ( level_idc == 11 && constraint_set3_flag == 1 )
- aLevel = 101; // level 1b
-
- return KErrNone;
-}
-
-
-// AddBytesToBuffer
-// Adds aNumBytes bytes to bit buffer aBitBuffer, reallocates the bit buffer data if necessary.
-TInt AddBytesToBuffer(bitbuffer_s *aBitBuffer, TUint aNumBytes)
-{
- TInt i;
-
- // Reallocate the bitbuffer data
- aBitBuffer->data = (TUint8 *) User::ReAlloc(aBitBuffer->data, (aBitBuffer->dataLen+aNumBytes));
-
- if (aBitBuffer->data == 0)
- return KErrNoMemory;
-
- // Set the new bytes as zeros
- for (i=aBitBuffer->dataLen; i<aBitBuffer->dataLen+aNumBytes; i++)
- {
- aBitBuffer->data[i] = 0;
- }
-
- return KErrNone;
-}
-
-
-#ifdef VIDEOEDITORENGINE_AVC_EDITING
-
-
-/*
- *
- * psGetAspectRatio:
- *
- * Parameters:
- * sps Sequence parameter set
- * width Horizontal size of the sample aspect ratio
- * height Vertical size of the sample aspect ratio
- *
- * Function:
- * Return sample aspect ratio in width and height
- *
- * Returns:
- * -
- */
-void psGetAspectRatio(seq_parameter_set_s *sps, int *width, int *height)
-{
- vui_parameters_s *vui;
-
- vui = &sps->vui_parameters;
-
- *width = 0;
- *height = 0;
-
- if (sps->vui_parameters_present_flag &&
- vui->aspect_ratio_info_present_flag &&
- vui->aspect_ratio_idc != 0 &&
- (vui->aspect_ratio_idc <= 13 || vui->aspect_ratio_idc == 255))
- {
- if (vui->aspect_ratio_idc == 255) {
- /* Extended_SAR */
- if (vui->sar_width != 0 && vui->sar_height != 0) {
- *width = vui->sar_width;
- *height = vui->sar_height;
- }
- }
- else {
- *width = aspectRatioArr[vui->aspect_ratio_idc-1].width;
- *height = aspectRatioArr[vui->aspect_ratio_idc-1].height;
- }
- }
-
-}
-
-
-// CompareSPSSets
-// Compares two SPS input sets to see if we can use one for both clips, if exact match is not required
-// then some parameters maybe be different in the two sets.
-TInt CompareSPSSets( seq_parameter_set_s *aSPSSet1, seq_parameter_set_s *aSPSSet2, TBool aExactMatch )
-{
- TUint i;
-
- // Different maxFrameNum & maxPOCLsb can be handled by modifying the slice header, thus do not return EFalse
- if ( aExactMatch )
- {
- // If exact match is required, return false for different max frame number value
- if ( aSPSSet1->log2_max_frame_num_minus4 != aSPSSet2->log2_max_frame_num_minus4 )
- return EFalse;
- }
-
- if ( aSPSSet1->pic_order_cnt_type != aSPSSet2->pic_order_cnt_type )
- {
- return EFalse;
- }
- else
- {
- if (aSPSSet1->pic_order_cnt_type == 0)
- {
- // Different maxFrameNum & maxPOCLsb can be handled by modifying the slice header, thus do not return EFalse
- if ( aExactMatch )
- {
- // If exact match is required, return false for different max POCLSB number value
- if ( aSPSSet1->log2_max_pic_order_cnt_lsb_minus4 != aSPSSet2->log2_max_pic_order_cnt_lsb_minus4 )
- return EFalse;
- }
-
- }
- else if (aSPSSet1->pic_order_cnt_type == 1)
- {
- if ( aSPSSet1->delta_pic_order_always_zero_flag != aSPSSet2->delta_pic_order_always_zero_flag ||
- aSPSSet1->offset_for_non_ref_pic != aSPSSet2->offset_for_non_ref_pic ||
- aSPSSet1->num_ref_frames_in_pic_order_cnt_cycle != aSPSSet2->num_ref_frames_in_pic_order_cnt_cycle )
- {
- return EFalse;
- }
-
- for (i = 0; i < aSPSSet1->num_ref_frames_in_pic_order_cnt_cycle; i++)
- {
- if ( aSPSSet1->offset_for_ref_frame[i] != aSPSSet2->offset_for_ref_frame[i] )
- {
- return EFalse;
- }
- }
- }
- }
-
- if ( aSPSSet1->num_ref_frames != aSPSSet2->num_ref_frames )
- {
- return EFalse;
- }
-
- // Direct 8x8 inference flag is not used in baseline, ignore
-
- return ETrue;
-}
-
-
-// IsSPSSupported
-// Checks if the input SPS contains supported values. Returns KErrNotSupported if
-// unsupported parameters are found.
-TInt IsSPSSupported( seq_parameter_set_s *aSPS )
-{
-
- // Only Baseline profile supported at the moment
- if ( aSPS->profile_idc != PS_BASELINE_PROFILE_IDC )
- {
- return KErrNotSupported;
- }
-
- // Check if maximum supported level is exceeded
- if ( aSPS->level_idc > PS_MAX_SUPPORTED_LEVEL )
- {
- return KErrNotSupported;
- }
-
- // For now more than one reference frames are not supported
- if ( aSPS->num_ref_frames > 1 )
- {
- return KErrNotSupported;
- }
-
- // Coded fields are not supported
- if ( !aSPS->frame_mbs_only_flag )
- {
- return KErrNotSupported;
- }
-
- if ( aSPS->vui_parameters_present_flag )
- {
- if ( aSPS->vui_parameters.num_reorder_frames != 0 && aSPS->pic_order_cnt_type != 2)
- {
- // Since we can't be sure how many input frames we have to buffer before getting
- // an output picture, return KErrNotSupported
- return KErrNotSupported;
- }
- }
- else
- {
- if ( aSPS->pic_order_cnt_type != 2)
- {
- // Since we can't be sure how many input frames we have to buffer before getting
- // an output picture, return KErrNotSupported
- return KErrNotSupported;
- }
- }
-
- return KErrNone;
-}
-
-
-// IsPPSSupported
-// Checks if the input PPS contains supported values. Returns KErrNotSupported if
-// unsupported parameters are found.
-TInt IsPPSSupported( pic_parameter_set_s *aPPS )
-{
-
- // For baseline, both prediction values shall be zero
- if( aPPS->weighted_pred_flag != 0 || aPPS->weighted_bipred_idc != 0)
- {
- return KErrNotSupported;
- }
-
- // For baseline, entropy coding mode shall be zero
- if ( aPPS->entropy_coding_mode_flag != 0 )
- {
- return KErrNotSupported;
- }
-
- if ( aPPS->num_slice_groups_minus1 > PS_BASELINE_MAX_SLICE_GROUPS )
- {
- return KErrNotSupported;
- }
-
- return KErrNone;
-}
-
-
-// psParseSPS
-// Parses the input SPS set. Modifies the SPS id if a conflicting id is found
-// and stores the modified data to codedSPSBuffer for later use.
-TInt psParseSPS( bitbuffer_s *bitbuf, seq_parameter_set_s **spsList, TUint aFrameFromEncoder, TBool *aEncodeUntilIDR, TUint *aNumSPS )
-{
- seq_parameter_set_s *sps;
- TUint i;
- TInt retCode;
- TUint bitPosit = 0;
- TUint bytePosit = 0;
- TUint profile_idc; // u(8)
- Boolean constraint_set0_flag; // u(1)
- Boolean constraint_set1_flag; // u(1)
- Boolean constraint_set2_flag; // u(1)
- Boolean constraint_set3_flag; // u(1)
- Boolean reserved_zero_4bits; // u(4)
- TUint level_idc; // u(8)
- TUint seq_parameter_set_id; // ue(v)
- TUint newSPSId = 0;
- TUint possibleIdConflict = 0;
- TUint useOneSPS = 0;
-
-
- if (!aFrameFromEncoder)
- {
- // Reset the encode until IDR flag if this SPS is not from the encoder.
- *aEncodeUntilIDR = EFalse;
- }
-
- // Parse sequence parameter set syntax until sps id
- if ((retCode = u_n(bitbuf, 8, &profile_idc)) < 0)
- return retCode;
-
- // If constraint_set0_flag == 1, stream is Baseline Profile compliant
- if ((retCode = u_n(bitbuf, 1, &constraint_set0_flag)) < 0)
- return retCode;
-
- // If constraint_set1_flag == 1, stream is Main Profile compliant
- if ((retCode = u_n(bitbuf, 1, &constraint_set1_flag)) < 0)
- return retCode;
-
- // If constraint_set2_flag == 1, stream is Extended Profile compliant
- if ((retCode = u_n(bitbuf, 1, &constraint_set2_flag)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &constraint_set3_flag)) < 0)
- return retCode;
-
- // If CABAC is not defined we support only baseline compliant streams
- if (profile_idc != PS_BASELINE_PROFILE_IDC && constraint_set0_flag == 0)
- return PS_ERR_UNSUPPORTED_PROFILE;
-
- // We don't care what is in these bits
- if ((retCode = u_n(bitbuf, 4, &reserved_zero_4bits)) < 0)
- return retCode;
-
- // Fetch level
- if ((retCode = u_n(bitbuf, 8, &level_idc)) < 0)
- return retCode;
-
- // Find level in the list of legal levels
- for (i = 0; i < NUM_LEVELS; i++)
- {
- if ((int)level_idc == levelArray[i].levelNumber)
- break;
- }
-
- // If level was not found in the list, return with error
- if (i == NUM_LEVELS)
- return PS_ERR_ILLEGAL_VALUE;
-
- // Get sequence parameter set id
- if ((retCode = ue_v(bitbuf, &seq_parameter_set_id, PS_MAX_NUM_OF_SPS-1)) < 0)
- return retCode;
-
- // Pointer to sequence parameter set structure
- sps = spsList[seq_parameter_set_id];
-
- // Allocate memory for SPS, if it has not been allocated already
- if (!sps)
- {
- sps = (seq_parameter_set_s *) User::Alloc(sizeof(seq_parameter_set_s));
-
- if (sps == 0)
- {
- PRINT((_L("Error while allocating memory for SPS.\n")));
- return PS_ERR_MEM_ALLOC;
- }
-
- memset( sps, 0, sizeof(seq_parameter_set_s));
- spsList[seq_parameter_set_id] = sps;
-
- sps->seq_parameter_set_id = seq_parameter_set_id;
- (*aNumSPS)++;
- }
- else
- {
- // There might be a conflicting Id with an existing SPS set
- // Give the new SPS set the next free SPS Id
- possibleIdConflict = 1;
- newSPSId = 0;
- useOneSPS = 1;
-
- // Search for the first free SPS id
- while (spsList[newSPSId])
- {
- newSPSId++;
- }
-
- // And allocate memory for the SPS
- sps = (seq_parameter_set_s *) User::Alloc(sizeof(seq_parameter_set_s));
-
- if (sps == 0)
- {
- PRINT((_L("Error while allocating memory for SPS.\n")));
- return PS_ERR_MEM_ALLOC;
- }
-
- memset( sps, 0, sizeof(seq_parameter_set_s));
-
- sps->seq_parameter_set_id = newSPSId;
-
- // Store the position of the bit buffer
- bitPosit = bitbuf->bitpos;
- bytePosit = bitbuf->bytePos;
- }
-
-
- // Copy temporary variables to sequence parameter set structure
- sps->profile_idc = profile_idc;
- sps->constraint_set0_flag = constraint_set0_flag;
- sps->constraint_set1_flag = constraint_set1_flag;
- sps->constraint_set2_flag = constraint_set2_flag;
- sps->constraint_set3_flag = constraint_set3_flag;
- sps->reserved_zero_4bits = reserved_zero_4bits;
- sps->level_idc = level_idc;
-
- // Initialize
- sps->maxFrameNumChanged = 0;
- sps->maxPOCNumChanged = 0;
-
- // This defines how many bits there are in frame_num syntax element
- if ((retCode = ue_v(bitbuf, &sps->log2_max_frame_num_minus4, 12)) < 0)
- return retCode;
-
- // Fetch POC type
- if ((retCode = ue_v(bitbuf, &sps->pic_order_cnt_type, 2)) < 0)
- return retCode;
-
- if (sps->pic_order_cnt_type == 0)
- {
- if ((retCode = ue_v(bitbuf, &sps->log2_max_pic_order_cnt_lsb_minus4, 12)) < 0)
- return retCode;
- }
- else if (sps->pic_order_cnt_type == 1)
- {
- if ((retCode = u_n(bitbuf, 1, &sps->delta_pic_order_always_zero_flag)) < 0)
- return retCode;
-
- if ((retCode = se_v_long(bitbuf, &sps->offset_for_non_ref_pic)) < 0)
- return retCode;
-
- if ((retCode = se_v_long(bitbuf, &sps->offset_for_top_to_bottom_field)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->num_ref_frames_in_pic_order_cnt_cycle, 255)) < 0)
- return retCode;
-
- for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
- {
- if ((retCode = se_v_long(bitbuf, &sps->offset_for_ref_frame[i])) < 0)
- return retCode;
- }
- }
-
- if ((retCode = ue_v(bitbuf, &sps->num_ref_frames, 16)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &sps->gaps_in_frame_num_value_allowed_flag)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->pic_width_in_mbs_minus1, MAX_PIC_WIDTH_IN_MBS-1)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->pic_height_in_map_units_minus1, MAX_PIC_WIDTH_IN_MBS-1)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &sps->frame_mbs_only_flag)) < 0)
- return retCode;
-
- if (!sps->frame_mbs_only_flag)
- {
- return PS_ERR_UNSUPPORTED_FEATURE;
- }
-
- if ((retCode = u_n(bitbuf, 1, &sps->direct_8x8_inference_flag)) < 0)
- return retCode;
-
- if ((retCode = u_n(bitbuf, 1, &sps->frame_cropping_flag)) < 0)
- return retCode;
-
- // Fetch cropping window
- if (sps->frame_cropping_flag)
- {
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_left_offset, 8*(sps->pic_width_in_mbs_minus1+1)-1)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_right_offset, 8*(sps->pic_width_in_mbs_minus1+1)-sps->frame_crop_left_offset-1)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_top_offset, 8*(sps->pic_height_in_map_units_minus1+1)-1)) < 0)
- return retCode;
-
- if ((retCode = ue_v(bitbuf, &sps->frame_crop_bottom_offset, 8*(sps->pic_height_in_map_units_minus1+1)-sps->frame_crop_top_offset-1)) < 0)
- return retCode;
- }
-
- if ((retCode = u_n(bitbuf, 1, &sps->vui_parameters_present_flag)) < 0)
- return retCode;
-
- setVUIdefaults(sps);
-
- if (sps->vui_parameters_present_flag)
- {
- if ((retCode = getVUI(bitbuf, &sps->vui_parameters)) < 0)
- return retCode;
- }
-
- if (bibSkipTrailingBits(bitbuf) < 0)
- return PS_ERROR;
-
- // Store the size of the SPS set
- sps->SPSlength = bitbuf->bytePos;
-
- syncBitBufferBitpos(bitbuf);
-
- // If we had a possible conflict, compare the SPS sets with the same id to see if only one SPS set can be used.
- if (possibleIdConflict)
- {
- // Check if one SPS can be used instead of two separate ones
- useOneSPS = CompareSPSSets(spsList[seq_parameter_set_id],sps,EFalse);
-
- if (!useOneSPS)
- {
- TUint trailingBits = GetNumTrailingBits(bitbuf);
- TInt diff = 0;
- TUint oldSPSId = seq_parameter_set_id;
- TUint oldIdLength = ReturnUnsignedExpGolombCodeLength(oldSPSId);
- TUint newIdLength = ReturnUnsignedExpGolombCodeLength(newSPSId);
- TUint storeSPS = 1;
-
- for (i=0; i<PS_MAX_NUM_OF_SPS; i++)
- {
- // Check if an older SPS matches exactly this one, then use the old
- if (spsList[i])
- useOneSPS = CompareSPSSets(spsList[i],sps,ETrue);
-
- if (useOneSPS)
- {
- newSPSId = i;
- storeSPS =0;
- break;
- }
- }
-
- if ( newSPSId > PS_MAX_NUM_OF_SPS )
- {
- // We have reached maximum number of SPS, return an error
- return PS_ERROR;
- }
-
- (*aNumSPS)++;
-
- // Set indexChanged to true and give the new index to old SPS, so that (new) PPS can refer to the new SPS
- spsList[seq_parameter_set_id]->indexChanged = 1;
- spsList[seq_parameter_set_id]->newSPSId = newSPSId; // The new Id
-
- if (aFrameFromEncoder)
- {
- spsList[seq_parameter_set_id]->encSPSId = newSPSId; // The new Id
-
- // Store information that there are different SPS in use, we have to encode until an IDR NAL unit.
- *aEncodeUntilIDR = ETrue;
- }
- else
- spsList[seq_parameter_set_id]->origSPSId = newSPSId; // The new Id
-
-
- // Store the new SPS at the new index and modify SPS id,
- // unless we are using a previously stored SPS
- if(storeSPS)
- {
- spsList[newSPSId] = sps;
-
- // Restore the bit buffer position at the SPS Id
- bitbuf->bitpos = bitPosit;
- bitbuf->bytePos = bytePosit;
-
- if(trailingBits > 8)
- {
- trailingBits = 8;
- }
-
- if ( oldIdLength == newIdLength )
- {
- // Just encode the new Id on top of the old Id
- bitbuf->bitpos += oldIdLength;
- if (bitbuf->bitpos > 8)
- {
- // Go to the right byte and bit position
- bitbuf->bytePos -= bitbuf->bitpos / 8;
- bitbuf->bitpos = bitbuf->bitpos % 8;
- }
-
- EncodeUnsignedExpGolombCode(bitbuf, newSPSId);
- }
- else if ( oldIdLength < newIdLength )
- {
- diff = newIdLength - oldIdLength;
-
- // Adjust the SPS length
- if (diff >= 8)
- {
- // Add as many extra bytes as is required
- sps->SPSlength += (diff / 8);
- }
-
- if ( trailingBits < (diff % 8) )
- {
- // Add one byte since there aren't enough trailing bits for the extra bits
- sps->SPSlength += 1;
- }
-
- ShiftBufferRight(bitbuf, diff, trailingBits, oldIdLength);
-
- // After shifting, encode the new value to the bit buffer
- EncodeUnsignedExpGolombCode(bitbuf, newSPSId);
- }
- else
- {
- // New id's length is smaller than old id's length
- diff = oldIdLength - newIdLength;
-
- if (diff >= 8)
- {
- // Adjust the SPS length
- sps->SPSlength -= (diff / 8);
- }
-
- ShiftBufferLeft(bitbuf, diff, oldIdLength);
-
- // After shifting, encode the new value to the bit buffer
- EncodeUnsignedExpGolombCode(bitbuf, newSPSId);
- }
- }
- }
- else // Use one SPS for both
- {
- // Reset indexChanged to false
- spsList[seq_parameter_set_id]->indexChanged = 0;
-
- // Check if the frame numbering or POC numbering has to be changed
- if (spsList[seq_parameter_set_id]->log2_max_frame_num_minus4 != sps->log2_max_frame_num_minus4)
- {
- spsList[seq_parameter_set_id]->maxFrameNumChanged = 1;
-
- if (aFrameFromEncoder)
- spsList[seq_parameter_set_id]->encMaxFrameNum = sps->log2_max_frame_num_minus4;
- else
- spsList[seq_parameter_set_id]->origMaxFrameNum = sps->log2_max_frame_num_minus4;
- }
- else
- {
- // Reset the value in case it was changed for another clip earlier
- spsList[seq_parameter_set_id]->maxFrameNumChanged = 0;
- }
-
- if (spsList[seq_parameter_set_id]->log2_max_pic_order_cnt_lsb_minus4 != sps->log2_max_pic_order_cnt_lsb_minus4)
- {
- spsList[seq_parameter_set_id]->maxPOCNumChanged = 1;
-
- if (aFrameFromEncoder)
- spsList[seq_parameter_set_id]->encMaxPOCNum = sps->log2_max_pic_order_cnt_lsb_minus4;
- else
- spsList[seq_parameter_set_id]->origMaxPOCNum = sps->log2_max_pic_order_cnt_lsb_minus4;
- }
- else
- {
- // Reset the value in case it was changed for another clip earlier
- spsList[seq_parameter_set_id]->maxPOCNumChanged = 0;
- }
- }
- }
-
- if ( IsSPSSupported(sps) == KErrNotSupported )
- return KErrNotSupported;
-
-
- // Store the buffer containing the SPS set in order to later pass it to the 3gpmp4library
- // If we use the same sps for both, don't allocate, otherwise allocate
- if ( !useOneSPS )
- {
-
- // Store the buffer containing the SPS set in order to later pass it to the 3gpmp4library
- sps->codedSPSBuffer = (TUint8*) User::Alloc(sps->SPSlength);
-
- if (sps->codedSPSBuffer == 0)
- return PS_ERR_MEM_ALLOC;
-
- for (i=0; i<sps->SPSlength; i++)
- {
- sps->codedSPSBuffer[i] = bitbuf->data[i];
- }
- }
- else if (possibleIdConflict)
- {
- // Free the SPS since we will use only one which has been already allocated earlier
- User::Free(sps);
- }
-
-
- return PS_OK;
-}
-
-
-// ComparePPSSets
-// Compares two input PPS sets to see if a single PPS set could be used for both.
-// Returns ETrue if the sets are similar enough, EFalse otherwise.
-TInt ComparePPSSets( pic_parameter_set_s *aPPSSet1, pic_parameter_set_s *aPPSSet2 )
-{
- TUint i;
-
- // This is the most likely parameter to differ, thus check it first
- if ( aPPSSet1->pic_init_qp_minus26 != aPPSSet2->pic_init_qp_minus26 ||
- aPPSSet1->pic_init_qs_minus26 != aPPSSet2->pic_init_qs_minus26 )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->entropy_coding_mode_flag != aPPSSet2->entropy_coding_mode_flag )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->pic_order_present_flag != aPPSSet2->pic_order_present_flag )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->num_slice_groups_minus1 != aPPSSet2->num_slice_groups_minus1 )
- {
- return EFalse;
- }
- else
- {
- if ( aPPSSet1->num_slice_groups_minus1 > 0 )
- {
- if ( aPPSSet1->slice_group_map_type != aPPSSet2->slice_group_map_type )
- {
- return EFalse;
- }
-
- switch ( aPPSSet1->slice_group_map_type )
- {
-
- case PS_SLICE_GROUP_MAP_TYPE_INTERLEAVED:
- for (i = 0; i <= aPPSSet1->num_slice_groups_minus1; i++)
- {
- if ( aPPSSet1->run_length_minus1[i] != aPPSSet2->run_length_minus1[i] )
- {
- return EFalse;
- }
- }
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_DISPERSED:
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_FOREGROUND:
- for (i = 0; i < aPPSSet1->num_slice_groups_minus1; i++)
- {
- if ( aPPSSet1->top_left[i] != aPPSSet2->top_left[i] ||
- aPPSSet1->bottom_right[i] != aPPSSet2->bottom_right[i] )
- {
- return EFalse;
- }
- }
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_CHANGING_3:
- case PS_SLICE_GROUP_MAP_TYPE_CHANGING_4:
- case PS_SLICE_GROUP_MAP_TYPE_CHANGING_5:
- if ( aPPSSet1->slice_group_change_direction_flag != aPPSSet2->slice_group_change_direction_flag ||
- aPPSSet1->slice_group_change_rate_minus1 != aPPSSet2->slice_group_change_rate_minus1 )
- {
- return EFalse;
- }
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_EXPLICIT:
- if ( aPPSSet1->pic_size_in_map_units_minus1 != aPPSSet2->pic_size_in_map_units_minus1 )
- {
- return EFalse;
- }
-
- for( i = 0; i <= aPPSSet1->pic_size_in_map_units_minus1; i++ )
- {
- if ( aPPSSet1->slice_group_id[i] != aPPSSet2->slice_group_id[i] )
- {
- return EFalse;
- }
- }
-
- break;
-
- default:
- // Cannnot happen
- break;
- }
- }
- }
-
- if ( aPPSSet1->num_ref_idx_l0_active_minus1 != aPPSSet2->num_ref_idx_l0_active_minus1 ||
- aPPSSet1->num_ref_idx_l1_active_minus1 != aPPSSet2->num_ref_idx_l1_active_minus1 )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->weighted_pred_flag != aPPSSet2->weighted_pred_flag ||
- aPPSSet1->weighted_bipred_idc != aPPSSet2->weighted_bipred_idc )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->chroma_qp_index_offset != aPPSSet2->chroma_qp_index_offset )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->deblocking_filter_parameters_present_flag != aPPSSet2->deblocking_filter_parameters_present_flag )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->constrained_intra_pred_flag != aPPSSet2->constrained_intra_pred_flag )
- {
- return EFalse;
- }
-
- if ( aPPSSet1->redundant_pic_cnt_present_flag != aPPSSet2->redundant_pic_cnt_present_flag )
- {
- return EFalse;
- }
-
- return ETrue;
-}
-
-
-// GetNumTrailingBits
-// Returns the number of trailing (zero) bits in the input bit buffer.
-TInt GetNumTrailingBits(bitbuffer_s *aBitBuffer)
-{
- TInt i;
- TUint bit = 0;
-
- for (i=0; i<8; i++)
- {
- // Get the i'th bit from the end
- bit = (aBitBuffer->data[aBitBuffer->dataLen - 1] & (1 << i)) >> i;
- if (bit)
- {
- return (i); // Return the number of trailing bits here
- }
- }
-
- // Return 9 for cases when there are one or more zero byte at the end
- return (9);
-}
-
-
-// ReturnUnsignedExpGolombCodeLength
-// Returns the amount of bits required for encoding the input aValue with unsigned Exp-Golomb codes.
-TInt ReturnUnsignedExpGolombCodeLength(TUint aValue)
-{
- TUint codeNumLength;
-
- codeNumLength = 0;
-
- aValue++;
-
- while ( aValue > 1 )
- {
- aValue >>= 1;
- codeNumLength++;
- }
-
- // The required code length is codeNumLength*2+1
- return ((codeNumLength << 1) + 1);
-}
-
-
-// EncodeUnsignedExpGolombCode
-// Encodes the input aValue to the bit buffer with unsigned Exp-Golomb codes.
-void EncodeUnsignedExpGolombCode(bitbuffer_s *aBitBuffer, TUint aValue)
-{
- TUint codeLength;
- TUint tempValue = aValue;
- TInt i;
- TUint8 byteValue;
-
- // First, compute the required code length
- codeLength = ReturnUnsignedExpGolombCodeLength(aValue);
-
- // The Exp-Golomb coded value is the same as value+1 with the prefix zero bits,
- // thus it can be simply coded by coding value+1 with the number of bits computed
- // by the above function.
- aValue++;
-
- // Then write the bits to the bit buffer one bit at a time
- for (i=codeLength-1; i>=0; i--)
- {
- tempValue = (aValue & (1 << i)) >> i;
-
- // Zero out the bitpos bit
- byteValue = aBitBuffer->data[aBitBuffer->bytePos-1] & ~(1<<(aBitBuffer->bitpos-1));
-
- // Add the bit from the value to be coded and store the result back to bit buffer
- byteValue |= tempValue << (aBitBuffer->bitpos-1);
- aBitBuffer->data[aBitBuffer->bytePos-1] = byteValue;
- aBitBuffer->bitpos--;
-
- if(aBitBuffer->bitpos == 0)
- {
- aBitBuffer->bytePos++;
- aBitBuffer->bitpos = 8;
- }
- }
-
- // Update the currentBits value
- aBitBuffer->currentBits = aBitBuffer->data[aBitBuffer->bytePos-1];
-}
-
-
-// ShiftBitBufferBitsRight
-// This function shifts bits right by aDiff in the aBitBuffer, note that if
-// the shift is more than 8 bits, full bytes should be shifted before calling this function.
-// The gap between unmodified and shofted part of the buffer is filled with zero bits
-void ShiftBitBufferBitsRight(bitbuffer_s *aBitBuffer, TInt aDiff)
-{
- TUint8 byteValue;
- TUint8 tempValue;
- TUint8 bitMask;
- TInt i;
-
- // Start from the end, shift bits in each byte until the current byte
- for (i=aBitBuffer->dataLen-1; i>=aBitBuffer->bytePos; i--)
- {
- bitMask = (1 << aDiff) - 1; // The aDiff lowest bits
-
- // Shift the bits in this byte right by aDiff
- byteValue = aBitBuffer->data[i];
- byteValue >>= aDiff;
-
- // The aDiff lowest bits from the next byte (to the left)
- tempValue = aBitBuffer->data[i-1] & bitMask;
-
- tempValue <<= (8 - aDiff);
- aBitBuffer->data[i] = byteValue | tempValue;
- }
-
- // Take care of the first byte separately
- bitMask = (1 << aBitBuffer->bitpos) - 1; // The bitPos lowest bits
- byteValue = aBitBuffer->data[aBitBuffer->bytePos-1] & bitMask;
- byteValue >>= aDiff; // Shift right by aDiff bits
-
- bitMask = 255 << (aBitBuffer->bitpos); // Mask the 8-bitPos upper bits
-
- // Write the shifted value back to bit buffer
- aBitBuffer->data[aBitBuffer->bytePos-1] = (bitMask & aBitBuffer->data[aBitBuffer->bytePos-1]) | byteValue;
-
- // Update the currentBits value
- aBitBuffer->currentBits = aBitBuffer->data[aBitBuffer->bytePos-1];
-}
-
-
-// ShiftBitBufferBitsLeft
-// This function shifts bits left by aDiff in the aBitBuffer, note that if
-// the shift is more than 8 bits, full bytes should be shifted before calling this function.
-void ShiftBitBufferBitsLeft(bitbuffer_s *aBitBuffer, TInt aDiff)
-{
- TUint8 byteValue;
- TUint8 tempValue;
- TUint8 bitMask;
- TInt i;
-
-
- // Take care of the first byte separately
- if ( aBitBuffer->bitpos > aDiff )
- {
- bitMask = (1 << aBitBuffer->bitpos) - 1; // The aBitBuf->bitpos lowest bits
- byteValue = aBitBuffer->currentBits & bitMask;
-
- // Shift the byteValue left by aDiff
- byteValue <<= aDiff;
- // Take only the bitpos lowest bits from this value
- byteValue &= bitMask;
-
- bitMask = 255 << (aBitBuffer->bitpos); // Mask the 8-bitPos upper bits, i.e. the bits to the left from the start of the shift
- byteValue = byteValue | (aBitBuffer->currentBits & bitMask);
- aBitBuffer->data[aBitBuffer->bytePos-1] = byteValue;
-
- bitMask = 255 << (8 - aDiff); // Mask the aDiff upper bits
- byteValue = aBitBuffer->data[aBitBuffer->bytePos] & bitMask;
- byteValue >>= (8 - aDiff);
-
- // "Add" the aDiff bits from the next byte (msb) to this byte (lsb)
- aBitBuffer->data[aBitBuffer->bytePos-1] |= byteValue;
- }
- else
- {
- bitMask = 255 << (aBitBuffer->bitpos); // Mask the 8-bitPos upper bits, i.e. the bits to the left from the start of the shift
- aBitBuffer->data[aBitBuffer->bytePos-1] = aBitBuffer->currentBits & bitMask;
-
- bitMask = (1 << (8-aDiff+aBitBuffer->bitpos)) - 1; // The 8-diff+aBitBuf->bitpos lowest bits
- tempValue = aBitBuffer->data[aBitBuffer->bytePos] & bitMask;
-
- // Shift tempValue right by 8 - diff bits, resulting in bitpos lowest bits
- tempValue >>= (8 - aDiff);
-
- aBitBuffer->data[aBitBuffer->bytePos-1] |= tempValue;
- }
-
-
- // Start from the current byte, shift bits in each byte until the end
- for (i=aBitBuffer->bytePos; i<(aBitBuffer->dataLen-1); i++)
- {
-
- bitMask = 255 << (8 - aDiff); // Mask the 8-aDiff upper bits
- byteValue = aBitBuffer->data[i+1] & bitMask;
- byteValue >>= (8 - aDiff);
-
- tempValue = aBitBuffer->data[i];
- tempValue <<= aDiff;
-
- aBitBuffer->data[i] = byteValue | tempValue;
- }
-
- // Take care of the last byte separately, just shift to the left
- aBitBuffer->data[aBitBuffer->dataLen-1] <<= aDiff;
-
- // Update the currentBits value
- aBitBuffer->currentBits = aBitBuffer->data[aBitBuffer->bytePos-1];
-}
-
-
-// ShiftBufferLeftByOneByte
-// Shifts the bytes left in the bit buffer by one position starting from the current byte position.
-void ShiftBufferLeftByOneByte(bitbuffer_s *aBitBuffer)
-{
- TInt i;
- TUint8 byteValue;
- TUint8 bitMask;
-
-
- // For the current byte, take 8-bitpos upper bits from this byte and bitpos lowest bits from the next
- // byte (this is ok since we are shift at least 8 bits when this function is called)
- bitMask = 255 << (aBitBuffer->bitpos); // Mask the 8-bitPos upper bits
- aBitBuffer->data[aBitBuffer->bytePos] &= bitMask;
-
- bitMask = (1 << aBitBuffer->bitpos) - 1; // The aBitBuf->bitpos lowest bits
- byteValue = aBitBuffer->data[aBitBuffer->bytePos+1] & bitMask;
- aBitBuffer->data[aBitBuffer->bytePos] |= byteValue;
-
- // Start from the next byte position, and go through the whole buffer
- for (i=aBitBuffer->bytePos+1; i<(aBitBuffer->dataLen-1); i++)
- {
- // Copy the next byte to here
- aBitBuffer->data[i] = aBitBuffer->data[i+1];
- }
-
- // Adjust the bit buffer length
- aBitBuffer->dataLen--;
-}
-
-
-// ShiftBufferRightByOneByte
-// Shifts the bytes right in the bit buffer by one position starting from the current byte position.
-void ShiftBufferRightByOneByte(bitbuffer_s *aBitBuffer)
-{
- TInt i;
-
- // Start from the last byte position, and go through the whole buffer until the current byte position
- // Note: also the current byte can be shifted, since the bits that should not be shifted from that byte
- // will be written over by the new value coded later, thus no error will be there.
- for (i=aBitBuffer->dataLen-1; i>=aBitBuffer->bytePos; i--)
- {
- // Copy the next byte to here
- aBitBuffer->data[i] = aBitBuffer->data[i-1];
- }
-}
-
-
-// ShiftBufferRight
-// Shifts bits right in the input bit buffer by aDiff value, the bit buffer length is modified if required.
-void ShiftBufferRight(bitbuffer_s *aBitBuffer, TInt aDiff, TUint aTrailingBits, TUint aOldIdLength)
-{
- TInt i;
-
- if ( aDiff >= 8 )
- {
- TUint bytesToShift = aDiff / 8;
-
- // Add byte(s) to the bit buffer
- aBitBuffer->dataLen += bytesToShift;
-
- // Shift full bytes to right
- for (i=0; i<bytesToShift; i++)
- {
- ShiftBufferRightByOneByte(aBitBuffer);
- aDiff -= 8;
- }
-
- aDiff = aDiff % 8;
- }
-
- // If there are less trailing bits than we need to shift then we have to add one byte to the buffer
- if ( aTrailingBits < aDiff )
- {
- // Have to add byte to the SPS set
- aBitBuffer->dataLen += 1;
- }
-
- if (aDiff != 0)
- {
- // Shift the bits in the bit buffer to the right
- ShiftBitBufferBitsRight(aBitBuffer, aDiff);
- }
-
- // Adjust the bitbuffer bitpos value
- aBitBuffer->bitpos += aOldIdLength;
- if ( aBitBuffer->bitpos > 8 )
- {
- aBitBuffer->bitpos -= 8;
- aBitBuffer->bytePos--;
- }
-}
-
-
-// ShiftBufferLeft
-// Shifts bits left in the input bit buffer by aDiff value.
-void ShiftBufferLeft(bitbuffer_s *aBitBuffer, TInt aDiff, TUint aOldIdLength)
-{
- TInt i;
-
- if (aDiff >= 8)
- {
- // Shift full bytes to the left before shifting bits
- TUint bytesToShift = aDiff / 8;
-
- // First, adjust the byte position to be correct
- aBitBuffer->bytePos -= bytesToShift;
-
- for (i=0; i<bytesToShift; i++)
- {
- ShiftBufferLeftByOneByte(aBitBuffer);
- aDiff -= 8;
- }
- }
-
- // Adjust the bit position of the bit buffer
- aBitBuffer->bitpos += aOldIdLength;
- if ( aBitBuffer->bitpos > 8 )
- {
- aBitBuffer->bitpos -= 8;
- aBitBuffer->bytePos--;
-
- aBitBuffer->currentBits = aBitBuffer->data[aBitBuffer->bytePos-1];
- }
-
- if ( aDiff != 0 )
- {
- // Shift the bits in the bit buffer to the left
- ShiftBitBufferBitsLeft(aBitBuffer, aDiff);
- }
-
-}
-
-
-// psParsePPS
-// Parses the input PPS set, the PPS and SPS id's are modified if necessary
-// and the modified data is stored in codedPPSBuffer.
-TInt psParsePPS( bitbuffer_s *bitbuf, pic_parameter_set_s **ppsList, seq_parameter_set_s **spsList,
- TUint aFrameFromEncoder, TUint *aNumPPS )
-{
- pic_parameter_set_s *pps;
- TUint i, tmp;
- TInt len;
- TUint pic_parameter_set_id;
- TInt retCode;
- TUint pic_size_in_map_units_minus1;
- TUint newPPSId = 0;
- TUint possibleIdConflict = 0;
- TUint modifySPSId = 0;
- TUint bitPosit = 0;
- TUint bytePosit = 0;
- TInt bitSPSPosit = 0;
- TUint byteSPSPosit = 0;
- TUint useOnePPS = 0;
-
- // Parse pps id
- if ((retCode = ue_v(bitbuf, &pic_parameter_set_id, PS_MAX_NUM_OF_PPS-1)) < 0)
- return retCode;
-
- // Allocate memory for pps if not already allocated
- pps = ppsList[pic_parameter_set_id];
-
- if (!pps)
- {
- pps = (pic_parameter_set_s *) User::Alloc(sizeof(pic_parameter_set_s));
-
- if (pps == 0)
- {
- PRINT((_L("Error while allocating memory for PPS.\n")));
- return PS_ERR_MEM_ALLOC;
- }
-
- memset( pps, 0, sizeof(pic_parameter_set_s));
- ppsList[pic_parameter_set_id] = pps;
-
- (*aNumPPS)++;
- }
- else
- {
- // There might be a conflicting Id with an existing PPS set
- // Give the new SPS set the next free PPS Id
- possibleIdConflict = 1;
- useOnePPS = 1;
- newPPSId = 0;
-
- while (ppsList[newPPSId])
- {
- newPPSId++;
- }
-
- // Allocate memory for the PPS
- pps = (pic_parameter_set_s *) User::Alloc(sizeof(pic_parameter_set_s));
-
- if (pps == 0)
- {
- PRINT((_L("Error while allocating memory for PPS.\n")));
- return PS_ERR_MEM_ALLOC;
- }
-
- memset( pps, 0, sizeof(pic_parameter_set_s));
- pps->pic_parameter_set_id = newPPSId;
-
- // Store the position of the bit buffer
- bitPosit = bitbuf->bitpos;
- bytePosit = bitbuf->bytePos;
- }
-
-
- // Parse the rest of the picture parameter set syntax
- if ((retCode = ue_v( bitbuf, &pps->seq_parameter_set_id, PS_MAX_NUM_OF_SPS-1)) < 0)
- return retCode;
-
- // Check if the Id of the SPS that this PPS refers to has changed (and that
- // the frame originated form the encoder)
- if( spsList[pps->seq_parameter_set_id]->indexChanged)
- {
- if ( !aFrameFromEncoder )
- {
- if (pps->seq_parameter_set_id != spsList[pps->seq_parameter_set_id]->origSPSId)
- {
- // Indicate a changed SPS Id, perform the change at the end (when we know the size of the PPS set)
- modifySPSId = ETrue;
-
- // Store the position of the bit buffer
- bitSPSPosit = bitbuf->bitpos;
- byteSPSPosit = bitbuf->bytePos;
- }
- }
- else
- {
- // Indicate a changed SPS Id, perform the change at the end (when we know the size of the PPS set)
- modifySPSId = ETrue;
-
- // Store the position of the bit buffer
- bitSPSPosit = bitbuf->bitpos;
- byteSPSPosit = bitbuf->bytePos;
- }
- }
-
- // Fetch entropy coding mode. Mode is 0 for CAVLC and 1 for CABAC
- if ((retCode = u_n( bitbuf, 1, &pps->entropy_coding_mode_flag)) < 0)
- return retCode;
-
- // If this flag is 1, POC related syntax elements are present in slice header
- if ((retCode = u_n( bitbuf, 1, &pps->pic_order_present_flag)) < 0)
- return retCode;
-
- // Fetch the number of slice groups minus 1
- if ((retCode = ue_v( bitbuf, &pps->num_slice_groups_minus1, PS_MAX_NUM_SLICE_GROUPS-1)) < 0)
- return retCode;
-
- if(pps->num_slice_groups_minus1 > 0 )
- {
-
- if ((retCode = ue_v( bitbuf, &pps->slice_group_map_type, 6)) < 0)
- return retCode;
-
- switch (pps->slice_group_map_type)
- {
-
- case PS_SLICE_GROUP_MAP_TYPE_INTERLEAVED:
- for (i = 0; i <= pps->num_slice_groups_minus1; i++)
- {
- if ((retCode = ue_v( bitbuf, &pps->run_length_minus1[i], MAX_PIC_SIZE_IN_MBS-1 )) < 0)
- return retCode;
- }
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_DISPERSED:
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_FOREGROUND:
- for (i = 0; i < pps->num_slice_groups_minus1; i++)
- {
- // Fetch MB address of the top-left corner
- if ((retCode = ue_v( bitbuf, &pps->top_left[i], MAX_PIC_SIZE_IN_MBS-1)) < 0)
- return retCode;
- // Fetch MB address of the bottom-right corner (top-left address must
- // be smaller than or equal to bottom-right address)
- if ((retCode = ue_v( bitbuf, &pps->bottom_right[i], MAX_PIC_SIZE_IN_MBS-1)) < 0)
- return retCode;
-
- if (pps->top_left[i] > pps->bottom_right[i])
- return PS_ERR_ILLEGAL_VALUE;
- }
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_CHANGING_3:
- case PS_SLICE_GROUP_MAP_TYPE_CHANGING_4:
- case PS_SLICE_GROUP_MAP_TYPE_CHANGING_5:
- if ((retCode = u_n( bitbuf, 1, &pps->slice_group_change_direction_flag)) < 0)
- return retCode;
- if ((retCode = ue_v( bitbuf, &pps->slice_group_change_rate_minus1, MAX_PIC_SIZE_IN_MBS-1)) < 0)
- return retCode;
- break;
-
- case PS_SLICE_GROUP_MAP_TYPE_EXPLICIT:
-
- if ((retCode = ue_v( bitbuf, &pic_size_in_map_units_minus1, MAX_PIC_SIZE_IN_MBS-1 )) < 0)
- return retCode;
-
- // Allocate array for slice group ids if not already allocated
- if (pic_size_in_map_units_minus1 != pps->pic_size_in_map_units_minus1)
- {
- User::Free(pps->slice_group_id);
-
- pps->slice_group_id = (unsigned int *)User::Alloc( (pic_size_in_map_units_minus1+1) * sizeof(int));
-
- if (pps->slice_group_id == 0)
- return PS_ERR_MEM_ALLOC;
-
- pps->pic_size_in_map_units_minus1 = pic_size_in_map_units_minus1;
- }
-
- // Calculate len = ceil( Log2( num_slice_groups_minus1 + 1 ) )
- tmp = pps->num_slice_groups_minus1 + 1;
- tmp = tmp >> 1;
- for( len = 0; len < 16 && tmp != 0; len++ )
- tmp >>= 1;
-
- if ( (((unsigned)1)<<len) < (pps->num_slice_groups_minus1 + 1) )
- len++;
-
- for( i = 0; i <= pps->pic_size_in_map_units_minus1; i++ )
- {
- if ((retCode = u_n( bitbuf, len, &pps->slice_group_id[i])) < 0)
- return retCode;
- }
-
- break;
-
- default:
- // Cannnot happen
- break;
- }
- }
-
- if ((retCode = ue_v( bitbuf, &pps->num_ref_idx_l0_active_minus1, 31 )) < 0)
- return retCode;
-
- if ((retCode = ue_v( bitbuf, &pps->num_ref_idx_l1_active_minus1, 31 )) < 0)
- return retCode;
-
- if ((retCode = u_n( bitbuf, 1, &pps->weighted_pred_flag)) < 0)
- return retCode;
-
- if ((retCode = u_n( bitbuf, 2, &pps->weighted_bipred_idc)) < 0)
- return retCode;
-
- if (pps->weighted_bipred_idc > 2)
- return PS_ERR_ILLEGAL_VALUE;
-
- if ((retCode = se_v( bitbuf, &pps->pic_init_qp_minus26, -26, 25 )) < 0)
- return retCode;
-
- if ((retCode = se_v( bitbuf, &pps->pic_init_qs_minus26, -26, 25 )) < 0)
- return retCode;
-
- if ((retCode = se_v( bitbuf, &pps->chroma_qp_index_offset, -12, 12 )) < 0)
- return retCode;
-
- pps->chroma_qp_index_offset = clip(MIN_CHROMA_QP_INDEX, MAX_CHROMA_QP_INDEX, pps->chroma_qp_index_offset);
-
- if ((retCode = u_n( bitbuf, 1, &pps->deblocking_filter_parameters_present_flag )) < 0)
- return retCode;
-
- if ((retCode = u_n( bitbuf, 1, &pps->constrained_intra_pred_flag )) < 0)
- return retCode;
-
- if ((retCode = u_n( bitbuf, 1, &pps->redundant_pic_cnt_present_flag )) < 0)
- return retCode;
-
- if (bibSkipTrailingBits(bitbuf) < 0)
- return PS_ERROR;
-
- // Store the size of the PPS set
- pps->PPSlength = bitbuf->bytePos;
-
- syncBitBufferBitpos(bitbuf);
-
- // If we had a possible conflict, compare the PPS sets with the same id to see if only one PPS set can be used.
- if (possibleIdConflict)
- {
- useOnePPS = ComparePPSSets(ppsList[pic_parameter_set_id],pps);
-
- if (!useOnePPS)
- {
- TUint trailingBits = GetNumTrailingBits(bitbuf);
- TInt diff = 0;
- TUint oldPPSId = pic_parameter_set_id;
- TUint oldIdLength = ReturnUnsignedExpGolombCodeLength(oldPPSId);
- TUint newIdLength = ReturnUnsignedExpGolombCodeLength(newPPSId);
-
- for (i=0; i<PS_MAX_NUM_OF_PPS; i++)
- {
- // Compared if a previously stored PPS might be used
- if (ppsList[i])
- useOnePPS = ComparePPSSets(ppsList[i],pps);
-
- if (useOnePPS)
- {
- // Check also that the SPS id's match
- if ( modifySPSId )
- {
- if (spsList[pps->seq_parameter_set_id]->newSPSId != ppsList[i]->seq_parameter_set_id)
- useOnePPS = 0;
- else
- {
- // We can use this previously generated PPSId here also
- newPPSId = i;
- break;
- }
- }
- else
- {
- if (pps->seq_parameter_set_id != ppsList[i]->seq_parameter_set_id)
- useOnePPS = 0;
- else
- {
- // We can use this previously generated PPSId here also
- newPPSId = i;
- break;
- }
- }
- }
- }
-
- if ( newPPSId > PS_MAX_NUM_OF_PPS )
- {
- // We have reached maximum number of PPS, return an error
- return PS_ERROR;
- }
-
- (*aNumPPS)++;
-
- // Set indexChanged to true and give the new index to old PPS, so that (new) slices can refer to the new PPS
- ppsList[pic_parameter_set_id]->indexChanged = 1;
- ppsList[pic_parameter_set_id]->newPPSId = newPPSId; // The new Id
-
- if (aFrameFromEncoder)
- ppsList[pic_parameter_set_id]->encPPSId = newPPSId; // The new Id
- else
- ppsList[pic_parameter_set_id]->origPPSId = newPPSId; // The new Id
-
- // Store the new PPS at the new index, unless we are using a previously stored PPS
- if (!ppsList[newPPSId])
- ppsList[newPPSId] = pps;
-
- // Restore the bit buffer position at the PPS Id
- bitbuf->bitpos = bitPosit;
- bitbuf->bytePos = bytePosit;
-
- if(trailingBits > 8)
- {
- trailingBits = 8;
- }
-
- if ( oldIdLength == newIdLength )
- {
- // Just encode the new Id on top of the old Id
- bitbuf->bitpos += oldIdLength;
- if (bitbuf->bitpos > 8)
- {
- // Go to the right byte and bit position
- bitbuf->bytePos -= bitbuf->bitpos / 8;
- bitbuf->bitpos = bitbuf->bitpos % 8;
- }
-
- EncodeUnsignedExpGolombCode(bitbuf, newPPSId);
- }
- else if ( oldIdLength < newIdLength )
- {
- diff = newIdLength - oldIdLength;
-
- // Adjust the PPS length
- if (diff >= 8)
- {
- // Add as many extra bytes as is required
- pps->PPSlength += (diff / 8);
- }
-
- if ( trailingBits < (diff % 8) )
- {
- // Add one byte since there aren't enough trailing bits for the extra bits
- pps->PPSlength += 1;
- }
-
- ShiftBufferRight(bitbuf, diff, trailingBits, oldIdLength);
-
- // After shifting, encode the new value to the bit buffer
- EncodeUnsignedExpGolombCode(bitbuf, newPPSId);
- }
- else
- {
- // New id's length is smaller than old id's length
- diff = oldIdLength - newIdLength;
-
- if (diff >= 8)
- {
- // Adjust the PPS length
- pps->PPSlength -= (diff / 8);
- }
-
- ShiftBufferLeft(bitbuf, diff, oldIdLength);
-
- // After shifting, encode the new value to the bit buffer
- EncodeUnsignedExpGolombCode(bitbuf, newPPSId);
- }
-
- // Store the position of the bit buffer for possible SPS id modification
- // The right bit position is the current minus the size of the SPS id length
- bitSPSPosit = bitbuf->bitpos - ReturnUnsignedExpGolombCodeLength(pps->seq_parameter_set_id);
- byteSPSPosit = bitbuf->bytePos;
-
- if(bitSPSPosit < 1)
- {
- byteSPSPosit++;
- bitSPSPosit += 8;
- }
- }
- else
- {
- // In case the index was changed for some earlier PPS,
- // reset the index changed value back to zero
- ppsList[pic_parameter_set_id]->indexChanged = 0;
- }
- }
-
- if ( modifySPSId )
- {
- TUint trailingBits = GetNumTrailingBits(bitbuf);
- TInt diff = 0;
-
- TUint oldSPSId = pps->seq_parameter_set_id;
- TUint newSPSId = spsList[pps->seq_parameter_set_id]->newSPSId;
-
- TUint oldIdLength = ReturnUnsignedExpGolombCodeLength(oldSPSId);
- TUint newIdLength = ReturnUnsignedExpGolombCodeLength(newSPSId);
-
-
- // Restore the bit buffer position at the SPS Id
- bitbuf->bitpos = bitSPSPosit;
- bitbuf->bytePos = byteSPSPosit;
-
- if(trailingBits > 8)
- {
- trailingBits = 8;
- }
-
- if ( oldIdLength == newIdLength )
- {
- // Just encode the new Id on top of the old Id
- bitbuf->bitpos += oldIdLength;
- if(bitbuf->bitpos > 8)
- {
- // Go to the right byte and bit position
- bitbuf->bytePos -= bitbuf->bitpos / 8;
- bitbuf->bitpos = bitbuf->bitpos % 8;
- }
-
- EncodeUnsignedExpGolombCode(bitbuf, newSPSId);
- }
- else if ( oldIdLength < newIdLength )
- {
- diff = newIdLength - oldIdLength;
-
- // Adjust the PPS length
- if (diff >= 8)
- {
- // Add as many extra bytes as is required
- pps->PPSlength += (diff / 8);
- }
-
- if ( trailingBits < (diff % 8) )
- {
- // Add one byte since there aren't enough trailing bits for the extra bits
- pps->PPSlength += 1;
- }
-
- ShiftBufferRight(bitbuf, diff, trailingBits, oldIdLength);
-
- // After shifting, encode the new value to the bit buffer
- EncodeUnsignedExpGolombCode(bitbuf, newSPSId);
-
- }
- else
- {
- // New id's length is smaller than old id's length
- diff = oldIdLength - newIdLength;
-
- if (diff >= 8)
- {
- // Adjust the PPS length
- pps->PPSlength -= (diff / 8);
- }
-
- ShiftBufferLeft(bitbuf, diff, oldIdLength);
-
- // After shifting, encode the new value to the bit buffer
- EncodeUnsignedExpGolombCode(bitbuf, newSPSId);
- }
-
- // Modify the SPS id in the pps
- pps->seq_parameter_set_id = newSPSId;
- }
-
- if ( IsPPSSupported(pps) == KErrNotSupported )
- return KErrNotSupported;
-
-
- // Allocate memory for the encoded PPS data in case we have a new PPS (i.e. a new original PPS or a PPS with a new index)
- if ( !useOnePPS )
- {
- // Store the buffer containing the PPS set in order to later pass it to the 3gpmp4library
- pps->codedPPSBuffer = (TUint8*) User::Alloc(pps->PPSlength);
-
- if (pps->codedPPSBuffer == 0)
- return PS_ERR_MEM_ALLOC;
-
- for (i=0; i<pps->PPSlength; i++)
- {
- pps->codedPPSBuffer[i] = bitbuf->data[i];
- }
- }
- else if (possibleIdConflict)
- {
- // In case of conflicting id and one PPS, free the PPS allocated here
- User::Free(pps);
- }
-
- return PS_OK;
-}
-
-#endif // VIDEOEDITORENGINE_AVC_EDITING
-