static void c_output(const char *infile, const char *define, int extend, const char *outfile) { definition *def; char *include; const char *outfilename; long tell; c_initialize(); open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); add_warning(); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); /* .h file already contains rpc/rpc.h */ } else f_print(fout, "#include <rpc/rpc.h>\n"); tell = ftell(fout); while ( (def = get_definition()) ) emit(def); if (extend && tell == ftell(fout)) unlink(outfilename); }
static void check_lag_in_frames_realtime_deadline( int lag_in_frames, int deadline, struct WarningList *warning_list) { if (deadline == VPX_DL_REALTIME && lag_in_frames != 0) add_warning(lag_in_frames_with_realtime, warning_list); }
/* * generate the dispatch table */ static void t_output (char *infile, char *define, int extend, char *outfile) { definition *def; int foundprogram = 0; char *outfilename; char *incfile; open_input (infile, define); outfilename = extend ? extendfile (infile, outfile) : outfile; incfile = extendfile (infile, ".h"); open_output (infile, outfilename); add_warning (); f_print (fout, "#include \"%s\"\n", incfile); while ((def = get_definition ())) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { (void) unlink (outfilename); return; } write_tables (); }
/** * on this pass we direct the graph to point to the right nodes * */ void TrexStreamsCompiler::direct_pass(GraphNodeMap *nodes) { /* second pass - direct the graph */ for (auto p : nodes->get_nodes()) { GraphNode *node = p.second; const TrexStream *stream = node->m_stream; /* check the stream points on an existing stream */ GraphNode *next_node = nodes->get(stream->m_next_stream_id); if (!next_node) { std::stringstream ss; ss << "stream " << node->get_stream_id() << " is pointing on non existent stream " << stream->m_next_stream_id; err(ss.str()); } node->m_next = next_node; /* do we have more than one parent ? */ next_node->m_parents.push_back(node); } /* check for multiple parents */ for (auto p : nodes->get_nodes()) { GraphNode *node = p.second; if (node->m_parents.size() > 0 ) { std::stringstream ss; ss << "stream " << node->get_stream_id() << " is triggered by multiple streams: "; for (auto x : node->m_parents) { ss << x->get_stream_id() << " "; } add_warning(ss.str()); } } }
de265_error de265_decode_NAL(de265_decoder_context* de265ctx, rbsp_buffer* data) { decoder_context* ctx = (decoder_context*)de265ctx; /* if (ctx->num_skipped_bytes>0) { printf("skipped bytes:\n "); for (int i=0;i<ctx->num_skipped_bytes;i++) printf("%d ",ctx->skipped_bytes[i]); printf("\n"); } */ de265_error err = DE265_OK; bitreader reader; bitreader_init(&reader, data); nal_header nal_hdr; nal_read_header(&reader, &nal_hdr); process_nal_hdr(ctx, &nal_hdr); logdebug(LogHighlevel,"NAL: 0x%x 0x%x - %d %d\n", data->data[0], data->data[1], nal_hdr.nal_unit_type, nal_hdr.nuh_temporal_id); if (nal_hdr.nal_unit_type<32) { logdebug(LogHeaders,"---> read slice segment header\n"); int sliceIndex = get_next_slice_index(ctx); slice_segment_header* hdr = &ctx->slice[sliceIndex]; hdr->slice_index = sliceIndex; read_slice_segment_header(&reader,hdr,ctx); dump_slice_segment_header(hdr, ctx); if ((err = process_slice_segment_header(ctx, hdr)) != DE265_OK) { return err; } skip_bits(&reader,1); // TODO: why? prepare_for_CABAC(&reader); // modify entry_point_offsets int headerLength = reader.data - data->data; for (int i=0;i<ctx->num_skipped_bytes;i++) { ctx->skipped_bytes[i] -= headerLength; } for (int i=0;i<hdr->num_entry_point_offsets;i++) { for (int k=ctx->num_skipped_bytes-1;k>=0;k--) if (ctx->skipped_bytes[k] <= hdr->entry_point_offset[i]) { hdr->entry_point_offset[i] -= k+1; break; } } int nRows = hdr->num_entry_point_offsets +1; bool use_WPP = (ctx->num_worker_threads > 0 && ctx->current_pps->entropy_coding_sync_enabled_flag); if (ctx->num_worker_threads > 0 && ctx->current_pps->entropy_coding_sync_enabled_flag == false) { add_warning(ctx, DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING, true); } if (!use_WPP) { init_thread_context(&hdr->thread_context[0]); init_CABAC_decoder(&hdr->thread_context[0].cabac_decoder, reader.data, reader.bytes_remaining); hdr->thread_context[0].shdr = hdr; hdr->thread_context[0].decctx = ctx; // fixed context 0 if ((err=read_slice_segment_data(ctx, &hdr->thread_context[0])) != DE265_OK) { return err; } } else { for (int i=0;i<nRows;i++) { int dataStartIndex; if (i==0) { dataStartIndex=0; } else { dataStartIndex=hdr->entry_point_offset[i-1]; } int dataEnd; if (i==nRows-1) dataEnd = reader.bytes_remaining; else dataEnd = hdr->entry_point_offset[i]; init_thread_context(&hdr->thread_context[i]); init_CABAC_decoder(&hdr->thread_context[i].cabac_decoder, &reader.data[dataStartIndex], dataEnd-dataStartIndex); hdr->thread_context[i].shdr = hdr; hdr->thread_context[i].decctx = ctx; } // TODO: hard-coded thread context add_CTB_decode_task_syntax(&hdr->thread_context[0], 0,0 ,0,0, NULL); /* for (int x=0;x<ctx->current_sps->PicWidthInCtbsY;x++) for (int y=0;y<ctx->current_sps->PicHeightInCtbsY;y++) { add_CTB_decode_task_syntax(&hdr->thread_context[y], x,y); } */ flush_thread_pool(&ctx->thread_pool); } } else switch (nal_hdr.nal_unit_type) { case NAL_UNIT_VPS_NUT: { logdebug(LogHeaders,"---> read VPS\n"); video_parameter_set vps; read_vps(&reader,&vps); dump_vps(&vps); process_vps(ctx, &vps); } break; case NAL_UNIT_SPS_NUT: { logdebug(LogHeaders,"----> read SPS\n"); seq_parameter_set sps; if ((err=read_sps(&reader,&sps, &ctx->ref_pic_sets)) != DE265_OK) { break; } dump_sps(&sps, ctx->ref_pic_sets); process_sps(ctx, &sps); } break; case NAL_UNIT_PPS_NUT: { logdebug(LogHeaders,"----> read PPS\n"); pic_parameter_set pps; init_pps(&pps); read_pps(&reader,&pps,ctx); dump_pps(&pps); process_pps(ctx,&pps); } break; case NAL_UNIT_PREFIX_SEI_NUT: case NAL_UNIT_SUFFIX_SEI_NUT: logdebug(LogHeaders,"----> read SEI\n"); sei_message sei; push_current_picture_to_output_queue(ctx); read_sei(&reader,&sei, nal_hdr.nal_unit_type==NAL_UNIT_SUFFIX_SEI_NUT, ctx); dump_sei(&sei, ctx); err = process_sei(&sei, ctx); break; } return err; }
static void h_output (char *infile, char *define, int extend, char *outfile) { definition *def; char *outfilename; long tell; char *guard; list *l; open_input (infile, define); outfilename = extend ? extendfile (infile, outfile) : outfile; open_output (infile, outfilename); add_warning (); guard = generate_guard (outfilename ? outfilename : infile); f_print (fout, "#ifndef _%s\n#define _%s\n\n", guard, guard); #if 0 f_print (fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION); f_print (fout, "#include <rpc/rpc.h>\n\n"); #else f_print (fout, "#include \"%s\"\n\n", incfile); #endif #if 0 f_print (fout, "#ifdef __cplusplus\n" "\n" "#ifndef EXTERN\n" "#define EXTERN extern \"C\" \n" "#define EXTERN_DEFINED_BY_%s\n" "#endif /* !EXTERN */\n" "#ifndef UNION_NAME\n" "#define UNION_NAME(name) u\n" "#define UNION_NAME_DEFINED_BY_%s 1\n" "#endif /* !UNION_NAME */\n" "#ifndef CONSTRUCT\n" "#define CONSTRUCT(Type, type) \\\n" "struct Type : public type { \\\n" " Type () { bzero ((type *) this, sizeof (type)); } \\\n" " ~Type () { xdr_free ((xdrproc_t) xdr_ ## type, \\\n" " (char *) (type *) this); } \\\n" "};\n" "#define CONSTRUCT_DEFINED_BY_%s\n" "#endif /* !CONSTRUCT */\n" "\n" "#else /* !__cplusplus */\n" "\n" "#ifndef EXTERN\n" "#define EXTERN extern\n" "#define EXTERN_DEFINED_BY_%s\n" "#endif /* !EXTERN */\n" "#ifndef UNION_NAME\n" "#define UNION_NAME(name) u\n" "#define UNION_NAME_DEFINED_BY_%s 1\n" "#endif /* !UNION_NAME */\n" "#ifndef CONSTRUCT\n" "#define CONSTRUCT(Type, type)\n" "#define CONSTRUCT_DEFINED_BY_%s\n" "#endif /* !CONSTRUCT */\n" "\n" "#endif /* !__cplusplus */\n", guard, guard, guard, guard, guard, guard); #endif tell = ftell (fout); /* print data definitions */ while ((def = get_definition ())) { print_datadef (def); } /* print function declarations. Do this after data definitions because they might be used as arguments for functions */ for (l = defined; l != NULL; l = l->next) { print_funcdef (l->val); } if (extend && tell == ftell (fout)) { (void) unlink (outfilename); } #if 0 f_print (fout, "\n#ifdef __cplusplus\n" "}\n" "#endif /* __cplusplus */\n"); #endif f_print (fout, "\n"); #if 0 f_print (fout, "#ifdef EXTERN_DEFINED_BY_%s\n" "#undef EXTERN\n" "#undef EXTERN_DEFINED_BY_%s\n" "#endif /* EXTERN_DEFINED_BY_%s */\n" "#ifdef UNION_NAME_DEFINED_BY_%s\n" "#undef UNION_NAME\n" "#undef UNION_NAME_DEFINED_BY_%s\n" "#endif /* UNION_NAME_DEFINED_BY_%s */\n" "#ifdef CONSTRUCT_DEFINED_BY_%s\n" "#undef CONSTRUCT\n" "#undef CONSTRUCT_DEFINED_BY_%s\n" "#endif /* CONSTRUCT_DEFINED_BY_%s */\n", guard, guard, guard, guard, guard, guard, guard, guard, guard); #endif f_print (fout, "\n#endif /* !_%s */\n", guard); }
de265_error de265_decode_NAL(de265_decoder_context* de265ctx, NAL_unit* nal) { decoder_context* ctx = (decoder_context*)de265ctx; rbsp_buffer* data = &nal->nal_data; de265_error err = DE265_OK; bitreader reader; bitreader_init(&reader, data); nal_header nal_hdr; nal_read_header(&reader, &nal_hdr); process_nal_hdr(ctx, &nal_hdr); loginfo(LogHighlevel,"NAL: 0x%x 0x%x - unit type:%s temporal id:%d\n", data->data[0], data->data[1], get_NAL_name(nal_hdr.nal_unit_type), nal_hdr.nuh_temporal_id); if (nal_hdr.nal_unit_type<32) { logdebug(LogHeaders,"---> read slice segment header\n"); //printf("-------- slice header --------\n"); int sliceIndex = get_next_slice_index(ctx); if (sliceIndex<0) { add_warning(ctx,DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED, true); return DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED; } slice_segment_header* hdr = &ctx->slice[sliceIndex]; bool continueDecoding; err = read_slice_segment_header(&reader,hdr,ctx, &continueDecoding); if (!continueDecoding) { return err; } else { hdr->slice_index = sliceIndex; if (ctx->param_slice_headers_fd>=0) { dump_slice_segment_header(hdr, ctx, ctx->param_slice_headers_fd); } if (process_slice_segment_header(ctx, hdr, &err, nal->pts, nal->user_data) == false) { ctx->img->integrity = INTEGRITY_NOT_DECODED; return err; } skip_bits(&reader,1); // TODO: why? prepare_for_CABAC(&reader); // modify entry_point_offsets int headerLength = reader.data - data->data; for (int i=0;i<nal->num_skipped_bytes;i++) { nal->skipped_bytes[i] -= headerLength; } for (int i=0;i<hdr->num_entry_point_offsets;i++) { for (int k=nal->num_skipped_bytes-1;k>=0;k--) if (nal->skipped_bytes[k] <= hdr->entry_point_offset[i]) { hdr->entry_point_offset[i] -= k+1; break; } } const pic_parameter_set* pps = ctx->current_pps; int ctbsWidth = ctx->current_sps->PicWidthInCtbsY; int nRows = hdr->num_entry_point_offsets +1; bool use_WPP = (ctx->num_worker_threads > 0 && ctx->current_pps->entropy_coding_sync_enabled_flag); bool use_tiles = (ctx->num_worker_threads > 0 && ctx->current_pps->tiles_enabled_flag); if (use_WPP && use_tiles) { //add_warning(ctx, DE265_WARNING_STREAMS_APPLIES_TILES_AND_WPP, true); } if (ctx->num_worker_threads > 0 && ctx->current_pps->entropy_coding_sync_enabled_flag == false && ctx->current_pps->tiles_enabled_flag == false) { // TODO: new error should be: no WPP and no Tiles ... add_warning(ctx, DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING, true); } if (!use_WPP && !use_tiles) { // --- single threaded decoding --- #if 0 int thread_context_idx = get_next_thread_context_index(ctx); if (thread_context_idx<0) { assert(false); // TODO } #else int thread_context_idx=0; #endif thread_context* tctx = &ctx->thread_context[thread_context_idx]; init_thread_context(tctx); init_CABAC_decoder(&tctx->cabac_decoder, reader.data, reader.bytes_remaining); tctx->shdr = hdr; tctx->decctx = ctx; tctx->CtbAddrInTS = pps->CtbAddrRStoTS[hdr->slice_segment_address]; // fixed context 0 if ((err=read_slice_segment_data(ctx, tctx)) != DE265_OK) { return err; } } else if (use_tiles && !use_WPP) { int nTiles = nRows; // TODO: rename 'nRows' if (nTiles > MAX_THREAD_CONTEXTS) { return DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED; } assert(nTiles == pps->num_tile_columns * pps->num_tile_rows); // TODO: handle other cases assert(ctx->img->tasks_pending == 0); increase_pending_tasks(ctx->img, nTiles); for (int ty=0;ty<pps->num_tile_rows;ty++) for (int tx=0;tx<pps->num_tile_columns;tx++) { int tile = tx + ty*pps->num_tile_columns; // set thread context ctx->thread_context[tile].shdr = hdr; ctx->thread_context[tile].decctx = ctx; ctx->thread_context[tile].CtbAddrInTS = pps->CtbAddrRStoTS[pps->colBd[tx] + pps->rowBd[ty]*ctbsWidth]; // init CABAC int dataStartIndex; if (tile==0) { dataStartIndex=0; } else { dataStartIndex=hdr->entry_point_offset[tile-1]; } int dataEnd; if (tile==nRows-1) dataEnd = reader.bytes_remaining; else dataEnd = hdr->entry_point_offset[tile]; init_thread_context(&ctx->thread_context[tile]); init_CABAC_decoder(&ctx->thread_context[tile].cabac_decoder, &reader.data[dataStartIndex], dataEnd-dataStartIndex); } // add tasks for (int i=0;i<nTiles;i++) { add_task_decode_slice_segment(ctx, i); } wait_for_completion(ctx->img); } else { if (nRows > MAX_THREAD_CONTEXTS) { return DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED; } assert(ctx->img->tasks_pending == 0); increase_pending_tasks(ctx->img, nRows); //printf("-------- decode --------\n"); for (int y=0;y<nRows;y++) { // set thread context for (int x=0;x<ctbsWidth;x++) { ctx->img->ctb_info[x+y*ctbsWidth].thread_context_id = y; // TODO: shouldn't be hardcoded } ctx->thread_context[y].shdr = hdr; ctx->thread_context[y].decctx = ctx; ctx->thread_context[y].CtbAddrInTS = pps->CtbAddrRStoTS[0 + y*ctbsWidth]; // init CABAC int dataStartIndex; if (y==0) { dataStartIndex=0; } else { dataStartIndex=hdr->entry_point_offset[y-1]; } int dataEnd; if (y==nRows-1) dataEnd = reader.bytes_remaining; else dataEnd = hdr->entry_point_offset[y]; init_thread_context(&ctx->thread_context[y]); init_CABAC_decoder(&ctx->thread_context[y].cabac_decoder, &reader.data[dataStartIndex], dataEnd-dataStartIndex); } // add tasks for (int y=0;y<nRows;y++) { add_task_decode_CTB_row(ctx, y, y==0); } wait_for_completion(ctx->img); } } } else switch (nal_hdr.nal_unit_type) { case NAL_UNIT_VPS_NUT: { logdebug(LogHeaders,"---> read VPS\n"); video_parameter_set vps; err=read_vps(ctx,&reader,&vps); if (err != DE265_OK) { break; } if (ctx->param_vps_headers_fd>=0) { dump_vps(&vps, ctx->param_vps_headers_fd); } process_vps(ctx, &vps); } break; case NAL_UNIT_SPS_NUT: { logdebug(LogHeaders,"----> read SPS\n"); seq_parameter_set sps; init_sps(&sps); if ((err=read_sps(ctx, &reader,&sps)) != DE265_OK) { break; } if (ctx->param_sps_headers_fd>=0) { dump_sps(&sps, ctx->param_sps_headers_fd); } process_sps(ctx, &sps); } break; case NAL_UNIT_PPS_NUT: { logdebug(LogHeaders,"----> read PPS\n"); pic_parameter_set pps; init_pps(&pps); bool success = read_pps(&reader,&pps,ctx); if (ctx->param_pps_headers_fd>=0) { dump_pps(&pps, ctx->param_pps_headers_fd); } if (success) { process_pps(ctx,&pps); } } break; case NAL_UNIT_PREFIX_SEI_NUT: case NAL_UNIT_SUFFIX_SEI_NUT: logdebug(LogHeaders,"----> read SEI\n"); sei_message sei; push_current_picture_to_output_queue(ctx); if (read_sei(&reader,&sei, nal_hdr.nal_unit_type==NAL_UNIT_SUFFIX_SEI_NUT, ctx)) { dump_sei(&sei, ctx); err = process_sei(&sei, ctx); } break; case NAL_UNIT_EOS_NUT: ctx->FirstAfterEndOfSequenceNAL = true; break; } return err; }
/* A ref-pic-set is coded either coded - as a list of the relative POC deltas themselves, or - by shifting an existing ref-pic-set by some number of frames When shifting an existing set, the frame 0 is also shifted as an additional reference frame. When coding the ref-pic-sets in the SPS, predicition is always from the previous set. In the slice header, the ref-pic-set can use any previous set as reference. */ bool read_short_term_ref_pic_set(decoder_context* ctx, const seq_parameter_set* sps, bitreader* br, ref_pic_set* out_set, // where to store the read set int idxRps, // index of the set to be read const ref_pic_set* sets, // previously read sets bool sliceRefPicSet) // is this in the slice header? { // --- is this set coded in prediction mode (not possible for the first set) char inter_ref_pic_set_prediction_flag; if (idxRps != 0) { inter_ref_pic_set_prediction_flag = get_bits(br,1); } else { inter_ref_pic_set_prediction_flag = 0; } if (inter_ref_pic_set_prediction_flag) { int vlc; /* Only for the last ref_pic_set (that's the one coded in the slice header), we can specify relative to which reference set we code the set. */ int delta_idx; if (sliceRefPicSet) { // idxRps == num_short_term_ref_pic_sets) { delta_idx = vlc = get_uvlc(br); delta_idx++; } else { delta_idx = 1; } int RIdx = idxRps - delta_idx; // this is our source set, which we will modify assert(RIdx>=0); int delta_rps_sign = get_bits(br,1); int abs_delta_rps = vlc = get_uvlc(br); abs_delta_rps++; int DeltaRPS = (delta_rps_sign ? -abs_delta_rps : abs_delta_rps); // bits are stored in this order: // - all bits for negative Pocs (forward), // - then all bits for positive Pocs (forward), // - then bits for '0', shifting of the current picture // in total, these are 'nDeltaPocsRIdx'+1 bits logtrace(LogHeaders,"predicted from %d with delta %d\n",RIdx,DeltaRPS); int nDeltaPocsRIdx= sets[RIdx].NumDeltaPocs; // size of source set char *const used_by_curr_pic_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char)); char *const use_delta_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char)); for (int j=0;j<=nDeltaPocsRIdx;j++) { used_by_curr_pic_flag[j] = get_bits(br,1); if (used_by_curr_pic_flag[j]) { use_delta_flag[j] = 1; // if this frame is used, we also have to apply the delta } else { use_delta_flag[j] = get_bits(br,1); // otherwise, it is only optionally included } } logtrace(LogHeaders,"flags: "); for (int j=0;j<=nDeltaPocsRIdx;j++) { logtrace(LogHeaders,"%d ", use_delta_flag[j]); } logtrace(LogHeaders,"\n"); int nNegativeRIdx = sets[RIdx].NumNegativePics; int nPositiveRIdx = sets[RIdx].NumPositivePics; // --- update list 0 (negative Poc) --- // Iterate through all Pocs in decreasing value order (positive reverse, 0, negative forward). int i=0; // target index // positive list for (int j=nPositiveRIdx-1;j>=0;j--) { int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS; // new delta if (dPoc<0 && use_delta_flag[nNegativeRIdx+j]) { out_set->DeltaPocS0[i] = dPoc; out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[nNegativeRIdx+j]; i++; } } // frame 0 if (DeltaRPS<0 && use_delta_flag[nDeltaPocsRIdx]) { out_set->DeltaPocS0[i] = DeltaRPS; out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[nDeltaPocsRIdx]; i++; } // negative list for (int j=0;j<nNegativeRIdx;j++) { int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS; if (dPoc<0 && use_delta_flag[j]) { out_set->DeltaPocS0[i] = dPoc; out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[j]; i++; } } out_set->NumNegativePics = i; // --- update list 1 (positive Poc) --- // Iterate through all Pocs in increasing value order (negative reverse, 0, positive forward) i=0; // target index // negative list for (int j=nNegativeRIdx-1;j>=0;j--) { int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS; if (dPoc>0 && use_delta_flag[j]) { out_set->DeltaPocS1[i] = dPoc; out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[j]; i++; } } // frame 0 if (DeltaRPS>0 && use_delta_flag[nDeltaPocsRIdx]) { out_set->DeltaPocS1[i] = DeltaRPS; out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[nDeltaPocsRIdx]; i++; } // positive list for (int j=0;j<nPositiveRIdx;j++) { int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS; if (dPoc>0 && use_delta_flag[nNegativeRIdx+j]) { out_set->DeltaPocS1[i] = dPoc; out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[nNegativeRIdx+j]; i++; } } out_set->NumPositivePics = i; out_set->NumDeltaPocs = out_set->NumNegativePics + out_set->NumPositivePics; } else { // --- first, read the number of past and future frames in this set --- int num_negative_pics = get_uvlc(br); int num_positive_pics = get_uvlc(br); // total number of reference pictures may not exceed buffer capacity if (num_negative_pics + num_positive_pics > sps->sps_max_dec_pic_buffering[ sps->sps_max_sub_layers-1 ]) { add_warning(ctx, DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED, false); return false; } out_set->NumNegativePics = num_negative_pics; out_set->NumPositivePics = num_positive_pics; out_set->NumDeltaPocs = num_positive_pics + num_negative_pics; // --- now, read the deltas between the reference frames to fill the lists --- // past frames int lastPocS=0; for (int i=0;i<num_negative_pics;i++) { int delta_poc_s0 = get_uvlc(br)+1; char used_by_curr_pic_s0_flag = get_bits(br,1); out_set->DeltaPocS0[i] = lastPocS - delta_poc_s0; out_set->UsedByCurrPicS0[i] = used_by_curr_pic_s0_flag; lastPocS = out_set->DeltaPocS0[i]; } // future frames lastPocS=0; for (int i=0;i<num_positive_pics;i++) { int delta_poc_s1 = get_uvlc(br)+1; char used_by_curr_pic_s1_flag = get_bits(br,1); out_set->DeltaPocS1[i] = lastPocS + delta_poc_s1; out_set->UsedByCurrPicS1[i] = used_by_curr_pic_s1_flag; lastPocS = out_set->DeltaPocS1[i]; } } compute_NumPoc(out_set); return true; }
static void check_quantizer(int min_q, int max_q, struct WarningList *warning_list) { const int lossless = min_q == 0 && max_q == 0; if (!lossless && (min_q == max_q || abs(max_q - min_q) < 8)) add_warning(quantizer_warning_string, warning_list); }
de265_error read_sps(decoder_context* ctx, bitreader* br, seq_parameter_set* sps, ref_pic_set** ref_pic_sets) { sps->video_parameter_set_id = get_bits(br,4); sps->sps_max_sub_layers = get_bits(br,3) +1; if (sps->sps_max_sub_layers>7) { return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; } sps->sps_temporal_id_nesting_flag = get_bits(br,1); read_profile_tier_level(br,&sps->profile_tier_level, sps->sps_max_sub_layers); sps->seq_parameter_set_id = get_uvlc(br); // --- decode chroma type --- sps->chroma_format_idc = get_uvlc(br); if (sps->chroma_format_idc == 3) { sps->separate_colour_plane_flag = get_bits(br,1); } else { sps->separate_colour_plane_flag = 0; } if (sps->separate_colour_plane_flag) { sps->ChromaArrayType = 0; } else { sps->ChromaArrayType = sps->chroma_format_idc; } sps->SubWidthC = SubWidthC [sps->chroma_format_idc]; sps->SubHeightC = SubHeightC[sps->chroma_format_idc]; // --- picture size --- sps->pic_width_in_luma_samples = get_uvlc(br); sps->pic_height_in_luma_samples = get_uvlc(br); sps->conformance_window_flag = get_bits(br,1); if (sps->conformance_window_flag) { sps->conf_win_left_offset = get_uvlc(br); sps->conf_win_right_offset = get_uvlc(br); sps->conf_win_top_offset = get_uvlc(br); sps->conf_win_bottom_offset= get_uvlc(br); } else { sps->conf_win_left_offset = 0; sps->conf_win_right_offset = 0; sps->conf_win_top_offset = 0; sps->conf_win_bottom_offset= 0; } if (sps->ChromaArrayType==0) { sps->WinUnitX = 1; sps->WinUnitY = 1; } else { sps->WinUnitX = SubWidthC[sps->chroma_format_idc]; sps->WinUnitY = SubHeightC[sps->chroma_format_idc]; } sps->bit_depth_luma = get_uvlc(br) +8; sps->bit_depth_chroma = get_uvlc(br) +8; sps->log2_max_pic_order_cnt_lsb = get_uvlc(br) +4; sps->MaxPicOrderCntLsb = 1<<(sps->log2_max_pic_order_cnt_lsb); // --- sub_layer_ordering_info --- sps->sps_sub_layer_ordering_info_present_flag = get_bits(br,1); int firstLayer = (sps->sps_sub_layer_ordering_info_present_flag ? 0 : sps->sps_max_sub_layers-1 ); for (int i=firstLayer ; i <= sps->sps_max_sub_layers-1; i++ ) { sps->sps_max_dec_pic_buffering[i] = get_uvlc(br); sps->sps_max_num_reorder_pics[i] = get_uvlc(br); sps->sps_max_latency_increase[i] = get_uvlc(br); } // copy info to all layers if only specified once if (sps->sps_sub_layer_ordering_info_present_flag) { int ref = sps->sps_max_sub_layers-1; for (int i=0 ; i < sps->sps_max_sub_layers-1; i++ ) { sps->sps_max_dec_pic_buffering[i] = sps->sps_max_dec_pic_buffering[ref]; sps->sps_max_num_reorder_pics[i] = sps->sps_max_num_reorder_pics[ref]; sps->sps_max_latency_increase[i] = sps->sps_max_latency_increase[ref]; } } sps->log2_min_luma_coding_block_size = get_uvlc(br)+3; sps->log2_diff_max_min_luma_coding_block_size = get_uvlc(br); sps->log2_min_transform_block_size = get_uvlc(br)+2; sps->log2_diff_max_min_transform_block_size = get_uvlc(br); sps->max_transform_hierarchy_depth_inter = get_uvlc(br); sps->max_transform_hierarchy_depth_intra = get_uvlc(br); sps->scaling_list_enable_flag = get_bits(br,1); if (sps->scaling_list_enable_flag) { sps->sps_scaling_list_data_present_flag = get_bits(br,1); if (sps->sps_scaling_list_data_present_flag) { return DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED; } } sps->amp_enabled_flag = get_bits(br,1); sps->sample_adaptive_offset_enabled_flag = get_bits(br,1); sps->pcm_enabled_flag = get_bits(br,1); if (sps->pcm_enabled_flag) { sps->pcm_sample_bit_depth_luma = get_bits(br,4)+1; sps->pcm_sample_bit_depth_chroma = get_bits(br,4)+1; sps->log2_min_pcm_luma_coding_block_size = get_uvlc(br)+3; sps->log2_diff_max_min_pcm_luma_coding_block_size = get_uvlc(br); sps->pcm_loop_filter_disable_flag = get_bits(br,1); } sps->num_short_term_ref_pic_sets = get_uvlc(br); if (sps->num_short_term_ref_pic_sets < 0 || sps->num_short_term_ref_pic_sets > 64) { add_warning(ctx, DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE, false); return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; } // --- allocate reference pic set --- // allocate one more for the ref-pic-set that may be sent in the slice header // TODO: should use "realloc" and only reallocate if necessary free(*ref_pic_sets); *ref_pic_sets = (ref_pic_set *)calloc(sizeof(ref_pic_set), sps->num_short_term_ref_pic_sets + 1); for (int i = 0; i < sps->num_short_term_ref_pic_sets; i++) { //alloc_ref_pic_set(&(*ref_pic_sets)[i], //sps->sps_max_dec_pic_buffering[sps->sps_max_sub_layers-1]); read_short_term_ref_pic_set(br,*ref_pic_sets, i, sps->num_short_term_ref_pic_sets); // dump_short_term_ref_pic_set(&(*ref_pic_sets)[i], fh); } sps->long_term_ref_pics_present_flag = get_bits(br,1); if (sps->long_term_ref_pics_present_flag) { sps->num_long_term_ref_pics_sps = get_uvlc(br); if (sps->num_long_term_ref_pics_sps > 32) { return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; } for (int i = 0; i < sps->num_long_term_ref_pics_sps; i++ ) { sps->lt_ref_pic_poc_lsb_sps[i] = get_bits(br, sps->log2_max_pic_order_cnt_lsb); sps->used_by_curr_pic_lt_sps_flag[i] = get_bits(br,1); } } else { sps->num_long_term_ref_pics_sps = 0; // NOTE: missing definition in standard ! } sps->sps_temporal_mvp_enabled_flag = get_bits(br,1); sps->strong_intra_smoothing_enable_flag = get_bits(br,1); sps->vui_parameters_present_flag = get_bits(br,1); #if 0 if (sps->vui_parameters_present_flag) { assert(false); /* vui_parameters() sps_extension_flag u(1) if( sps_extension_flag ) while( more_rbsp_data() ) sps_extension_data_flag u(1) rbsp_trailing_bits() */ } sps->sps_extension_flag = get_bits(br,1); if (sps->sps_extension_flag) { assert(false); } check_rbsp_trailing_bits(br); #endif // --- compute derived values --- sps->BitDepth_Y = sps->bit_depth_luma; sps->QpBdOffset_Y = 6*(sps->bit_depth_luma-8); sps->BitDepth_C = sps->bit_depth_chroma; sps->QpBdOffset_C = 6*(sps->bit_depth_chroma-8); sps->Log2MinCbSizeY = sps->log2_min_luma_coding_block_size; sps->Log2CtbSizeY = sps->Log2MinCbSizeY + sps->log2_diff_max_min_luma_coding_block_size; sps->MinCbSizeY = 1 << sps->Log2MinCbSizeY; sps->CtbSizeY = 1 << sps->Log2CtbSizeY; sps->PicWidthInMinCbsY = sps->pic_width_in_luma_samples / sps->MinCbSizeY; sps->PicWidthInCtbsY = ceil_div(sps->pic_width_in_luma_samples, sps->CtbSizeY); sps->PicHeightInMinCbsY = sps->pic_height_in_luma_samples / sps->MinCbSizeY; sps->PicHeightInCtbsY = ceil_div(sps->pic_height_in_luma_samples,sps->CtbSizeY); sps->PicSizeInMinCbsY = sps->PicWidthInMinCbsY * sps->PicHeightInMinCbsY; sps->PicSizeInCtbsY = sps->PicWidthInCtbsY * sps->PicHeightInCtbsY; sps->PicSizeInSamplesY = sps->pic_width_in_luma_samples * sps->pic_height_in_luma_samples; if (sps->chroma_format_idc==0 || sps->separate_colour_plane_flag) { sps->CtbWidthC = 0; sps->CtbHeightC = 0; } else { sps->CtbWidthC = sps->CtbSizeY / sps->SubWidthC; sps->CtbHeightC = sps->CtbSizeY / sps->SubHeightC; } sps->Log2MinTrafoSize = sps->log2_min_transform_block_size; sps->Log2MaxTrafoSize = sps->log2_min_transform_block_size + sps->log2_diff_max_min_transform_block_size; sps->Log2MinPUSize = sps->Log2MinCbSizeY-1; sps->PicWidthInMinPUs = sps->PicWidthInCtbsY << (sps->Log2CtbSizeY - sps->Log2MinPUSize); sps->PicHeightInMinPUs = sps->PicHeightInCtbsY << (sps->Log2CtbSizeY - sps->Log2MinPUSize); // the following are not in the standard sps->PicWidthInTbsY = sps->PicWidthInCtbsY << (sps->Log2CtbSizeY - sps->Log2MinTrafoSize); sps->PicHeightInTbsY = sps->PicHeightInCtbsY << (sps->Log2CtbSizeY - sps->Log2MinTrafoSize); sps->PicSizeInTbsY = sps->PicWidthInTbsY * sps->PicHeightInTbsY; sps->sps_read = true; return DE265_OK; }
bool read_pps(bitreader* br, pic_parameter_set* pps, decoder_context* ctx) { pps->pps_read = false; // incomplete pps int uvlc; pps->pic_parameter_set_id = uvlc = get_uvlc(br); if (uvlc >= DE265_MAX_PPS_SETS || uvlc == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_NONEXISTING_PPS_REFERENCED, false); return false; } pps->seq_parameter_set_id = uvlc = get_uvlc(br); if (uvlc >= DE265_MAX_PPS_SETS || uvlc == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_NONEXISTING_SPS_REFERENCED, false); return false; } pps->dependent_slice_segments_enabled_flag = get_bits(br,1); pps->output_flag_present_flag = get_bits(br,1); pps->num_extra_slice_header_bits = get_bits(br,3); pps->sign_data_hiding_flag = get_bits(br,1); pps->cabac_init_present_flag = get_bits(br,1); pps->num_ref_idx_l0_default_active = uvlc = get_uvlc(br); if (uvlc == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->num_ref_idx_l0_default_active++; pps->num_ref_idx_l1_default_active = uvlc = get_uvlc(br); if (uvlc == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->num_ref_idx_l1_default_active++; seq_parameter_set* sps = get_sps(ctx, pps->seq_parameter_set_id); if (sps==NULL) { add_warning(ctx, DE265_WARNING_NONEXISTING_SPS_REFERENCED, false); return false; } if ((pps->pic_init_qp = get_svlc(br)) == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->pic_init_qp += 26; pps->constrained_intra_pred_flag = get_bits(br,1); pps->transform_skip_enabled_flag = get_bits(br,1); pps->cu_qp_delta_enabled_flag = get_bits(br,1); if (pps->cu_qp_delta_enabled_flag) { if ((pps->diff_cu_qp_delta_depth = get_uvlc(br)) == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } } else { pps->diff_cu_qp_delta_depth = 0; } if ((pps->pic_cb_qp_offset = get_svlc(br)) == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } if ((pps->pic_cr_qp_offset = get_svlc(br)) == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->pps_slice_chroma_qp_offsets_present_flag = get_bits(br,1); pps->weighted_pred_flag = get_bits(br,1); pps->weighted_bipred_flag = get_bits(br,1); pps->transquant_bypass_enable_flag = get_bits(br,1); pps->tiles_enabled_flag = get_bits(br,1); pps->entropy_coding_sync_enabled_flag = get_bits(br,1); // --- tiles --- if (pps->tiles_enabled_flag ) { pps->num_tile_columns = get_uvlc(br); if (pps->num_tile_columns == UVLC_ERROR || pps->num_tile_columns > DE265_MAX_TILE_COLUMNS) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->num_tile_columns++; pps->num_tile_rows = get_uvlc(br); if (pps->num_tile_rows == UVLC_ERROR || pps->num_tile_rows > DE265_MAX_TILE_ROWS) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->num_tile_rows++; pps->uniform_spacing_flag = get_bits(br,1); if (pps->uniform_spacing_flag==false) { int lastColumnWidth = sps->PicWidthInCtbsY; int lastRowHeight = sps->PicHeightInCtbsY; for (int i=0; i<pps->num_tile_columns-1; i++) { pps->colWidth[i] = get_uvlc(br); if (pps->colWidth[i] == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->colWidth[i]++; lastColumnWidth -= pps->colWidth[i]; } pps->colWidth[pps->num_tile_columns-1] = lastColumnWidth; for (int i=0; i<pps->num_tile_rows-1; i++) { pps->rowHeight[i] = get_uvlc(br); if (pps->rowHeight[i] == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->rowHeight[i]++; lastRowHeight -= pps->rowHeight[i]; } pps->rowHeight[pps->num_tile_rows-1] = lastRowHeight; } pps->loop_filter_across_tiles_enabled_flag = get_bits(br,1); } else { pps->num_tile_columns = 1; pps->num_tile_rows = 1; pps->uniform_spacing_flag = 1; } if (pps->uniform_spacing_flag) { // set columns widths int *const colPos = (int *)alloca((pps->num_tile_columns+1) * sizeof(int)); for (int i=0;i<=pps->num_tile_columns;i++) { colPos[i] = i*sps->PicWidthInCtbsY / pps->num_tile_columns; } for (int i=0;i<pps->num_tile_columns;i++) { pps->colWidth[i] = colPos[i+1] - colPos[i]; } // set row heights int *const rowPos = (int *)alloca((pps->num_tile_rows+1) * sizeof(int)); for (int i=0;i<=pps->num_tile_rows;i++) { rowPos[i] = i*sps->PicHeightInCtbsY / pps->num_tile_rows; } for (int i=0;i<pps->num_tile_rows;i++) { pps->rowHeight[i] = rowPos[i+1] - rowPos[i]; } } // set tile boundaries pps->colBd[0]=0; for (int i=0;i<pps->num_tile_columns;i++) { pps->colBd[i+1] = pps->colBd[i] + pps->colWidth[i]; } pps->rowBd[0]=0; for (int i=0;i<pps->num_tile_rows;i++) { pps->rowBd[i+1] = pps->rowBd[i] + pps->rowHeight[i]; } // alloc raster scan arrays if (pps->CtbAddrRStoTS) { free(pps->CtbAddrRStoTS); } if (pps->CtbAddrTStoRS) { free(pps->CtbAddrTStoRS); } if (pps->TileId) { free(pps->TileId); } if (pps->TileIdRS) { free(pps->TileIdRS); } if (pps->MinTbAddrZS) { free(pps->MinTbAddrZS); } pps->CtbAddrRStoTS = (int *)malloc( sizeof(int) * sps->PicSizeInCtbsY ); pps->CtbAddrTStoRS = (int *)malloc( sizeof(int) * sps->PicSizeInCtbsY ); pps->TileId = (int *)malloc( sizeof(int) * sps->PicSizeInCtbsY ); pps->TileIdRS = (int *)malloc( sizeof(int) * sps->PicSizeInCtbsY ); pps->MinTbAddrZS = (int *)malloc( sizeof(int) * sps->PicSizeInTbsY ); // raster scan (RS) <-> tile scan (TS) conversion for (int ctbAddrRS=0 ; ctbAddrRS < sps->PicSizeInCtbsY ; ctbAddrRS++) { int tbX = ctbAddrRS % sps->PicWidthInCtbsY; int tbY = ctbAddrRS / sps->PicWidthInCtbsY; int tileX=-1,tileY=-1; for (int i=0;i<pps->num_tile_columns;i++) if (tbX >= pps->colBd[i]) tileX=i; for (int j=0;j<pps->num_tile_rows;j++) if (tbY >= pps->rowBd[j]) tileY=j; pps->CtbAddrRStoTS[ctbAddrRS] = 0; for (int i=0;i<tileX;i++) pps->CtbAddrRStoTS[ctbAddrRS] += pps->rowHeight[tileY]*pps->colWidth[i]; for (int j=0;j<tileY;j++) { //pps->CtbAddrRStoTS[ctbAddrRS] += (tbY - pps->rowBd[tileY])*pps->colWidth[tileX]; //pps->CtbAddrRStoTS[ctbAddrRS] += tbX - pps->colBd[tileX]; pps->CtbAddrRStoTS[ctbAddrRS] += sps->PicWidthInCtbsY * pps->rowHeight[j]; } assert(tileX>=0 && tileY>=0); pps->CtbAddrRStoTS[ctbAddrRS] += (tbY-pps->rowBd[tileY])*pps->colWidth[tileX]; pps->CtbAddrRStoTS[ctbAddrRS] += tbX - pps->colBd[tileX]; // inverse mapping pps->CtbAddrTStoRS[ pps->CtbAddrRStoTS[ctbAddrRS] ] = ctbAddrRS; } logtrace(LogHeaders,"6.5.1 CtbAddrRSToTS\n"); for (int y=0;y<sps->PicHeightInCtbsY;y++) { for (int x=0;x<sps->PicWidthInCtbsY;x++) { logtrace(LogHeaders,"%3d ", pps->CtbAddrRStoTS[x + y*sps->PicWidthInCtbsY]); } logtrace(LogHeaders,"\n"); } // tile id for (int j=0, tIdx=0 ; j<pps->num_tile_rows ; j++) for (int i=0 ; i<pps->num_tile_columns;i++) { for (int y=pps->rowBd[j] ; y<pps->rowBd[j+1] ; y++) for (int x=pps->colBd[i] ; x<pps->colBd[i+1] ; x++) { pps->TileId [ pps->CtbAddrRStoTS[y*sps->PicWidthInCtbsY + x] ] = tIdx; pps->TileIdRS[ y*sps->PicWidthInCtbsY + x ] = tIdx; //logtrace(LogHeaders,"tileID[%d,%d] = %d\n",x,y,pps->TileIdRS[ y*sps->PicWidthInCtbsY + x ]); } tIdx++; } logtrace(LogHeaders,"Tile IDs RS:\n"); for (int y=0;y<sps->PicHeightInCtbsY;y++) { for (int x=0;x<sps->PicWidthInCtbsY;x++) { logtrace(LogHeaders,"%2d ",pps->TileIdRS[y*sps->PicWidthInCtbsY+x]); } logtrace(LogHeaders,"\n"); } // 6.5.2 Z-scan order array initialization process for (int y=0;y<sps->PicHeightInTbsY;y++) for (int x=0;x<sps->PicWidthInTbsY;x++) { int tbX = (x<<sps->Log2MinTrafoSize)>>sps->Log2CtbSizeY; int tbY = (y<<sps->Log2MinTrafoSize)>>sps->Log2CtbSizeY; int ctbAddrRS = sps->PicWidthInCtbsY*tbY + tbX; pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY] = pps->CtbAddrRStoTS[ctbAddrRS] << ((sps->Log2CtbSizeY-sps->Log2MinTrafoSize)*2); int p=0; for (int i=0 ; i<(sps->Log2CtbSizeY - sps->Log2MinTrafoSize) ; i++) { int m=1<<i; p += (m & x ? m*m : 0) + (m & y ? 2*m*m : 0); } pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY] += p; } // --- debug logging --- /* logtrace(LogHeaders,"6.5.2 Z-scan order array\n"); for (int y=0;y<sps->PicHeightInTbsY;y++) { for (int x=0;x<sps->PicWidthInTbsY;x++) { logtrace(LogHeaders,"%4d ", pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY]); } logtrace(LogHeaders,"\n"); } for (int i=0;i<sps->PicSizeInTbsY;i++) { for (int y=0;y<sps->PicHeightInTbsY;y++) { for (int x=0;x<sps->PicWidthInTbsY;x++) { if (pps->MinTbAddrZS[x + y*sps->PicWidthInTbsY] == i) { logtrace(LogHeaders,"%d %d\n",x,y); } } } } */ // END tiles pps->Log2MinCuQpDeltaSize = sps->Log2CtbSizeY - pps->diff_cu_qp_delta_depth; pps->beta_offset = 0; // default value pps->tc_offset = 0; // default value pps->pps_loop_filter_across_slices_enabled_flag = get_bits(br,1); pps->deblocking_filter_control_present_flag = get_bits(br,1); if (pps->deblocking_filter_control_present_flag) { pps->deblocking_filter_override_enabled_flag = get_bits(br,1); pps->pic_disable_deblocking_filter_flag = get_bits(br,1); if (!pps->pic_disable_deblocking_filter_flag) { pps->beta_offset = get_svlc(br); if (pps->beta_offset == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->beta_offset *= 2; pps->tc_offset = get_svlc(br); if (pps->tc_offset == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->tc_offset *= 2; } } else { pps->deblocking_filter_override_enabled_flag = 0; pps->pic_disable_deblocking_filter_flag = 0; } pps->pic_scaling_list_data_present_flag = get_bits(br,1); if (pps->pic_scaling_list_data_present_flag) { assert(false); //scaling_list_data() } pps->lists_modification_present_flag = get_bits(br,1); pps->log2_parallel_merge_level = get_uvlc(br); if (pps->log2_parallel_merge_level == UVLC_ERROR) { add_warning(ctx, DE265_WARNING_PPS_HEADER_INVALID, false); return false; } pps->log2_parallel_merge_level += 2; pps->slice_segment_header_extension_present_flag = get_bits(br,1); pps->pps_extension_flag = get_bits(br,1); if (pps->pps_extension_flag) { //assert(false); /* while( more_rbsp_data() ) pps_extension_data_flag u(1) rbsp_trailing_bits() } */ } pps->pps_read = true; return true; }