/* Adds slice headers to picture */ bool VaapiEncoderH264::addSliceHeaders (const PicturePtr& picture) const { VAEncSliceParameterBufferH264 *sliceParam; uint32_t sliceOfMbs, sliceModMbs, curSliceMbs; uint32_t mbSize; uint32_t lastMbIndex; assert (picture); if (picture->m_type != VAAPI_PICTURE_TYPE_I) { /* have one reference frame at least */ assert(m_refList0.size() > 0); } mbSize = m_mbWidth * m_mbHeight; assert (m_numSlices && m_numSlices < mbSize); sliceOfMbs = mbSize / m_numSlices; sliceModMbs = mbSize % m_numSlices; lastMbIndex = 0; for (uint32_t i = 0; i < m_numSlices; ++i) { curSliceMbs = sliceOfMbs; if (sliceModMbs) { ++curSliceMbs; --sliceModMbs; } if (!picture->newSlice(sliceParam)) return false; sliceParam->macroblock_address = lastMbIndex; sliceParam->num_macroblocks = curSliceMbs; sliceParam->macroblock_info = VA_INVALID_ID; sliceParam->slice_type = h264_get_slice_type (picture->m_type); assert (sliceParam->slice_type != -1); sliceParam->idr_pic_id = m_idrNum; sliceParam->pic_order_cnt_lsb = picture->m_poc; sliceParam->num_ref_idx_active_override_flag = 1; if (picture->m_type != VAAPI_PICTURE_TYPE_I && m_refList0.size() > 0) sliceParam->num_ref_idx_l0_active_minus1 = m_refList0.size() - 1; if (picture->m_type == VAAPI_PICTURE_TYPE_B && m_refList1.size() > 0) sliceParam->num_ref_idx_l1_active_minus1 = m_refList1.size() - 1; fillReferenceList(sliceParam); sliceParam->slice_qp_delta = initQP() - minQP(); if (sliceParam->slice_qp_delta > 4) sliceParam->slice_qp_delta = 4; sliceParam->slice_alpha_c0_offset_div2 = 2; sliceParam->slice_beta_offset_div2 = 2; /* set calculation for next slice */ lastMbIndex += curSliceMbs; } assert (lastMbIndex == mbSize); return true; }
bool VaapiDecoderH265::fillSlice(const PicturePtr& picture, const H265SliceHdr* const theSlice, const H265NalUnit* const nalu) { const H265SliceHdr* slice = theSlice; VASliceParameterBufferHEVC* sliceParam; if (!picture->newSlice(sliceParam, nalu->data + nalu->offset, nalu->size)) return false; sliceParam->slice_data_byte_offset = getSliceDataByteOffset(slice, nalu->header_bytes); sliceParam->slice_segment_address = slice->segment_address; #define FILL_LONG(f) sliceParam->LongSliceFlags.fields.f = slice->f #define FILL_LONG_SLICE(f) sliceParam->LongSliceFlags.fields.slice_##f = slice->f //how to fill this //LastSliceOfPic FILL_LONG(dependent_slice_segment_flag); //follow spec if (slice->dependent_slice_segment_flag) { slice = m_prevSlice.get(); } if (!fillReferenceIndex(sliceParam, slice)) return false; FILL_LONG_SLICE(type); sliceParam->LongSliceFlags.fields.color_plane_id = slice->colour_plane_id; FILL_LONG_SLICE(sao_luma_flag); FILL_LONG_SLICE(sao_chroma_flag); FILL_LONG(mvd_l1_zero_flag); FILL_LONG(cabac_init_flag); FILL_LONG_SLICE(temporal_mvp_enabled_flag); if (slice->deblocking_filter_override_flag) FILL_LONG_SLICE(deblocking_filter_disabled_flag); else sliceParam->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag= slice->pps->deblocking_filter_disabled_flag; FILL_LONG(collocated_from_l0_flag); FILL_LONG_SLICE(loop_filter_across_slices_enabled_flag); #define FILL(f) sliceParam->f = slice->f #define FILL_SLICE(f) sliceParam->slice_##f = slice->f FILL(collocated_ref_idx); /* following fields fill in fillReference num_ref_idx_l0_active_minus1 num_ref_idx_l1_active_minus1*/ FILL_SLICE(qp_delta); FILL_SLICE(cb_qp_offset); FILL_SLICE(cr_qp_offset); FILL_SLICE(beta_offset_div2); FILL_SLICE(tc_offset_div2); if (!fillPredWeightTable(sliceParam, slice)) return false; FILL(five_minus_max_num_merge_cand); return true; }
bool VaapiDecoderVP9::ensureSlice(const PicturePtr& picture, const void* data, int size) { #define FILL_FIELD(field) vaseg.field = seg.field; VASliceParameterBufferVP9* slice; if (!picture->newSlice(slice, data, size)) return false; for (int i = 0; i < VP9_MAX_SEGMENTS; i++) { VASegmentParameterVP9& vaseg = slice->seg_param[i]; Vp9Segmentation& seg = m_parser->segmentation[i]; memcpy(vaseg.filter_level, seg.filter_level, sizeof(seg.filter_level)); FILL_FIELD(luma_ac_quant_scale) FILL_FIELD(luma_dc_quant_scale) FILL_FIELD(chroma_ac_quant_scale) FILL_FIELD(chroma_dc_quant_scale) vaseg.segment_flags.fields.segment_reference_skipped = seg.reference_skip; vaseg.segment_flags.fields.segment_reference_enabled = seg.reference_frame_enabled; vaseg.segment_flags.fields.segment_reference = seg.reference_frame; } #undef FILL_FIELD return true; }