| 1 | /*************************************************************************** |
|---|
| 2 | * Copyright (c) 2003-2012, Broadcom Corporation |
|---|
| 3 | * All Rights Reserved |
|---|
| 4 | * Confidential Property of Broadcom Corporation |
|---|
| 5 | * |
|---|
| 6 | * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE |
|---|
| 7 | * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR |
|---|
| 8 | * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 9 | * |
|---|
| 10 | * $brcm_Workfile: bxvd_decoder.c $ |
|---|
| 11 | * $brcm_Revision: Hydra_Software_Devel/50 $ |
|---|
| 12 | * $brcm_Date: 3/16/12 11:58a $ |
|---|
| 13 | * |
|---|
| 14 | * [File Description:] |
|---|
| 15 | * |
|---|
| 16 | * Revision History: |
|---|
| 17 | * |
|---|
| 18 | * $brcm_Log: /magnum/portinginterface/xvd/7401/bxvd_decoder.c $ |
|---|
| 19 | * |
|---|
| 20 | * Hydra_Software_Devel/50 3/16/12 11:58a btosi |
|---|
| 21 | * SW7425-2536: added support for displayInterruptStatus_isr |
|---|
| 22 | * |
|---|
| 23 | * Hydra_Software_Devel/49 2/10/12 11:18a btosi |
|---|
| 24 | * SW7425-2247: add support for bar data |
|---|
| 25 | * |
|---|
| 26 | * Hydra_Software_Devel/48 1/13/12 9:48a btosi |
|---|
| 27 | * SW7405-4736: fixed warning on the 7630 build |
|---|
| 28 | * |
|---|
| 29 | * Hydra_Software_Devel/47 1/12/12 3:23p btosi |
|---|
| 30 | * SW7405-4736: added debug support for new PPB field flags_ext0 |
|---|
| 31 | * |
|---|
| 32 | * Hydra_Software_Devel/46 1/10/12 1:32p btosi |
|---|
| 33 | * SW7425-1001: added support for bLast flag |
|---|
| 34 | * |
|---|
| 35 | * Hydra_Software_Devel/45 12/16/11 8:32a btosi |
|---|
| 36 | * SWDTV-8681: add support for VP8 display size |
|---|
| 37 | * |
|---|
| 38 | * Hydra_Software_Devel/44 12/5/11 2:54p btosi |
|---|
| 39 | * SWCHECKFRAME-80: execute the PPBReceived callback prior to processing |
|---|
| 40 | * the PPB data. |
|---|
| 41 | * |
|---|
| 42 | * Hydra_Software_Devel/43 12/1/11 1:12p pblanco |
|---|
| 43 | * SW7425-1780: Implemented picture id support for transcode userdata. |
|---|
| 44 | * |
|---|
| 45 | * Hydra_Software_Devel/42 9/20/11 3:32p btosi |
|---|
| 46 | * SW7425-1261: only clear bTruncatingGop in ..._ReleaseGopTail |
|---|
| 47 | * |
|---|
| 48 | * Hydra_Software_Devel/41 7/28/11 11:38a btosi |
|---|
| 49 | * SW7405-4736: added the PPB flags to the BXVD_UP message |
|---|
| 50 | * |
|---|
| 51 | * Hydra_Software_Devel/40 7/27/11 12:08p btosi |
|---|
| 52 | * SWDTV-7795: added support for RV9 cropping |
|---|
| 53 | * |
|---|
| 54 | * Hydra_Software_Devel/39 7/20/11 3:07p davidp |
|---|
| 55 | * SW7420-2001: Reorder header-file includes. |
|---|
| 56 | * |
|---|
| 57 | * Hydra_Software_Devel/38 6/27/11 4:18p davidp |
|---|
| 58 | * SW7425-542: Merge devel branch to mainline. |
|---|
| 59 | * |
|---|
| 60 | * Hydra_Software_Devel/SW7425-542/2 6/24/11 8:53a davidp |
|---|
| 61 | * SW7425-542: Add BXVD_P_DBG_PIC_QUES to enable queue processing log. |
|---|
| 62 | * |
|---|
| 63 | * Hydra_Software_Devel/SW7425-542/1 6/14/11 10:40a btosi |
|---|
| 64 | * SW7425-542: cleaned up warning |
|---|
| 65 | * |
|---|
| 66 | * Hydra_Software_Devel/37 6/8/11 1:04p btosi |
|---|
| 67 | * SW7425-542: moved the delivery/release queue management macros to the |
|---|
| 68 | * platform files |
|---|
| 69 | * |
|---|
| 70 | * Hydra_Software_Devel/36 6/1/11 3:15p btosi |
|---|
| 71 | * SW7425-542: added macros for accessing the AVD queue read and write |
|---|
| 72 | * offsets |
|---|
| 73 | * |
|---|
| 74 | * Hydra_Software_Devel/35 5/20/11 11:55a btosi |
|---|
| 75 | * SW7425-609: check bPictureDropped before linking the dependent to the |
|---|
| 76 | * base picture |
|---|
| 77 | * |
|---|
| 78 | * Hydra_Software_Devel/34 5/3/11 1:32p btosi |
|---|
| 79 | * SW7405-4736: reset stUnifiedContext in ..._UpdateReadOffset, fixes |
|---|
| 80 | * crash in StereoSeqError check test |
|---|
| 81 | * |
|---|
| 82 | * Hydra_Software_Devel/33 4/18/11 9:33a btosi |
|---|
| 83 | * SW7405-4736: pre increment uiPPBSerialNumber so that the Decoder and |
|---|
| 84 | * XDM debug messages match |
|---|
| 85 | * |
|---|
| 86 | * Hydra_Software_Devel/32 4/15/11 3:31p btosi |
|---|
| 87 | * SW7405-4736: backed out change for incrementing uiPPBSerialNumber |
|---|
| 88 | * |
|---|
| 89 | * Hydra_Software_Devel/31 4/15/11 10:50a btosi |
|---|
| 90 | * SW7405-4736: added support to print the SEI messages |
|---|
| 91 | * |
|---|
| 92 | * Hydra_Software_Devel/30 4/4/11 11:28a btosi |
|---|
| 93 | * SW7405-4736: added support for BXVD_DecoderDbg_P_PrintUnifiedPicture |
|---|
| 94 | * |
|---|
| 95 | * Hydra_Software_Devel/29 3/15/11 10:17a btosi |
|---|
| 96 | * SW7425-160: updated to use Broadcom standard types |
|---|
| 97 | * |
|---|
| 98 | * Hydra_Software_Devel/28 2/25/11 11:14a btosi |
|---|
| 99 | * SW7425-106: work around the issue with the DQ read offset increment |
|---|
| 100 | * |
|---|
| 101 | * Hydra_Software_Devel/27 2/17/11 2:01p btosi |
|---|
| 102 | * SW7405-5135: if the SEI arrangement_cancel flag is set, set both the |
|---|
| 103 | * Unified and MFD picture orientations to 2D |
|---|
| 104 | * |
|---|
| 105 | * Hydra_Software_Devel/26 2/8/11 12:51p btosi |
|---|
| 106 | * SW7425-82: use frame_packing_arrangement_type to determine the type of |
|---|
| 107 | * frame packing. |
|---|
| 108 | * |
|---|
| 109 | * Hydra_Software_Devel/25 2/2/11 1:41p btosi |
|---|
| 110 | * SW7125-808: fixed the issue of the drop count going negative in |
|---|
| 111 | * BXVD_Decoder_GetPictureDropPendingCount_isr when the deliver queue |
|---|
| 112 | * is empty |
|---|
| 113 | * |
|---|
| 114 | * Hydra_Software_Devel/24 1/25/11 3:56p davidp |
|---|
| 115 | * SW7422-22: Add support for SVC Picture Order Count. |
|---|
| 116 | * |
|---|
| 117 | * Hydra_Software_Devel/23 12/16/10 9:20a btosi |
|---|
| 118 | * SW7422-72: fixed warning |
|---|
| 119 | * |
|---|
| 120 | * Hydra_Software_Devel/22 12/10/10 1:22p btosi |
|---|
| 121 | * SWBLURAY-23835: added check for a picture being released multiple times |
|---|
| 122 | * |
|---|
| 123 | * Hydra_Software_Devel/21 11/24/10 1:22p btosi |
|---|
| 124 | * SW7422-72: added BXVD_LEGACY_MVC_SUPPORT and bSetNextPointer for MVC on |
|---|
| 125 | * older DVD chips |
|---|
| 126 | * |
|---|
| 127 | * Hydra_Software_Devel/20 11/23/10 10:25a btosi |
|---|
| 128 | * SW7422-72: with the exception of older DVD chips, 2D is now the default |
|---|
| 129 | * orientation for MVC streams |
|---|
| 130 | * |
|---|
| 131 | * Hydra_Software_Devel/19 10/29/10 11:39a btosi |
|---|
| 132 | * SW7422-72: merging 3D changes to mainline |
|---|
| 133 | * |
|---|
| 134 | * Hydra_Software_Devel/SW7422-72/2 10/29/10 11:34a btosi |
|---|
| 135 | * SW7422-72: added support for AVC 3D |
|---|
| 136 | * |
|---|
| 137 | * Hydra_Software_Devel/SW7422-72/1 10/19/10 10:29a btosi |
|---|
| 138 | * SW7422-72: expanded support for 3D |
|---|
| 139 | * |
|---|
| 140 | * Hydra_Software_Devel/18 10/19/10 9:08a delkert |
|---|
| 141 | * SW7405-4044: Add support for |
|---|
| 142 | * BAVC_TransferCharacteristics_eIec_61966_2_4 to support xvYCC |
|---|
| 143 | * |
|---|
| 144 | * Hydra_Software_Devel/17 8/9/10 1:24p btosi |
|---|
| 145 | * SW7405-4733: set eSequence to eInterlaced instead of defaulting to |
|---|
| 146 | * eUnknown |
|---|
| 147 | * |
|---|
| 148 | * Hydra_Software_Devel/16 7/29/10 11:22a btosi |
|---|
| 149 | * SW7405-4560: added support for the SEI "new message" flag. |
|---|
| 150 | * |
|---|
| 151 | * Hydra_Software_Devel/15 7/27/10 11:36a btosi |
|---|
| 152 | * SW7401-4426: added support for the H264 timecode |
|---|
| 153 | * |
|---|
| 154 | * Hydra_Software_Devel/14 7/7/10 2:40p btosi |
|---|
| 155 | * SWBLURAY-21461: for MPEG and VC1, use the display width/height provided |
|---|
| 156 | * in the PPB |
|---|
| 157 | * |
|---|
| 158 | * Hydra_Software_Devel/13 6/28/10 2:48p btosi |
|---|
| 159 | * SW7405-4365: added support to selectively compile the function timing |
|---|
| 160 | * code. |
|---|
| 161 | * |
|---|
| 162 | * Hydra_Software_Devel/12 6/25/10 2:13p btosi |
|---|
| 163 | * SW7405-4365: added use of local variables in |
|---|
| 164 | * BXVD_Decoder_S_UnifiedQ_ValidatePicture to |
|---|
| 165 | * improve performance |
|---|
| 166 | * |
|---|
| 167 | * Hydra_Software_Devel/11 6/16/10 12:56p btosi |
|---|
| 168 | * SW7405-4365: added support for using the new timer functions |
|---|
| 169 | * |
|---|
| 170 | * Hydra_Software_Devel/10 6/11/10 10:54a davidp |
|---|
| 171 | * SW7405-3925: Fix compiler warning. |
|---|
| 172 | * |
|---|
| 173 | * Hydra_Software_Devel/9 6/7/10 10:23a delkert |
|---|
| 174 | * SW7405-3925: When retrieving pending drop count, first check that there |
|---|
| 175 | * are pictures in the Q to avoid "ping-ponging" between vTSM and TSM |
|---|
| 176 | * selection mode. Modify request drop API to update the request count. |
|---|
| 177 | * Removed duplicated assertion |
|---|
| 178 | * |
|---|
| 179 | * Hydra_Software_Devel/8 6/3/10 11:55a btosi |
|---|
| 180 | * SW7630-83: fixed handling of mismatched pairs of pictures as well as |
|---|
| 181 | * general cleanup |
|---|
| 182 | * |
|---|
| 183 | * Hydra_Software_Devel/7 5/12/10 2:44p btosi |
|---|
| 184 | * SWBLURAY-20606: fixed assignment of |
|---|
| 185 | * stBluRay3DGraphicsOffset.puiOffsetData |
|---|
| 186 | * |
|---|
| 187 | * Hydra_Software_Devel/6 5/4/10 10:41a btosi |
|---|
| 188 | * SW7405-3996: added support for new SEI message format |
|---|
| 189 | * |
|---|
| 190 | * Hydra_Software_Devel/5 5/4/10 9:12a pblanco |
|---|
| 191 | * SW7125-386: Fixed malformed BXVD_DBG_ERR calls. |
|---|
| 192 | * |
|---|
| 193 | * Hydra_Software_Devel/4 4/29/10 4:12p btosi |
|---|
| 194 | * SW7630-79: set stBufferInfo.bValid to false if a pictureless PPB |
|---|
| 195 | * |
|---|
| 196 | * Hydra_Software_Devel/3 4/16/10 10:50a pblanco |
|---|
| 197 | * SW7405-2993: Added some conditionalized debugging output. |
|---|
| 198 | * |
|---|
| 199 | * Hydra_Software_Devel/2 3/1/10 4:58p nilesh |
|---|
| 200 | * SW7405-2993: Fix coverity warnings |
|---|
| 201 | * |
|---|
| 202 | * Hydra_Software_Devel/1 2/25/10 4:24p nilesh |
|---|
| 203 | * SW7405-2993: XDM Merge |
|---|
| 204 | * |
|---|
| 205 | ***************************************************************************/ |
|---|
| 206 | |
|---|
| 207 | #include "bstd.h" |
|---|
| 208 | #include "bdbg.h" /* Dbglib */ |
|---|
| 209 | #include "bmth_fix.h" |
|---|
| 210 | |
|---|
| 211 | #include "bxvd_platform.h" |
|---|
| 212 | #include "bxvd_priv.h" |
|---|
| 213 | #include "bxvd_reg.h" |
|---|
| 214 | #include "bxdm_decoder.h" |
|---|
| 215 | #include "bxvd_decoder.h" |
|---|
| 216 | #include "bxvd_decoder_dbg.h" |
|---|
| 217 | |
|---|
| 218 | #include "bxvd_vdec_info.h" |
|---|
| 219 | |
|---|
| 220 | #if BXVD_DM_ENABLE_YUV_GRAB_MODE |
|---|
| 221 | #include <stdio.h> |
|---|
| 222 | #include <stdlib.h> |
|---|
| 223 | #include "bxvd_reg.h" |
|---|
| 224 | #endif |
|---|
| 225 | |
|---|
| 226 | |
|---|
| 227 | BDBG_MODULE(BXVD_DECODER); |
|---|
| 228 | |
|---|
| 229 | /*************************************************************************** |
|---|
| 230 | * |
|---|
| 231 | * Local constant and type definitions. |
|---|
| 232 | * |
|---|
| 233 | ***************************************************************************/ |
|---|
| 234 | |
|---|
| 235 | /* Number of pictures in this set. Should use the data provided with the |
|---|
| 236 | * picture, i.e. "pstPicCntxt->uiSetCount". Waiting on the firmware. |
|---|
| 237 | */ |
|---|
| 238 | #define BXVD_DECODER_S_PICTURES_PER_SET 2 |
|---|
| 239 | |
|---|
| 240 | /* |
|---|
| 241 | * Set this to non-zero for extra AVD debugging help |
|---|
| 242 | */ |
|---|
| 243 | #define BXVD_DECODER_AVD_DEBUG_HELP 0 |
|---|
| 244 | |
|---|
| 245 | |
|---|
| 246 | /* sAVCStripeWidthLUT maps the stripe width from XVD to the proper |
|---|
| 247 | * BAVC_StripeWidth enum |
|---|
| 248 | */ |
|---|
| 249 | static const BAVC_StripeWidth sAVCStripeWidthLUT[BXVD_P_STRIPE_WIDTH_NUM] = |
|---|
| 250 | { |
|---|
| 251 | BAVC_StripeWidth_e64Byte, |
|---|
| 252 | BAVC_StripeWidth_e128Byte |
|---|
| 253 | |
|---|
| 254 | }; /* end of sAVCStripeWidthLUT[] */ |
|---|
| 255 | |
|---|
| 256 | |
|---|
| 257 | static const BXDM_Picture_Rate sFrameRateEnumToIntLUT[BAVC_FrameRateCode_eMax] = |
|---|
| 258 | { |
|---|
| 259 | { 30000, 1000}, /* BAVC_FrameRateCode_eUnknown */ |
|---|
| 260 | { 24000, 1001}, /* BAVC_FrameRateCode_e23_976 */ |
|---|
| 261 | { 24000, 1000}, /* BAVC_FrameRateCode_e24 */ |
|---|
| 262 | { 25000, 1000}, /* BAVC_FrameRateCode_e25 */ |
|---|
| 263 | { 30000, 1001}, /* BAVC_FrameRateCode_e29_97 */ |
|---|
| 264 | { 30000, 1000}, /* BAVC_FrameRateCode_e30 */ |
|---|
| 265 | { 50000, 1000}, /* BAVC_FrameRateCode_e50 */ |
|---|
| 266 | { 60000, 1001}, /* BAVC_FrameRateCode_e59_94 */ |
|---|
| 267 | { 60000, 1000}, /* BAVC_FrameRateCode_e60 */ |
|---|
| 268 | { 15000, 1001}, /* BAVC_FrameRateCode_e14_985 */ |
|---|
| 269 | { 7500, 1001} /* BAVC_FrameRateCode_e7_493 */ |
|---|
| 270 | }; |
|---|
| 271 | |
|---|
| 272 | |
|---|
| 273 | typedef struct BXVD_Decoder_S_SampleAspectRatio |
|---|
| 274 | { |
|---|
| 275 | uint16_t uiSampleAspectRatioX; |
|---|
| 276 | uint16_t uiSampleAspectRatioY; |
|---|
| 277 | } BXVD_Decoder_S_SampleAspectRatio; |
|---|
| 278 | |
|---|
| 279 | #define BXVD_DECODER_S_SAMPLE_ASPECT_RATIO_LUT_SIZE BXVD_P_PPB_AspectRatio_e221_1 + 1 |
|---|
| 280 | |
|---|
| 281 | static const BXVD_Decoder_S_SampleAspectRatio sSampleAspectRatioLUT[BXVD_DECODER_S_SAMPLE_ASPECT_RATIO_LUT_SIZE] = |
|---|
| 282 | { |
|---|
| 283 | {0,0}, |
|---|
| 284 | {1,1}, |
|---|
| 285 | {12,11}, |
|---|
| 286 | {10,11}, |
|---|
| 287 | {16,11}, |
|---|
| 288 | {40,33}, |
|---|
| 289 | {24,11}, |
|---|
| 290 | {20,11}, |
|---|
| 291 | {32,11}, |
|---|
| 292 | {80,33}, |
|---|
| 293 | {18,11}, |
|---|
| 294 | {15,11}, |
|---|
| 295 | {64,33}, |
|---|
| 296 | {160,99}, |
|---|
| 297 | {4,3}, |
|---|
| 298 | {3,2}, |
|---|
| 299 | {2,1}, |
|---|
| 300 | {16,9}, |
|---|
| 301 | {221,1} |
|---|
| 302 | }; /* end of sSampleAspectRatioLUT[] */ |
|---|
| 303 | |
|---|
| 304 | /* DNR Related Defines */ |
|---|
| 305 | #define BXVD_Decoder_S_DNR_INTRA_DEFAULT 2114 |
|---|
| 306 | #define BXVD_Decoder_S_DNR_INTER_DEFAULT 964 |
|---|
| 307 | |
|---|
| 308 | #define BXVD_Decoder_S_DNR_INTRA_DEFAULT_AVC 1680 |
|---|
| 309 | #define BXVD_Decoder_S_DNR_INTER_DEFAULT_AVC 1507 |
|---|
| 310 | |
|---|
| 311 | /* Lookup Tables */ |
|---|
| 312 | #define BXVD_DECODER_S_MATRIX_COEFFICIENTS_LUT_SIZE (BXVD_P_PPB_MatrixCoeff_eSMPTE293M + 1) |
|---|
| 313 | static const BAVC_MatrixCoefficients sMatrixCoefficientsLUT[BXVD_DECODER_S_MATRIX_COEFFICIENTS_LUT_SIZE] = |
|---|
| 314 | { |
|---|
| 315 | BAVC_MatrixCoefficients_eUnknown, /* BXVD_P_PPB_MatrixCoeff_eUnknown */ |
|---|
| 316 | BAVC_MatrixCoefficients_eItu_R_BT_709, /* BXVD_P_PPB_MatrixCoeff_eBT709 */ |
|---|
| 317 | BAVC_MatrixCoefficients_eUnknown, /* BXVD_P_PPB_MatrixCoeff_eUnspecified */ |
|---|
| 318 | BAVC_MatrixCoefficients_eUnknown, /* BXVD_P_PPB_MatrixCoeff_eReserved */ |
|---|
| 319 | BAVC_MatrixCoefficients_eFCC, /* BXVD_P_PPB_MatrixCoeff_eFCC */ |
|---|
| 320 | BAVC_MatrixCoefficients_eItu_R_BT_470_2_BG, /* BXVD_P_PPB_MatrixCoeff_eBT740_2BG */ |
|---|
| 321 | BAVC_MatrixCoefficients_eSmpte_170M, /* BXVD_P_PPB_MatrixCoeff_eSMPTE170M */ |
|---|
| 322 | BAVC_MatrixCoefficients_eSmpte_240M, /* BXVD_P_PPB_MatrixCoeff_eSMPTE240M */ |
|---|
| 323 | BAVC_MatrixCoefficients_eUnknown /* BXVD_P_PPB_MatrixCoeff_eSMPTE293M */ |
|---|
| 324 | }; /* end of sMatrixCoefficientsLUT[] */ |
|---|
| 325 | |
|---|
| 326 | #define BXVD_DECODER_S_COLOR_PRIMARIES_LUT_SIZE (BXVD_P_PPB_ColorPrimaries_eBT1361 + 1) |
|---|
| 327 | static const BAVC_ColorPrimaries sColorPrimariesLUT[BXVD_DECODER_S_COLOR_PRIMARIES_LUT_SIZE] = |
|---|
| 328 | { |
|---|
| 329 | BAVC_ColorPrimaries_eUnknown, /* BXVD_P_PPB_ColorPrimaries_eUnknown */ |
|---|
| 330 | BAVC_ColorPrimaries_eItu_R_BT_709, /* BXVD_P_PPB_ColorPrimaries_eBT709 */ |
|---|
| 331 | BAVC_ColorPrimaries_eUnknown, /* BXVD_P_PPB_ColorPrimaries_eUnspecified */ |
|---|
| 332 | BAVC_ColorPrimaries_eUnknown, /* BXVD_P_PPB_ColorPrimaries_eReserved */ |
|---|
| 333 | BAVC_ColorPrimaries_eItu_R_BT_470_2_M, /* BXVD_P_PPB_ColorPrimaries_eBT470_2M */ |
|---|
| 334 | BAVC_ColorPrimaries_eItu_R_BT_470_2_BG, /* BXVD_P_PPB_ColorPrimaries_eBT470_2BG */ |
|---|
| 335 | BAVC_ColorPrimaries_eSmpte_170M, /* BXVD_P_PPB_ColorPrimaries_eSMPTE170M */ |
|---|
| 336 | BAVC_ColorPrimaries_eSmpte_240M, /* BXVD_P_PPB_ColorPrimaries_eSMPTE240M */ |
|---|
| 337 | BAVC_ColorPrimaries_eGenericFilm, /* BXVD_P_PPB_ColorPrimaries_eGenericFilm */ |
|---|
| 338 | BAVC_ColorPrimaries_eUnknown /* BXVD_P_PPB_ColorPrimaries_eBT1361 */ |
|---|
| 339 | }; /* end of sColorPrimariesLUT[] */ |
|---|
| 340 | |
|---|
| 341 | #define BXVD_DECODER_S_TRANSFER_CHARACTERISICS_LUT_SIZE (BXVD_P_PPB_TransferChar_eIec_61966_2_4 + 1) |
|---|
| 342 | static const BAVC_TransferCharacteristics sTransferCharacteristicsLUT[BXVD_DECODER_S_TRANSFER_CHARACTERISICS_LUT_SIZE] = |
|---|
| 343 | { |
|---|
| 344 | BAVC_TransferCharacteristics_eUnknown, /* BXVD_P_PPB_TransferChar_eUnknown */ |
|---|
| 345 | BAVC_TransferCharacteristics_eItu_R_BT_709, /* BXVD_P_PPB_TransferChar_eBT709 */ |
|---|
| 346 | BAVC_TransferCharacteristics_eUnknown, /* BXVD_P_PPB_TransferChar_eUnspecified */ |
|---|
| 347 | BAVC_TransferCharacteristics_eUnknown, /* BXVD_P_PPB_TransferChar_eReserved */ |
|---|
| 348 | BAVC_TransferCharacteristics_eItu_R_BT_470_2_M, /* BXVD_P_PPB_TransferChar_eBT479_2M */ |
|---|
| 349 | BAVC_TransferCharacteristics_eItu_R_BT_470_2_BG, /* BXVD_P_PPB_TransferChar_eBT479_2BG */ |
|---|
| 350 | BAVC_TransferCharacteristics_eSmpte_170M, /* BXVD_P_PPB_TransferChar_eSMPTE170M */ |
|---|
| 351 | BAVC_TransferCharacteristics_eSmpte_240M, /* BXVD_P_PPB_TransferChar_eSMPTE240M */ |
|---|
| 352 | BAVC_TransferCharacteristics_eLinear, /* BXVD_P_PPB_TransferChar_eLinear */ |
|---|
| 353 | BAVC_TransferCharacteristics_eUnknown, /* BXVD_P_PPB_TransferChar_eLog100_1 */ |
|---|
| 354 | BAVC_TransferCharacteristics_eUnknown, /* BXVD_P_PPB_TransferChar_eLog31622777_1 */ |
|---|
| 355 | BAVC_TransferCharacteristics_eIec_61966_2_4 /* BXVD_P_PPB_TransferChar_eIec_61966_2_4 */ |
|---|
| 356 | }; /* end of sTransferCharacteristicsLUT[] */ |
|---|
| 357 | |
|---|
| 358 | /*************************************************************************** |
|---|
| 359 | * |
|---|
| 360 | * Function prototypes. |
|---|
| 361 | * |
|---|
| 362 | ***************************************************************************/ |
|---|
| 363 | |
|---|
| 364 | static void BXVD_Decoder_S_Increment_0BasedOffset( |
|---|
| 365 | uint32_t * pOffset, |
|---|
| 366 | uint32_t uiCount, |
|---|
| 367 | uint32_t uiMaxValue |
|---|
| 368 | ); |
|---|
| 369 | |
|---|
| 370 | static void BXVD_Decoder_S_Decrement_0BasedOffset( |
|---|
| 371 | uint32_t * pOffset, |
|---|
| 372 | uint32_t uiCount, |
|---|
| 373 | uint32_t uiMaxValue |
|---|
| 374 | ); |
|---|
| 375 | |
|---|
| 376 | static void BXVD_Decoder_S_Decrement_2BasedOffset( |
|---|
| 377 | uint32_t * pOffset, |
|---|
| 378 | uint32_t uiCount, |
|---|
| 379 | uint32_t uiMaxValue |
|---|
| 380 | ); |
|---|
| 381 | |
|---|
| 382 | static void BXVD_Decoder_S_DeliveryQ_UpdateReadOffset( |
|---|
| 383 | BXVD_ChannelHandle hXvdCh, |
|---|
| 384 | BXVD_Decoder_P_LocalState* pstLocalState, |
|---|
| 385 | uint32_t uiDeltaChange |
|---|
| 386 | ); |
|---|
| 387 | |
|---|
| 388 | static void BXVD_Decoder_S_UnifiedQ_ValidatePicture( |
|---|
| 389 | BXVD_ChannelHandle hXvdCh, |
|---|
| 390 | BXVD_Decoder_P_PictureContext * pstPictureCntxt, |
|---|
| 391 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext, |
|---|
| 392 | bool bPictureDropped |
|---|
| 393 | ); |
|---|
| 394 | |
|---|
| 395 | static bool BXVD_Decoder_S_DeliveryQ_CheckForDeadlock( |
|---|
| 396 | BXVD_ChannelHandle hXvdCh, |
|---|
| 397 | uint32_t uiNumPicturesToProcess |
|---|
| 398 | ); |
|---|
| 399 | |
|---|
| 400 | static void BXVD_Decoder_S_DeliveryQ_ReleaseGopTail( |
|---|
| 401 | BXVD_ChannelHandle hXvdCh, |
|---|
| 402 | BXVD_Decoder_P_LocalState * pstLocalState |
|---|
| 403 | ); |
|---|
| 404 | |
|---|
| 405 | static void BXVD_Decoder_S_ReleaseQ_AddPPB( |
|---|
| 406 | BXVD_ChannelHandle hXvdCh, |
|---|
| 407 | BXVD_P_PPB *pPPBPhysical |
|---|
| 408 | ); |
|---|
| 409 | |
|---|
| 410 | static void BXVD_Decoder_S_UnifiedQ_Initialize( |
|---|
| 411 | BXVD_ChannelHandle hXvdCh |
|---|
| 412 | ); |
|---|
| 413 | |
|---|
| 414 | static void BXVD_Decoder_S_UnifiedQ_AddPicture( |
|---|
| 415 | BXVD_ChannelHandle hXvdCh, |
|---|
| 416 | BXVD_Decoder_P_PictureContext * pstPictureCntxt, |
|---|
| 417 | bool bBasePicture |
|---|
| 418 | ); |
|---|
| 419 | |
|---|
| 420 | static void BXVD_Decoder_S_UnifiedQ_GetNextFreeElement( |
|---|
| 421 | BXVD_ChannelHandle hXvdCh, |
|---|
| 422 | BXVD_Decoder_P_UnifiedPictureContext ** ppstUnifiedContext |
|---|
| 423 | ); |
|---|
| 424 | |
|---|
| 425 | static void BXVD_Decoder_S_UnifiedQ_GetLastElement( |
|---|
| 426 | BXVD_ChannelHandle hXvdCh, |
|---|
| 427 | BXVD_Decoder_P_UnifiedPictureContext ** ppstUnifiedContext, |
|---|
| 428 | bool bBumpReadOffset |
|---|
| 429 | ); |
|---|
| 430 | |
|---|
| 431 | static void BXVD_Decoder_S_UnifiedQ_DumpElement( |
|---|
| 432 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext, |
|---|
| 433 | bool bDependentPicture |
|---|
| 434 | ); |
|---|
| 435 | |
|---|
| 436 | static void BXVD_Decoder_S_UnifiedQ_ReleaseElement( |
|---|
| 437 | BXVD_ChannelHandle hXvdCh, |
|---|
| 438 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext |
|---|
| 439 | ); |
|---|
| 440 | |
|---|
| 441 | static uint32_t BXVD_Decoder_S_UnifiedQ_GetFreeCount( |
|---|
| 442 | BXVD_ChannelHandle hXvdCh |
|---|
| 443 | ); |
|---|
| 444 | |
|---|
| 445 | static uint32_t BXVD_Decoder_S_UnifiedQ_GetPictureCount( |
|---|
| 446 | BXVD_ChannelHandle hXvdCh |
|---|
| 447 | ); |
|---|
| 448 | |
|---|
| 449 | static void BXVD_Decoder_S_ComputeAspectRatio( |
|---|
| 450 | BXVD_P_PPB * pPPB, |
|---|
| 451 | BXDM_Picture * pstXdmPicture, |
|---|
| 452 | BAVC_VideoCompressionStd eProtocol |
|---|
| 453 | ); |
|---|
| 454 | |
|---|
| 455 | #if BXVD_DM_ENABLE_YUV_GRAB_MODE |
|---|
| 456 | void BXVD_Decoder_S_Dbg_DumpPPB( BXVD_P_PPB *ppb ); |
|---|
| 457 | void BXVD_Decoder_S_Dbg_DumpRVC( BXVD_ChannelHandle hXvdCh ); |
|---|
| 458 | void BXVD_Decoder_S_Dbg_DumpYUV( BXVD_ChannelHandle hXvdCh, BXVD_P_PPB *ppb ); |
|---|
| 459 | #endif |
|---|
| 460 | |
|---|
| 461 | /*************************************************************************** |
|---|
| 462 | * |
|---|
| 463 | * Local macros. |
|---|
| 464 | * |
|---|
| 465 | ***************************************************************************/ |
|---|
| 466 | |
|---|
| 467 | /*************************************************************************** |
|---|
| 468 | * |
|---|
| 469 | * Private functions. |
|---|
| 470 | * |
|---|
| 471 | ***************************************************************************/ |
|---|
| 472 | |
|---|
| 473 | #if BXVD_P_DBG_PIC_QUES |
|---|
| 474 | static void BXVD_Decoder_S_Printf( char * pszFormat, ... ) |
|---|
| 475 | { |
|---|
| 476 | va_list pArg; |
|---|
| 477 | |
|---|
| 478 | va_start( pArg, pszFormat ); |
|---|
| 479 | BKNI_Vprintf( pszFormat, pArg ); |
|---|
| 480 | va_end( pArg ); |
|---|
| 481 | } |
|---|
| 482 | |
|---|
| 483 | #else |
|---|
| 484 | static void BXVD_Decoder_S_Printf( char * pszFormat, ... ) |
|---|
| 485 | { |
|---|
| 486 | BSTD_UNUSED( pszFormat ); |
|---|
| 487 | BDBG_NOP(); |
|---|
| 488 | } |
|---|
| 489 | #endif |
|---|
| 490 | |
|---|
| 491 | static void BXVD_Decoder_S_Increment_0BasedOffset( |
|---|
| 492 | uint32_t* pOffset, |
|---|
| 493 | uint32_t uiCount, |
|---|
| 494 | uint32_t uiMaxValue |
|---|
| 495 | ) |
|---|
| 496 | { |
|---|
| 497 | uint32_t i; |
|---|
| 498 | |
|---|
| 499 | for ( i=0; i < uiCount; i++ ) |
|---|
| 500 | { |
|---|
| 501 | /* If the offset is about to go off the end of the queue, |
|---|
| 502 | * set it back to the beginning. Otherwise just increment it. |
|---|
| 503 | */ |
|---|
| 504 | if( *pOffset >= uiMaxValue - 1/*(BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE - 1)*/ ) |
|---|
| 505 | { |
|---|
| 506 | *pOffset = 0; |
|---|
| 507 | } |
|---|
| 508 | else |
|---|
| 509 | { |
|---|
| 510 | (*pOffset)++; |
|---|
| 511 | } |
|---|
| 512 | } |
|---|
| 513 | |
|---|
| 514 | return; |
|---|
| 515 | } |
|---|
| 516 | |
|---|
| 517 | |
|---|
| 518 | static void BXVD_Decoder_S_Decrement_0BasedOffset( |
|---|
| 519 | uint32_t* pOffset, |
|---|
| 520 | uint32_t uiCount, |
|---|
| 521 | uint32_t uiMaxValue |
|---|
| 522 | ) |
|---|
| 523 | { |
|---|
| 524 | uint32_t i; |
|---|
| 525 | |
|---|
| 526 | for ( i=0; i < uiCount; i++ ) |
|---|
| 527 | { |
|---|
| 528 | /* If the offset is about to go off the beginning of the queue, |
|---|
| 529 | * set it to the end. Otherwise just decrement it. |
|---|
| 530 | */ |
|---|
| 531 | if( *pOffset == 0 ) |
|---|
| 532 | { |
|---|
| 533 | *pOffset = uiMaxValue - 1/*BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE - 1*/; |
|---|
| 534 | } |
|---|
| 535 | else |
|---|
| 536 | { |
|---|
| 537 | (*pOffset)--; |
|---|
| 538 | } |
|---|
| 539 | } |
|---|
| 540 | |
|---|
| 541 | return; |
|---|
| 542 | } |
|---|
| 543 | |
|---|
| 544 | static void BXVD_Decoder_S_Decrement_2BasedOffset( |
|---|
| 545 | uint32_t* pOffset, |
|---|
| 546 | uint32_t uiCount, |
|---|
| 547 | uint32_t uiMaxValue |
|---|
| 548 | ) |
|---|
| 549 | { |
|---|
| 550 | uint32_t i; |
|---|
| 551 | |
|---|
| 552 | for ( i=0; i < uiCount; i++ ) |
|---|
| 553 | { |
|---|
| 554 | /* If the offset is about to go off the beginning of the queue, |
|---|
| 555 | * set it to the end. Otherwise just decrement it. |
|---|
| 556 | */ |
|---|
| 557 | if( *pOffset <= BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE ) |
|---|
| 558 | { |
|---|
| 559 | *pOffset = uiMaxValue - 1 /*BXVD_P_DISP_FIFO_DEPTH - 1*/; |
|---|
| 560 | } |
|---|
| 561 | else |
|---|
| 562 | { |
|---|
| 563 | (*pOffset)--; |
|---|
| 564 | } |
|---|
| 565 | } |
|---|
| 566 | |
|---|
| 567 | return; |
|---|
| 568 | } |
|---|
| 569 | |
|---|
| 570 | /*************************************************************************** |
|---|
| 571 | * |
|---|
| 572 | * Routines for managing the delivery queue. |
|---|
| 573 | * |
|---|
| 574 | ***************************************************************************/ |
|---|
| 575 | |
|---|
| 576 | static bool BXVD_Decoder_S_ContextQ_PeekAtNextElement( |
|---|
| 577 | BXVD_ChannelHandle hXvdCh, |
|---|
| 578 | BXVD_Decoder_P_PictureContext ** pstPicCntxt |
|---|
| 579 | ) |
|---|
| 580 | { |
|---|
| 581 | bool bReturn; |
|---|
| 582 | uint32_t uiContextQReadOffset0Based; |
|---|
| 583 | |
|---|
| 584 | BXVD_Decoder_P_PictureContextQueue * pstContextQueue = &(hXvdCh->stDecoderContext.stPictureContextQueue); |
|---|
| 585 | |
|---|
| 586 | BDBG_ENTER(BXVD_Decoder_S_ContextQ_PeekAtNextElement); |
|---|
| 587 | |
|---|
| 588 | /* Return the appropriate display queue read offset based on the state of DQT. |
|---|
| 589 | * If playing backwards, return "uiReverseReadOffset" which is walking backwards |
|---|
| 590 | * through each GOP. Else, return the standard "read offset". |
|---|
| 591 | */ |
|---|
| 592 | if ( true == hXvdCh->stDecoderContext.stDqtCntxt.bDqtEnabled ) |
|---|
| 593 | { |
|---|
| 594 | uiContextQReadOffset0Based = hXvdCh->stDecoderContext.stDqtCntxt.uiReverseReadOffset; |
|---|
| 595 | } |
|---|
| 596 | else |
|---|
| 597 | { |
|---|
| 598 | BXVD_AVD_P_DELIVERY_QUEUE_GET_READ_OFFSET( hXvdCh, uiContextQReadOffset0Based ); |
|---|
| 599 | } |
|---|
| 600 | |
|---|
| 601 | uiContextQReadOffset0Based -= BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 602 | |
|---|
| 603 | /* If the read offset is equal to the context queue write offset, |
|---|
| 604 | * both the deliver and context queues are empty, i.e. all the |
|---|
| 605 | * pictures have been processed and are on the unified picture queue. |
|---|
| 606 | */ |
|---|
| 607 | if ( uiContextQReadOffset0Based == pstContextQueue->uiWriteOffset ) |
|---|
| 608 | { |
|---|
| 609 | bReturn = false; |
|---|
| 610 | *pstPicCntxt = NULL; |
|---|
| 611 | } |
|---|
| 612 | else |
|---|
| 613 | { |
|---|
| 614 | /* Queue has data, simply return a pointer to the next element. */ |
|---|
| 615 | |
|---|
| 616 | bReturn = true; |
|---|
| 617 | *pstPicCntxt = &(pstContextQueue->astPictureContext[ uiContextQReadOffset0Based ]); |
|---|
| 618 | } |
|---|
| 619 | |
|---|
| 620 | |
|---|
| 621 | BDBG_LEAVE(BXVD_Decoder_S_ContextQ_PeekAtNextElement); |
|---|
| 622 | |
|---|
| 623 | return bReturn; |
|---|
| 624 | } |
|---|
| 625 | |
|---|
| 626 | /**************************************************************************************************** |
|---|
| 627 | ** |
|---|
| 628 | ** Local "utility" routines. |
|---|
| 629 | ** |
|---|
| 630 | *****************************************************************************************************/ |
|---|
| 631 | |
|---|
| 632 | static void BXVD_Decoder_S_Log_Init( |
|---|
| 633 | BXVD_ChannelHandle hXvdCh |
|---|
| 634 | ) |
|---|
| 635 | { |
|---|
| 636 | BDBG_ENTER( BXVD_Decoder_S_Log_Init ); |
|---|
| 637 | |
|---|
| 638 | BKNI_Memset( &(hXvdCh->stDecoderContext.stLogData), 0, sizeof( BXVD_Decoder_P_LogData )); |
|---|
| 639 | |
|---|
| 640 | /* Want to print out the results roughly once per second. |
|---|
| 641 | * We'll count vsyncs to measure time. |
|---|
| 642 | */ |
|---|
| 643 | switch ( hXvdCh->sChSettings.ui32MonitorRefreshRate ) |
|---|
| 644 | { |
|---|
| 645 | case BXVD_MONITOR_REFRESH_RATE_50Hz: |
|---|
| 646 | hXvdCh->stDecoderContext.stLogData.uiVsyncsPerSecond = 50; |
|---|
| 647 | break; |
|---|
| 648 | |
|---|
| 649 | case BXVD_MONITOR_REFRESH_RATE_59_94Hz: |
|---|
| 650 | case BXVD_MONITOR_REFRESH_RATE_60Hz: |
|---|
| 651 | hXvdCh->stDecoderContext.stLogData.uiVsyncsPerSecond = 60; |
|---|
| 652 | break; |
|---|
| 653 | |
|---|
| 654 | case BXVD_MONITOR_REFRESH_RATE_23_976Hz: |
|---|
| 655 | case BXVD_MONITOR_REFRESH_RATE_24Hz: |
|---|
| 656 | hXvdCh->stDecoderContext.stLogData.uiVsyncsPerSecond = 24; |
|---|
| 657 | break; |
|---|
| 658 | |
|---|
| 659 | case BXVD_MONITOR_REFRESH_RATE_25Hz: |
|---|
| 660 | hXvdCh->stDecoderContext.stLogData.uiVsyncsPerSecond = 25; |
|---|
| 661 | break; |
|---|
| 662 | |
|---|
| 663 | case BXVD_MONITOR_REFRESH_RATE_30Hz: |
|---|
| 664 | case BXVD_MONITOR_REFRESH_RATE_29_97Hz: |
|---|
| 665 | hXvdCh->stDecoderContext.stLogData.uiVsyncsPerSecond = 30; |
|---|
| 666 | break; |
|---|
| 667 | |
|---|
| 668 | case BXVD_MONITOR_REFRESH_RATE_48Hz: |
|---|
| 669 | hXvdCh->stDecoderContext.stLogData.uiVsyncsPerSecond = 48; |
|---|
| 670 | break; |
|---|
| 671 | |
|---|
| 672 | case BXVD_MONITOR_REFRESH_RATE_INVALID: |
|---|
| 673 | default: |
|---|
| 674 | hXvdCh->stDecoderContext.stLogData.uiVsyncsPerSecond = 60; |
|---|
| 675 | break; |
|---|
| 676 | } |
|---|
| 677 | |
|---|
| 678 | BDBG_LEAVE( BXVD_Decoder_S_Log_Init ); |
|---|
| 679 | |
|---|
| 680 | return; |
|---|
| 681 | |
|---|
| 682 | } /* end of BXVD_Decoder_S_Log_Init */ |
|---|
| 683 | |
|---|
| 684 | static void BXVD_Decoder_S_Log_Print( |
|---|
| 685 | BXVD_ChannelHandle hXvdCh, |
|---|
| 686 | BXVD_Decoder_P_LocalState * pstLocalState |
|---|
| 687 | ) |
|---|
| 688 | { |
|---|
| 689 | BXVD_Decoder_P_LogData * pstLogData = &(hXvdCh->stDecoderContext.stLogData); |
|---|
| 690 | |
|---|
| 691 | BDBG_ENTER( BXVD_Decoder_S_Log_Print ); |
|---|
| 692 | |
|---|
| 693 | /* Print out the results roughly once per second. */ |
|---|
| 694 | if ( pstLogData->uiCallbackCount >= pstLogData->uiVsyncsPerSecond ) |
|---|
| 695 | { |
|---|
| 696 | uint32_t uiReadOffset; |
|---|
| 697 | uint32_t uiWriteOffset; |
|---|
| 698 | uint32_t uiDeliveryQDepth; |
|---|
| 699 | uint32_t uiReleaseQDepth; |
|---|
| 700 | uint32_t uiUnifiedQDepth; |
|---|
| 701 | uint32_t uiMaskHighWord, uiMaskLowWord; |
|---|
| 702 | int32_t i; |
|---|
| 703 | |
|---|
| 704 | BXVD_P_PictureDeliveryQueue * pstDeliveryQueue; |
|---|
| 705 | BXVD_P_PictureReleaseQueue * pstReleaseQueue; |
|---|
| 706 | |
|---|
| 707 | BXVD_Decoder_P_UnifiedPictureQueue * pstUnifiedQueue; |
|---|
| 708 | |
|---|
| 709 | /* Retrieve the read/write offsets for the delivery queue. |
|---|
| 710 | * Adjust them to be '0' based. |
|---|
| 711 | */ |
|---|
| 712 | BXVD_AVD_P_DELIVERY_QUEUE_GET_ADDR( hXvdCh, pstDeliveryQueue ); |
|---|
| 713 | |
|---|
| 714 | BXVD_AVD_P_DELIVERY_QUEUE_GET_READ_OFFSET( hXvdCh, uiReadOffset ); |
|---|
| 715 | |
|---|
| 716 | uiReadOffset -= BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 717 | uiWriteOffset = pstLocalState->uiDeliveryQueueWriteOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 718 | |
|---|
| 719 | BXVD_AVD_P_GET_QUEUE_DEPTH( uiReadOffset, uiWriteOffset, uiDeliveryQDepth ); |
|---|
| 720 | |
|---|
| 721 | /* Retrieve the read/write offsets for the release queue. |
|---|
| 722 | * Adjust them to be '0' based. |
|---|
| 723 | */ |
|---|
| 724 | BXVD_AVD_P_RELEASE_QUEUE_GET_ADDR( hXvdCh, pstReleaseQueue ); |
|---|
| 725 | |
|---|
| 726 | BXVD_AVD_P_RELEASE_QUEUE_GET_READ_OFFSET( hXvdCh, uiReadOffset ); |
|---|
| 727 | BXVD_AVD_P_RELEASE_QUEUE_GET_SHADOW_WRITE_OFFSET( hXvdCh, uiWriteOffset ); |
|---|
| 728 | |
|---|
| 729 | uiReadOffset -= BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 730 | uiWriteOffset -= BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 731 | |
|---|
| 732 | BXVD_AVD_P_GET_QUEUE_DEPTH( uiReadOffset, uiWriteOffset, uiReleaseQDepth ); |
|---|
| 733 | |
|---|
| 734 | uiUnifiedQDepth = BXVD_Decoder_S_UnifiedQ_GetPictureCount( hXvdCh ); |
|---|
| 735 | |
|---|
| 736 | uiMaskHighWord = uiMaskLowWord = 0; |
|---|
| 737 | pstUnifiedQueue = &(hXvdCh->stDecoderContext.stUnifiedPictureQueue); |
|---|
| 738 | |
|---|
| 739 | /* Generate a mask of the Unified Queue elements in use. */ |
|---|
| 740 | for ( i = (BXVD_P_DECODER_PICTURE_QUEUE_DEPTH - 1); i >= 0; i-- ) |
|---|
| 741 | { |
|---|
| 742 | if ( pstUnifiedQueue->astUnifiedContext[ i ].bInUse ) |
|---|
| 743 | { |
|---|
| 744 | if ( i > 31 ) |
|---|
| 745 | { |
|---|
| 746 | uiMaskHighWord |= 1; |
|---|
| 747 | } |
|---|
| 748 | else |
|---|
| 749 | { |
|---|
| 750 | uiMaskLowWord |= 1; |
|---|
| 751 | } |
|---|
| 752 | } |
|---|
| 753 | |
|---|
| 754 | if ( i > 32 ) |
|---|
| 755 | { |
|---|
| 756 | uiMaskHighWord <<= 1; |
|---|
| 757 | } |
|---|
| 758 | else if ( i < 32 && i > 0 ) |
|---|
| 759 | { |
|---|
| 760 | uiMaskLowWord <<= 1; |
|---|
| 761 | } |
|---|
| 762 | } |
|---|
| 763 | |
|---|
| 764 | BXVD_DBG_MSG( hXvdCh, ("AVD: %d/%d Dec: %d/%d Dq: %d Rq: %d Uq: %d InUse: %08x%08x", |
|---|
| 765 | pstLogData->uiPicturesFromAvd, |
|---|
| 766 | pstLogData->uiPicturesToAvd, |
|---|
| 767 | pstLogData->uiPicturesToPP, |
|---|
| 768 | pstLogData->uiPicturesFromPP, |
|---|
| 769 | uiDeliveryQDepth, |
|---|
| 770 | uiReleaseQDepth, |
|---|
| 771 | uiUnifiedQDepth, |
|---|
| 772 | uiMaskHighWord, |
|---|
| 773 | uiMaskLowWord |
|---|
| 774 | )); |
|---|
| 775 | |
|---|
| 776 | pstLogData->uiCallbackCount = 0; |
|---|
| 777 | } |
|---|
| 778 | |
|---|
| 779 | pstLogData->uiCallbackCount++; |
|---|
| 780 | |
|---|
| 781 | BDBG_LEAVE( BXVD_Decoder_S_Log_Print ); |
|---|
| 782 | |
|---|
| 783 | return; |
|---|
| 784 | |
|---|
| 785 | } /* end of BXVD_Decoder_S_Log_Print */ |
|---|
| 786 | |
|---|
| 787 | static void BXVD_Decoder_S_OpenChannel( |
|---|
| 788 | BXVD_ChannelHandle hXvdCh |
|---|
| 789 | ) |
|---|
| 790 | { |
|---|
| 791 | BDBG_ENTER( BXVD_Decoder_S_OpenChannel ); |
|---|
| 792 | |
|---|
| 793 | hXvdCh->stDecoderContext.bHostSparseMode = false; |
|---|
| 794 | |
|---|
| 795 | /* Initialize the Unified Picture Queue */ |
|---|
| 796 | BXVD_Decoder_S_UnifiedQ_Initialize( hXvdCh ); |
|---|
| 797 | |
|---|
| 798 | BDBG_LEAVE( BXVD_Decoder_S_OpenChannel ); |
|---|
| 799 | |
|---|
| 800 | return; |
|---|
| 801 | |
|---|
| 802 | } /* end of BXVD_Decoder_S_OpenChannel */ |
|---|
| 803 | |
|---|
| 804 | /* |
|---|
| 805 | * A wrapper routine to be called by the still picture ISR handler. |
|---|
| 806 | */ |
|---|
| 807 | BERR_Code BXVD_Decoder_P_ComputeAspectRatio( |
|---|
| 808 | BXVD_P_PPB * pPPB, |
|---|
| 809 | BXDM_Picture * pstXdmPicture |
|---|
| 810 | ) |
|---|
| 811 | { |
|---|
| 812 | BDBG_ASSERT( pPPB ); |
|---|
| 813 | BDBG_ASSERT( pstXdmPicture ); |
|---|
| 814 | |
|---|
| 815 | BDBG_ENTER(BXVD_Decoder_P_ComputeAspectRatio); |
|---|
| 816 | |
|---|
| 817 | BXVD_Decoder_S_ComputeAspectRatio( pPPB, pstXdmPicture, pPPB->protocol ); |
|---|
| 818 | |
|---|
| 819 | BDBG_LEAVE(BXVD_Decoder_P_ComputeAspectRatio); |
|---|
| 820 | |
|---|
| 821 | return BERR_SUCCESS; |
|---|
| 822 | } |
|---|
| 823 | |
|---|
| 824 | /* |
|---|
| 825 | * |
|---|
| 826 | */ |
|---|
| 827 | static void BXVD_Decoder_S_ComputeAspectRatio( |
|---|
| 828 | BXVD_P_PPB * pPPB, |
|---|
| 829 | BXDM_Picture * pstXdmPicture, |
|---|
| 830 | BAVC_VideoCompressionStd eProtocol |
|---|
| 831 | ) |
|---|
| 832 | { |
|---|
| 833 | BDBG_ENTER(BXVD_Decoder_S_ComputeAspectRatio); |
|---|
| 834 | |
|---|
| 835 | BDBG_ASSERT( pPPB ); |
|---|
| 836 | BDBG_ASSERT( pstXdmPicture ); |
|---|
| 837 | |
|---|
| 838 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioX = 0; |
|---|
| 839 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioY = 0; |
|---|
| 840 | |
|---|
| 841 | switch ( eProtocol ) |
|---|
| 842 | { |
|---|
| 843 | case BAVC_VideoCompressionStd_eMPEG2: |
|---|
| 844 | case BAVC_VideoCompressionStd_eMPEG2DTV: |
|---|
| 845 | case BAVC_VideoCompressionStd_eMPEG2_DSS_PES: |
|---|
| 846 | /* In MPEG2 streams, the decoder sends a subset of SAR |
|---|
| 847 | * values (Sample Aspect Ratio). The subset of SAR values |
|---|
| 848 | * maps directly to explicit Display Aspect Ratio (DAR) |
|---|
| 849 | * values that the VDC supports */ |
|---|
| 850 | switch ( pPPB->aspect_ratio ) |
|---|
| 851 | { |
|---|
| 852 | case BXVD_P_PPB_AspectRatio_eSquare: |
|---|
| 853 | pstXdmPicture->stAspectRatio.eAspectRatio = BFMT_AspectRatio_eSquarePxl; |
|---|
| 854 | pstXdmPicture->stAspectRatio.bValid = true; |
|---|
| 855 | break; |
|---|
| 856 | |
|---|
| 857 | case BXVD_P_PPB_AspectRatio_e4_3: |
|---|
| 858 | pstXdmPicture->stAspectRatio.eAspectRatio = BFMT_AspectRatio_e4_3; |
|---|
| 859 | pstXdmPicture->stAspectRatio.bValid = true; |
|---|
| 860 | break; |
|---|
| 861 | |
|---|
| 862 | case BXVD_P_PPB_AspectRatio_e16_9: |
|---|
| 863 | pstXdmPicture->stAspectRatio.eAspectRatio = BFMT_AspectRatio_e16_9; |
|---|
| 864 | pstXdmPicture->stAspectRatio.bValid = true; |
|---|
| 865 | break; |
|---|
| 866 | |
|---|
| 867 | case BXVD_P_PPB_AspectRatio_e221_1: |
|---|
| 868 | pstXdmPicture->stAspectRatio.eAspectRatio = BFMT_AspectRatio_e221_1; |
|---|
| 869 | pstXdmPicture->stAspectRatio.bValid = true; |
|---|
| 870 | break; |
|---|
| 871 | |
|---|
| 872 | default: |
|---|
| 873 | pstXdmPicture->stAspectRatio.bValid = false; |
|---|
| 874 | } |
|---|
| 875 | break; |
|---|
| 876 | |
|---|
| 877 | default: |
|---|
| 878 | /* In H.264 streams, the decoder sends SAR values (Sample |
|---|
| 879 | * Aspect Ratio). VDC normally expects DAR values (Display |
|---|
| 880 | * Aspect Ratio) that are in the MPEG2 streams, so for |
|---|
| 881 | * H.264, we need to use the BFMT_AspectRatio_eSAR aspect |
|---|
| 882 | * ratio and set the ratios explicitly */ |
|---|
| 883 | |
|---|
| 884 | if ( BXVD_P_PPB_AspectRatio_eOther == pPPB->aspect_ratio ) |
|---|
| 885 | { |
|---|
| 886 | pstXdmPicture->stAspectRatio.eAspectRatio = BFMT_AspectRatio_eSAR; |
|---|
| 887 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioX = pPPB->custom_aspect_ratio_width_height & 0xFFFF; |
|---|
| 888 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioY = (pPPB->custom_aspect_ratio_width_height >> 16) & 0xFFFF; |
|---|
| 889 | pstXdmPicture->stAspectRatio.bValid = true; |
|---|
| 890 | } |
|---|
| 891 | else if ( BXVD_P_PPB_AspectRatio_eUnknown == pPPB->aspect_ratio ) |
|---|
| 892 | { |
|---|
| 893 | pstXdmPicture->stAspectRatio.eAspectRatio = BFMT_AspectRatio_eUnknown; |
|---|
| 894 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioX = sSampleAspectRatioLUT[pPPB->aspect_ratio].uiSampleAspectRatioX; |
|---|
| 895 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioY = sSampleAspectRatioLUT[pPPB->aspect_ratio].uiSampleAspectRatioY; |
|---|
| 896 | pstXdmPicture->stAspectRatio.bValid = true; |
|---|
| 897 | } |
|---|
| 898 | else if (( pPPB->aspect_ratio >= BXVD_P_PPB_AspectRatio_eSquare ) |
|---|
| 899 | && ( pPPB->aspect_ratio <= BXVD_P_PPB_AspectRatio_e221_1 )) |
|---|
| 900 | { |
|---|
| 901 | pstXdmPicture->stAspectRatio.eAspectRatio = BFMT_AspectRatio_eSAR; |
|---|
| 902 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioX = sSampleAspectRatioLUT[pPPB->aspect_ratio].uiSampleAspectRatioX; |
|---|
| 903 | pstXdmPicture->stAspectRatio.uiSampleAspectRatioY = sSampleAspectRatioLUT[pPPB->aspect_ratio].uiSampleAspectRatioY; |
|---|
| 904 | pstXdmPicture->stAspectRatio.bValid = true; |
|---|
| 905 | } |
|---|
| 906 | else |
|---|
| 907 | { |
|---|
| 908 | pstXdmPicture->stAspectRatio.bValid = false; |
|---|
| 909 | } |
|---|
| 910 | break; |
|---|
| 911 | } |
|---|
| 912 | |
|---|
| 913 | BDBG_LEAVE(BXVD_Decoder_S_ComputeAspectRatio); |
|---|
| 914 | |
|---|
| 915 | } /* end of BXVD_Decoder_S_ComputeAspectRatio() */ |
|---|
| 916 | |
|---|
| 917 | static void BXVD_Decoder_S_ComputeDigitalNoiseReduction( |
|---|
| 918 | BXVD_ChannelHandle hXvdCh, |
|---|
| 919 | BXVD_P_PPB * pPPB, |
|---|
| 920 | BXDM_Picture * pUnifiedPicture, |
|---|
| 921 | BAVC_VideoCompressionStd eProtocol |
|---|
| 922 | ) |
|---|
| 923 | { |
|---|
| 924 | bool ref_pic_flag; |
|---|
| 925 | unsigned long avg_qp_cur; |
|---|
| 926 | unsigned long avg_qp_ref; |
|---|
| 927 | unsigned long intra_mb_cnt; |
|---|
| 928 | unsigned long inter_coded_mb_cnt; |
|---|
| 929 | unsigned long total_mb_cnt; |
|---|
| 930 | unsigned long intra_low_sum; |
|---|
| 931 | unsigned long intra_hi_sum; |
|---|
| 932 | unsigned long inter_low_sum; |
|---|
| 933 | unsigned long inter_hi_sum; |
|---|
| 934 | |
|---|
| 935 | unsigned long act_qp_ref; |
|---|
| 936 | unsigned long adj_Qp = 0; |
|---|
| 937 | unsigned long intra_default; |
|---|
| 938 | unsigned long inter_default; |
|---|
| 939 | |
|---|
| 940 | signed long wf1, wf2, sf1, sf2; |
|---|
| 941 | signed long var1,var2; |
|---|
| 942 | signed long var3,var4,var5,var6; |
|---|
| 943 | signed long Quo, Rem, Divd, Divs; |
|---|
| 944 | |
|---|
| 945 | bool p_forwarding; |
|---|
| 946 | signed long alpha; |
|---|
| 947 | |
|---|
| 948 | BDBG_ENTER(BXVD_Decoder_S_ComputeDigitalNoiseReduction); |
|---|
| 949 | |
|---|
| 950 | BDBG_ASSERT(pPPB); |
|---|
| 951 | BDBG_ASSERT(pUnifiedPicture); |
|---|
| 952 | |
|---|
| 953 | if ( NULL == pPPB ) |
|---|
| 954 | { |
|---|
| 955 | pUnifiedPicture->stDigitalNoiseReduction.bValid = false; |
|---|
| 956 | } |
|---|
| 957 | else |
|---|
| 958 | { |
|---|
| 959 | pUnifiedPicture->stDigitalNoiseReduction.bValid = true; |
|---|
| 960 | |
|---|
| 961 | /* Prepare DNR parameters */ |
|---|
| 962 | if (BAVC_VideoCompressionStd_eH264 == eProtocol) |
|---|
| 963 | { |
|---|
| 964 | intra_default = BXVD_Decoder_S_DNR_INTRA_DEFAULT_AVC; |
|---|
| 965 | inter_default = BXVD_Decoder_S_DNR_INTER_DEFAULT_AVC; |
|---|
| 966 | } |
|---|
| 967 | else{ |
|---|
| 968 | |
|---|
| 969 | intra_default = BXVD_Decoder_S_DNR_INTRA_DEFAULT; |
|---|
| 970 | inter_default = BXVD_Decoder_S_DNR_INTER_DEFAULT; |
|---|
| 971 | |
|---|
| 972 | } |
|---|
| 973 | |
|---|
| 974 | /* Ref Picture Flag is set if it is I or P picture */ |
|---|
| 975 | if ( (pPPB->dnr.pic_flags & BXVD_P_PPB_DNR_FLAG_REFPIC) == BXVD_P_PPB_DNR_FLAG_REFPIC ) |
|---|
| 976 | { |
|---|
| 977 | ref_pic_flag = 1; |
|---|
| 978 | } |
|---|
| 979 | else |
|---|
| 980 | { |
|---|
| 981 | ref_pic_flag = 0; |
|---|
| 982 | } |
|---|
| 983 | |
|---|
| 984 | /* Calculate the avg QP for current picture */ |
|---|
| 985 | if ( pPPB->dnr.num_mb_cur != 0 ) |
|---|
| 986 | { |
|---|
| 987 | /* avg_qp_cur = (pPPB->dnr.sum_qp_cur / pPPB->dnr.num_mb_cur) ;*/ |
|---|
| 988 | Divd = pPPB->dnr.sum_qp_cur; |
|---|
| 989 | Divs = pPPB->dnr.num_mb_cur; |
|---|
| 990 | |
|---|
| 991 | if (Divs != 0) |
|---|
| 992 | { |
|---|
| 993 | Quo = Divd/Divs; |
|---|
| 994 | } |
|---|
| 995 | else |
|---|
| 996 | { |
|---|
| 997 | Quo = Divd; |
|---|
| 998 | } |
|---|
| 999 | |
|---|
| 1000 | Rem = Divd - (Quo * Divs); |
|---|
| 1001 | |
|---|
| 1002 | Quo = BMTH_FIX_SIGNED_ITOFIX(Quo, 26, 5); |
|---|
| 1003 | Rem = BMTH_FIX_SIGNED_ITOFIX(Rem, 16, 15); |
|---|
| 1004 | Divs = BMTH_FIX_SIGNED_ITOFIX(Divs, 31, 0); |
|---|
| 1005 | |
|---|
| 1006 | if (Divs != 0) |
|---|
| 1007 | { |
|---|
| 1008 | avg_qp_cur = BMTH_FIX_SIGNED_DIV(Rem, Divs, 16, 15, 31, 0, 16, 15); |
|---|
| 1009 | avg_qp_cur = BMTH_FIX_SIGNED_CONVERT(avg_qp_cur, 16, 15, 26, 5); |
|---|
| 1010 | |
|---|
| 1011 | avg_qp_cur = avg_qp_cur + Quo; |
|---|
| 1012 | } |
|---|
| 1013 | else |
|---|
| 1014 | { |
|---|
| 1015 | avg_qp_cur = Quo; |
|---|
| 1016 | } |
|---|
| 1017 | |
|---|
| 1018 | /* avg_qp_cur (26,5)*/ |
|---|
| 1019 | |
|---|
| 1020 | } |
|---|
| 1021 | else |
|---|
| 1022 | { |
|---|
| 1023 | avg_qp_cur = 0; |
|---|
| 1024 | } |
|---|
| 1025 | |
|---|
| 1026 | /* Calculate the avg QP for reference picture */ |
|---|
| 1027 | if ( pPPB->dnr.num_mb_ref != 0 ) |
|---|
| 1028 | { |
|---|
| 1029 | /* avg_qp_ref = pPPB->dnr.sum_qp_ref / |
|---|
| 1030 | pPPB->dnr.num_mb_ref;*/ |
|---|
| 1031 | |
|---|
| 1032 | Divd = pPPB->dnr.sum_qp_ref; |
|---|
| 1033 | Divs = (pPPB->dnr.num_mb_ref); |
|---|
| 1034 | |
|---|
| 1035 | if (Divs != 0) |
|---|
| 1036 | { |
|---|
| 1037 | Quo = Divd/Divs; |
|---|
| 1038 | } |
|---|
| 1039 | else |
|---|
| 1040 | { |
|---|
| 1041 | Quo = Divd; |
|---|
| 1042 | } |
|---|
| 1043 | |
|---|
| 1044 | Rem = Divd - (Quo * Divs); |
|---|
| 1045 | |
|---|
| 1046 | Quo = BMTH_FIX_SIGNED_ITOFIX(Quo, 26, 5); |
|---|
| 1047 | Rem = BMTH_FIX_SIGNED_ITOFIX(Rem, 16, 15); |
|---|
| 1048 | Divs = BMTH_FIX_SIGNED_ITOFIX(Divs, 31, 0); |
|---|
| 1049 | |
|---|
| 1050 | if (Divs != 0) |
|---|
| 1051 | { |
|---|
| 1052 | avg_qp_ref = BMTH_FIX_SIGNED_DIV(Rem, Divs, 16, 15, 31, 0, 16, 15); |
|---|
| 1053 | avg_qp_ref = BMTH_FIX_SIGNED_CONVERT(avg_qp_cur, 16, 15, 26, 5); |
|---|
| 1054 | |
|---|
| 1055 | avg_qp_ref = avg_qp_ref + Quo; |
|---|
| 1056 | } |
|---|
| 1057 | else |
|---|
| 1058 | { |
|---|
| 1059 | avg_qp_ref = Quo; |
|---|
| 1060 | } |
|---|
| 1061 | |
|---|
| 1062 | /* avg_qp_ref (26,5) */ |
|---|
| 1063 | |
|---|
| 1064 | } |
|---|
| 1065 | else |
|---|
| 1066 | { |
|---|
| 1067 | avg_qp_ref = 0; |
|---|
| 1068 | } |
|---|
| 1069 | |
|---|
| 1070 | |
|---|
| 1071 | /* Extract the intra and inter MB count */ |
|---|
| 1072 | intra_mb_cnt = pPPB->dnr.mb_count_intra_inter >> 16; |
|---|
| 1073 | inter_coded_mb_cnt = (pPPB->dnr.mb_count_intra_inter & 0xffff); |
|---|
| 1074 | |
|---|
| 1075 | /* Store the total number of MB in current picture */ |
|---|
| 1076 | total_mb_cnt = pPPB->dnr.num_mb_cur; |
|---|
| 1077 | |
|---|
| 1078 | /* Extract the Intra sum */ |
|---|
| 1079 | intra_low_sum = pPPB->dnr.intra_qmat_sum_lo_hi >> 16; |
|---|
| 1080 | intra_hi_sum = pPPB->dnr.intra_qmat_sum_lo_hi & 0xffff; |
|---|
| 1081 | |
|---|
| 1082 | /* Extract the Inter sum */ |
|---|
| 1083 | inter_low_sum = pPPB->dnr.inter_qmat_sum_lo_hi >> 16; |
|---|
| 1084 | inter_hi_sum = pPPB->dnr.inter_qmat_sum_lo_hi & 0xffff; |
|---|
| 1085 | |
|---|
| 1086 | |
|---|
| 1087 | /* Initializing few parameters */ |
|---|
| 1088 | p_forwarding = 1; |
|---|
| 1089 | /* alpha = 0.5; */ |
|---|
| 1090 | alpha = 0x8; /* Q4 for 0.5 */ |
|---|
| 1091 | |
|---|
| 1092 | |
|---|
| 1093 | if ( (pPPB->dnr.pic_flags & BXVD_P_PPB_DNR_FLAG_GOPHEADER) == BXVD_P_PPB_DNR_FLAG_GOPHEADER ) |
|---|
| 1094 | { |
|---|
| 1095 | /* PR 36460 : XVD : DM in PI : Reset mechanism of DNR on */ |
|---|
| 1096 | /* closed GOP and /or video sequence header, is erroneous.*/ |
|---|
| 1097 | /* */ |
|---|
| 1098 | /* At the beginning of each video sequence or closed GOP */ |
|---|
| 1099 | /* boundary, old wrong code initializes these variables: */ |
|---|
| 1100 | /* adj_Qp_pre = 0; */ |
|---|
| 1101 | /* adj_Qp_ref = 0; */ |
|---|
| 1102 | /* */ |
|---|
| 1103 | /* but the correct reset mechanism is : */ |
|---|
| 1104 | /* */ |
|---|
| 1105 | /* At the beginning of each video sequence or closed GOP */ |
|---|
| 1106 | /* boundary, initialize these variables: */ |
|---|
| 1107 | /* adj_Qp_pre = adj_Qp; */ |
|---|
| 1108 | /* adj_Qp_ref = 0; */ |
|---|
| 1109 | /* */ |
|---|
| 1110 | /* hXdmPP->stDMContextState.stDNRInfo.adj_Qp_pre = 0; */ |
|---|
| 1111 | hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_ref = 0; |
|---|
| 1112 | } |
|---|
| 1113 | |
|---|
| 1114 | /* To avoid Divided By Zero Exception */ |
|---|
| 1115 | if ( total_mb_cnt == 0 ) |
|---|
| 1116 | { |
|---|
| 1117 | total_mb_cnt = hXvdCh->stDecoderContext.stDNRInfo.saved_mb_cnt; |
|---|
| 1118 | } |
|---|
| 1119 | else |
|---|
| 1120 | { |
|---|
| 1121 | hXvdCh->stDecoderContext.stDNRInfo.saved_mb_cnt = total_mb_cnt; |
|---|
| 1122 | } |
|---|
| 1123 | if ( (1 == p_forwarding) && |
|---|
| 1124 | (0 != hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_ref) ) |
|---|
| 1125 | { |
|---|
| 1126 | act_qp_ref = hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_ref; |
|---|
| 1127 | } |
|---|
| 1128 | else |
|---|
| 1129 | { |
|---|
| 1130 | act_qp_ref = avg_qp_ref; |
|---|
| 1131 | } |
|---|
| 1132 | |
|---|
| 1133 | if ( ref_pic_flag == 1 ) |
|---|
| 1134 | { |
|---|
| 1135 | /* w1 = (float)intra_mb_cnt / (float)total_mb_cnt; |
|---|
| 1136 | s1 = (float)(intra_low_sum + intra_hi_sum) / BXVD_P_INTRA_DEFAULT; |
|---|
| 1137 | w2 = (float)inter_coded_mb_cnt / (float)total_mb_cnt; |
|---|
| 1138 | s2 = (float)(inter_low_sum + inter_hi_sum) / BXVD_P_INTER_DEFAULT; |
|---|
| 1139 | adj_Qp = ((float)(w1 * s1 * avg_qp_cur +w2 * s2 * avg_qp_cur +(1 - w1 - w2) * act_qp_ref)+ 0.5); |
|---|
| 1140 | */ |
|---|
| 1141 | |
|---|
| 1142 | var1 = BMTH_FIX_SIGNED_ITOFIX(intra_mb_cnt, 16, 15); |
|---|
| 1143 | var2 = BMTH_FIX_SIGNED_ITOFIX(total_mb_cnt, 31, 0); |
|---|
| 1144 | if ( var2 != 0 ) |
|---|
| 1145 | { |
|---|
| 1146 | wf1 = BMTH_FIX_SIGNED_DIV(var1, var2, 16, 15, 31, 0, 16, 15) ; |
|---|
| 1147 | } |
|---|
| 1148 | else |
|---|
| 1149 | { |
|---|
| 1150 | wf1 = var1; |
|---|
| 1151 | } |
|---|
| 1152 | |
|---|
| 1153 | var1 = BMTH_FIX_SIGNED_ITOFIX((intra_low_sum + intra_hi_sum), 17, 14); |
|---|
| 1154 | var2 = BMTH_FIX_SIGNED_ITOFIX(intra_default, 31, 0); |
|---|
| 1155 | sf1 = BMTH_FIX_SIGNED_DIV(var1, var2, 17, 14, 31, 0, 17, 14) ; |
|---|
| 1156 | |
|---|
| 1157 | var1 = BMTH_FIX_SIGNED_ITOFIX(inter_coded_mb_cnt, 16, 15); |
|---|
| 1158 | var2 = BMTH_FIX_SIGNED_ITOFIX(total_mb_cnt, 31, 0); |
|---|
| 1159 | if ( var2 != 0 ) |
|---|
| 1160 | { |
|---|
| 1161 | wf2 = BMTH_FIX_SIGNED_DIV(var1, var2, 16, 15, 31, 0, 16, 15) ; |
|---|
| 1162 | } |
|---|
| 1163 | else |
|---|
| 1164 | { |
|---|
| 1165 | wf2 = var1; |
|---|
| 1166 | } |
|---|
| 1167 | |
|---|
| 1168 | var1 = BMTH_FIX_SIGNED_ITOFIX((inter_low_sum + inter_hi_sum), 17, 14); |
|---|
| 1169 | var2 = BMTH_FIX_SIGNED_ITOFIX(inter_default, 31, 0); |
|---|
| 1170 | sf2 = BMTH_FIX_SIGNED_DIV(var1, var2, 17, 14, 31, 0, 17, 14) ; |
|---|
| 1171 | |
|---|
| 1172 | var2 = BMTH_FIX_SIGNED_MUL(wf1, avg_qp_cur, 16, 15, 26, 5, 11, 20); |
|---|
| 1173 | var2 = BMTH_FIX_SIGNED_CONVERT(var2, 11, 20, 21, 10); |
|---|
| 1174 | sf1 = BMTH_FIX_SIGNED_CONVERT(sf1, 17, 14, 21, 10); |
|---|
| 1175 | var3 = BMTH_FIX_SIGNED_MUL(sf1, var2, 21, 10, 21, 10, 11, 20); |
|---|
| 1176 | |
|---|
| 1177 | var2 = BMTH_FIX_SIGNED_MUL(wf2, avg_qp_cur, 16, 15, 26, 5, 11, 20); |
|---|
| 1178 | var2 = BMTH_FIX_SIGNED_CONVERT(var2, 11, 20, 21, 10); |
|---|
| 1179 | sf2 = BMTH_FIX_SIGNED_CONVERT(sf2, 17, 14, 21, 10); |
|---|
| 1180 | var4 = BMTH_FIX_SIGNED_MUL(sf2, var2, 21, 10, 21, 10, 11, 20); |
|---|
| 1181 | |
|---|
| 1182 | var1 = (wf1 + wf2); |
|---|
| 1183 | var2 = BMTH_FIX_SIGNED_ITOFIX(1, 16, 15); |
|---|
| 1184 | var2 = var2 - var1; |
|---|
| 1185 | var5 = BMTH_FIX_SIGNED_MUL(var2, act_qp_ref, 16, 15, 26, 5, 11, 20); |
|---|
| 1186 | |
|---|
| 1187 | var6 = var3 + var4 + var5; |
|---|
| 1188 | var6 = BMTH_FIX_SIGNED_CONVERT(var6, 11, 20, 15, 16); |
|---|
| 1189 | |
|---|
| 1190 | adj_Qp = var6; |
|---|
| 1191 | |
|---|
| 1192 | /* hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_ref = adj_Qp; */ |
|---|
| 1193 | hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_ref = BMTH_FIX_SIGNED_CONVERT(adj_Qp, 15, 16, 26, 5); |
|---|
| 1194 | } |
|---|
| 1195 | else |
|---|
| 1196 | { |
|---|
| 1197 | /* w1 = (float)intra_mb_cnt / (float)total_mb_cnt; |
|---|
| 1198 | s1 = (float)(intra_low_sum + intra_hi_sum) / BXVD_P_INTRA_DEFAULT; |
|---|
| 1199 | w2 = (float)inter_coded_mb_cnt / (float)total_mb_cnt; |
|---|
| 1200 | s2 = (float)(inter_low_sum + inter_hi_sum) / BXVD_P_INTER_DEFAULT; |
|---|
| 1201 | adj_Qp = ((float)(w1 * s1 * avg_qp_cur +w2 * s2 * avg_qp_cur +(1 - w1 - w2) * act_qp_ref)+ 0.5); |
|---|
| 1202 | */ |
|---|
| 1203 | var1 = BMTH_FIX_SIGNED_ITOFIX(intra_mb_cnt, 16, 15); |
|---|
| 1204 | var2 = BMTH_FIX_SIGNED_ITOFIX(total_mb_cnt, 31, 0); |
|---|
| 1205 | if ( var2 != 0 ) |
|---|
| 1206 | { |
|---|
| 1207 | wf1 = BMTH_FIX_SIGNED_DIV(var1, var2, 16, 15, 31, 0, 16, 15) ; |
|---|
| 1208 | } |
|---|
| 1209 | else |
|---|
| 1210 | { |
|---|
| 1211 | wf1 = var1; |
|---|
| 1212 | } |
|---|
| 1213 | |
|---|
| 1214 | var1 = BMTH_FIX_SIGNED_ITOFIX((intra_low_sum + intra_hi_sum), 17, 14); |
|---|
| 1215 | var2 = BMTH_FIX_SIGNED_ITOFIX(intra_default, 31, 0); |
|---|
| 1216 | sf1 = BMTH_FIX_SIGNED_DIV(var1, var2, 17, 14, 31, 0, 17, 14) ; |
|---|
| 1217 | |
|---|
| 1218 | var1 = BMTH_FIX_SIGNED_ITOFIX(inter_coded_mb_cnt, 16, 15); |
|---|
| 1219 | var2 = BMTH_FIX_SIGNED_ITOFIX(total_mb_cnt, 31, 0); |
|---|
| 1220 | if ( var2 != 0 ) |
|---|
| 1221 | { |
|---|
| 1222 | wf2 = BMTH_FIX_SIGNED_DIV(var1, var2, 16, 15, 31, 0, 16, 15) ; |
|---|
| 1223 | } |
|---|
| 1224 | else |
|---|
| 1225 | { |
|---|
| 1226 | wf2 = var1; |
|---|
| 1227 | } |
|---|
| 1228 | |
|---|
| 1229 | var1 = BMTH_FIX_SIGNED_ITOFIX((inter_low_sum + inter_hi_sum), 17, 14); |
|---|
| 1230 | var2 = BMTH_FIX_SIGNED_ITOFIX(inter_default, 31, 0); |
|---|
| 1231 | sf2 = BMTH_FIX_SIGNED_DIV(var1, var2, 17, 14, 31, 0, 17, 14) ; |
|---|
| 1232 | |
|---|
| 1233 | var2 = BMTH_FIX_SIGNED_MUL(wf1, avg_qp_cur, 16, 15, 26, 5, 11, 20); |
|---|
| 1234 | var2 = BMTH_FIX_SIGNED_CONVERT(var2, 11, 20, 21, 10); |
|---|
| 1235 | sf1 = BMTH_FIX_SIGNED_CONVERT(sf1, 17, 14, 21, 10); |
|---|
| 1236 | var3 = BMTH_FIX_SIGNED_MUL(sf1, var2, 21, 10, 21, 10, 11, 20); |
|---|
| 1237 | |
|---|
| 1238 | var2 = BMTH_FIX_SIGNED_MUL(wf2, avg_qp_cur, 16, 15, 26, 5, 11, 20); |
|---|
| 1239 | var2 = BMTH_FIX_SIGNED_CONVERT(var2, 11, 20, 21, 10); |
|---|
| 1240 | sf2 = BMTH_FIX_SIGNED_CONVERT(sf2, 17, 14, 21, 10); |
|---|
| 1241 | var4 = BMTH_FIX_SIGNED_MUL(sf2, var2, 21, 10, 21, 10, 11, 20); |
|---|
| 1242 | |
|---|
| 1243 | var1 = (wf1 + wf2); |
|---|
| 1244 | var2 = BMTH_FIX_SIGNED_ITOFIX(1, 16, 15); |
|---|
| 1245 | var2 = var2 - var1; |
|---|
| 1246 | var5 = BMTH_FIX_SIGNED_MUL(var2, act_qp_ref, 16, 15, 26, 5, 11, 20); |
|---|
| 1247 | |
|---|
| 1248 | var6 = var3 + var4 + var5; |
|---|
| 1249 | var6 = BMTH_FIX_SIGNED_CONVERT(var6, 11, 20, 15, 16); |
|---|
| 1250 | |
|---|
| 1251 | adj_Qp = var6; |
|---|
| 1252 | } |
|---|
| 1253 | |
|---|
| 1254 | /* adj_Qp = (float)(alpha * adj_Qp) + (float)((1 - alpha) * (hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_pre)); |
|---|
| 1255 | hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_pre = adj_Qp;*/ |
|---|
| 1256 | |
|---|
| 1257 | /* PR 36460 : XVD : DM in PI : Reset mechanism of DNR on */ |
|---|
| 1258 | /* closed GOP and /or video sequence header, is erroneous.*/ |
|---|
| 1259 | /* */ |
|---|
| 1260 | /* At the beginning of each video sequence or closed GOP */ |
|---|
| 1261 | /* boundary, old wrong code initializes these variables: */ |
|---|
| 1262 | /* adj_Qp_pre = 0; */ |
|---|
| 1263 | /* adj_Qp_ref = 0; */ |
|---|
| 1264 | /* */ |
|---|
| 1265 | /* but the correct reset mechanism is : */ |
|---|
| 1266 | /* */ |
|---|
| 1267 | /* At the beginning of each video sequence or closed GOP */ |
|---|
| 1268 | /* boundary, initialize these variables: */ |
|---|
| 1269 | /* adj_Qp_pre = adj_Qp; */ |
|---|
| 1270 | /* adj_Qp_ref = 0; */ |
|---|
| 1271 | /* */ |
|---|
| 1272 | if ( (pPPB->dnr.pic_flags & BXVD_P_PPB_DNR_FLAG_GOPHEADER) == BXVD_P_PPB_DNR_FLAG_GOPHEADER ) |
|---|
| 1273 | { |
|---|
| 1274 | hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_pre = adj_Qp; |
|---|
| 1275 | } |
|---|
| 1276 | |
|---|
| 1277 | var1 = BMTH_FIX_SIGNED_MUL(alpha, adj_Qp, 27, 4, 15, 16, 11, 20); |
|---|
| 1278 | var2 = BMTH_FIX_SIGNED_CONVERT(1, 31, 0, 27, 4); |
|---|
| 1279 | |
|---|
| 1280 | var2 = var2-alpha; |
|---|
| 1281 | var2 = BMTH_FIX_SIGNED_MUL(hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_pre, var2, 15, 16, 27, 4, 11, 20); |
|---|
| 1282 | |
|---|
| 1283 | adj_Qp = var1 + var2; |
|---|
| 1284 | hXvdCh->stDecoderContext.stDNRInfo.adj_Qp_pre = BMTH_FIX_SIGNED_CONVERT(adj_Qp, 11, 20, 15, 16); |
|---|
| 1285 | adj_Qp = BMTH_FIX_SIGNED_FIXTOI(adj_Qp, 11, 20); |
|---|
| 1286 | |
|---|
| 1287 | pUnifiedPicture->stDigitalNoiseReduction.uiAdjustedQuantizationParameter = adj_Qp; |
|---|
| 1288 | } |
|---|
| 1289 | |
|---|
| 1290 | BDBG_LEAVE(BXVD_Decoder_S_ComputeDigitalNoiseReduction); |
|---|
| 1291 | return; |
|---|
| 1292 | } /* end of BXVD_Decoder_S_ComputeDigitalNoiseReduction() */ |
|---|
| 1293 | |
|---|
| 1294 | /******************************************************************************** |
|---|
| 1295 | ** |
|---|
| 1296 | ** Routines for managing the unified queue. |
|---|
| 1297 | ** |
|---|
| 1298 | ********************************************************************************/ |
|---|
| 1299 | |
|---|
| 1300 | static void BXVD_Decoder_S_UnifiedQ_DumpElement( |
|---|
| 1301 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext, |
|---|
| 1302 | bool bDependentPicture |
|---|
| 1303 | ) |
|---|
| 1304 | { |
|---|
| 1305 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_DumpElement ); |
|---|
| 1306 | |
|---|
| 1307 | if ( NULL != pstUnifiedContext ) |
|---|
| 1308 | { |
|---|
| 1309 | if ( true == bDependentPicture ) |
|---|
| 1310 | { |
|---|
| 1311 | BXVD_Decoder_S_Printf("\t", NULL ); |
|---|
| 1312 | } |
|---|
| 1313 | |
|---|
| 1314 | BXVD_Decoder_S_Printf("pUniCntxt: 0x%x index %d pPPB: 0x%x\n", |
|---|
| 1315 | pstUnifiedContext, |
|---|
| 1316 | pstUnifiedContext->uiIndex, |
|---|
| 1317 | pstUnifiedContext->pPPBPhysical |
|---|
| 1318 | ); |
|---|
| 1319 | |
|---|
| 1320 | if ( NULL != pstUnifiedContext->pstDependentUniContext ) |
|---|
| 1321 | { |
|---|
| 1322 | BXVD_Decoder_S_UnifiedQ_DumpElement( pstUnifiedContext->pstDependentUniContext, true ); |
|---|
| 1323 | } |
|---|
| 1324 | } |
|---|
| 1325 | |
|---|
| 1326 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_DumpElement ); |
|---|
| 1327 | |
|---|
| 1328 | return; |
|---|
| 1329 | |
|---|
| 1330 | } /* end of BXVD_Decoder_S_UnifiedQ_DumpElement */ |
|---|
| 1331 | |
|---|
| 1332 | static void BXVD_Decoder_S_UnifiedQ_Initialize( |
|---|
| 1333 | BXVD_ChannelHandle hXvdCh |
|---|
| 1334 | ) |
|---|
| 1335 | { |
|---|
| 1336 | BXVD_Decoder_P_UnifiedPictureQueue * pstUnifiedQueue; |
|---|
| 1337 | |
|---|
| 1338 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_Initialize ); |
|---|
| 1339 | |
|---|
| 1340 | /* |
|---|
| 1341 | * Initialize the Unified Picture Queue |
|---|
| 1342 | */ |
|---|
| 1343 | pstUnifiedQueue = &(hXvdCh->stDecoderContext.stUnifiedPictureQueue); |
|---|
| 1344 | |
|---|
| 1345 | BKNI_Memset( pstUnifiedQueue, 0, sizeof( BXVD_Decoder_P_UnifiedPictureQueue ) ); |
|---|
| 1346 | |
|---|
| 1347 | pstUnifiedQueue->pstContextTail = &(pstUnifiedQueue->astUnifiedContext[0]); |
|---|
| 1348 | pstUnifiedQueue->pstContextHead = &(pstUnifiedQueue->astUnifiedContext[0]); |
|---|
| 1349 | |
|---|
| 1350 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_Initialize ); |
|---|
| 1351 | |
|---|
| 1352 | return; |
|---|
| 1353 | |
|---|
| 1354 | } /* end of BXVD_Decoder_S_UnifiedQ_Initialize */ |
|---|
| 1355 | |
|---|
| 1356 | static void BXVD_Decoder_S_UnifiedQ_InvalidateElement( |
|---|
| 1357 | BXVD_ChannelHandle hXvdCh, |
|---|
| 1358 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext |
|---|
| 1359 | ) |
|---|
| 1360 | { |
|---|
| 1361 | BDBG_ENTER(BXVD_Decoder_S_UnifiedQ_InvalidateElement); |
|---|
| 1362 | |
|---|
| 1363 | BDBG_ASSERT(hXvdCh); |
|---|
| 1364 | BDBG_ASSERT(pstUnifiedContext); |
|---|
| 1365 | |
|---|
| 1366 | hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumUsedElements--; |
|---|
| 1367 | |
|---|
| 1368 | /* The element count should never go below 0. |
|---|
| 1369 | * If it does, these is a bug in the logic. |
|---|
| 1370 | */ |
|---|
| 1371 | BDBG_ASSERT(hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumUsedElements >= 0); |
|---|
| 1372 | |
|---|
| 1373 | pstUnifiedContext->bInUse = false; |
|---|
| 1374 | |
|---|
| 1375 | pstUnifiedContext->pstNextUniContext = NULL; |
|---|
| 1376 | pstUnifiedContext->pstPreviousUniContext = NULL; |
|---|
| 1377 | pstUnifiedContext->pstDependentUniContext = NULL; |
|---|
| 1378 | |
|---|
| 1379 | BDBG_LEAVE(BXVD_Decoder_S_UnifiedQ_InvalidateElement); |
|---|
| 1380 | |
|---|
| 1381 | return; |
|---|
| 1382 | } |
|---|
| 1383 | |
|---|
| 1384 | static void BXVD_Decoder_S_UnifiedQ_ParseSeiFramePackMsg( |
|---|
| 1385 | BXVD_P_SEI_FramePacking * pstAvdSEIData, |
|---|
| 1386 | BXDM_Picture_3D * pst3D |
|---|
| 1387 | ) |
|---|
| 1388 | { |
|---|
| 1389 | /* (SW7405-5135) The H264 specification was not completely rigorous in the definition of the |
|---|
| 1390 | * "arrangement_cancel" bit in the flags works. We are assuming that if this bit is set, none |
|---|
| 1391 | * of the other fields in the message are valid. This then implies that the picture is a 2D |
|---|
| 1392 | * picture. The orientation will be set to "2D" in both the Unified and MFD picture structures. |
|---|
| 1393 | */ |
|---|
| 1394 | if ( pstAvdSEIData->flags & BXVD_P_PPB_FLAG_SEI_FRAMEPACK_ARRANGEMENT_CANCEL ) |
|---|
| 1395 | { |
|---|
| 1396 | pst3D->eOrientation = BXDM_Picture_Orientation_e2D; |
|---|
| 1397 | pst3D->eFrameRelationship = BXDM_Picture_FrameRelationship_eUnknown; |
|---|
| 1398 | pst3D->uiFrameNum = 0; |
|---|
| 1399 | } |
|---|
| 1400 | else |
|---|
| 1401 | { |
|---|
| 1402 | /* Cancel bit is NOT set, parse the message and set the picture |
|---|
| 1403 | * orientation accordingly. |
|---|
| 1404 | */ |
|---|
| 1405 | switch( pstAvdSEIData->frame_packing_arrangement_type ) |
|---|
| 1406 | { |
|---|
| 1407 | case BXVD_P_PPB_SEI_FRAMEPACK_TYPE_CHECKER: |
|---|
| 1408 | pst3D->eOrientation = BXDM_Picture_Orientation_e3D_Checker; |
|---|
| 1409 | break; |
|---|
| 1410 | |
|---|
| 1411 | case BXVD_P_PPB_SEI_FRAMEPACK_TYPE_COLUMN: |
|---|
| 1412 | pst3D->eOrientation = BXDM_Picture_Orientation_e3D_Column; |
|---|
| 1413 | break; |
|---|
| 1414 | |
|---|
| 1415 | case BXVD_P_PPB_SEI_FRAMEPACK_TYPE_ROW: |
|---|
| 1416 | pst3D->eOrientation = BXDM_Picture_Orientation_e3D_Row; |
|---|
| 1417 | break; |
|---|
| 1418 | |
|---|
| 1419 | case BXVD_P_PPB_SEI_FRAMEPACK_TYPE_SIDE_BY_SIDE: |
|---|
| 1420 | pst3D->eOrientation = BXDM_Picture_Orientation_e3D_SideBySide; |
|---|
| 1421 | break; |
|---|
| 1422 | |
|---|
| 1423 | case BXVD_P_PPB_SEI_FRAMEPACK_TYPE_OVER_UNDER: |
|---|
| 1424 | pst3D->eOrientation = BXDM_Picture_Orientation_e3D_TopBottom; |
|---|
| 1425 | break; |
|---|
| 1426 | |
|---|
| 1427 | case BXVD_P_PPB_SEI_FRAMEPACK_TYPE_ALTERNATING: |
|---|
| 1428 | pst3D->eOrientation = BXDM_Picture_Orientation_e3D_FullFrame; |
|---|
| 1429 | break; |
|---|
| 1430 | |
|---|
| 1431 | default: |
|---|
| 1432 | pst3D->eOrientation = BXDM_Picture_Orientation_e2D; |
|---|
| 1433 | break; |
|---|
| 1434 | } |
|---|
| 1435 | |
|---|
| 1436 | switch( pstAvdSEIData->content_interpretation_type ) |
|---|
| 1437 | { |
|---|
| 1438 | case BXVD_P_PPB_SEI_FRAMEPACK_INTERPRET_FRAME0_LEFT: |
|---|
| 1439 | pst3D->eFrameRelationship = BXDM_Picture_FrameRelationship_eFrame0Left; |
|---|
| 1440 | break; |
|---|
| 1441 | |
|---|
| 1442 | case BXVD_P_PPB_SEI_FRAMEPACK_INTERPRET_FRAME0_RIGHT: |
|---|
| 1443 | pst3D->eFrameRelationship = BXDM_Picture_FrameRelationship_eFrame0Right; |
|---|
| 1444 | break; |
|---|
| 1445 | |
|---|
| 1446 | case BXVD_P_PPB_SEI_FRAMEPACK_INTERPRET_UNSPECIFIED: |
|---|
| 1447 | default: |
|---|
| 1448 | pst3D->eFrameRelationship = BXDM_Picture_FrameRelationship_eUnknown; |
|---|
| 1449 | break; |
|---|
| 1450 | } |
|---|
| 1451 | |
|---|
| 1452 | if ( pstAvdSEIData->flags & BXVD_P_PPB_FLAG_SEI_FRAMEPACK_CURRENT_FRAME_IS_FRAME0 ) |
|---|
| 1453 | { |
|---|
| 1454 | pst3D->uiFrameNum = 0; |
|---|
| 1455 | } |
|---|
| 1456 | else |
|---|
| 1457 | { |
|---|
| 1458 | pst3D->uiFrameNum = 1; |
|---|
| 1459 | } |
|---|
| 1460 | |
|---|
| 1461 | } /* end else (cancel bit is not set ) */ |
|---|
| 1462 | |
|---|
| 1463 | return; |
|---|
| 1464 | |
|---|
| 1465 | } /* end of BXVD_Decoder_S_UnifiedQ_ParseSeiFramePackMsg() */ |
|---|
| 1466 | |
|---|
| 1467 | static void BXVD_Decoder_S_UnifiedQ_ValidatePicture( |
|---|
| 1468 | BXVD_ChannelHandle hXvdCh, |
|---|
| 1469 | BXVD_Decoder_P_PictureContext * pstPictureCntxt, |
|---|
| 1470 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext, |
|---|
| 1471 | bool bPictureDropped |
|---|
| 1472 | ) |
|---|
| 1473 | { |
|---|
| 1474 | bool bMpegProtocol; |
|---|
| 1475 | uint32_t uiTemp; |
|---|
| 1476 | BXVD_P_PPB * pPPB; |
|---|
| 1477 | BXDM_Picture * pstXdmPicture; |
|---|
| 1478 | |
|---|
| 1479 | /* SW7405-4365: local variables to improve performance. */ |
|---|
| 1480 | uint32_t uiFlags; |
|---|
| 1481 | uint32_t uiFlagsExt0=0; |
|---|
| 1482 | BXVD_P_PPB_PullDown ePulldown; |
|---|
| 1483 | BAVC_VideoCompressionStd eProtocol; |
|---|
| 1484 | BAVC_FrameRateCode eFrameRate; |
|---|
| 1485 | |
|---|
| 1486 | BDBG_ENTER(BXVD_Decoder_S_UnifiedQ_ValidatePicture); |
|---|
| 1487 | |
|---|
| 1488 | BDBG_ASSERT(hXvdCh); |
|---|
| 1489 | BDBG_ASSERT(pstPictureCntxt); |
|---|
| 1490 | BDBG_ASSERT(pstUnifiedContext); |
|---|
| 1491 | |
|---|
| 1492 | pstXdmPicture = &(pstUnifiedContext->stUnifiedPicture); |
|---|
| 1493 | |
|---|
| 1494 | /* Reset the unified picture */ |
|---|
| 1495 | BKNI_Memset( pstXdmPicture, 0 , sizeof( BXDM_Picture ) ); |
|---|
| 1496 | |
|---|
| 1497 | /* Need to preserve the PPB address for use in BXVD_Decoder_ReleasePicture_isr |
|---|
| 1498 | * when releasing the picture. |
|---|
| 1499 | */ |
|---|
| 1500 | BDBG_ASSERT(pstPictureCntxt->stPPB.pPPBPhysical); |
|---|
| 1501 | |
|---|
| 1502 | pstUnifiedContext->pPPBPhysical = pstPictureCntxt->stPPB.pPPBPhysical; |
|---|
| 1503 | pstUnifiedContext->pPPB = pstPictureCntxt->stPPB.pPPB; |
|---|
| 1504 | pstXdmPicture->pPrivateContext = pstUnifiedContext; |
|---|
| 1505 | |
|---|
| 1506 | BDBG_ASSERT(pstPictureCntxt->stPPB.pPPB); |
|---|
| 1507 | |
|---|
| 1508 | /* SW7405-4365: Originally this routine was taking 35-40 usec's. Mapping |
|---|
| 1509 | * the PPB pointer to a cached address reduced this to ~20 usec's. However when the |
|---|
| 1510 | * call to invalidate the cache was added, the execution time was ~26 usec's. |
|---|
| 1511 | * If the non-cached PPB address is used and the most frequently used PPB elements |
|---|
| 1512 | * are copied to local variables, the execution time is in the 28-30 usec's range. |
|---|
| 1513 | * While not the most aesthetic solution, going with the local variables avoids any |
|---|
| 1514 | * potential performance hit from invalidating the cache for every picture. |
|---|
| 1515 | */ |
|---|
| 1516 | #if 1 |
|---|
| 1517 | pPPB = pstPictureCntxt->stPPB.pPPB; |
|---|
| 1518 | #else |
|---|
| 1519 | { |
|---|
| 1520 | /* SW7405-4365: experiment with using a cached PPB address. |
|---|
| 1521 | * If this code is enabled, handle failures more gracefully. |
|---|
| 1522 | */ |
|---|
| 1523 | BERR_Code berrCode; |
|---|
| 1524 | |
|---|
| 1525 | /* Update the PPB pointer to use a cached address. */ |
|---|
| 1526 | berrCode = BMEM_Heap_ConvertAddressToCached( |
|---|
| 1527 | hXvdCh->hSystemHeap, |
|---|
| 1528 | pstPictureCntxt->stPPB.pPPB, |
|---|
| 1529 | (void *)&pPPB |
|---|
| 1530 | ); |
|---|
| 1531 | |
|---|
| 1532 | BDBG_ASSERT( !berrCode ); |
|---|
| 1533 | |
|---|
| 1534 | /* The PPB is in shared physical memory. The MIPS cache has no "knowledge" that |
|---|
| 1535 | * this memory will be modified by AVD. To insure coherency, the cache must |
|---|
| 1536 | * be invalidated. The MIPS never writes anything to the PPB address, the following |
|---|
| 1537 | * flush should only be peforming an invalidate not a write back. |
|---|
| 1538 | */ |
|---|
| 1539 | berrCode = BMEM_Heap_FlushCache( |
|---|
| 1540 | hXvdCh->hSystemHeap, |
|---|
| 1541 | pPPB, |
|---|
| 1542 | sizeof( BXVD_P_PPB ) |
|---|
| 1543 | ); |
|---|
| 1544 | |
|---|
| 1545 | BDBG_ASSERT( !berrCode ); |
|---|
| 1546 | |
|---|
| 1547 | } |
|---|
| 1548 | #endif |
|---|
| 1549 | |
|---|
| 1550 | /* SW7405-4365: Copy the most frequently used PPB elements to local variables. |
|---|
| 1551 | */ |
|---|
| 1552 | uiFlags = pPPB->flags; |
|---|
| 1553 | ePulldown = pPPB->pulldown; |
|---|
| 1554 | eProtocol = pPPB->protocol; |
|---|
| 1555 | eFrameRate = pPPB->frame_rate; |
|---|
| 1556 | |
|---|
| 1557 | #if BXVD_P_PPB_EXTENDED |
|---|
| 1558 | uiFlagsExt0 = pPPB->flags_ext0; |
|---|
| 1559 | #else |
|---|
| 1560 | uiFlagsExt0 = 0; /* need to avoid a warning on some non-debug builds. */ |
|---|
| 1561 | #endif |
|---|
| 1562 | |
|---|
| 1563 | #if BXVD_DECODER_AVD_DEBUG_HELP |
|---|
| 1564 | BKNI_Printf("%d,%d\n", |
|---|
| 1565 | pPPB->il_perf_data.decode_cycle_count, |
|---|
| 1566 | pPPB->il_perf_data.inst_cache_miss); |
|---|
| 1567 | #endif |
|---|
| 1568 | |
|---|
| 1569 | /***************************/ |
|---|
| 1570 | /* BXDM_Picture_BufferInfo */ |
|---|
| 1571 | /***************************/ |
|---|
| 1572 | |
|---|
| 1573 | /* If a pictureless PPB, the buffer info will not be valid. */ |
|---|
| 1574 | pstXdmPicture->stBufferInfo.bValid = ( uiFlags & BXVD_P_PPB_FLAG_PICTURE_LESS_PPB ) ? false : true ; |
|---|
| 1575 | |
|---|
| 1576 | /* Set the picture heap */ |
|---|
| 1577 | BDBG_ASSERT(hXvdCh->hPictureHeap); |
|---|
| 1578 | pstXdmPicture->stBufferInfo.hHeap = hXvdCh->hPictureHeap; |
|---|
| 1579 | |
|---|
| 1580 | /* pLuminanceFrameBufferAddress */ |
|---|
| 1581 | BMEM_ConvertOffsetToAddress( |
|---|
| 1582 | pstXdmPicture->stBufferInfo.hHeap, |
|---|
| 1583 | pPPB->luma_video_address, |
|---|
| 1584 | &(pstXdmPicture->stBufferInfo.pLumaBufferVirtualAddress) |
|---|
| 1585 | ); |
|---|
| 1586 | |
|---|
| 1587 | /* pChrominanceFrameBufferAddress */ |
|---|
| 1588 | BMEM_ConvertOffsetToAddress( |
|---|
| 1589 | pstXdmPicture->stBufferInfo.hHeap, |
|---|
| 1590 | pPPB->chroma_video_address, |
|---|
| 1591 | &(pstXdmPicture->stBufferInfo.pChromaBufferVirtualAddress) |
|---|
| 1592 | ); |
|---|
| 1593 | |
|---|
| 1594 | /* source size */ |
|---|
| 1595 | pstXdmPicture->stBufferInfo.stSource.bValid = true; |
|---|
| 1596 | pstXdmPicture->stBufferInfo.stSource.uiWidth = pPPB->video_width; |
|---|
| 1597 | pstXdmPicture->stBufferInfo.stSource.uiHeight = pPPB->video_height; |
|---|
| 1598 | |
|---|
| 1599 | /* display size |
|---|
| 1600 | * SWBLURAY-21461: handle MPEG and AVS in a similar manner as VC1. |
|---|
| 1601 | */ |
|---|
| 1602 | switch ( eProtocol ) |
|---|
| 1603 | { |
|---|
| 1604 | case BAVC_VideoCompressionStd_eVC1: |
|---|
| 1605 | case BAVC_VideoCompressionStd_eVC1SimpleMain: |
|---|
| 1606 | pstXdmPicture->stBufferInfo.stDisplay.bValid = true; |
|---|
| 1607 | pstXdmPicture->stBufferInfo.stDisplay.uiWidth = pPPB->other.vc1.display_horizontal_size; |
|---|
| 1608 | pstXdmPicture->stBufferInfo.stDisplay.uiHeight = pPPB->other.vc1.display_vertical_size; |
|---|
| 1609 | break; |
|---|
| 1610 | |
|---|
| 1611 | case BAVC_VideoCompressionStd_eMPEG2: |
|---|
| 1612 | case BAVC_VideoCompressionStd_eMPEG1: |
|---|
| 1613 | case BAVC_VideoCompressionStd_eMPEG2DTV: |
|---|
| 1614 | case BAVC_VideoCompressionStd_eMPEG2_DSS_PES: |
|---|
| 1615 | pstXdmPicture->stBufferInfo.stDisplay.bValid = true; |
|---|
| 1616 | pstXdmPicture->stBufferInfo.stDisplay.uiWidth = pPPB->other.mpeg.display_horizontal_size; |
|---|
| 1617 | pstXdmPicture->stBufferInfo.stDisplay.uiHeight = pPPB->other.mpeg.display_vertical_size; |
|---|
| 1618 | break; |
|---|
| 1619 | |
|---|
| 1620 | case BAVC_VideoCompressionStd_eAVS: |
|---|
| 1621 | pstXdmPicture->stBufferInfo.stDisplay.bValid = true; |
|---|
| 1622 | pstXdmPicture->stBufferInfo.stDisplay.uiWidth = pPPB->other.avs.display_horizontal_size; |
|---|
| 1623 | pstXdmPicture->stBufferInfo.stDisplay.uiHeight = pPPB->other.avs.display_vertical_size; |
|---|
| 1624 | break; |
|---|
| 1625 | |
|---|
| 1626 | /* SWDTV-8681: add support for VP8 display size */ |
|---|
| 1627 | case BAVC_VideoCompressionStd_eVP8: |
|---|
| 1628 | pstXdmPicture->stBufferInfo.stDisplay.bValid = true; |
|---|
| 1629 | pstXdmPicture->stBufferInfo.stDisplay.uiWidth = pPPB->other.vp8.display_horizontal_size; |
|---|
| 1630 | pstXdmPicture->stBufferInfo.stDisplay.uiHeight = pPPB->other.vp8.display_vertical_size; |
|---|
| 1631 | break; |
|---|
| 1632 | |
|---|
| 1633 | default: |
|---|
| 1634 | pstXdmPicture->stBufferInfo.stDisplay.bValid = false; |
|---|
| 1635 | pstXdmPicture->stBufferInfo.stDisplay.uiWidth = 0; |
|---|
| 1636 | pstXdmPicture->stBufferInfo.stDisplay.uiHeight = 0; |
|---|
| 1637 | break; |
|---|
| 1638 | } |
|---|
| 1639 | |
|---|
| 1640 | /* BAVC_StripeWidth */ |
|---|
| 1641 | pstXdmPicture->stBufferInfo.eStripeWidth = sAVCStripeWidthLUT[hXvdCh->pXvd->uiDecode_StripeWidth]; |
|---|
| 1642 | |
|---|
| 1643 | /* Number of macroblocks size in the vertical direction |
|---|
| 1644 | * Should the shift happen here or in the output code? |
|---|
| 1645 | */ |
|---|
| 1646 | pstXdmPicture->stBufferInfo.uiLumaStripeHeight = pPPB->luma_stripe_height /* >> 4*/; |
|---|
| 1647 | pstXdmPicture->stBufferInfo.uiChromaStripeHeight = pPPB->chroma_stripe_height /* >> 4*/; |
|---|
| 1648 | |
|---|
| 1649 | /* Set the pulldown, start by range check. |
|---|
| 1650 | * (This is needed in case corrupted data is delivered.) |
|---|
| 1651 | * TODO: is the range checking appropriate? |
|---|
| 1652 | * TODO: is BXVD_DMTSM_S_ApplyCDTOverride handled in the Picture Provider? |
|---|
| 1653 | */ |
|---|
| 1654 | if (( ePulldown > BXVD_P_PPB_PullDown_eFrameX4 ) |
|---|
| 1655 | || ( ePulldown < BXVD_P_PPB_PullDown_eTop ) ) |
|---|
| 1656 | { |
|---|
| 1657 | pstXdmPicture->stBufferInfo.ePulldown = BXVD_P_PPB_PullDown_eTopBottom; |
|---|
| 1658 | } |
|---|
| 1659 | else |
|---|
| 1660 | { |
|---|
| 1661 | pstXdmPicture->stBufferInfo.ePulldown = ePulldown; |
|---|
| 1662 | } |
|---|
| 1663 | |
|---|
| 1664 | /* SW7601-180: conditionally override TB->TBT and BT->BTB, |
|---|
| 1665 | * if |
|---|
| 1666 | * - the application specified "BXVD_MPEGPulldownOverride_eRFF" |
|---|
| 1667 | * - AND an MPEG stream |
|---|
| 1668 | * - AND the video decoder set "repeat_first_field" |
|---|
| 1669 | */ |
|---|
| 1670 | bMpegProtocol = ( BAVC_VideoCompressionStd_eMPEG2 == eProtocol ); |
|---|
| 1671 | bMpegProtocol |= ( BAVC_VideoCompressionStd_eMPEG1 == eProtocol ); |
|---|
| 1672 | bMpegProtocol |= ( BAVC_VideoCompressionStd_eMPEG2DTV == eProtocol ); |
|---|
| 1673 | bMpegProtocol |= ( BAVC_VideoCompressionStd_eMPEG2_DSS_PES == eProtocol ); |
|---|
| 1674 | |
|---|
| 1675 | if ( BXVD_MPEGPulldownOverride_eRFF == hXvdCh->stDecoderContext.ePulldownOverride |
|---|
| 1676 | && true == bMpegProtocol ) |
|---|
| 1677 | { |
|---|
| 1678 | if ( 0 != pPPB->other.mpeg.repeat_first_field ) |
|---|
| 1679 | { |
|---|
| 1680 | switch( pstXdmPicture->stBufferInfo.ePulldown ) |
|---|
| 1681 | { |
|---|
| 1682 | case BXVD_P_PPB_PullDown_eTopBottom: |
|---|
| 1683 | pstXdmPicture->stBufferInfo.ePulldown = BXVD_P_PPB_PullDown_eTopBottomTop; |
|---|
| 1684 | break; |
|---|
| 1685 | |
|---|
| 1686 | case BXVD_P_PPB_PullDown_eBottomTop: |
|---|
| 1687 | pstXdmPicture->stBufferInfo.ePulldown = BXVD_P_PPB_PullDown_eBottomTopBottom; |
|---|
| 1688 | break; |
|---|
| 1689 | |
|---|
| 1690 | default: |
|---|
| 1691 | break; |
|---|
| 1692 | } |
|---|
| 1693 | } |
|---|
| 1694 | } |
|---|
| 1695 | |
|---|
| 1696 | /* Set the chroma location based on the protocol. (PR50994) |
|---|
| 1697 | * - if:: AVC and the VUI (Video Usability Information) parameters are |
|---|
| 1698 | * valid, copy the appropriate value from the PPB. |
|---|
| 1699 | * - else if:: MPEG1, use "BAVC_MpegType_eMpeg1". |
|---|
| 1700 | * - else:: default to "BAVC_MpegType_eMpeg2". |
|---|
| 1701 | */ |
|---|
| 1702 | if (( BAVC_VideoCompressionStd_eH264 == eProtocol ) |
|---|
| 1703 | && ( BXVD_P_PPB_H264_VALID_VUI & pPPB->other.h264.valid )) |
|---|
| 1704 | { |
|---|
| 1705 | /* If pulldown indicates |
|---|
| 1706 | * - only a bottom field, use the chroma bottom location |
|---|
| 1707 | * - an interlaced field, the Picture Provider will need to select the location based on the interrupt polarity |
|---|
| 1708 | * - only a top field or a frame, use the chroma top location |
|---|
| 1709 | */ |
|---|
| 1710 | switch( pstXdmPicture->stBufferInfo.ePulldown ) |
|---|
| 1711 | { |
|---|
| 1712 | case BXVD_P_PPB_PullDown_eBottom: |
|---|
| 1713 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eBotField].eMpegType = pPPB->other.h264.chroma_bottom; |
|---|
| 1714 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eBotField].bValid = true; |
|---|
| 1715 | break; |
|---|
| 1716 | |
|---|
| 1717 | case BXVD_P_PPB_PullDown_eTop: |
|---|
| 1718 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eTopField].eMpegType = pPPB->other.h264.chroma_top; |
|---|
| 1719 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eTopField].bValid = true; |
|---|
| 1720 | break; |
|---|
| 1721 | |
|---|
| 1722 | case BXVD_P_PPB_PullDown_eTopBottom: |
|---|
| 1723 | case BXVD_P_PPB_PullDown_eBottomTop: |
|---|
| 1724 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eBotField].eMpegType = pPPB->other.h264.chroma_bottom; |
|---|
| 1725 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eBotField].bValid = true; |
|---|
| 1726 | |
|---|
| 1727 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eTopField].eMpegType = pPPB->other.h264.chroma_top; |
|---|
| 1728 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eTopField].bValid = true; |
|---|
| 1729 | |
|---|
| 1730 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].eMpegType = pPPB->other.h264.chroma_top; |
|---|
| 1731 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].bValid = true; |
|---|
| 1732 | break; |
|---|
| 1733 | |
|---|
| 1734 | default: |
|---|
| 1735 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].eMpegType = pPPB->other.h264.chroma_top; |
|---|
| 1736 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].bValid = true; |
|---|
| 1737 | break; |
|---|
| 1738 | } |
|---|
| 1739 | } |
|---|
| 1740 | else if ( BAVC_VideoCompressionStd_eMPEG1 == eProtocol ) |
|---|
| 1741 | { |
|---|
| 1742 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].eMpegType = BAVC_MpegType_eMpeg1; |
|---|
| 1743 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].bValid = true; |
|---|
| 1744 | } |
|---|
| 1745 | else |
|---|
| 1746 | { |
|---|
| 1747 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].eMpegType = BAVC_MpegType_eMpeg2; |
|---|
| 1748 | pstXdmPicture->stBufferInfo.stChromaLocation[BAVC_Polarity_eFrame].bValid = true; |
|---|
| 1749 | } |
|---|
| 1750 | |
|---|
| 1751 | /* eYCbCrType, always the same for AVD |
|---|
| 1752 | * TODO: make this configurable? |
|---|
| 1753 | */ |
|---|
| 1754 | pstXdmPicture->stBufferInfo.eYCbCrType = BAVC_YCbCrType_e4_2_0; |
|---|
| 1755 | |
|---|
| 1756 | |
|---|
| 1757 | /* eSourceFormat: from the AVD PPB document |
|---|
| 1758 | * Bit 3:2 |
|---|
| 1759 | * - Value 00 indicates Progressive Source format |
|---|
| 1760 | * - Value 01 indicates Interlace Source format |
|---|
| 1761 | * - Value 1x indicates Unknown Source format |
|---|
| 1762 | */ |
|---|
| 1763 | uiTemp = ( uiFlags & BXVD_P_PPB_FLAG_EXTRACT_SOURCE_FORMAT_MASK ) >> BXVD_P_PPB_FLAG_EXTRACT_SOURCE_FORMAT_SHIFT; |
|---|
| 1764 | |
|---|
| 1765 | if ( 0 == uiTemp ) |
|---|
| 1766 | { |
|---|
| 1767 | pstXdmPicture->stBufferInfo.eSourceFormat = BXDM_Picture_SourceFormat_eProgressive; |
|---|
| 1768 | } |
|---|
| 1769 | else if ( 1 == uiTemp ) |
|---|
| 1770 | { |
|---|
| 1771 | pstXdmPicture->stBufferInfo.eSourceFormat = BXDM_Picture_SourceFormat_eInterlaced; |
|---|
| 1772 | } |
|---|
| 1773 | else |
|---|
| 1774 | { |
|---|
| 1775 | pstXdmPicture->stBufferInfo.eSourceFormat = BXDM_Picture_SourceFormat_eUnknown; |
|---|
| 1776 | } |
|---|
| 1777 | |
|---|
| 1778 | /*************************/ |
|---|
| 1779 | /* BXDM_Picture_Clipping */ |
|---|
| 1780 | /*************************/ |
|---|
| 1781 | if ( BAVC_VideoCompressionStd_eH264 == eProtocol ) |
|---|
| 1782 | { |
|---|
| 1783 | /* In H264, clipping information may be present, so we need to |
|---|
| 1784 | * tell VDC to read in the cropped region */ |
|---|
| 1785 | if ( pPPB->other.h264.valid & BXVD_P_PPB_H264_VALID_SPS_CROP ) |
|---|
| 1786 | { |
|---|
| 1787 | pstXdmPicture->stClipping.bValid = true; |
|---|
| 1788 | pstXdmPicture->stClipping.uiLeft = (pPPB->other.h264.sps_crop_horiz >> 16) & 0xFFFF; |
|---|
| 1789 | pstXdmPicture->stClipping.uiRight = pPPB->other.h264.sps_crop_horiz & 0xFFFF; |
|---|
| 1790 | pstXdmPicture->stClipping.uiTop = (pPPB->other.h264.sps_crop_vert >> 16) & 0xFFFF; |
|---|
| 1791 | pstXdmPicture->stClipping.uiBottom = pPPB->other.h264.sps_crop_vert & 0xFFFF; |
|---|
| 1792 | } |
|---|
| 1793 | } |
|---|
| 1794 | else if ( BAVC_VideoCompressionStd_eRV9 == eProtocol ) |
|---|
| 1795 | { |
|---|
| 1796 | /* SWDTV-7795: For RV9, clipping information will always be valid. |
|---|
| 1797 | * Set the clipping information so that VDC will crop. |
|---|
| 1798 | */ |
|---|
| 1799 | pstXdmPicture->stClipping.bValid = true; |
|---|
| 1800 | pstXdmPicture->stClipping.uiLeft = (pPPB->other.rv9.crop_horiz >> 16) & 0xFFFF; |
|---|
| 1801 | pstXdmPicture->stClipping.uiRight = pPPB->other.rv9.crop_horiz & 0xFFFF; |
|---|
| 1802 | pstXdmPicture->stClipping.uiTop = (pPPB->other.rv9.crop_vert >> 16) & 0xFFFF; |
|---|
| 1803 | pstXdmPicture->stClipping.uiBottom = pPPB->other.rv9.crop_vert & 0xFFFF; |
|---|
| 1804 | } |
|---|
| 1805 | |
|---|
| 1806 | |
|---|
| 1807 | |
|---|
| 1808 | /*************************/ |
|---|
| 1809 | /* BXDM_Picture_Protocol */ |
|---|
| 1810 | /*************************/ |
|---|
| 1811 | pstXdmPicture->stProtocol.eProtocol = eProtocol; |
|---|
| 1812 | pstXdmPicture->stProtocol.eLevel = (( pPPB->profile_level & BXVD_P_PPB_PROTOCOL_LEVEL_MASK ) >> BXVD_P_PPB_PROTOCOL_LEVEL_SHIFT ); |
|---|
| 1813 | pstXdmPicture->stProtocol.eProfile = (( pPPB->profile_level & BXVD_P_PPB_PROTOCOL_PROFILE_MASK ) >> BXVD_P_PPB_PROTOCOL_PROFILE_SHIFT ); |
|---|
| 1814 | |
|---|
| 1815 | /*********************/ |
|---|
| 1816 | /* BXDM_Picture_Type */ |
|---|
| 1817 | /*********************/ |
|---|
| 1818 | switch ( uiFlags & BXVD_P_PPB_FLAG_PICTURE_TYPE_MASK ) |
|---|
| 1819 | { |
|---|
| 1820 | case BXVD_P_PPB_FLAG_I_PICTURE: |
|---|
| 1821 | pstXdmPicture->stPictureType.eCoding = BXDM_Picture_Coding_eI; |
|---|
| 1822 | break; |
|---|
| 1823 | |
|---|
| 1824 | case BXVD_P_PPB_FLAG_P_PICTURE: |
|---|
| 1825 | pstXdmPicture->stPictureType.eCoding = BXDM_Picture_Coding_eP; |
|---|
| 1826 | break; |
|---|
| 1827 | |
|---|
| 1828 | case BXVD_P_PPB_FLAG_B_PICTURE: |
|---|
| 1829 | pstXdmPicture->stPictureType.eCoding = BXDM_Picture_Coding_eB; |
|---|
| 1830 | break; |
|---|
| 1831 | |
|---|
| 1832 | default: |
|---|
| 1833 | pstXdmPicture->stPictureType.eCoding = BXDM_Picture_Coding_eUnknown; |
|---|
| 1834 | } |
|---|
| 1835 | |
|---|
| 1836 | if ( uiFlags & BXVD_P_PPB_FLAG_PROG_SEQUENCE ) |
|---|
| 1837 | { |
|---|
| 1838 | pstXdmPicture->stPictureType.eSequence = BXDM_Picture_Sequence_eProgressive; |
|---|
| 1839 | } |
|---|
| 1840 | else |
|---|
| 1841 | { |
|---|
| 1842 | pstXdmPicture->stPictureType.eSequence = BXDM_Picture_Sequence_eInterlaced; |
|---|
| 1843 | } |
|---|
| 1844 | |
|---|
| 1845 | if (uiFlags & BXVD_P_PPB_FLAG_REF_PICTURE) |
|---|
| 1846 | { |
|---|
| 1847 | pstXdmPicture->stPictureType.bReference = true; |
|---|
| 1848 | } |
|---|
| 1849 | |
|---|
| 1850 | if (uiFlags & BXVD_P_PPB_FLAG_RAP_PICTURE) |
|---|
| 1851 | { |
|---|
| 1852 | pstXdmPicture->stPictureType.bRandomAccessPoint = true; |
|---|
| 1853 | } |
|---|
| 1854 | |
|---|
| 1855 | switch ( eProtocol ) |
|---|
| 1856 | { |
|---|
| 1857 | case BAVC_VideoCompressionStd_eMPEG2: |
|---|
| 1858 | case BAVC_VideoCompressionStd_eMPEG1: |
|---|
| 1859 | case BAVC_VideoCompressionStd_eMPEG2DTV: |
|---|
| 1860 | case BAVC_VideoCompressionStd_eMPEG2_DSS_PES: |
|---|
| 1861 | pstXdmPicture->stPictureType.bLowDelay = (( pPPB->other.mpeg.low_delay_video_format >> 16 ) & 0x3 ) ? true : false; |
|---|
| 1862 | break; |
|---|
| 1863 | |
|---|
| 1864 | default: |
|---|
| 1865 | pstXdmPicture->stPictureType.bLowDelay = false; |
|---|
| 1866 | break; |
|---|
| 1867 | } |
|---|
| 1868 | |
|---|
| 1869 | #if BXVD_P_PPB_EXTENDED |
|---|
| 1870 | |
|---|
| 1871 | /* SW7425-1001: effectively an EOS flag. Currently defined to |
|---|
| 1872 | * only be delivered with a "picture-less" PPB. |
|---|
| 1873 | */ |
|---|
| 1874 | if ( uiFlagsExt0 & BXVD_P_PPB_EXT0_FLAG_LAST_PICTURE ) |
|---|
| 1875 | { |
|---|
| 1876 | if ( uiFlags & BXVD_P_PPB_FLAG_PICTURE_LESS_PPB ) |
|---|
| 1877 | { |
|---|
| 1878 | pstXdmPicture->stPictureType.bLastPicture = true; |
|---|
| 1879 | } |
|---|
| 1880 | else |
|---|
| 1881 | { |
|---|
| 1882 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_ValidatePicture:: BXVD_P_PPB_EXT0_FLAG_LAST_PICTURE set for a standard PPB")); |
|---|
| 1883 | } |
|---|
| 1884 | } |
|---|
| 1885 | #endif |
|---|
| 1886 | |
|---|
| 1887 | /**********************/ |
|---|
| 1888 | /* BXDM_Picture_Error */ |
|---|
| 1889 | /**********************/ |
|---|
| 1890 | if( uiFlags & BXVD_P_PPB_FLAG_DECODE_ERROR ) |
|---|
| 1891 | { |
|---|
| 1892 | pstXdmPicture->stError.bThisPicture = true; |
|---|
| 1893 | } |
|---|
| 1894 | |
|---|
| 1895 | if( uiFlags & BXVD_P_PPB_FLAG_DECODE_REF_ERROR ) |
|---|
| 1896 | { |
|---|
| 1897 | pstXdmPicture->stError.bPreviousRefPic = true; |
|---|
| 1898 | } |
|---|
| 1899 | |
|---|
| 1900 | /* If the decoder input has overflowed, bump the count. */ |
|---|
| 1901 | |
|---|
| 1902 | if ( uiFlags & BXVD_P_PPB_FLAG_INPUT_OVERFLOW ) |
|---|
| 1903 | { |
|---|
| 1904 | hXvdCh->stDecoderContext.stCounters.uiDecoderInputOverflow++; |
|---|
| 1905 | } |
|---|
| 1906 | |
|---|
| 1907 | |
|---|
| 1908 | /**********************************/ |
|---|
| 1909 | /* BXDM_Picture_PictureOrderCount */ |
|---|
| 1910 | /**********************************/ |
|---|
| 1911 | if ( BAVC_VideoCompressionStd_eH264 == eProtocol ) |
|---|
| 1912 | { |
|---|
| 1913 | int32_t iPocBottom = pPPB->other.h264.poc_bottom; |
|---|
| 1914 | int32_t iPocTop = pPPB->other.h264.poc_top; |
|---|
| 1915 | |
|---|
| 1916 | pstXdmPicture->stPOC.uiPictureId = pPPB->other.h264.idr_pic_id; |
|---|
| 1917 | pstXdmPicture->stPOC.bValid = true; |
|---|
| 1918 | |
|---|
| 1919 | if ( iPocTop < iPocBottom ) |
|---|
| 1920 | { |
|---|
| 1921 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eFrame].iValue = iPocTop; |
|---|
| 1922 | } |
|---|
| 1923 | else |
|---|
| 1924 | { |
|---|
| 1925 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eFrame].iValue = iPocBottom; |
|---|
| 1926 | } |
|---|
| 1927 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eFrame].bValid = true; |
|---|
| 1928 | |
|---|
| 1929 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eTopField].iValue = iPocTop; |
|---|
| 1930 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eTopField].bValid = true; |
|---|
| 1931 | |
|---|
| 1932 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eBotField].iValue = iPocBottom; |
|---|
| 1933 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eBotField].bValid = true; |
|---|
| 1934 | } |
|---|
| 1935 | else if ( BAVC_VideoCompressionStd_eSVC == eProtocol ) |
|---|
| 1936 | { |
|---|
| 1937 | int32_t iPocBottom = pPPB->other.svc.poc_bottom; |
|---|
| 1938 | int32_t iPocTop = pPPB->other.svc.poc_top; |
|---|
| 1939 | |
|---|
| 1940 | pstXdmPicture->stPOC.uiPictureId = pPPB->other.svc.idr_pic_id; |
|---|
| 1941 | pstXdmPicture->stPOC.bValid = true; |
|---|
| 1942 | |
|---|
| 1943 | if ( iPocTop < iPocBottom ) |
|---|
| 1944 | { |
|---|
| 1945 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eFrame].iValue = iPocTop; |
|---|
| 1946 | } |
|---|
| 1947 | else |
|---|
| 1948 | { |
|---|
| 1949 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eFrame].iValue = iPocBottom; |
|---|
| 1950 | } |
|---|
| 1951 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eFrame].bValid = true; |
|---|
| 1952 | |
|---|
| 1953 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eTopField].iValue = iPocTop; |
|---|
| 1954 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eTopField].bValid = true; |
|---|
| 1955 | |
|---|
| 1956 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eBotField].iValue = iPocBottom; |
|---|
| 1957 | pstXdmPicture->stPOC.stPictureOrderCount[BAVC_Polarity_eBotField].bValid = true; |
|---|
| 1958 | } |
|---|
| 1959 | |
|---|
| 1960 | |
|---|
| 1961 | /**************************/ |
|---|
| 1962 | /* BXDM_Picture_FrameRate */ |
|---|
| 1963 | /**************************/ |
|---|
| 1964 | if ( eFrameRate == BAVC_FrameRateCode_eUnknown |
|---|
| 1965 | || eFrameRate > BAVC_FrameRateCode_e7_493 |
|---|
| 1966 | ) |
|---|
| 1967 | { |
|---|
| 1968 | pstXdmPicture->stFrameRate.bValid = true; |
|---|
| 1969 | |
|---|
| 1970 | pstXdmPicture->stFrameRate.stRate.uiNumerator = 0; |
|---|
| 1971 | pstXdmPicture->stFrameRate.stRate.uiDenominator = 0; |
|---|
| 1972 | } |
|---|
| 1973 | else |
|---|
| 1974 | { |
|---|
| 1975 | pstXdmPicture->stFrameRate.bValid = true; |
|---|
| 1976 | |
|---|
| 1977 | pstXdmPicture->stFrameRate.stRate = sFrameRateEnumToIntLUT[ eFrameRate ]; |
|---|
| 1978 | } |
|---|
| 1979 | |
|---|
| 1980 | /* SW3556-836: dereference the fixed_frame_rate_flag */ |
|---|
| 1981 | pstXdmPicture->stFrameRate.eType = ( uiFlags & BXVD_P_PPB_FLAG_FIXED_FRAME_RATE ) ? BXDM_Picture_FrameRateType_eFixed : BXDM_Picture_FrameRateType_eUnknown; |
|---|
| 1982 | |
|---|
| 1983 | switch ( eProtocol ) |
|---|
| 1984 | { |
|---|
| 1985 | case BAVC_VideoCompressionStd_eMPEG2: |
|---|
| 1986 | case BAVC_VideoCompressionStd_eMPEG1: |
|---|
| 1987 | case BAVC_VideoCompressionStd_eMPEG2DTV: |
|---|
| 1988 | case BAVC_VideoCompressionStd_eMPEG2_DSS_PES: |
|---|
| 1989 | /* frame_rate_extension:: [6:5]=frame_rate_extn_n, [4:0]=frame_rate_extn_d */ |
|---|
| 1990 | pstXdmPicture->stFrameRate.stExtension.uiNumerator = (( pPPB->other.mpeg.frame_rate_extension >> 5 ) & 0x3 ); |
|---|
| 1991 | pstXdmPicture->stFrameRate.stExtension.uiDenominator = ( pPPB->other.mpeg.frame_rate_extension & 0x1F ); |
|---|
| 1992 | break; |
|---|
| 1993 | |
|---|
| 1994 | default: |
|---|
| 1995 | pstXdmPicture->stFrameRate.stExtension.uiNumerator = 0; |
|---|
| 1996 | pstXdmPicture->stFrameRate.stExtension.uiDenominator = 0; |
|---|
| 1997 | break; |
|---|
| 1998 | } |
|---|
| 1999 | |
|---|
| 2000 | /********************/ |
|---|
| 2001 | /* BXDM_Picture_PTS */ |
|---|
| 2002 | /********************/ |
|---|
| 2003 | if ( uiFlags & BXVD_P_PPB_FLAG_PTS_PRESENT ) |
|---|
| 2004 | { |
|---|
| 2005 | pstXdmPicture->stPTS.bValid = true; |
|---|
| 2006 | pstXdmPicture->stPTS.uiValue = pPPB->pts;; |
|---|
| 2007 | |
|---|
| 2008 | /* "n_drop" is a running tally from AVD of the number of pictures dropped |
|---|
| 2009 | * in response to a request from the Picture Provider to drop pictures. |
|---|
| 2010 | * The "pending drop count" is the difference between the requested number |
|---|
| 2011 | * and "n_drop". While the "pending drop count" is non-zero, the Picture |
|---|
| 2012 | * Provider will run in VSYNC mode. When it does become zero, the PP will |
|---|
| 2013 | * switch to TSM mode. For this reason, we want to hold off reporting the |
|---|
| 2014 | * "pending drop count" as zero until a coded PTS has been received. Hence |
|---|
| 2015 | * this logic to only sample "n_drop" for pictures with a coded PTS. |
|---|
| 2016 | */ |
|---|
| 2017 | if ( BXVD_Decoder_P_PictureSet_eDependent != pstPictureCntxt->eSetType ) |
|---|
| 2018 | { |
|---|
| 2019 | hXvdCh->stDecoderContext.uiDropCountSnapshot = pPPB->n_drop; |
|---|
| 2020 | } |
|---|
| 2021 | } |
|---|
| 2022 | |
|---|
| 2023 | /* The drop count for this picture is the one that came with the last coded PTS. |
|---|
| 2024 | */ |
|---|
| 2025 | pstUnifiedContext->uiDropCount = hXvdCh->stDecoderContext.uiDropCountSnapshot; |
|---|
| 2026 | |
|---|
| 2027 | /**************************/ |
|---|
| 2028 | /* BXDM_Picture_PCROffset */ |
|---|
| 2029 | /**************************/ |
|---|
| 2030 | if ( uiFlags & BXVD_P_PPB_FLAG_PCR_OFFSET_PRESENT ) |
|---|
| 2031 | { |
|---|
| 2032 | pstXdmPicture->stPCROffset.bValid = true; |
|---|
| 2033 | pstXdmPicture->stPCROffset.uiValue = pPPB->pcr_offset; |
|---|
| 2034 | } |
|---|
| 2035 | |
|---|
| 2036 | if ( uiFlags & BXVD_P_PPB_FLAG_DISCONT_PCR_OFFSET ) |
|---|
| 2037 | { |
|---|
| 2038 | pstXdmPicture->stPCROffset.bDiscontinuity = true; |
|---|
| 2039 | } |
|---|
| 2040 | |
|---|
| 2041 | /****************************/ |
|---|
| 2042 | /* BXDM_Picture_GopTimeCode */ |
|---|
| 2043 | /****************************/ |
|---|
| 2044 | switch ( eProtocol ) |
|---|
| 2045 | { |
|---|
| 2046 | case BAVC_VideoCompressionStd_eMPEG2: |
|---|
| 2047 | case BAVC_VideoCompressionStd_eMPEG1: |
|---|
| 2048 | case BAVC_VideoCompressionStd_eMPEG2DTV: |
|---|
| 2049 | case BAVC_VideoCompressionStd_eMPEG2_DSS_PES: |
|---|
| 2050 | pstXdmPicture->stGOPTimeCode.uiHours = ( pPPB->other.mpeg.gop_time_code & BXVD_P_PPB_MPEG_GOP_HOUR_MASK ) >> BXVD_P_PPB_MPEG_GOP_HOUR_SHIFT; |
|---|
| 2051 | pstXdmPicture->stGOPTimeCode.uiMinutes = ( pPPB->other.mpeg.gop_time_code & BXVD_P_PPB_MPEG_GOP_MINUTE_MASK ) >> BXVD_P_PPB_MPEG_GOP_MINUTE_SHIFT; |
|---|
| 2052 | pstXdmPicture->stGOPTimeCode.uiSeconds = ( pPPB->other.mpeg.gop_time_code & BXVD_P_PPB_MPEG_GOP_SECOND_MASK ) >> BXVD_P_PPB_MPEG_GOP_SECOND_SHIFT; |
|---|
| 2053 | pstXdmPicture->stGOPTimeCode.uiPictures = ( pPPB->other.mpeg.gop_time_code & BXVD_P_PPB_MPEG_GOP_PICTURE_MASK ); |
|---|
| 2054 | pstXdmPicture->stGOPTimeCode.bValid = true; |
|---|
| 2055 | break; |
|---|
| 2056 | |
|---|
| 2057 | /* SW7401-4426: Extract the H264 time code. */ |
|---|
| 2058 | case BAVC_VideoCompressionStd_eH264: |
|---|
| 2059 | pstXdmPicture->stGOPTimeCode.uiHours = ( pPPB->time_code & BXVD_P_PPB_H264_GOP_HOUR_MASK ) >> BXVD_P_PPB_H264_GOP_HOUR_SHIFT; |
|---|
| 2060 | pstXdmPicture->stGOPTimeCode.uiMinutes = ( pPPB->time_code & BXVD_P_PPB_H264_GOP_MINUTE_MASK ) >> BXVD_P_PPB_H264_GOP_MINUTE_SHIFT; |
|---|
| 2061 | pstXdmPicture->stGOPTimeCode.uiSeconds = ( pPPB->time_code & BXVD_P_PPB_H264_GOP_SECOND_MASK ) >> BXVD_P_PPB_H264_GOP_SECOND_SHIFT; |
|---|
| 2062 | pstXdmPicture->stGOPTimeCode.uiPictures = ( pPPB->time_code & BXVD_P_PPB_H264_GOP_PICTURE_MASK ); |
|---|
| 2063 | pstXdmPicture->stGOPTimeCode.bValid = true; |
|---|
| 2064 | break; |
|---|
| 2065 | |
|---|
| 2066 | default: |
|---|
| 2067 | pstXdmPicture->stGOPTimeCode.bValid = false; |
|---|
| 2068 | break; |
|---|
| 2069 | } |
|---|
| 2070 | |
|---|
| 2071 | /********************/ |
|---|
| 2072 | /* BXDM_Picture_Tag */ |
|---|
| 2073 | /********************/ |
|---|
| 2074 | if ( uiFlags & BXVD_P_PPB_FLAG_PIC_TAG_PRESENT ) |
|---|
| 2075 | { |
|---|
| 2076 | pstXdmPicture->stPictureTag.uiValue = pPPB->picture_tag; |
|---|
| 2077 | pstXdmPicture->stPictureTag.bValid = true; |
|---|
| 2078 | } |
|---|
| 2079 | |
|---|
| 2080 | if ( uiFlags & BXVD_P_PPB_NEW_PIC_TAG_AVAIL ) |
|---|
| 2081 | { |
|---|
| 2082 | pstXdmPicture->stPictureTag.bNewTagAvailable = true; |
|---|
| 2083 | } |
|---|
| 2084 | |
|---|
| 2085 | /***********************/ |
|---|
| 2086 | /* BXDM_Picture_Marker */ |
|---|
| 2087 | /***********************/ |
|---|
| 2088 | pstXdmPicture->stPictureMarker.uiValue = pPPB->timing_marker; |
|---|
| 2089 | pstXdmPicture->stPictureMarker.bValid = true; |
|---|
| 2090 | |
|---|
| 2091 | /*************************/ |
|---|
| 2092 | /* BXDM_Picture_Overscan */ |
|---|
| 2093 | /*************************/ |
|---|
| 2094 | /* PR54677: Expose the overscan PPB flags to the app */ |
|---|
| 2095 | pstXdmPicture->stOverscan.bValid = ( uiFlags & BXVD_P_PPB_OVERSCAN_FLAG ) ? true : false; |
|---|
| 2096 | pstXdmPicture->stOverscan.bOverscanAppropriate = ( uiFlags & BXVD_P_PPB_OVERSCAN_APPROPRIATE_FLAG ) ? true : false; |
|---|
| 2097 | |
|---|
| 2098 | /****************************/ |
|---|
| 2099 | /* BXDM_Picture_DisplayInfo */ |
|---|
| 2100 | /****************************/ |
|---|
| 2101 | pstXdmPicture->stDisplayInfo.bValid = true; |
|---|
| 2102 | { |
|---|
| 2103 | uint8_t uiMatrixCoefficients, uiColorPrimaries, uiTransferCharacteristics; |
|---|
| 2104 | |
|---|
| 2105 | uiMatrixCoefficients = ((pPPB->display_info >> 24) & 0xFF); |
|---|
| 2106 | uiColorPrimaries = ((pPPB->display_info >> 16) & 0xFF); |
|---|
| 2107 | uiTransferCharacteristics = ((pPPB->display_info >> 8) & 0xFF); |
|---|
| 2108 | |
|---|
| 2109 | /* Set Matrix Coefficients */ |
|---|
| 2110 | if ( uiMatrixCoefficients >= BXVD_DECODER_S_MATRIX_COEFFICIENTS_LUT_SIZE ) |
|---|
| 2111 | { |
|---|
| 2112 | pstXdmPicture->stDisplayInfo.eMatrixCoefficients = BAVC_MatrixCoefficients_eUnknown; |
|---|
| 2113 | BXVD_DBG_MSG(hXvdCh, ("Unknown matrix coefficients: %#x", uiMatrixCoefficients)); |
|---|
| 2114 | } |
|---|
| 2115 | else |
|---|
| 2116 | { |
|---|
| 2117 | pstXdmPicture->stDisplayInfo.eMatrixCoefficients = sMatrixCoefficientsLUT[uiMatrixCoefficients]; |
|---|
| 2118 | } |
|---|
| 2119 | |
|---|
| 2120 | /* Set Color Primaries */ |
|---|
| 2121 | if ( uiColorPrimaries >= BXVD_DECODER_S_COLOR_PRIMARIES_LUT_SIZE ) |
|---|
| 2122 | { |
|---|
| 2123 | pstXdmPicture->stDisplayInfo.eColorPrimaries = BAVC_ColorPrimaries_eUnknown; |
|---|
| 2124 | BXVD_DBG_MSG(hXvdCh,("Unknown color primaries: %#x", uiColorPrimaries)); |
|---|
| 2125 | } |
|---|
| 2126 | else |
|---|
| 2127 | { |
|---|
| 2128 | pstXdmPicture->stDisplayInfo.eColorPrimaries = sColorPrimariesLUT[uiColorPrimaries]; |
|---|
| 2129 | } |
|---|
| 2130 | |
|---|
| 2131 | /* Set Transfer Characteristics */ |
|---|
| 2132 | if ( uiTransferCharacteristics >= BXVD_DECODER_S_TRANSFER_CHARACTERISICS_LUT_SIZE ) |
|---|
| 2133 | { |
|---|
| 2134 | pstXdmPicture->stDisplayInfo.eTransferCharacteristics = BAVC_TransferCharacteristics_eUnknown; |
|---|
| 2135 | BXVD_DBG_MSG(hXvdCh,("Unknown transfer characterisics: %#x", uiTransferCharacteristics)); |
|---|
| 2136 | } |
|---|
| 2137 | else |
|---|
| 2138 | { |
|---|
| 2139 | pstXdmPicture->stDisplayInfo.eTransferCharacteristics = sTransferCharacteristicsLUT[uiTransferCharacteristics]; |
|---|
| 2140 | } |
|---|
| 2141 | } |
|---|
| 2142 | |
|---|
| 2143 | switch ( eProtocol ) |
|---|
| 2144 | { |
|---|
| 2145 | case BAVC_VideoCompressionStd_eMPEG2: |
|---|
| 2146 | case BAVC_VideoCompressionStd_eMPEG1: |
|---|
| 2147 | case BAVC_VideoCompressionStd_eMPEG2DTV: |
|---|
| 2148 | case BAVC_VideoCompressionStd_eMPEG2_DSS_PES: |
|---|
| 2149 | /* low_delay_video_format:: [17:16]=low_delay, [2:0]=video_format */ |
|---|
| 2150 | pstXdmPicture->stDisplayInfo.eVideoFormat = ( pPPB->other.mpeg.low_delay_video_format & 0x7 ); |
|---|
| 2151 | break; |
|---|
| 2152 | |
|---|
| 2153 | default: |
|---|
| 2154 | pstXdmPicture->stDisplayInfo.eVideoFormat = BXDM_Picture_VideoFormat_eUnknown; |
|---|
| 2155 | break; |
|---|
| 2156 | } |
|---|
| 2157 | |
|---|
| 2158 | /************************/ |
|---|
| 2159 | /* BXDM_Picture_PanScan */ |
|---|
| 2160 | /************************/ |
|---|
| 2161 | switch ( eProtocol ) |
|---|
| 2162 | { |
|---|
| 2163 | case BAVC_VideoCompressionStd_eMPEG2: |
|---|
| 2164 | case BAVC_VideoCompressionStd_eMPEG1: |
|---|
| 2165 | case BAVC_VideoCompressionStd_eMPEG2DTV: |
|---|
| 2166 | case BAVC_VideoCompressionStd_eMPEG2_DSS_PES: |
|---|
| 2167 | { |
|---|
| 2168 | if ( pPPB->other.mpeg.offset_count > 0 ) |
|---|
| 2169 | { |
|---|
| 2170 | uint32_t uiPanScanIndex; |
|---|
| 2171 | |
|---|
| 2172 | pstXdmPicture->stPanScan.uiCount = pPPB->other.mpeg.offset_count; |
|---|
| 2173 | |
|---|
| 2174 | for ( uiPanScanIndex = 0; uiPanScanIndex < pstXdmPicture->stPanScan.uiCount; uiPanScanIndex++ ) |
|---|
| 2175 | { |
|---|
| 2176 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].eType = BXDM_Picture_PanScanVectorType_eSourceWindow; |
|---|
| 2177 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iHorizontal = pPPB->other.mpeg.horizontal_offset[uiPanScanIndex]; |
|---|
| 2178 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iVertical = pPPB->other.mpeg.vertical_offset[uiPanScanIndex]; |
|---|
| 2179 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiWidth = pPPB->other.mpeg.display_horizontal_size; |
|---|
| 2180 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiHeight = pPPB->other.mpeg.display_vertical_size; |
|---|
| 2181 | } |
|---|
| 2182 | } |
|---|
| 2183 | } |
|---|
| 2184 | break; |
|---|
| 2185 | |
|---|
| 2186 | case BAVC_VideoCompressionStd_eH264: |
|---|
| 2187 | { |
|---|
| 2188 | if ( pPPB->other.h264.valid & BXVD_P_PPB_H264_VALID_PANSCAN ) |
|---|
| 2189 | { |
|---|
| 2190 | int16_t iLeftOffset, iRightOffset, iTopOffset, iBottomOffset; |
|---|
| 2191 | |
|---|
| 2192 | /* Determine pan-scan index. According to H264 spec, the 3 |
|---|
| 2193 | * sets of pan-scan values are used depending on which field |
|---|
| 2194 | * of the frame is displayed. When |
|---|
| 2195 | * BXVD_P_PPB.other.BXVD_P_PPB_H264.pan_scan_count is 1, then |
|---|
| 2196 | * the one set of values is valid for all fields displayed of |
|---|
| 2197 | * the current frame. Otherwise, the index of the values map |
|---|
| 2198 | * to the field that is displayed. In 3:2 pull-down cases, |
|---|
| 2199 | * there should be 3 values for frames which are displayed |
|---|
| 2200 | * for 3 fields. */ |
|---|
| 2201 | if ( pPPB->other.h264.pan_scan_count > 0 ) |
|---|
| 2202 | { |
|---|
| 2203 | uint32_t uiPanScanIndex; |
|---|
| 2204 | |
|---|
| 2205 | pstXdmPicture->stPanScan.uiCount = pPPB->other.h264.pan_scan_count; |
|---|
| 2206 | |
|---|
| 2207 | for ( uiPanScanIndex = 0; uiPanScanIndex < pstXdmPicture->stPanScan.uiCount; uiPanScanIndex++ ) |
|---|
| 2208 | { |
|---|
| 2209 | iLeftOffset = (int16_t) ((pPPB->other.h264.pan_scan_horiz[uiPanScanIndex] >> 16) & 0xFFFF); |
|---|
| 2210 | iRightOffset = (int16_t) (pPPB->other.h264.pan_scan_horiz[uiPanScanIndex] & 0xFFFF); |
|---|
| 2211 | iTopOffset = (int16_t) ((pPPB->other.h264.pan_scan_vert[uiPanScanIndex] >> 16) & 0xFFFF); |
|---|
| 2212 | iBottomOffset = (int16_t) (pPPB->other.h264.pan_scan_vert[uiPanScanIndex] & 0xFFFF); |
|---|
| 2213 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].eType = BXDM_Picture_PanScanVectorType_eSourceCrop; |
|---|
| 2214 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iHorizontal = -(iLeftOffset + iRightOffset)/2; |
|---|
| 2215 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iVertical = -(iTopOffset + iBottomOffset)/2; |
|---|
| 2216 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiWidth = ((iLeftOffset - iRightOffset) >> 4); |
|---|
| 2217 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiHeight = ((iTopOffset - iBottomOffset) >> 4); |
|---|
| 2218 | } |
|---|
| 2219 | } |
|---|
| 2220 | } |
|---|
| 2221 | } |
|---|
| 2222 | break; |
|---|
| 2223 | |
|---|
| 2224 | case BAVC_VideoCompressionStd_eVC1: |
|---|
| 2225 | case BAVC_VideoCompressionStd_eVC1SimpleMain: |
|---|
| 2226 | { |
|---|
| 2227 | if ( uiFlags & BXVD_P_PPB_VC1_VALID_PANSCAN ) |
|---|
| 2228 | { |
|---|
| 2229 | int32_t iDisplayHorizontalCenterSP, iDisplayVerticalCenterSP, iPanScanHorizontalCenterSP, iPanScanVerticalCenterSP; |
|---|
| 2230 | uint32_t uiPanScanWidth, uiPanScanHeight; |
|---|
| 2231 | |
|---|
| 2232 | /* Determine pan-scan index. According to VC1 spec, the 4 |
|---|
| 2233 | * sets of pan-scan values are used depending on which field |
|---|
| 2234 | * of the frame is displayed. When |
|---|
| 2235 | * BXVD_P_PPB.other.BXVD_P_PPB_VC1.num_panscan_windows is 1, |
|---|
| 2236 | * then the one set of values is valid for all fields |
|---|
| 2237 | * displayed of the current frame. Otherwise, the index of |
|---|
| 2238 | * the values map to the field that is displayed. In 3:2 |
|---|
| 2239 | * pull-down cases, there should be 3 values for frames which |
|---|
| 2240 | * are displayed for 3 fields. */ |
|---|
| 2241 | if ( pPPB->other.vc1.num_panscan_windows > 0 ) |
|---|
| 2242 | { |
|---|
| 2243 | uint32_t uiPanScanIndex; |
|---|
| 2244 | |
|---|
| 2245 | pstXdmPicture->stPanScan.uiCount = pPPB->other.vc1.num_panscan_windows; |
|---|
| 2246 | |
|---|
| 2247 | for ( uiPanScanIndex = 0; uiPanScanIndex < pstXdmPicture->stPanScan.uiCount; uiPanScanIndex++ ) |
|---|
| 2248 | { |
|---|
| 2249 | /* Note: VC1 pan scan values are relative to the |
|---|
| 2250 | * _display_ size and NOT the _source_ size. VDC |
|---|
| 2251 | * requires the latter, so we need to scale the |
|---|
| 2252 | * values accordingly. |
|---|
| 2253 | * |
|---|
| 2254 | * The offsets define the upper left corner of the |
|---|
| 2255 | * pan scan rectange, and NOT the offset from |
|---|
| 2256 | * center, so we need to calculate the center offset |
|---|
| 2257 | * first. |
|---|
| 2258 | * |
|---|
| 2259 | * The offsets are in sub pixel precision but the |
|---|
| 2260 | * dimensions are in pixel precision, so we need to |
|---|
| 2261 | * convert accordingly. |
|---|
| 2262 | */ |
|---|
| 2263 | |
|---|
| 2264 | /* Calculate center coordinates relative to the |
|---|
| 2265 | * display region using 1/16 sub pixel prevision. |
|---|
| 2266 | * We need to multiply by 16 to get sub-pixel |
|---|
| 2267 | * precision and then divide by 2 to get the center, |
|---|
| 2268 | * hence the resulting left shift of 3 */ |
|---|
| 2269 | iDisplayHorizontalCenterSP = pPPB->other.vc1.display_horizontal_size << 3; |
|---|
| 2270 | iDisplayVerticalCenterSP = pPPB->other.vc1.display_vertical_size << 3; |
|---|
| 2271 | uiPanScanWidth = (pPPB->other.vc1.ps_horiz_offset_width[uiPanScanIndex] & 0x3FFF); |
|---|
| 2272 | uiPanScanHeight = (pPPB->other.vc1.ps_vert_offset_height[uiPanScanIndex] & 0x3FFF); |
|---|
| 2273 | iPanScanHorizontalCenterSP = ((pPPB->other.vc1.ps_horiz_offset_width[uiPanScanIndex] >> 14) & 0x3FFFF) + (uiPanScanWidth << 3); |
|---|
| 2274 | iPanScanVerticalCenterSP = ((pPPB->other.vc1.ps_vert_offset_height[uiPanScanIndex] >> 14) & 0x3FFFF) + (uiPanScanHeight << 3); |
|---|
| 2275 | |
|---|
| 2276 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].eType = BXDM_Picture_PanScanVectorType_eDisplayWindow; |
|---|
| 2277 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iHorizontal = (iPanScanHorizontalCenterSP - iDisplayHorizontalCenterSP); |
|---|
| 2278 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iVertical = (iPanScanVerticalCenterSP - iDisplayVerticalCenterSP); |
|---|
| 2279 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiWidth = uiPanScanWidth; |
|---|
| 2280 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiHeight = uiPanScanHeight; |
|---|
| 2281 | } |
|---|
| 2282 | } |
|---|
| 2283 | } |
|---|
| 2284 | } |
|---|
| 2285 | break; |
|---|
| 2286 | |
|---|
| 2287 | case BAVC_VideoCompressionStd_eAVS: |
|---|
| 2288 | { |
|---|
| 2289 | if ( pPPB->other.avs.offset_count > 0 ) |
|---|
| 2290 | { |
|---|
| 2291 | uint32_t uiPanScanIndex; |
|---|
| 2292 | |
|---|
| 2293 | pstXdmPicture->stPanScan.uiCount = pPPB->other.avs.offset_count; |
|---|
| 2294 | |
|---|
| 2295 | for ( uiPanScanIndex = 0; uiPanScanIndex < pstXdmPicture->stPanScan.uiCount; uiPanScanIndex++ ) |
|---|
| 2296 | { |
|---|
| 2297 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].eType = BXDM_Picture_PanScanVectorType_eSourceWindow; |
|---|
| 2298 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iHorizontal = pPPB->other.avs.horizontal_offset[uiPanScanIndex]; |
|---|
| 2299 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].iVertical = pPPB->other.avs.vertical_offset[uiPanScanIndex]; |
|---|
| 2300 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiWidth = pPPB->other.avs.display_horizontal_size; |
|---|
| 2301 | pstXdmPicture->stPanScan.stVector[uiPanScanIndex].uiHeight = pPPB->other.avs.display_vertical_size; |
|---|
| 2302 | } |
|---|
| 2303 | } |
|---|
| 2304 | } |
|---|
| 2305 | break; |
|---|
| 2306 | |
|---|
| 2307 | default: |
|---|
| 2308 | break; |
|---|
| 2309 | } |
|---|
| 2310 | |
|---|
| 2311 | /****************************/ |
|---|
| 2312 | /* BXDM_Picture_AspectRatio */ |
|---|
| 2313 | /****************************/ |
|---|
| 2314 | BXVD_Decoder_S_ComputeAspectRatio( |
|---|
| 2315 | pPPB, |
|---|
| 2316 | pstXdmPicture, |
|---|
| 2317 | eProtocol ); |
|---|
| 2318 | |
|---|
| 2319 | /**************************************/ |
|---|
| 2320 | /* BXDM_Picture_DigitalNoiseReduction */ |
|---|
| 2321 | /**************************************/ |
|---|
| 2322 | BXVD_Decoder_S_ComputeDigitalNoiseReduction( |
|---|
| 2323 | hXvdCh, |
|---|
| 2324 | pPPB, |
|---|
| 2325 | pstXdmPicture, |
|---|
| 2326 | eProtocol ); |
|---|
| 2327 | |
|---|
| 2328 | /* BXDM_Picture_RangeRemapping */ |
|---|
| 2329 | switch ( eProtocol ) |
|---|
| 2330 | { |
|---|
| 2331 | case BAVC_VideoCompressionStd_eVC1: |
|---|
| 2332 | case BAVC_VideoCompressionStd_eVC1SimpleMain: |
|---|
| 2333 | pstXdmPicture->stRangeRemapping.bValid = true; |
|---|
| 2334 | pstXdmPicture->stRangeRemapping.uiLuma = (pPPB->other.vc1.range_remapping_ratio >> 16) & 0xFFFF; |
|---|
| 2335 | pstXdmPicture->stRangeRemapping.uiChroma = pPPB->other.vc1.range_remapping_ratio & 0xFFFF; |
|---|
| 2336 | break; |
|---|
| 2337 | |
|---|
| 2338 | default: |
|---|
| 2339 | pstXdmPicture->stRangeRemapping.bValid = false; |
|---|
| 2340 | break; |
|---|
| 2341 | } |
|---|
| 2342 | |
|---|
| 2343 | /****************************************/ |
|---|
| 2344 | /* BXDM_Picture_ActiveFormatDescription */ |
|---|
| 2345 | /****************************************/ |
|---|
| 2346 | if ( uiFlags & BXVD_P_PPB_FLAG_AFD_VALID ) |
|---|
| 2347 | { |
|---|
| 2348 | pstXdmPicture->stActiveFormatDescription.bValid = true; |
|---|
| 2349 | pstXdmPicture->stActiveFormatDescription.uiValue = pPPB->afd_val; |
|---|
| 2350 | } |
|---|
| 2351 | else |
|---|
| 2352 | { |
|---|
| 2353 | pstXdmPicture->stActiveFormatDescription.bValid = false; |
|---|
| 2354 | } |
|---|
| 2355 | |
|---|
| 2356 | /************************/ |
|---|
| 2357 | /* BXDM_Picture_BarData */ |
|---|
| 2358 | /************************/ |
|---|
| 2359 | |
|---|
| 2360 | /* SW7425-2247: support for bar data */ |
|---|
| 2361 | if ( pPPB->bar_data & BXVD_P_PPB_BAR_DATA_FLAG_VALID ) |
|---|
| 2362 | { |
|---|
| 2363 | pstXdmPicture->stBarData.eBarDataType = |
|---|
| 2364 | ( pPPB->bar_data & BXVD_P_PPB_BAR_DATA_FLAG_TOP_BOTTOM ) ? BAVC_BarDataType_eTopBottom : BAVC_BarDataType_eLeftRight ; |
|---|
| 2365 | |
|---|
| 2366 | pstXdmPicture->stBarData.uiTopLeftBarValue = ( pPPB->bar_data & BXVD_P_PPB_BAR_DATA_TOP_LEFT_MASK ) >> BXVD_P_PPB_BAR_DATA_TOP_LEFT_SHIFT ; |
|---|
| 2367 | pstXdmPicture->stBarData.uiBotRightBarValue = ( pPPB->bar_data & BXVD_P_PPB_BAR_DATA_BOT_RIGHT_MASK ) >> BXVD_P_PPB_BAR_DATA_BOT_RIGHT_SHIFT ; |
|---|
| 2368 | } |
|---|
| 2369 | else |
|---|
| 2370 | { |
|---|
| 2371 | pstXdmPicture->stBarData.eBarDataType = BAVC_BarDataType_eInvalid; |
|---|
| 2372 | } |
|---|
| 2373 | |
|---|
| 2374 | /**********************/ |
|---|
| 2375 | /* BXDM_Picture_Stats */ |
|---|
| 2376 | /**********************/ |
|---|
| 2377 | pstXdmPicture->stStats.stMacroBlockCount.bValid = true; |
|---|
| 2378 | pstXdmPicture->stStats.stMacroBlockCount.uiInterCoded = ( pPPB->dnr.mb_count_intra_inter >> 16 ); |
|---|
| 2379 | pstXdmPicture->stStats.stMacroBlockCount.uiIntraCoded = ( pPPB->dnr.mb_count_intra_inter & 0xffff ); |
|---|
| 2380 | pstXdmPicture->stStats.stMacroBlockCount.uiTotal = pPPB->dnr.num_mb_cur; |
|---|
| 2381 | |
|---|
| 2382 | if ( BAVC_VideoCompressionStd_eMPEG2 == eProtocol |
|---|
| 2383 | || BAVC_VideoCompressionStd_eMPEG1 == eProtocol |
|---|
| 2384 | || BAVC_VideoCompressionStd_eMPEG2DTV == eProtocol |
|---|
| 2385 | || BAVC_VideoCompressionStd_eMPEG2_DSS_PES == eProtocol |
|---|
| 2386 | ) |
|---|
| 2387 | { |
|---|
| 2388 | pstXdmPicture->stStats.uiBitRate = pPPB->other.mpeg.bit_rate_value; |
|---|
| 2389 | } |
|---|
| 2390 | |
|---|
| 2391 | pstXdmPicture->stStats.uiDeltaPicturesSeen = pstUnifiedContext->pPPB->delta_pic_seen; |
|---|
| 2392 | |
|---|
| 2393 | /* Use a pre-increment so that the serial numbers start at '1' instead of '0'. */ |
|---|
| 2394 | pstXdmPicture->uiSerialNumber = ++hXvdCh->uiPPBSerialNumber; |
|---|
| 2395 | |
|---|
| 2396 | /************/ |
|---|
| 2397 | /* CRC Mode */ |
|---|
| 2398 | /************/ |
|---|
| 2399 | if ( true == hXvdCh->stDecoderContext.bCRCMode ) |
|---|
| 2400 | { |
|---|
| 2401 | switch ( uiFlags & BXVD_P_PPB_FLAG_BUFFER_TYPE_MASK) |
|---|
| 2402 | { |
|---|
| 2403 | case BXVD_P_PPB_FLAG_FRAME: |
|---|
| 2404 | pstXdmPicture->stBufferInfo.ePulldown = BXDM_Picture_PullDown_eFrameX1; |
|---|
| 2405 | pstXdmPicture->stBufferInfo.eSourceFormat = BXDM_Picture_SourceFormat_eProgressive; |
|---|
| 2406 | pstXdmPicture->stPictureType.eSequence = BXDM_Picture_Sequence_eProgressive; |
|---|
| 2407 | break; |
|---|
| 2408 | |
|---|
| 2409 | case BXVD_P_PPB_FLAG_FIELDPAIR: |
|---|
| 2410 | pstXdmPicture->stBufferInfo.ePulldown = BXDM_Picture_PullDown_eTopBottom; |
|---|
| 2411 | pstXdmPicture->stBufferInfo.eSourceFormat = BXDM_Picture_SourceFormat_eInterlaced; |
|---|
| 2412 | pstXdmPicture->stPictureType.eSequence = BXDM_Picture_Sequence_eInterlaced; |
|---|
| 2413 | break; |
|---|
| 2414 | |
|---|
| 2415 | case BXVD_P_PPB_FLAG_TOPFIELD: |
|---|
| 2416 | pstXdmPicture->stBufferInfo.ePulldown = BXDM_Picture_PullDown_eTop; |
|---|
| 2417 | pstXdmPicture->stBufferInfo.eSourceFormat = BXDM_Picture_SourceFormat_eInterlaced; |
|---|
| 2418 | pstXdmPicture->stPictureType.eSequence = BXDM_Picture_Sequence_eInterlaced; |
|---|
| 2419 | break; |
|---|
| 2420 | |
|---|
| 2421 | case BXVD_P_PPB_FLAG_BOTTOMFIELD: |
|---|
| 2422 | pstXdmPicture->stBufferInfo.ePulldown = BXDM_Picture_PullDown_eBottom; |
|---|
| 2423 | pstXdmPicture->stBufferInfo.eSourceFormat = BXDM_Picture_SourceFormat_eInterlaced; |
|---|
| 2424 | pstXdmPicture->stPictureType.eSequence = BXDM_Picture_Sequence_eInterlaced; |
|---|
| 2425 | break; |
|---|
| 2426 | } |
|---|
| 2427 | } |
|---|
| 2428 | |
|---|
| 2429 | /* Linked list of dependent unified pictures |
|---|
| 2430 | * TODO: add error checking for type and pointers? |
|---|
| 2431 | * That was the motivation for saving the settype and count. |
|---|
| 2432 | */ |
|---|
| 2433 | pstUnifiedContext->eSetType = pstPictureCntxt->eSetType; |
|---|
| 2434 | pstUnifiedContext->uiSetCount = pstPictureCntxt->uiSetCount; |
|---|
| 2435 | |
|---|
| 2436 | /* validate any linked dependent pictures. |
|---|
| 2437 | */ |
|---|
| 2438 | if ( NULL != pstPictureCntxt->pDependentPicture ) |
|---|
| 2439 | { |
|---|
| 2440 | BXVD_Decoder_S_UnifiedQ_AddPicture( hXvdCh, pstPictureCntxt->pDependentPicture, false ); |
|---|
| 2441 | } |
|---|
| 2442 | |
|---|
| 2443 | #if 0 |
|---|
| 2444 | /* for debug */ |
|---|
| 2445 | pstUnifiedContext->eSetType = BXVD_Decoder_P_PictureSet_eSingle; |
|---|
| 2446 | pstUnifiedContext->uiSetCount = 1; |
|---|
| 2447 | #endif |
|---|
| 2448 | |
|---|
| 2449 | /* link the dependent unified picture to the preceeding picture |
|---|
| 2450 | * Currently we only support picture sets of 2, the preceeding |
|---|
| 2451 | * picture should be a base picture. |
|---|
| 2452 | * |
|---|
| 2453 | * SW7425-609: With a MVC stream, it is possible to startup on the dependent |
|---|
| 2454 | * (enhanced) picture. This is an error condition and the picture will be dropped. |
|---|
| 2455 | * The twist here is that preceding picture context will not have been validated, |
|---|
| 2456 | * i.e. pstPreviousUniContext will be NULL. Why is this routine being executed |
|---|
| 2457 | * if the picture is going to be dropped? For debug, solely to fill in the |
|---|
| 2458 | * Unified Picture structure and then call BXVD_DecoderDbg_P_PrintUnifiedPicture. |
|---|
| 2459 | * To avoid a crash if pstPreviousUniContext is NULL, check " bPictureDropped" |
|---|
| 2460 | * in the following "if" statement. |
|---|
| 2461 | */ |
|---|
| 2462 | if ( BXVD_Decoder_P_PictureSet_eDependent == pstUnifiedContext->eSetType |
|---|
| 2463 | && false == bPictureDropped |
|---|
| 2464 | ) |
|---|
| 2465 | { |
|---|
| 2466 | /* Link the unified pictures for use by XDM... */ |
|---|
| 2467 | pstUnifiedContext->pstPreviousUniContext->stUnifiedPicture.pNextPicture = pstXdmPicture; |
|---|
| 2468 | |
|---|
| 2469 | /* Link the picture context's for use by the decoder. */ |
|---|
| 2470 | pstUnifiedContext->pstPreviousUniContext->pstDependentUniContext = pstUnifiedContext; |
|---|
| 2471 | |
|---|
| 2472 | /* The error handling logic only looks at the base picture. Conditionally |
|---|
| 2473 | * set the error bits on the base picture. |
|---|
| 2474 | */ |
|---|
| 2475 | if( true == pstXdmPicture->stError.bThisPicture ) |
|---|
| 2476 | { |
|---|
| 2477 | pstUnifiedContext->pstPreviousUniContext->stUnifiedPicture.stError.bThisPicture = true; |
|---|
| 2478 | } |
|---|
| 2479 | |
|---|
| 2480 | if( true == pstXdmPicture->stError.bPreviousRefPic ) |
|---|
| 2481 | { |
|---|
| 2482 | pstUnifiedContext->pstPreviousUniContext->stUnifiedPicture.stError.bPreviousRefPic = true; |
|---|
| 2483 | } |
|---|
| 2484 | |
|---|
| 2485 | /* Link the dependent extension data to the base. This will allow an application |
|---|
| 2486 | * to access both blocks of data in the ePictureExtensionData callback. |
|---|
| 2487 | */ |
|---|
| 2488 | pstUnifiedContext->pstPreviousUniContext->stUnifiedPicture.stExtensionInfo.pNext = |
|---|
| 2489 | &(pstUnifiedContext->stUnifiedPicture.stExtensionInfo); |
|---|
| 2490 | |
|---|
| 2491 | } |
|---|
| 2492 | |
|---|
| 2493 | /******************************/ |
|---|
| 2494 | /* BXDM_Picture_ExtensionInfo */ |
|---|
| 2495 | /* BXDM_Picture_3D */ |
|---|
| 2496 | /******************************/ |
|---|
| 2497 | |
|---|
| 2498 | /* default to a 2D picture. */ |
|---|
| 2499 | pstXdmPicture->st3D.eOrientation = BXDM_Picture_Orientation_e2D; |
|---|
| 2500 | pstXdmPicture->st3D.eFrameRelationship = BXDM_Picture_FrameRelationship_eUnknown; |
|---|
| 2501 | |
|---|
| 2502 | |
|---|
| 2503 | /* SW7405-3996: add support for SEI frame packing. */ |
|---|
| 2504 | if ( BAVC_VideoCompressionStd_eH264 == eProtocol |
|---|
| 2505 | || BAVC_VideoCompressionStd_eMVC == eProtocol |
|---|
| 2506 | ) |
|---|
| 2507 | { |
|---|
| 2508 | uint32_t uiSEIOffset=0; |
|---|
| 2509 | BXVD_P_SEI_Message * pSEIMessage; |
|---|
| 2510 | uint32_t uiSerialNumber = pstXdmPicture->uiSerialNumber; /* For debug. */ |
|---|
| 2511 | |
|---|
| 2512 | if ( BAVC_VideoCompressionStd_eH264 == eProtocol ) |
|---|
| 2513 | { |
|---|
| 2514 | /* Check for an SEI message on a single picture. */ |
|---|
| 2515 | |
|---|
| 2516 | uiSEIOffset = (uint32_t)pPPB->other.h264.pstSEIMessageOffset; |
|---|
| 2517 | } |
|---|
| 2518 | else if ( BAVC_VideoCompressionStd_eMVC == eProtocol |
|---|
| 2519 | && BXVD_Decoder_P_PictureSet_eBase == pstUnifiedContext->eSetType |
|---|
| 2520 | && NULL != pstPictureCntxt->pDependentPicture |
|---|
| 2521 | ) |
|---|
| 2522 | { |
|---|
| 2523 | /* This case is for retrieving graphics offsets which might be delivered in an MVC stream. |
|---|
| 2524 | * The offsets are delivered by AVD with the dependent (or extended) pictures. |
|---|
| 2525 | * The middleware is expecting the offsets to be bound to the base pictures. |
|---|
| 2526 | * We hold off parsing these messages until this routine is finishing up with the base picture. |
|---|
| 2527 | * Note: this routine is called recursively. The preceding call to "BXVD_Decoder_S_UnifiedQ_AddPicture" |
|---|
| 2528 | * will have processed the dependent/extended picture. |
|---|
| 2529 | */ |
|---|
| 2530 | uiSEIOffset = (uint32_t)pstPictureCntxt->pDependentPicture->stPPB.pPPB->other.h264.pstSEIMessageOffset; |
|---|
| 2531 | |
|---|
| 2532 | /* For debug. */ |
|---|
| 2533 | if ( pstXdmPicture->pNextPicture ) |
|---|
| 2534 | { |
|---|
| 2535 | uiSerialNumber = ((BXDM_Picture *)(pstXdmPicture->pNextPicture))->uiSerialNumber; |
|---|
| 2536 | } |
|---|
| 2537 | |
|---|
| 2538 | #if BXVD_LEGACY_MVC_SUPPORT |
|---|
| 2539 | /* SW7422-72: to support the original MVC behavior on the older DVD chips, mark the set as |
|---|
| 2540 | * full frame 3D with frame 0 as the left image. On newer chips, the application/middleware |
|---|
| 2541 | * will need to call "BXDM_PictureProvider_Set3D_isr()" to specify the orientation. If this |
|---|
| 2542 | * call is not made, XDM will deliver the content as 2D to VDC. |
|---|
| 2543 | */ |
|---|
| 2544 | pstXdmPicture->st3D.eOrientation = BXDM_Picture_Orientation_e3D_FullFrame; |
|---|
| 2545 | pstXdmPicture->st3D.eFrameRelationship = BXDM_Picture_FrameRelationship_eFrame0Left; |
|---|
| 2546 | #endif |
|---|
| 2547 | } |
|---|
| 2548 | |
|---|
| 2549 | while ( 0 != uiSEIOffset ) |
|---|
| 2550 | { |
|---|
| 2551 | BXDM_Picture_ExtensionData * pstExtensionData; |
|---|
| 2552 | uint32_t uiIndex; |
|---|
| 2553 | |
|---|
| 2554 | if ( pstXdmPicture->stExtensionInfo.uiCount >= BXDM_MAX_PICTURE_EXTENSION_INFO ) |
|---|
| 2555 | { |
|---|
| 2556 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_ValidatePicture:: number of SEI messages is greater than BXDM_MAX_PICTURE_EXTENSION_INFO")); |
|---|
| 2557 | break; |
|---|
| 2558 | } |
|---|
| 2559 | |
|---|
| 2560 | |
|---|
| 2561 | /* Convert the BXVD_P_SEI_Message offset to a virtual address. */ |
|---|
| 2562 | BMEM_ConvertOffsetToAddress( |
|---|
| 2563 | hXvdCh->hSystemHeap, |
|---|
| 2564 | uiSEIOffset, |
|---|
| 2565 | (void *)&( pSEIMessage ) |
|---|
| 2566 | ); |
|---|
| 2567 | |
|---|
| 2568 | switch( pSEIMessage->uiMsgType ) |
|---|
| 2569 | { |
|---|
| 2570 | case BXVD_P_PPB_SEI_MSG_FRAMEPACKING: |
|---|
| 2571 | { |
|---|
| 2572 | /* Needed pstAvdSEIData to prevent the compiler warning |
|---|
| 2573 | * "dereferencing type-punned pointer will break strict-aliasing rules" |
|---|
| 2574 | */ |
|---|
| 2575 | BXVD_P_SEI_FramePacking * pstAvdSEIData = (BXVD_P_SEI_FramePacking *)&(pSEIMessage->data.stSEIFramePacking); |
|---|
| 2576 | |
|---|
| 2577 | /* Dereference the offset data. */ |
|---|
| 2578 | uiIndex = pstXdmPicture->stExtensionInfo.uiCount; |
|---|
| 2579 | pstExtensionData = &(pstXdmPicture->stExtensionInfo.astExtensionData[uiIndex]); |
|---|
| 2580 | |
|---|
| 2581 | /* Set the appropriate values. */ |
|---|
| 2582 | pstExtensionData->eType = BXDM_Picture_ExtensionType_eSEIMsg_FramePacking; |
|---|
| 2583 | pstExtensionData->data.stSEIFramePacking.pstSeiData = (BXDM_Picture_Extension_SEIFramePacking *)pstAvdSEIData; |
|---|
| 2584 | |
|---|
| 2585 | if ( uiFlags & BXVD_P_PPB_FLAG_NEW_SEI_MSG ) |
|---|
| 2586 | { |
|---|
| 2587 | pstExtensionData->data.stSEIFramePacking.uiFlags = BXDM_PICTURE_SEIMSG_FRAMEPACK_NEW_MESSAGE_FLAG; |
|---|
| 2588 | } |
|---|
| 2589 | |
|---|
| 2590 | /* For 3D, fill in the pstXdmPicture->st3D.eOrientation |
|---|
| 2591 | * and pstXdmPicture->st3D.eFrameRelationship fields. |
|---|
| 2592 | */ |
|---|
| 2593 | BXVD_Decoder_S_UnifiedQ_ParseSeiFramePackMsg( pstAvdSEIData, &(pstXdmPicture->st3D) ); |
|---|
| 2594 | |
|---|
| 2595 | /* Conditionally print the SEI message */ |
|---|
| 2596 | BXVD_DecoderDbg_P_PrintSeiMessage( hXvdCh, pSEIMessage, uiSerialNumber ); |
|---|
| 2597 | |
|---|
| 2598 | /* Bump the extension count.*/ |
|---|
| 2599 | pstXdmPicture->stExtensionInfo.uiCount++; |
|---|
| 2600 | break; |
|---|
| 2601 | } |
|---|
| 2602 | |
|---|
| 2603 | case BXVD_P_PPB_SEI_MSG_MVC_GRAPHICS_OFFSET: |
|---|
| 2604 | { |
|---|
| 2605 | |
|---|
| 2606 | /* NOTE: This code only grabs data from the first dependent picture. |
|---|
| 2607 | * Perhaps that is all we will need. |
|---|
| 2608 | */ |
|---|
| 2609 | BXVD_P_MVC_Offset_Meta * pMetaData = (BXVD_P_MVC_Offset_Meta *)&(pSEIMessage->data.stOffsetMeta); |
|---|
| 2610 | |
|---|
| 2611 | /* Dereference the offset data. */ |
|---|
| 2612 | uiIndex = pstXdmPicture->stExtensionInfo.uiCount; |
|---|
| 2613 | pstExtensionData = &(pstXdmPicture->stExtensionInfo.astExtensionData[uiIndex]); |
|---|
| 2614 | |
|---|
| 2615 | |
|---|
| 2616 | /* Set the appropriate values. */ |
|---|
| 2617 | pstExtensionData->eType = BXDM_Picture_ExtensionType_eBluRay3DGraphicsOffset; |
|---|
| 2618 | pstExtensionData->data.stBluRay3DGraphicsOffset.uiCount = pMetaData->size; |
|---|
| 2619 | pstExtensionData->data.stBluRay3DGraphicsOffset.puiOffsetData = &(pMetaData->offset[0]); |
|---|
| 2620 | |
|---|
| 2621 | /* Conditionally print the SEI message */ |
|---|
| 2622 | BXVD_DecoderDbg_P_PrintSeiMessage( hXvdCh, pSEIMessage, uiSerialNumber ); |
|---|
| 2623 | |
|---|
| 2624 | /* Bump the extension count.*/ |
|---|
| 2625 | pstXdmPicture->stExtensionInfo.uiCount++; |
|---|
| 2626 | break; |
|---|
| 2627 | } |
|---|
| 2628 | |
|---|
| 2629 | default: |
|---|
| 2630 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_ValidatePicture:: invalid SEI message type %d", pSEIMessage->uiMsgType )); |
|---|
| 2631 | break; |
|---|
| 2632 | } |
|---|
| 2633 | |
|---|
| 2634 | /* Check for another message. Note: while there are provisions to support multiple |
|---|
| 2635 | * messages per PPB, the current thinking is that this will not happen. |
|---|
| 2636 | */ |
|---|
| 2637 | uiSEIOffset = (uint32_t)pSEIMessage->pstNextSEIMsgOffset; |
|---|
| 2638 | |
|---|
| 2639 | } /* end of while ( 0 != uiSEIOffset ) */ |
|---|
| 2640 | } /* end of if ( BAVC_VideoCompressionStd_eH264 ) */ |
|---|
| 2641 | |
|---|
| 2642 | |
|---|
| 2643 | /* Conditionally print the Unified Picture. |
|---|
| 2644 | * If this is the 2nd picture of a pair of pictures, hold off printing until we hit |
|---|
| 2645 | * this point for the 1st (base) picture of the pair. However if the picture is being |
|---|
| 2646 | * dropped, go ahead and do the print. |
|---|
| 2647 | */ |
|---|
| 2648 | if ( BXVD_Decoder_P_PictureSet_eSingle == pstUnifiedContext->eSetType |
|---|
| 2649 | || BXVD_Decoder_P_PictureSet_eBase == pstUnifiedContext->eSetType |
|---|
| 2650 | || true == bPictureDropped ) |
|---|
| 2651 | { |
|---|
| 2652 | BXVD_Decoder_P_UnifiedPictureContext * pstTempContext = pstUnifiedContext; |
|---|
| 2653 | |
|---|
| 2654 | while ( 0 != pstTempContext ) |
|---|
| 2655 | { |
|---|
| 2656 | BXVD_DecoderDbg_P_PrintUnifiedPicture( hXvdCh, uiFlags, uiFlagsExt0, pstTempContext, bPictureDropped ); |
|---|
| 2657 | pstTempContext = pstTempContext->pstDependentUniContext; |
|---|
| 2658 | } |
|---|
| 2659 | } |
|---|
| 2660 | |
|---|
| 2661 | BDBG_LEAVE(BXVD_Decoder_S_UnifiedQ_ValidatePicture); |
|---|
| 2662 | |
|---|
| 2663 | return; |
|---|
| 2664 | |
|---|
| 2665 | } /* BXVD_Decoder_S_UnifiedQ_ValidatePicture() */ |
|---|
| 2666 | |
|---|
| 2667 | /* |
|---|
| 2668 | * The picture count would take into account picture sets. |
|---|
| 2669 | */ |
|---|
| 2670 | static uint32_t BXVD_Decoder_S_UnifiedQ_GetFreeCount( |
|---|
| 2671 | BXVD_ChannelHandle hXvdCh |
|---|
| 2672 | ) |
|---|
| 2673 | { |
|---|
| 2674 | uint32_t uiFreeCount; |
|---|
| 2675 | |
|---|
| 2676 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_GetFreeCount ); |
|---|
| 2677 | |
|---|
| 2678 | uiFreeCount = BXVD_P_DECODER_PICTURE_QUEUE_DEPTH - hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumUsedElements; |
|---|
| 2679 | |
|---|
| 2680 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_GetFreeCount ); |
|---|
| 2681 | |
|---|
| 2682 | return uiFreeCount; |
|---|
| 2683 | } |
|---|
| 2684 | |
|---|
| 2685 | static uint32_t BXVD_Decoder_S_UnifiedQ_GetPictureCount( |
|---|
| 2686 | BXVD_ChannelHandle hXvdCh |
|---|
| 2687 | ) |
|---|
| 2688 | { |
|---|
| 2689 | return hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumPictures; |
|---|
| 2690 | } |
|---|
| 2691 | |
|---|
| 2692 | /* Gets the entry at the tail of the unified context queue. |
|---|
| 2693 | * TODO: return a bool; false if the queue is empty? |
|---|
| 2694 | */ |
|---|
| 2695 | static void BXVD_Decoder_S_UnifiedQ_UnifiedContextGet( |
|---|
| 2696 | BXVD_ChannelHandle hXvdCh, |
|---|
| 2697 | BXVD_Decoder_P_UnifiedPictureContext ** ppstUnifiedContext, |
|---|
| 2698 | bool bBumpReadOffset |
|---|
| 2699 | ) |
|---|
| 2700 | { |
|---|
| 2701 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_UnifiedContextGet ); |
|---|
| 2702 | |
|---|
| 2703 | |
|---|
| 2704 | if ( true == bBumpReadOffset ) |
|---|
| 2705 | { |
|---|
| 2706 | hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumPictures--; |
|---|
| 2707 | } |
|---|
| 2708 | |
|---|
| 2709 | /* The picture count should never go below 0. |
|---|
| 2710 | * If it does, there is a bug in the logic. |
|---|
| 2711 | */ |
|---|
| 2712 | BDBG_ASSERT( hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumPictures >= 0 ); |
|---|
| 2713 | |
|---|
| 2714 | BXVD_Decoder_S_UnifiedQ_GetLastElement( hXvdCh, ppstUnifiedContext, bBumpReadOffset ); |
|---|
| 2715 | |
|---|
| 2716 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_UnifiedContextGet ); |
|---|
| 2717 | |
|---|
| 2718 | return; |
|---|
| 2719 | |
|---|
| 2720 | } /* end of BXVD_Decoder_S_UnifiedQ_UnifiedContextGet() */ |
|---|
| 2721 | |
|---|
| 2722 | static void BXVD_Decoder_S_UnifiedQ_GetLastElement( |
|---|
| 2723 | BXVD_ChannelHandle hXvdCh, |
|---|
| 2724 | BXVD_Decoder_P_UnifiedPictureContext ** ppstUnifiedContext, |
|---|
| 2725 | bool bBumpReadOffset |
|---|
| 2726 | ) |
|---|
| 2727 | { |
|---|
| 2728 | BXVD_Decoder_P_UnifiedPictureQueue * pstUnifiedQueue = &hXvdCh->stDecoderContext.stUnifiedPictureQueue; |
|---|
| 2729 | |
|---|
| 2730 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_GetLastElement ); |
|---|
| 2731 | |
|---|
| 2732 | BDBG_ASSERT( hXvdCh ); |
|---|
| 2733 | BDBG_ASSERT( ppstUnifiedContext ); |
|---|
| 2734 | |
|---|
| 2735 | /* TODO: what to return if the queue is empty? */ |
|---|
| 2736 | |
|---|
| 2737 | *ppstUnifiedContext = pstUnifiedQueue->pstContextTail; |
|---|
| 2738 | |
|---|
| 2739 | if ( true == bBumpReadOffset ) |
|---|
| 2740 | { |
|---|
| 2741 | BXVD_Decoder_S_UnifiedQ_DumpElement( *ppstUnifiedContext, false ); |
|---|
| 2742 | |
|---|
| 2743 | /* Increment picture context queue read pointer */ |
|---|
| 2744 | |
|---|
| 2745 | /* For debug / error checking. */ |
|---|
| 2746 | if ( BXVD_Decoder_P_PictureSet_eSingle == (*ppstUnifiedContext)->eSetType |
|---|
| 2747 | && 1 != (*ppstUnifiedContext)->uiSetCount |
|---|
| 2748 | ) |
|---|
| 2749 | { |
|---|
| 2750 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_GetNextPicture_isr:: BXVD_Decoder_P_PictureSet_eSingle uiSetCount = %d", (*ppstUnifiedContext)->uiSetCount )); |
|---|
| 2751 | } |
|---|
| 2752 | else if ( BXVD_Decoder_P_PictureSet_eBase == (*ppstUnifiedContext)->eSetType |
|---|
| 2753 | && 2 != (*ppstUnifiedContext)->uiSetCount |
|---|
| 2754 | ) |
|---|
| 2755 | { |
|---|
| 2756 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_GetNextPicture_isr:: BXVD_Decoder_P_PictureSet_eBase uiSetCount = %d", (*ppstUnifiedContext)->uiSetCount )); |
|---|
| 2757 | } |
|---|
| 2758 | |
|---|
| 2759 | /* Walk through all the linked dependent pictures. */ |
|---|
| 2760 | while( NULL != pstUnifiedQueue->pstContextTail->pstDependentUniContext ) |
|---|
| 2761 | { |
|---|
| 2762 | pstUnifiedQueue->pstContextTail = pstUnifiedQueue->pstContextTail->pstDependentUniContext; |
|---|
| 2763 | } |
|---|
| 2764 | |
|---|
| 2765 | /* Move the tail pointer if there is another picture. */ |
|---|
| 2766 | if ( NULL != pstUnifiedQueue->pstContextTail->pstNextUniContext ) |
|---|
| 2767 | { |
|---|
| 2768 | pstUnifiedQueue->pstContextTail = pstUnifiedQueue->pstContextTail->pstNextUniContext; |
|---|
| 2769 | |
|---|
| 2770 | /* Do we need to Break the link between the elements? |
|---|
| 2771 | * Note: the element is actually release in the call to BXVD_Decoder_S_UnifiedQ_UnifiedContextRelease. |
|---|
| 2772 | */ |
|---|
| 2773 | pstUnifiedQueue->pstContextTail->pstPreviousUniContext->pstNextUniContext = NULL; |
|---|
| 2774 | pstUnifiedQueue->pstContextTail->pstPreviousUniContext->pstPreviousUniContext = NULL; |
|---|
| 2775 | } |
|---|
| 2776 | |
|---|
| 2777 | } |
|---|
| 2778 | |
|---|
| 2779 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_GetLastElement ); |
|---|
| 2780 | |
|---|
| 2781 | return; |
|---|
| 2782 | |
|---|
| 2783 | } /* end of BXVD_Decoder_S_UnifiedQ_GetLastElement() */ |
|---|
| 2784 | #if 0 |
|---|
| 2785 | static void BXVD_Decoder_S_UnifiedQ_InitializeElement( |
|---|
| 2786 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext |
|---|
| 2787 | ) |
|---|
| 2788 | { |
|---|
| 2789 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_InitializeElement ); |
|---|
| 2790 | |
|---|
| 2791 | BDBG_ASSERT( pstUnifiedContext ); |
|---|
| 2792 | |
|---|
| 2793 | BKNI_Memset( pstUnifiedContext, 0, sizeof( BXVD_Decoder_P_UnifiedPictureContext ) ); |
|---|
| 2794 | |
|---|
| 2795 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_InitializeElement ); |
|---|
| 2796 | |
|---|
| 2797 | return; |
|---|
| 2798 | |
|---|
| 2799 | } /* end of BXVD_Decoder_S_UnifiedQ_InitializeElement() */ |
|---|
| 2800 | #endif |
|---|
| 2801 | |
|---|
| 2802 | /* |
|---|
| 2803 | * Sets the pointer to the head of the unified picture queue. |
|---|
| 2804 | */ |
|---|
| 2805 | static void BXVD_Decoder_S_UnifiedQ_GetNextFreeElement( |
|---|
| 2806 | BXVD_ChannelHandle hXvdCh, |
|---|
| 2807 | BXVD_Decoder_P_UnifiedPictureContext ** ppstUnifiedContext |
|---|
| 2808 | ) |
|---|
| 2809 | { |
|---|
| 2810 | uint32_t uiElementsEvaluated=0; |
|---|
| 2811 | bool bFoundFreeElement=false; |
|---|
| 2812 | |
|---|
| 2813 | BXVD_Decoder_P_UnifiedPictureQueue * pstUnifiedQueue = &hXvdCh->stDecoderContext.stUnifiedPictureQueue; |
|---|
| 2814 | |
|---|
| 2815 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_GetNextFreeElement ); |
|---|
| 2816 | |
|---|
| 2817 | /* The call to "BXVD_Decoder_S_UnifiedQ_GetFreeCount()" in "BXVD_Decoder_S_UnifiedQ_Update()" |
|---|
| 2818 | * should ensure that the queue has enough room. Keep this check as a safety valve. |
|---|
| 2819 | */ |
|---|
| 2820 | if ( !BXVD_Decoder_S_UnifiedQ_GetFreeCount( hXvdCh ) ) |
|---|
| 2821 | { |
|---|
| 2822 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_GetNextFreeElement:: queue is full.", NULL)); |
|---|
| 2823 | BDBG_ASSERT( 0 ); |
|---|
| 2824 | } |
|---|
| 2825 | |
|---|
| 2826 | /* Set the pointer to the free element. */ |
|---|
| 2827 | *ppstUnifiedContext = &(pstUnifiedQueue->astUnifiedContext[ pstUnifiedQueue->uiSearchIndex ]); |
|---|
| 2828 | |
|---|
| 2829 | /* Mark the entry as used. */ |
|---|
| 2830 | (*ppstUnifiedContext)->bInUse = true; |
|---|
| 2831 | |
|---|
| 2832 | hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumUsedElements++; |
|---|
| 2833 | BDBG_ASSERT( hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumUsedElements <= BXVD_P_DECODER_PICTURE_QUEUE_DEPTH ); |
|---|
| 2834 | |
|---|
| 2835 | /* uiElementsEvaluated To check if the code has looped around, |
|---|
| 2836 | * should not happen if "iNumUsedElements" is correct. |
|---|
| 2837 | */ |
|---|
| 2838 | |
|---|
| 2839 | /* Step through the queue until the next free element is found. */ |
|---|
| 2840 | |
|---|
| 2841 | while ( uiElementsEvaluated < BXVD_P_DECODER_PICTURE_QUEUE_DEPTH ) |
|---|
| 2842 | { |
|---|
| 2843 | BXVD_Decoder_S_Increment_0BasedOffset( |
|---|
| 2844 | &(pstUnifiedQueue->uiSearchIndex), |
|---|
| 2845 | 1, |
|---|
| 2846 | BXVD_P_DECODER_PICTURE_QUEUE_DEPTH |
|---|
| 2847 | ); |
|---|
| 2848 | |
|---|
| 2849 | if ( false == pstUnifiedQueue->astUnifiedContext[ pstUnifiedQueue->uiSearchIndex ].bInUse ) |
|---|
| 2850 | { |
|---|
| 2851 | bFoundFreeElement = true; |
|---|
| 2852 | break; |
|---|
| 2853 | } |
|---|
| 2854 | |
|---|
| 2855 | |
|---|
| 2856 | uiElementsEvaluated++; |
|---|
| 2857 | } |
|---|
| 2858 | |
|---|
| 2859 | if ( true == bFoundFreeElement ) |
|---|
| 2860 | { |
|---|
| 2861 | /* Set the head of the list to this new context. */ |
|---|
| 2862 | pstUnifiedQueue->pstContextHead = &(pstUnifiedQueue->astUnifiedContext[ pstUnifiedQueue->uiSearchIndex ]); |
|---|
| 2863 | |
|---|
| 2864 | /* for debug */ |
|---|
| 2865 | pstUnifiedQueue->pstContextHead->uiIndex = pstUnifiedQueue->uiSearchIndex; |
|---|
| 2866 | } |
|---|
| 2867 | else |
|---|
| 2868 | { |
|---|
| 2869 | /* The preceeding calls to "BXVD_Decoder_S_UnifiedQ_GetFreeCount()" |
|---|
| 2870 | * should ensure that the queue has enough room. Keep this check as a safety valve. |
|---|
| 2871 | */ |
|---|
| 2872 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_GetNextFreeElement:: did not find a free element.", NULL)); |
|---|
| 2873 | BDBG_ASSERT( 0 ); |
|---|
| 2874 | } |
|---|
| 2875 | |
|---|
| 2876 | /* Link this element to the preceeding. */ |
|---|
| 2877 | pstUnifiedQueue->pstContextHead->pstPreviousUniContext = *ppstUnifiedContext; |
|---|
| 2878 | |
|---|
| 2879 | /* Link the preceeding element to this one. */ |
|---|
| 2880 | (*ppstUnifiedContext)->pstNextUniContext = pstUnifiedQueue->pstContextHead; |
|---|
| 2881 | #if 0 |
|---|
| 2882 | BXVD_Decoder_S_Printf("this: %d ", (*ppstUnifiedContext)->uiIndex ); |
|---|
| 2883 | |
|---|
| 2884 | if ( NULL == (*ppstUnifiedContext)->pstNextUniContext ) |
|---|
| 2885 | BXVD_Decoder_S_Printf("next: NULL ", NULL ); |
|---|
| 2886 | else |
|---|
| 2887 | BXVD_Decoder_S_Printf("next: %d ", (*ppstUnifiedContext)->pstNextUniContext->uiIndex ); |
|---|
| 2888 | |
|---|
| 2889 | if ( NULL == (*ppstUnifiedContext)->pstPreviousUniContext ) |
|---|
| 2890 | BXVD_Decoder_S_Printf("prev: NULL ", NULL ); |
|---|
| 2891 | else |
|---|
| 2892 | BXVD_Decoder_S_Printf("prev: %d ", (*ppstUnifiedContext)->pstPreviousUniContext->uiIndex ); |
|---|
| 2893 | |
|---|
| 2894 | BXVD_Decoder_S_Printf("head: %d ", pstUnifiedQueue->pstContextHead->uiIndex ); |
|---|
| 2895 | |
|---|
| 2896 | if ( NULL == pstUnifiedQueue->pstContextHead->pstNextUniContext ) |
|---|
| 2897 | BXVD_Decoder_S_Printf("hnext: NULL ", NULL ); |
|---|
| 2898 | else |
|---|
| 2899 | BXVD_Decoder_S_Printf("hnext: %d ", pstUnifiedQueue->pstContextHead->pstNextUniContext->uiIndex ); |
|---|
| 2900 | if ( NULL == pstUnifiedQueue->pstContextHead->pstPreviousUniContext ) |
|---|
| 2901 | BXVD_Decoder_S_Printf("hprev: NULL\n", NULL ); |
|---|
| 2902 | else |
|---|
| 2903 | BXVD_Decoder_S_Printf("hprev: %d\n", pstUnifiedQueue->pstContextHead->pstPreviousUniContext->uiIndex ); |
|---|
| 2904 | #endif |
|---|
| 2905 | |
|---|
| 2906 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_GetNextFreeElement ); |
|---|
| 2907 | |
|---|
| 2908 | return; |
|---|
| 2909 | |
|---|
| 2910 | } /* end of BXVD_Decoder_S_UnifiedQ_GetNextFreeElement() */ |
|---|
| 2911 | |
|---|
| 2912 | |
|---|
| 2913 | /* |
|---|
| 2914 | * |
|---|
| 2915 | */ |
|---|
| 2916 | static void BXVD_Decoder_S_UnifiedQ_UnifiedContextRelease( |
|---|
| 2917 | BXVD_ChannelHandle hXvdCh, |
|---|
| 2918 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext |
|---|
| 2919 | ) |
|---|
| 2920 | { |
|---|
| 2921 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_UnifiedContextRelease ); |
|---|
| 2922 | |
|---|
| 2923 | BDBG_ASSERT( hXvdCh ); |
|---|
| 2924 | BDBG_ASSERT( pstUnifiedContext ); |
|---|
| 2925 | |
|---|
| 2926 | BXVD_Decoder_S_UnifiedQ_DumpElement( pstUnifiedContext, false ); |
|---|
| 2927 | |
|---|
| 2928 | BXVD_Decoder_S_UnifiedQ_ReleaseElement( hXvdCh, pstUnifiedContext ); |
|---|
| 2929 | |
|---|
| 2930 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_UnifiedContextRelease ); |
|---|
| 2931 | |
|---|
| 2932 | return; |
|---|
| 2933 | } |
|---|
| 2934 | |
|---|
| 2935 | static void BXVD_Decoder_S_UnifiedQ_ReleaseElement( |
|---|
| 2936 | BXVD_ChannelHandle hXvdCh, |
|---|
| 2937 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext |
|---|
| 2938 | ) |
|---|
| 2939 | { |
|---|
| 2940 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_ReleaseElement ); |
|---|
| 2941 | |
|---|
| 2942 | BDBG_ASSERT( hXvdCh ); |
|---|
| 2943 | BDBG_ASSERT( pstUnifiedContext ); |
|---|
| 2944 | |
|---|
| 2945 | /* Release the unified picture(s) as well as the the associated PPB(s). |
|---|
| 2946 | * SWBLURAY-23835: Each picture should only be release once. To |
|---|
| 2947 | * accommodate poorly behaving software, check "bInUse" to see if a |
|---|
| 2948 | * picture was previously released. |
|---|
| 2949 | */ |
|---|
| 2950 | if ( true == pstUnifiedContext->bInUse ) |
|---|
| 2951 | { |
|---|
| 2952 | if ( NULL != pstUnifiedContext->pstDependentUniContext ) |
|---|
| 2953 | { |
|---|
| 2954 | BXVD_Decoder_S_UnifiedQ_ReleaseElement( hXvdCh, pstUnifiedContext->pstDependentUniContext ); |
|---|
| 2955 | } |
|---|
| 2956 | |
|---|
| 2957 | BXVD_Decoder_S_ReleaseQ_AddPPB( hXvdCh, pstUnifiedContext->pPPBPhysical ); |
|---|
| 2958 | BXVD_Decoder_S_UnifiedQ_InvalidateElement( hXvdCh, pstUnifiedContext ); |
|---|
| 2959 | } |
|---|
| 2960 | else |
|---|
| 2961 | { |
|---|
| 2962 | BXVD_DBG_ERR(hXvdCh,("BXVD_Decoder_S_UnifiedQ_ReleaseElement:: picture released multiple times.", NULL)); |
|---|
| 2963 | } |
|---|
| 2964 | |
|---|
| 2965 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_ReleaseElement ); |
|---|
| 2966 | |
|---|
| 2967 | return; |
|---|
| 2968 | |
|---|
| 2969 | } /* end of BXVD_Decoder_S_UnifiedQ_ReleaseElement() */ |
|---|
| 2970 | |
|---|
| 2971 | #if 0 |
|---|
| 2972 | /* |
|---|
| 2973 | * |
|---|
| 2974 | */ |
|---|
| 2975 | static void BXVD_Decoder_S_UnifiedQ_UnifiedContextAdd( |
|---|
| 2976 | BXVD_ChannelHandle hXvdCh, |
|---|
| 2977 | BXVD_Decoder_P_PictureContext * pstPictureCntxt |
|---|
| 2978 | ) |
|---|
| 2979 | { |
|---|
| 2980 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_UnifiedContextAdd ); |
|---|
| 2981 | |
|---|
| 2982 | hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumPictures++; |
|---|
| 2983 | |
|---|
| 2984 | /* TODO: add a return value here? */ |
|---|
| 2985 | BXVD_Decoder_S_UnifiedQ_AddPicture( hXvdCh, pstPictureCntxt ); |
|---|
| 2986 | |
|---|
| 2987 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_UnifiedContextAdd ); |
|---|
| 2988 | |
|---|
| 2989 | return; |
|---|
| 2990 | |
|---|
| 2991 | } /* end of BXVD_Decoder_S_UnifiedQ_UnifiedContextAdd() */ |
|---|
| 2992 | #endif |
|---|
| 2993 | |
|---|
| 2994 | static void BXVD_Decoder_S_UnifiedQ_AddPicture( |
|---|
| 2995 | BXVD_ChannelHandle hXvdCh, |
|---|
| 2996 | BXVD_Decoder_P_PictureContext * pstPictureCntxt, |
|---|
| 2997 | bool bBasePicture |
|---|
| 2998 | ) |
|---|
| 2999 | { |
|---|
| 3000 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext=NULL; |
|---|
| 3001 | |
|---|
| 3002 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_AddPicture ); |
|---|
| 3003 | |
|---|
| 3004 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_AddPic ); |
|---|
| 3005 | |
|---|
| 3006 | /* Bump the count of sets of pictures on the Unified Queue when |
|---|
| 3007 | * the base picture is added. |
|---|
| 3008 | */ |
|---|
| 3009 | if ( true == bBasePicture ) |
|---|
| 3010 | { |
|---|
| 3011 | hXvdCh->stDecoderContext.stUnifiedPictureQueue.iNumPictures++; |
|---|
| 3012 | } |
|---|
| 3013 | |
|---|
| 3014 | /* Get the BXDM_Picture element at the head of the unified queue. |
|---|
| 3015 | * The call to "BXVD_Decoder_S_UnifiedQ_GetFreeCount()" in "BXVD_Decoder_S_UnifiedQ_Update()" |
|---|
| 3016 | * should ensure that the queue has enough room. |
|---|
| 3017 | */ |
|---|
| 3018 | BXVD_Decoder_S_UnifiedQ_GetNextFreeElement( hXvdCh, &pstUnifiedContext ); |
|---|
| 3019 | |
|---|
| 3020 | /* This should never happen. We should only get here if there is a free |
|---|
| 3021 | * element on the Unified Queue. |
|---|
| 3022 | */ |
|---|
| 3023 | if ( NULL == pstUnifiedContext ) |
|---|
| 3024 | { |
|---|
| 3025 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_AddPicture:: failed to get an element.", NULL)); |
|---|
| 3026 | BDBG_ASSERT( 0 ); |
|---|
| 3027 | } |
|---|
| 3028 | |
|---|
| 3029 | /* Dereference the PPB and fill in the BXDM_Picture structure. |
|---|
| 3030 | */ |
|---|
| 3031 | BXVD_Decoder_S_UnifiedQ_ValidatePicture( hXvdCh, pstPictureCntxt, pstUnifiedContext, false ); |
|---|
| 3032 | |
|---|
| 3033 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_AddPic ); |
|---|
| 3034 | |
|---|
| 3035 | |
|---|
| 3036 | BDBG_LEAVE( BXVD_Decoder_S_UnifiedQ_AddPicture ); |
|---|
| 3037 | |
|---|
| 3038 | return; |
|---|
| 3039 | |
|---|
| 3040 | } /* end of BXVD_Decoder_S_UnifiedQ_AddPicture() */ |
|---|
| 3041 | |
|---|
| 3042 | static void BXVD_Decoder_S_PPBReceived( |
|---|
| 3043 | BXVD_ChannelHandle hXvdCh, |
|---|
| 3044 | BXVD_P_PPB **pstPPB |
|---|
| 3045 | ) |
|---|
| 3046 | { |
|---|
| 3047 | bool bSignalPPBReceived; |
|---|
| 3048 | |
|---|
| 3049 | BDBG_ENTER(BXVD_Decoder_S_PPBReceived); |
|---|
| 3050 | |
|---|
| 3051 | BDBG_ASSERT( hXvdCh ); |
|---|
| 3052 | |
|---|
| 3053 | /* First check that a callback function has been registered */ |
|---|
| 3054 | bSignalPPBReceived = ( NULL != hXvdCh->stInterruptCallbackInfo[BXVD_Interrupt_ePPBReceived].BXVD_P_pAppIntCallbackPtr ); |
|---|
| 3055 | |
|---|
| 3056 | /* Then check that the callback mask bit is set. */ |
|---|
| 3057 | bSignalPPBReceived &= ( true == hXvdCh->stCallbackReq.bPPBReceived ); |
|---|
| 3058 | |
|---|
| 3059 | /* If all the conditions have been met, execute the callback. */ |
|---|
| 3060 | if( bSignalPPBReceived ) |
|---|
| 3061 | { |
|---|
| 3062 | BXVD_DecoderTimer_P_SnapshotCallbackStartTime( hXvdCh, BXVD_DecoderTimer_P_eCbPPBReceived ); |
|---|
| 3063 | |
|---|
| 3064 | hXvdCh->stInterruptCallbackInfo[BXVD_Interrupt_ePPBReceived].BXVD_P_pAppIntCallbackPtr ( |
|---|
| 3065 | hXvdCh->stInterruptCallbackInfo[BXVD_Interrupt_ePPBReceived].pParm1, |
|---|
| 3066 | hXvdCh->stInterruptCallbackInfo[BXVD_Interrupt_ePPBReceived].parm2, |
|---|
| 3067 | pstPPB |
|---|
| 3068 | ) ; |
|---|
| 3069 | |
|---|
| 3070 | BXVD_DecoderTimer_P_SnapshotCallbackEndTime( hXvdCh, BXVD_DecoderTimer_P_eCbPPBReceived ); |
|---|
| 3071 | |
|---|
| 3072 | } |
|---|
| 3073 | |
|---|
| 3074 | BDBG_LEAVE(BXVD_Decoder_S_PPBReceived); |
|---|
| 3075 | |
|---|
| 3076 | return; |
|---|
| 3077 | |
|---|
| 3078 | } /* end of BBXVD_Decoder_S_PPBReceived() */ |
|---|
| 3079 | |
|---|
| 3080 | static void BXVD_Decoder_S_UnifiedQ_GetSetType( |
|---|
| 3081 | BXVD_ChannelHandle hXvdCh, |
|---|
| 3082 | BXVD_Decoder_P_LocalState * pstLocalState, |
|---|
| 3083 | BXVD_Decoder_P_PictureContext * pstPicCntxt |
|---|
| 3084 | ) |
|---|
| 3085 | { |
|---|
| 3086 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_GetSetType ); |
|---|
| 3087 | |
|---|
| 3088 | BDBG_ASSERT( hXvdCh ); |
|---|
| 3089 | BDBG_ASSERT( pstPicCntxt ); |
|---|
| 3090 | BSTD_UNUSED( pstLocalState ); |
|---|
| 3091 | |
|---|
| 3092 | if ( BAVC_VideoCompressionStd_eH264 == pstPicCntxt->stPPB.pPPB->protocol ) |
|---|
| 3093 | { |
|---|
| 3094 | /* If AVC, check the SEI messages to determine if 3D. */ |
|---|
| 3095 | |
|---|
| 3096 | uint32_t uiSEIOffset=0; |
|---|
| 3097 | BXVD_P_SEI_Message * pSEIMessage; |
|---|
| 3098 | |
|---|
| 3099 | /* SW7405-4883: set a default of 2D. */ |
|---|
| 3100 | pstPicCntxt->st3D.eOrientation = BXDM_Picture_Orientation_e2D; |
|---|
| 3101 | pstPicCntxt->st3D.eFrameRelationship = BXDM_Picture_FrameRelationship_eUnknown; |
|---|
| 3102 | |
|---|
| 3103 | /* TODO: the following is a partial duplicate of the SEI parsing in |
|---|
| 3104 | * the validate routine, clean this up. |
|---|
| 3105 | */ |
|---|
| 3106 | uiSEIOffset = (uint32_t)pstPicCntxt->stPPB.pPPB->other.h264.pstSEIMessageOffset; |
|---|
| 3107 | |
|---|
| 3108 | while ( 0 != uiSEIOffset ) |
|---|
| 3109 | { |
|---|
| 3110 | /* Convert the BXVD_P_SEI_Message offset to a virtual address. */ |
|---|
| 3111 | BMEM_ConvertOffsetToAddress( |
|---|
| 3112 | hXvdCh->hSystemHeap, |
|---|
| 3113 | uiSEIOffset, |
|---|
| 3114 | (void *)&( pSEIMessage ) |
|---|
| 3115 | ); |
|---|
| 3116 | |
|---|
| 3117 | if ( BXVD_P_PPB_SEI_MSG_FRAMEPACKING == pSEIMessage->uiMsgType ) |
|---|
| 3118 | { |
|---|
| 3119 | /* Needed pstAvdSEIData to prevent the compiler warning |
|---|
| 3120 | * "dereferencing type-punned pointer will break strict-aliasing rules" |
|---|
| 3121 | */ |
|---|
| 3122 | BXVD_P_SEI_FramePacking * pstAvdSEIData = (BXVD_P_SEI_FramePacking *)&(pSEIMessage->data.stSEIFramePacking); |
|---|
| 3123 | |
|---|
| 3124 | /* For 3D, fill in the pstXdmPicture->st3D.eOrientation |
|---|
| 3125 | * and pstXdmPicture->st3D.eFrameRelationship fields. |
|---|
| 3126 | */ |
|---|
| 3127 | BXVD_Decoder_S_UnifiedQ_ParseSeiFramePackMsg( pstAvdSEIData, &(pstPicCntxt->st3D) ); |
|---|
| 3128 | |
|---|
| 3129 | /* TODO: if multiple messages, break on the first?*/ |
|---|
| 3130 | break; |
|---|
| 3131 | } |
|---|
| 3132 | |
|---|
| 3133 | /* Check for another message. */ |
|---|
| 3134 | uiSEIOffset = (uint32_t)pSEIMessage->pstNextSEIMsgOffset; |
|---|
| 3135 | |
|---|
| 3136 | } /* end of while ( 0 != uiSEIOffset ) */ |
|---|
| 3137 | |
|---|
| 3138 | /* Convert SEI parameters into the appropriate "set" information. |
|---|
| 3139 | */ |
|---|
| 3140 | switch( pstPicCntxt->st3D.eOrientation ) |
|---|
| 3141 | { |
|---|
| 3142 | case BXDM_Picture_Orientation_e3D_FullFrame: |
|---|
| 3143 | /* Frame 0 is the base picture. */ |
|---|
| 3144 | |
|---|
| 3145 | if ( 0 == pstPicCntxt->st3D.uiFrameNum ) |
|---|
| 3146 | { |
|---|
| 3147 | pstPicCntxt->eSetType = BXVD_Decoder_P_PictureSet_eBase; |
|---|
| 3148 | } |
|---|
| 3149 | else |
|---|
| 3150 | { |
|---|
| 3151 | pstPicCntxt->eSetType = BXVD_Decoder_P_PictureSet_eDependent; |
|---|
| 3152 | } |
|---|
| 3153 | |
|---|
| 3154 | /* Expecting two pictures for full frame 3D */ |
|---|
| 3155 | pstPicCntxt->uiSetCount = 2; |
|---|
| 3156 | |
|---|
| 3157 | break; |
|---|
| 3158 | |
|---|
| 3159 | case BXDM_Picture_Orientation_e2D: |
|---|
| 3160 | case BXDM_Picture_Orientation_e3D_Checker: |
|---|
| 3161 | case BXDM_Picture_Orientation_e3D_Column: |
|---|
| 3162 | case BXDM_Picture_Orientation_e3D_Row: |
|---|
| 3163 | case BXDM_Picture_Orientation_e3D_SideBySide: |
|---|
| 3164 | case BXDM_Picture_Orientation_e3D_TopBottom: |
|---|
| 3165 | default: |
|---|
| 3166 | pstPicCntxt->eSetType = BXVD_Decoder_P_PictureSet_eSingle; |
|---|
| 3167 | pstPicCntxt->uiSetCount = 1; |
|---|
| 3168 | break; |
|---|
| 3169 | } |
|---|
| 3170 | |
|---|
| 3171 | } |
|---|
| 3172 | else |
|---|
| 3173 | { |
|---|
| 3174 | /* Extract the picture set type and set count. This is to support MVC and |
|---|
| 3175 | * perhaps other multipicture protocols. |
|---|
| 3176 | */ |
|---|
| 3177 | if ( !(pstPicCntxt->stPPB.pPPB->flags & BXVD_P_PPB_MULTIVIEW_FIELD_MASK) ) |
|---|
| 3178 | { |
|---|
| 3179 | pstPicCntxt->eSetType = BXVD_Decoder_P_PictureSet_eSingle; |
|---|
| 3180 | pstPicCntxt->uiSetCount = 1; |
|---|
| 3181 | } |
|---|
| 3182 | else |
|---|
| 3183 | { |
|---|
| 3184 | if ( pstPicCntxt->stPPB.pPPB->flags & BXVD_P_PPB_MULTIVIEW_BASE_FLAG ) |
|---|
| 3185 | { |
|---|
| 3186 | pstPicCntxt->eSetType = BXVD_Decoder_P_PictureSet_eBase; |
|---|
| 3187 | pstPicCntxt->uiSetCount = (( pstPicCntxt->stPPB.pPPB->flags & BXVD_P_PPB_MULTIVIEW_COUNT_MASK ) >> BXVD_P_PPB_MULTIVIEW_COUNT_SHIFT ); |
|---|
| 3188 | |
|---|
| 3189 | /* Should be generalized to use "pstPicCntxt->uiSetCount", waiting on the firmware.*/ |
|---|
| 3190 | pstPicCntxt->uiSetCount = BXVD_DECODER_S_PICTURES_PER_SET; |
|---|
| 3191 | } |
|---|
| 3192 | else |
|---|
| 3193 | { |
|---|
| 3194 | pstPicCntxt->eSetType = BXVD_Decoder_P_PictureSet_eDependent; |
|---|
| 3195 | pstPicCntxt->uiSetCount = BXVD_DECODER_S_PICTURES_PER_SET; |
|---|
| 3196 | } |
|---|
| 3197 | } |
|---|
| 3198 | } |
|---|
| 3199 | |
|---|
| 3200 | |
|---|
| 3201 | BDBG_ENTER( BXVD_Decoder_S_UnifiedQ_GetSetType ); |
|---|
| 3202 | |
|---|
| 3203 | return; |
|---|
| 3204 | } |
|---|
| 3205 | |
|---|
| 3206 | |
|---|
| 3207 | /* |
|---|
| 3208 | * |
|---|
| 3209 | */ |
|---|
| 3210 | static void BXVD_Decoder_S_UnifiedQ_Update( |
|---|
| 3211 | BXVD_ChannelHandle hXvdCh, |
|---|
| 3212 | BXVD_Decoder_P_LocalState * pstLocalState |
|---|
| 3213 | ) |
|---|
| 3214 | { |
|---|
| 3215 | BXVD_P_PictureDeliveryQueue * pstDeliveryQueue; |
|---|
| 3216 | BXVD_Decoder_P_UnifiedPictureQueue * pstUnifiedQueue = &hXvdCh->stDecoderContext.stUnifiedPictureQueue; |
|---|
| 3217 | uint32_t uiDeliveryQWriteOffset0Based; |
|---|
| 3218 | uint32_t uiDeliveryQReadOffset0Based; |
|---|
| 3219 | BXVD_Decoder_P_PictureContext * pstPicCntxt = NULL; |
|---|
| 3220 | BXVD_Decoder_P_PictureContext * pstPrevPicCntxt = NULL; |
|---|
| 3221 | |
|---|
| 3222 | BXVD_Decoder_P_PictureContextQueue * pstContextQueue = &(hXvdCh->stDecoderContext.stPictureContextQueue); |
|---|
| 3223 | |
|---|
| 3224 | uint32_t uiNumPicturesToProcess; |
|---|
| 3225 | |
|---|
| 3226 | uint32_t uiDeliveryQ_PicturesToProcess; |
|---|
| 3227 | uint32_t uiUniQFreeElements; |
|---|
| 3228 | |
|---|
| 3229 | BXVD_Decoder_P_DQTContext * pDQTCntxt = &( hXvdCh->stDecoderContext.stDqtCntxt ); |
|---|
| 3230 | bool bSearchForStartOfNextGop; |
|---|
| 3231 | bool bDeadlock = false; |
|---|
| 3232 | bool bFoundEndOfGop = false; |
|---|
| 3233 | bool bDqtMvcError = false; |
|---|
| 3234 | |
|---|
| 3235 | /* Update the Unified Picture Queue. |
|---|
| 3236 | * |
|---|
| 3237 | * There are three queues in play here: |
|---|
| 3238 | * - Delivery Queue, contains the PPB's from the video decoder |
|---|
| 3239 | * - Picture Context Queue, temporary values needed for processing pictures (e.g. PPB virtual addresses) |
|---|
| 3240 | * - Unified Picture Queue, the "cooked" pictures for consumption by the Picture Provider |
|---|
| 3241 | * |
|---|
| 3242 | * The conversion of PPB's into Unified Pictures is handled in three phases. |
|---|
| 3243 | * |
|---|
| 3244 | * Phase 1: vetting of the PPB's |
|---|
| 3245 | * - calculate the virtual address of the PPB |
|---|
| 3246 | * - check that there are matched sets of base and dependent pictures (e.g. MVC protocol) |
|---|
| 3247 | * - when DQT is enabled, search for the start of the next GOP |
|---|
| 3248 | * - generate the PPBReceived callback |
|---|
| 3249 | * |
|---|
| 3250 | * Phase 2: DQT cleanup (if DQT is enabled) |
|---|
| 3251 | * - determine if a GOP needs to be truncated |
|---|
| 3252 | * - set the appropriate pointers for processing the PPB's in reverse order |
|---|
| 3253 | * - handle MVC errors |
|---|
| 3254 | * (will this ever be supported? needs to be tested more thoroughly!!) |
|---|
| 3255 | * |
|---|
| 3256 | * Phase 3: validate Unified Picture Queue. |
|---|
| 3257 | * - interpret the PPB's fields to set appropriate Unified Picture elements |
|---|
| 3258 | * - link the dependent pictures to the base pictures |
|---|
| 3259 | */ |
|---|
| 3260 | |
|---|
| 3261 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_Vet ); |
|---|
| 3262 | |
|---|
| 3263 | BXVD_Decoder_S_Printf("\n> ", NULL ); |
|---|
| 3264 | |
|---|
| 3265 | /* Cleanup pictures at the end of a GOP that are not going to be displayed. |
|---|
| 3266 | */ |
|---|
| 3267 | if ( true == pDQTCntxt->bTruncatingGop ) |
|---|
| 3268 | { |
|---|
| 3269 | BXVD_Decoder_S_DeliveryQ_ReleaseGopTail( hXvdCh, pstLocalState ); |
|---|
| 3270 | } |
|---|
| 3271 | |
|---|
| 3272 | /* If ... |
|---|
| 3273 | * - DQT is enabled |
|---|
| 3274 | * - NOT in the middle of displaying a GOP |
|---|
| 3275 | * - NOT throwing away pictures at the end of the GOP |
|---|
| 3276 | * then it is time to look for the start of the next GOP. |
|---|
| 3277 | */ |
|---|
| 3278 | bSearchForStartOfNextGop = ( true == pDQTCntxt->bDqtEnabled ); |
|---|
| 3279 | bSearchForStartOfNextGop &= ( false == pDQTCntxt->bConvertGopToUniPics ); |
|---|
| 3280 | bSearchForStartOfNextGop &= ( false == pDQTCntxt->bTruncatingGop ); |
|---|
| 3281 | |
|---|
| 3282 | if ( true == bSearchForStartOfNextGop ) |
|---|
| 3283 | { |
|---|
| 3284 | BXVD_Decoder_S_Printf(" findNext ", NULL ); |
|---|
| 3285 | } |
|---|
| 3286 | |
|---|
| 3287 | /* Retrieve the read/write offsets for the delivery queue. |
|---|
| 3288 | * Adjust them to be '0' based. |
|---|
| 3289 | */ |
|---|
| 3290 | BXVD_AVD_P_DELIVERY_QUEUE_GET_ADDR( hXvdCh, pstDeliveryQueue ); |
|---|
| 3291 | |
|---|
| 3292 | BXVD_AVD_P_DELIVERY_QUEUE_GET_READ_OFFSET( hXvdCh, uiDeliveryQReadOffset0Based ); |
|---|
| 3293 | |
|---|
| 3294 | uiDeliveryQReadOffset0Based -= BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 3295 | |
|---|
| 3296 | uiDeliveryQWriteOffset0Based = pstLocalState->uiDeliveryQueueWriteOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 3297 | |
|---|
| 3298 | |
|---|
| 3299 | /* SW7405-3137: calculate the number of pictures on the delivery queue. |
|---|
| 3300 | * Hold off the processing of pictures until a complete "set" has |
|---|
| 3301 | * been delivered. (i.e. detects incomplete sets at the head of the queue.) |
|---|
| 3302 | * TODO: does this work with DQT? Handle in the search routine? |
|---|
| 3303 | */ |
|---|
| 3304 | BXVD_AVD_P_GET_QUEUE_DEPTH( uiDeliveryQReadOffset0Based, uiDeliveryQWriteOffset0Based, uiDeliveryQ_PicturesToProcess ); |
|---|
| 3305 | |
|---|
| 3306 | /* SW7405-3137: calculate the number of pictures to be processed on this call. |
|---|
| 3307 | * Hold off processing the one(s) at the tail of the queue until a complete |
|---|
| 3308 | * "set" has been delivered. (i.e detects incomplete sets at the tail of the queue.) |
|---|
| 3309 | */ |
|---|
| 3310 | BXVD_AVD_P_GET_QUEUE_DEPTH( pstContextQueue->uiWriteOffset, uiDeliveryQWriteOffset0Based, uiNumPicturesToProcess ); |
|---|
| 3311 | |
|---|
| 3312 | /* If in the middle of processing a GOP, hold off processing more pictures |
|---|
| 3313 | * until done with this GOP. This check should not be needed since the queue's are |
|---|
| 3314 | * reconcile as soon as the next GOP is delivered. The only way this could |
|---|
| 3315 | * happen, is if the Unified Picture Queue was full and the validation |
|---|
| 3316 | * need to be stalled until the Unified Queue was drained. |
|---|
| 3317 | */ |
|---|
| 3318 | if ( true == pDQTCntxt->bConvertGopToUniPics ) |
|---|
| 3319 | { |
|---|
| 3320 | BXVD_Decoder_S_Printf("rPlay ", NULL ); |
|---|
| 3321 | goto ProcessGop; |
|---|
| 3322 | } |
|---|
| 3323 | |
|---|
| 3324 | /* If DQT is enabled, check for a dead lock condition, i.e. the DM is waiting for the next |
|---|
| 3325 | * picture to be delivered and the decoder is waiting for a picture to be freed. |
|---|
| 3326 | * Don't bother with the check if the queue is empty; this will prevent false deadlock |
|---|
| 3327 | * detections when simply waiting for the video decoder. |
|---|
| 3328 | */ |
|---|
| 3329 | if ( true == bSearchForStartOfNextGop |
|---|
| 3330 | && uiDeliveryQReadOffset0Based != uiDeliveryQWriteOffset0Based |
|---|
| 3331 | ) |
|---|
| 3332 | { |
|---|
| 3333 | bDeadlock = BXVD_Decoder_S_DeliveryQ_CheckForDeadlock( hXvdCh, uiNumPicturesToProcess ); |
|---|
| 3334 | bFoundEndOfGop = bDeadlock; |
|---|
| 3335 | } |
|---|
| 3336 | |
|---|
| 3337 | |
|---|
| 3338 | BXVD_Decoder_S_Printf("start vetting:: DQrd:%d DQwr:%d CQwr:%d trnc:%d\n", |
|---|
| 3339 | uiDeliveryQReadOffset0Based, |
|---|
| 3340 | uiDeliveryQWriteOffset0Based, |
|---|
| 3341 | pstContextQueue->uiWriteOffset, |
|---|
| 3342 | pDQTCntxt->bTruncatingGop |
|---|
| 3343 | ); |
|---|
| 3344 | |
|---|
| 3345 | /* Phase 1: walk through the deliver queue vetting the PPB's. |
|---|
| 3346 | * |
|---|
| 3347 | * Loop through until: |
|---|
| 3348 | * - the PictureContextQueue write offset is equal to the DeliveryQueue write offset |
|---|
| 3349 | * - OR an incomplete set of pictures is encountered at either the tail or head of the DeliveryQueue. |
|---|
| 3350 | * - OR an error condition, i.e. an incomplete set of pictures is encountered in |
|---|
| 3351 | * the middle of the DeliveryQueue. |
|---|
| 3352 | * - OR DQT is enabled and the start of the next GOP has been found |
|---|
| 3353 | * |
|---|
| 3354 | * Note: "uiNumPicturesToProcess" will equal "0" during a deadlock condtion. Checking the |
|---|
| 3355 | * deadlock flag was added to the while statement for documentation purposes. |
|---|
| 3356 | */ |
|---|
| 3357 | while ( 0 != uiNumPicturesToProcess |
|---|
| 3358 | && false == bDeadlock ) |
|---|
| 3359 | { |
|---|
| 3360 | /* Get the next element on the picture context queue. */ |
|---|
| 3361 | pstPicCntxt = &pstContextQueue->astPictureContext[pstContextQueue->uiWriteOffset]; |
|---|
| 3362 | |
|---|
| 3363 | /* Reset the picture parameters and other elements */ |
|---|
| 3364 | BKNI_Memset( pstPicCntxt, 0, sizeof( BXVD_Decoder_P_PictureContext ) ); |
|---|
| 3365 | |
|---|
| 3366 | /* Get the PPB address */ |
|---|
| 3367 | pstPicCntxt->stPPB.pPPBPhysical = (BXVD_P_PPB *)( pstDeliveryQueue->display_elements[ pstContextQueue->uiWriteOffset ]); |
|---|
| 3368 | |
|---|
| 3369 | BMEM_ConvertOffsetToAddress( |
|---|
| 3370 | hXvdCh->hSystemHeap, |
|---|
| 3371 | (uint32_t)( pstPicCntxt->stPPB.pPPBPhysical ), |
|---|
| 3372 | (void *)&( pstPicCntxt->stPPB.pPPB ) |
|---|
| 3373 | ); |
|---|
| 3374 | |
|---|
| 3375 | /* Just for debug. */ |
|---|
| 3376 | if ( true == pDQTCntxt->bDqtEnabled ) |
|---|
| 3377 | { |
|---|
| 3378 | BXVD_Decoder_S_Printf("\n\tsearch:: DQ:%d/%d CQ:x/%d curTag=%u picTag=%u ", |
|---|
| 3379 | uiDeliveryQReadOffset0Based, |
|---|
| 3380 | uiDeliveryQWriteOffset0Based, |
|---|
| 3381 | pstContextQueue->uiWriteOffset, |
|---|
| 3382 | pDQTCntxt->uiCurrentPicTag, |
|---|
| 3383 | pstPicCntxt->stPPB.pPPB->picture_tag |
|---|
| 3384 | ); |
|---|
| 3385 | } |
|---|
| 3386 | |
|---|
| 3387 | /* SWCHECKFRAME-80: execute the PPBReceived callback prior to processing the PPB data. |
|---|
| 3388 | */ |
|---|
| 3389 | BXVD_Decoder_S_PPBReceived( hXvdCh, &(pstPicCntxt->stPPB.pPPB) ); |
|---|
| 3390 | |
|---|
| 3391 | /* Extract the picture set type and set count. This is to |
|---|
| 3392 | * support 3D and any multipicture protocol. |
|---|
| 3393 | */ |
|---|
| 3394 | BXVD_Decoder_S_UnifiedQ_GetSetType( hXvdCh, pstLocalState, pstPicCntxt ); |
|---|
| 3395 | |
|---|
| 3396 | if ( BXVD_Decoder_P_PictureSet_eSingle == pstPicCntxt->eSetType ) |
|---|
| 3397 | { |
|---|
| 3398 | BXVD_Decoder_S_Printf("S/%d ", pstContextQueue->uiWriteOffset ); |
|---|
| 3399 | } |
|---|
| 3400 | else if ( BXVD_Decoder_P_PictureSet_eBase == pstPicCntxt->eSetType ) |
|---|
| 3401 | { |
|---|
| 3402 | BXVD_Decoder_S_Printf("B/%d ", pstContextQueue->uiWriteOffset ); |
|---|
| 3403 | |
|---|
| 3404 | /* An incomplete set of pictures at the head of the delivery queue. */ |
|---|
| 3405 | |
|---|
| 3406 | if ( uiDeliveryQ_PicturesToProcess < pstPicCntxt->uiSetCount ) |
|---|
| 3407 | { |
|---|
| 3408 | BXVD_Decoder_S_Printf("break at head\n", NULL ); |
|---|
| 3409 | break; |
|---|
| 3410 | } |
|---|
| 3411 | } |
|---|
| 3412 | else if ( BXVD_Decoder_P_PictureSet_eDependent == pstPicCntxt->eSetType ) |
|---|
| 3413 | { |
|---|
| 3414 | BXVD_Decoder_S_Printf("d/%d ", pstContextQueue->uiWriteOffset ); |
|---|
| 3415 | } |
|---|
| 3416 | else |
|---|
| 3417 | { |
|---|
| 3418 | BXVD_DBG_ERR(hXvdCh,("BXVD_Decoder_S_UnifiedQ_Update:: unknown set type %d", pstPicCntxt->eSetType)); |
|---|
| 3419 | |
|---|
| 3420 | pstPicCntxt->eSetType = BXVD_Decoder_P_PictureSet_eSingle; |
|---|
| 3421 | pstPicCntxt->uiSetCount = 1; |
|---|
| 3422 | } |
|---|
| 3423 | |
|---|
| 3424 | |
|---|
| 3425 | /* If DQT is enabled, check for the start of the next GOP. |
|---|
| 3426 | * Don't look at the picture tag on dependent pictures. |
|---|
| 3427 | * GOP's should always start on a "base" or single picture. |
|---|
| 3428 | */ |
|---|
| 3429 | if ( BXVD_Decoder_P_PictureSet_eDependent != pstPicCntxt->eSetType |
|---|
| 3430 | && true == pDQTCntxt->bDqtEnabled |
|---|
| 3431 | ) |
|---|
| 3432 | { |
|---|
| 3433 | /* If "bValidPicTag" is false, the start of a GOP was detected the previous time |
|---|
| 3434 | * through this loop. Snapshot the new picture tag. |
|---|
| 3435 | */ |
|---|
| 3436 | if ( false == pDQTCntxt->bValidPicTag ) |
|---|
| 3437 | { |
|---|
| 3438 | pDQTCntxt->uiCurrentPicTag = pstPicCntxt->stPPB.pPPB->picture_tag; |
|---|
| 3439 | pDQTCntxt->bValidPicTag = true; |
|---|
| 3440 | BXVD_Decoder_S_Printf(" set tag %d ", pDQTCntxt->uiCurrentPicTag ); |
|---|
| 3441 | } |
|---|
| 3442 | |
|---|
| 3443 | /* If the new picture tag doesn't match the old one, the start of |
|---|
| 3444 | * the next GOP has been found. Break out of this loop and begin |
|---|
| 3445 | * displaying the GOP in reverse. |
|---|
| 3446 | */ |
|---|
| 3447 | if ( true == pDQTCntxt->bValidPicTag |
|---|
| 3448 | && pDQTCntxt->uiCurrentPicTag != pstPicCntxt->stPPB.pPPB->picture_tag |
|---|
| 3449 | ) |
|---|
| 3450 | { |
|---|
| 3451 | bFoundEndOfGop = true; |
|---|
| 3452 | |
|---|
| 3453 | BXVD_Decoder_S_Printf("\n\tfound EOG picTagThis=%u picTagNext=%u ", |
|---|
| 3454 | pDQTCntxt->uiCurrentPicTag, |
|---|
| 3455 | pstPicCntxt->stPPB.pPPB->picture_tag |
|---|
| 3456 | ); |
|---|
| 3457 | |
|---|
| 3458 | break; |
|---|
| 3459 | } |
|---|
| 3460 | |
|---|
| 3461 | } /* end of if( !BXVD_Decoder_P_PictureSet_eDependent && pDQTCntxt->bDqtEnabled ) */ |
|---|
| 3462 | |
|---|
| 3463 | |
|---|
| 3464 | /* Check for an error sequence. If the picture sequence is fine, |
|---|
| 3465 | * generate the "BXVD_Interrupt_ePPBReceived" callback and |
|---|
| 3466 | * validate the static picture context. |
|---|
| 3467 | * |
|---|
| 3468 | * The error sequences are |
|---|
| 3469 | * - "base" followed by "single" |
|---|
| 3470 | * - "base" followed by "base" |
|---|
| 3471 | * - "single" followed by "dependent" |
|---|
| 3472 | * - "dependent" followed by "dependent" |
|---|
| 3473 | * |
|---|
| 3474 | * Note: the first two scenarios can span a call to this routine, the |
|---|
| 3475 | * last two cannot. |
|---|
| 3476 | * Note: the POC will be the same for all pictures in the set, is this of any use? |
|---|
| 3477 | */ |
|---|
| 3478 | if ( BXVD_Decoder_P_PictureSet_eSingle == pstPicCntxt->eSetType |
|---|
| 3479 | || BXVD_Decoder_P_PictureSet_eBase == pstPicCntxt->eSetType |
|---|
| 3480 | ) |
|---|
| 3481 | { |
|---|
| 3482 | /* Check for a bad picture sequence. A "base" picture can not be followed |
|---|
| 3483 | * by a "base" or "single" picture; this indicates a missing "dependent" picture. |
|---|
| 3484 | * Evaluation of picture sets won't span a call to this routine, don't perform |
|---|
| 3485 | * the check for the first picture, i.e. "NULL == pstPrevPicCntxt". |
|---|
| 3486 | */ |
|---|
| 3487 | if ( NULL != pstPrevPicCntxt |
|---|
| 3488 | && BXVD_Decoder_P_PictureSet_eBase == pstPrevPicCntxt->eSetType |
|---|
| 3489 | ) |
|---|
| 3490 | { |
|---|
| 3491 | uint32_t uiTempWriteOffset; |
|---|
| 3492 | |
|---|
| 3493 | BXVD_Decoder_S_Printf("bad picture sequence Base followed by %d\n", pstPicCntxt->eSetType ); |
|---|
| 3494 | |
|---|
| 3495 | /* The picture in error is the previous one, backup the write pointer */ |
|---|
| 3496 | |
|---|
| 3497 | uiTempWriteOffset = pstContextQueue->uiWriteOffset; |
|---|
| 3498 | |
|---|
| 3499 | BXVD_Decoder_S_Decrement_0BasedOffset( |
|---|
| 3500 | &(uiTempWriteOffset), |
|---|
| 3501 | 1, |
|---|
| 3502 | BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE |
|---|
| 3503 | ); |
|---|
| 3504 | |
|---|
| 3505 | pstPicCntxt = &pstContextQueue->astPictureContext[uiTempWriteOffset]; |
|---|
| 3506 | |
|---|
| 3507 | if ( true == pDQTCntxt->bDqtEnabled ) |
|---|
| 3508 | { |
|---|
| 3509 | /* The error picture will be handled by the DQT truncation logic. */ |
|---|
| 3510 | bFoundEndOfGop = true; |
|---|
| 3511 | bDqtMvcError = true; |
|---|
| 3512 | break; |
|---|
| 3513 | } |
|---|
| 3514 | else |
|---|
| 3515 | { |
|---|
| 3516 | /* Mark the picture to be dropped. By "continue-ing", the error picture |
|---|
| 3517 | * will be dealt with at the top of this loop. |
|---|
| 3518 | * Drop the picture "in line". |
|---|
| 3519 | * Mark it as dropped so that the uni validation logic ignores it. |
|---|
| 3520 | */ |
|---|
| 3521 | pstPicCntxt->bDropPicture = true; |
|---|
| 3522 | break; |
|---|
| 3523 | } |
|---|
| 3524 | } |
|---|
| 3525 | |
|---|
| 3526 | if ( BXVD_Decoder_P_PictureSet_eBase == pstPicCntxt->eSetType ) |
|---|
| 3527 | { |
|---|
| 3528 | /* If a Base picture, check for an incomplete set of pictures at the |
|---|
| 3529 | * tail of the delivery queue. Wait for all the pictures before |
|---|
| 3530 | * processing this set. |
|---|
| 3531 | */ |
|---|
| 3532 | if ( uiNumPicturesToProcess < BXVD_DECODER_S_PICTURES_PER_SET /*pstPicCntxt->uiSetCount*/ ) |
|---|
| 3533 | { |
|---|
| 3534 | BXVD_Decoder_S_Printf("break at tail, pics on queue %d\n", uiDeliveryQ_PicturesToProcess ); |
|---|
| 3535 | break; |
|---|
| 3536 | } |
|---|
| 3537 | } |
|---|
| 3538 | #if 0 |
|---|
| 3539 | /* Generate the PPBReceived callback */ |
|---|
| 3540 | BXVD_Decoder_S_PPBReceived( hXvdCh, &(pstPicCntxt->stPPB.pPPB) ); |
|---|
| 3541 | #endif |
|---|
| 3542 | } |
|---|
| 3543 | else |
|---|
| 3544 | { |
|---|
| 3545 | /* Check for a bad picture sequence. A "dependent" picture can not follow either a |
|---|
| 3546 | * a "single" or a "dependent" picture; this would indicate a missing "base" picture. |
|---|
| 3547 | * Evaluation of picture sets won't span a call to this routine, if the first picture evaluated |
|---|
| 3548 | * is a "dependent" picture, the "base" picture is missing. |
|---|
| 3549 | */ |
|---|
| 3550 | if ( NULL == pstPrevPicCntxt |
|---|
| 3551 | || BXVD_Decoder_P_PictureSet_eDependent == pstPrevPicCntxt->eSetType |
|---|
| 3552 | || BXVD_Decoder_P_PictureSet_eSingle == pstPrevPicCntxt->eSetType |
|---|
| 3553 | ) |
|---|
| 3554 | { |
|---|
| 3555 | if ( NULL == pstPrevPicCntxt ) |
|---|
| 3556 | { |
|---|
| 3557 | BXVD_Decoder_S_Printf("bad picture sequence NULL followed by Dependent\n", NULL ); |
|---|
| 3558 | } |
|---|
| 3559 | else |
|---|
| 3560 | { |
|---|
| 3561 | BXVD_Decoder_S_Printf("bad picture sequence %d followed by Dependent\n", pstPrevPicCntxt->eSetType ); |
|---|
| 3562 | } |
|---|
| 3563 | |
|---|
| 3564 | if ( true == pDQTCntxt->bDqtEnabled ) |
|---|
| 3565 | { |
|---|
| 3566 | /* The error picture will be handled by the DQT truncation logic. */ |
|---|
| 3567 | bFoundEndOfGop = true; |
|---|
| 3568 | bDqtMvcError = true; |
|---|
| 3569 | break; |
|---|
| 3570 | } |
|---|
| 3571 | else |
|---|
| 3572 | { |
|---|
| 3573 | /* The picture in error is the current one, mark it to be dropped. */ |
|---|
| 3574 | |
|---|
| 3575 | pstPicCntxt->bDropPicture = true; |
|---|
| 3576 | |
|---|
| 3577 | /* Increment PictureContextQueue write offset */ |
|---|
| 3578 | BXVD_Decoder_S_Increment_0BasedOffset( |
|---|
| 3579 | &(pstContextQueue->uiWriteOffset), |
|---|
| 3580 | 1, |
|---|
| 3581 | BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ); |
|---|
| 3582 | |
|---|
| 3583 | break; |
|---|
| 3584 | } |
|---|
| 3585 | } |
|---|
| 3586 | |
|---|
| 3587 | /* An extended picture, link it to the preceding base picture. "pstPrevPicCntxt" should never be |
|---|
| 3588 | * NULL when processing complete sets. The preceding error logic ensures this. |
|---|
| 3589 | */ |
|---|
| 3590 | if ( NULL != pstPrevPicCntxt ) |
|---|
| 3591 | { |
|---|
| 3592 | /* Link this picture to the base. */ |
|---|
| 3593 | pstPrevPicCntxt->pDependentPicture = pstPicCntxt; |
|---|
| 3594 | |
|---|
| 3595 | /* Line this picture to the base. */ |
|---|
| 3596 | pstPicCntxt->pBasePicture = pstPrevPicCntxt; |
|---|
| 3597 | } |
|---|
| 3598 | else |
|---|
| 3599 | { |
|---|
| 3600 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_Update:: failed to link dependent picture to base.", NULL)); |
|---|
| 3601 | } |
|---|
| 3602 | } |
|---|
| 3603 | |
|---|
| 3604 | /* Increment PictureContextQueue write offset */ |
|---|
| 3605 | BXVD_Decoder_S_Increment_0BasedOffset( |
|---|
| 3606 | &(pstContextQueue->uiWriteOffset), |
|---|
| 3607 | 1, |
|---|
| 3608 | BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ); |
|---|
| 3609 | |
|---|
| 3610 | /* Decrement the count of pictures needing to be processed. */ |
|---|
| 3611 | uiNumPicturesToProcess--; |
|---|
| 3612 | |
|---|
| 3613 | /* Save the pointer to the context in order to link base and dependent pictures. */ |
|---|
| 3614 | pstPrevPicCntxt = pstPicCntxt; |
|---|
| 3615 | |
|---|
| 3616 | } /* end of while ( uiDeliveryQWriteOffset0Based != pstContextQueue->uiWriteOffset ) */ |
|---|
| 3617 | |
|---|
| 3618 | |
|---|
| 3619 | BXVD_Decoder_S_Printf("\nend vetting:: DQrd:%d DQwr:%d CQwr:%d", |
|---|
| 3620 | uiDeliveryQReadOffset0Based, |
|---|
| 3621 | uiDeliveryQWriteOffset0Based, |
|---|
| 3622 | pstContextQueue->uiWriteOffset |
|---|
| 3623 | ); |
|---|
| 3624 | |
|---|
| 3625 | if ( true == pDQTCntxt->bDqtEnabled ) |
|---|
| 3626 | { |
|---|
| 3627 | BXVD_Decoder_S_Printf(" search:%d found:%d deadlock:%d", |
|---|
| 3628 | bSearchForStartOfNextGop, |
|---|
| 3629 | bFoundEndOfGop, |
|---|
| 3630 | bDeadlock |
|---|
| 3631 | ); |
|---|
| 3632 | } |
|---|
| 3633 | |
|---|
| 3634 | BXVD_Decoder_S_Printf("\n", NULL ); |
|---|
| 3635 | |
|---|
| 3636 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_Vet ); |
|---|
| 3637 | |
|---|
| 3638 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_DQT ); |
|---|
| 3639 | |
|---|
| 3640 | /* Phase 2: |
|---|
| 3641 | * Now that done vetting the delivery queue, deal with DQT clean up. |
|---|
| 3642 | * If the end of the GOP was found on a previous call to this routine, determining that the queue |
|---|
| 3643 | * has data is fairly straight forward. If still searching for the start of the next GOP, |
|---|
| 3644 | * it gets more involved. |
|---|
| 3645 | * If the start of the next GOP has NOT been found, the picture queue is effectively empty. |
|---|
| 3646 | */ |
|---|
| 3647 | if ( true == pDQTCntxt->bDqtEnabled |
|---|
| 3648 | && true == bSearchForStartOfNextGop |
|---|
| 3649 | && true == bFoundEndOfGop ) |
|---|
| 3650 | { |
|---|
| 3651 | /* If a deadlock situation, then the GOP needs to be truncated. */ |
|---|
| 3652 | if ( bDeadlock ) |
|---|
| 3653 | { |
|---|
| 3654 | pDQTCntxt->bTruncatingGop = true; |
|---|
| 3655 | BXVD_Decoder_S_Printf("\n\tDeadLock:: CQwr=%d ", pstContextQueue->uiWriteOffset ); |
|---|
| 3656 | } |
|---|
| 3657 | |
|---|
| 3658 | /* Need to acquire the picture tag of the next GOP. */ |
|---|
| 3659 | pDQTCntxt->bValidPicTag = false; |
|---|
| 3660 | |
|---|
| 3661 | /* "pstContextQueue->uiWriteOffset" points to the next picture on the queue. |
|---|
| 3662 | * It could be the start of the next GOP or with MVC, an error picture. |
|---|
| 3663 | * In a deadlock scenario, it simply points just beyond the last picture received. |
|---|
| 3664 | * Load the following offsets with this value. |
|---|
| 3665 | */ |
|---|
| 3666 | pDQTCntxt->uiEndOfGopOffset = pstContextQueue->uiWriteOffset; |
|---|
| 3667 | pDQTCntxt->uiReverseReadOffset = pstContextQueue->uiWriteOffset; |
|---|
| 3668 | |
|---|
| 3669 | /* Backup to the last picture of this GOP. |
|---|
| 3670 | * Still in picture context queue "domain", use "0" based routines. |
|---|
| 3671 | */ |
|---|
| 3672 | BXVD_Decoder_S_Decrement_0BasedOffset( &(pDQTCntxt->uiReverseReadOffset), 1, BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ); |
|---|
| 3673 | |
|---|
| 3674 | /* Get the context of this last picture. */ |
|---|
| 3675 | pstPicCntxt = &pstContextQueue->astPictureContext[pDQTCntxt->uiReverseReadOffset]; |
|---|
| 3676 | |
|---|
| 3677 | /* Is there only one picture in the GOP? */ |
|---|
| 3678 | |
|---|
| 3679 | if ( pDQTCntxt->uiReverseReadOffset == uiDeliveryQReadOffset0Based ) |
|---|
| 3680 | { |
|---|
| 3681 | /* Only one picture for this GOP. |
|---|
| 3682 | * If it is a "single" picture, all is good. |
|---|
| 3683 | * If it is from an incomplete set, an error condition; |
|---|
| 3684 | * will needed to trigger the DQT truncation logic. |
|---|
| 3685 | * This error condition will not be detected in the main "while" loop. |
|---|
| 3686 | */ |
|---|
| 3687 | if ( BXVD_Decoder_P_PictureSet_eSingle == pstPicCntxt->eSetType ) |
|---|
| 3688 | { |
|---|
| 3689 | pDQTCntxt->bConvertGopToUniPics = true; |
|---|
| 3690 | bSearchForStartOfNextGop = false; |
|---|
| 3691 | /*pDQTCntxt->bTruncatingGop = false;*/ /* SW7425-1261: only clear bTruncatingGop in ..._ReleaseGopTail */ |
|---|
| 3692 | |
|---|
| 3693 | BXVD_Decoder_S_Printf("\n\tSinglePic(good):: rr=%d eog=%d ", |
|---|
| 3694 | pDQTCntxt->uiReverseReadOffset, |
|---|
| 3695 | pDQTCntxt->uiEndOfGopOffset |
|---|
| 3696 | ); |
|---|
| 3697 | } |
|---|
| 3698 | else |
|---|
| 3699 | { |
|---|
| 3700 | pDQTCntxt->bConvertGopToUniPics = false; |
|---|
| 3701 | pDQTCntxt->bTruncatingGop = true; |
|---|
| 3702 | |
|---|
| 3703 | /* Need to backup the EOG offset to error picture */ |
|---|
| 3704 | BXVD_Decoder_S_Decrement_0BasedOffset( &(pDQTCntxt->uiEndOfGopOffset), 1, BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ); |
|---|
| 3705 | |
|---|
| 3706 | BXVD_Decoder_S_Printf("\n\tSinglePic(bad):: rr=%d eog=%d ", |
|---|
| 3707 | pDQTCntxt->uiReverseReadOffset, |
|---|
| 3708 | pDQTCntxt->uiEndOfGopOffset |
|---|
| 3709 | ); |
|---|
| 3710 | |
|---|
| 3711 | } |
|---|
| 3712 | } |
|---|
| 3713 | else |
|---|
| 3714 | { |
|---|
| 3715 | /* More than one picture in the GOP. */ |
|---|
| 3716 | |
|---|
| 3717 | if ( true == bDqtMvcError ) |
|---|
| 3718 | { |
|---|
| 3719 | pDQTCntxt->bTruncatingGop = true; |
|---|
| 3720 | BXVD_Decoder_S_Printf("MVC error "); |
|---|
| 3721 | } |
|---|
| 3722 | |
|---|
| 3723 | /* If a deadlock and a multipicture protocol, we may have left off |
|---|
| 3724 | * on a base picture. Backup the pointers to the next picture. |
|---|
| 3725 | * If at the first picture of the GOP, the code block above will |
|---|
| 3726 | * be executed. |
|---|
| 3727 | */ |
|---|
| 3728 | if ( BXVD_Decoder_P_PictureSet_eBase == pstPicCntxt->eSetType ) |
|---|
| 3729 | { |
|---|
| 3730 | BXVD_Decoder_S_Decrement_0BasedOffset( &(pDQTCntxt->uiReverseReadOffset), 1, BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ); |
|---|
| 3731 | BXVD_Decoder_S_Decrement_0BasedOffset( &(pDQTCntxt->uiEndOfGopOffset), 1, BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ); |
|---|
| 3732 | } |
|---|
| 3733 | |
|---|
| 3734 | /* If a multipicture protocol (like MVC) backup until either |
|---|
| 3735 | * - the first picture of a complete set is found |
|---|
| 3736 | * - OR the head of the queue is reached. |
|---|
| 3737 | */ |
|---|
| 3738 | while ( pDQTCntxt->uiReverseReadOffset != uiDeliveryQReadOffset0Based |
|---|
| 3739 | && BXVD_Decoder_P_PictureSet_eDependent == pstPicCntxt->eSetType |
|---|
| 3740 | ) |
|---|
| 3741 | { |
|---|
| 3742 | BXVD_Decoder_S_Decrement_0BasedOffset( &(pDQTCntxt->uiReverseReadOffset), 1, BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ); |
|---|
| 3743 | pstPicCntxt = &pstContextQueue->astPictureContext[pDQTCntxt->uiReverseReadOffset]; |
|---|
| 3744 | } |
|---|
| 3745 | |
|---|
| 3746 | pDQTCntxt->bConvertGopToUniPics = ( pDQTCntxt->uiEndOfGopOffset != uiDeliveryQReadOffset0Based ); |
|---|
| 3747 | bSearchForStartOfNextGop = ( false == pDQTCntxt->bConvertGopToUniPics ); |
|---|
| 3748 | |
|---|
| 3749 | BXVD_Decoder_S_Printf("\n\tEndGop:: rr=%d eog=%d\n", |
|---|
| 3750 | pDQTCntxt->uiReverseReadOffset, |
|---|
| 3751 | pDQTCntxt->uiEndOfGopOffset |
|---|
| 3752 | ); |
|---|
| 3753 | |
|---|
| 3754 | } /* end of else ( uiReverseReadOffset != uiReadOffset ) */ |
|---|
| 3755 | |
|---|
| 3756 | |
|---|
| 3757 | /* Convert back to "2-based" offsets. */ |
|---|
| 3758 | pDQTCntxt->uiEndOfGopOffset += BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 3759 | pDQTCntxt->uiReverseReadOffset += BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 3760 | |
|---|
| 3761 | } /* end of if ( true == pDQTCntxt->bDqtEnabled && .... ) */ |
|---|
| 3762 | |
|---|
| 3763 | BXVD_Decoder_S_Printf("start validation:: Tail:%d Head:%d ", |
|---|
| 3764 | pstUnifiedQueue->pstContextTail->uiIndex, |
|---|
| 3765 | pstUnifiedQueue->pstContextHead->uiIndex |
|---|
| 3766 | ); |
|---|
| 3767 | |
|---|
| 3768 | if ( true == pDQTCntxt->bDqtEnabled ) |
|---|
| 3769 | { |
|---|
| 3770 | BXVD_Decoder_S_Printf(" search:%d found:%d deadlock:%d ", |
|---|
| 3771 | bSearchForStartOfNextGop, |
|---|
| 3772 | bFoundEndOfGop, |
|---|
| 3773 | bDeadlock |
|---|
| 3774 | ); |
|---|
| 3775 | } |
|---|
| 3776 | |
|---|
| 3777 | BXVD_Decoder_S_Printf("\n", NULL ); |
|---|
| 3778 | |
|---|
| 3779 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_DQT ); |
|---|
| 3780 | |
|---|
| 3781 | ProcessGop: |
|---|
| 3782 | |
|---|
| 3783 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_Val ); |
|---|
| 3784 | |
|---|
| 3785 | /* Phase 3: update the Unified Picture Queue, i.e. add pictures (or sets of pictures) |
|---|
| 3786 | * to the Unified Queue in display order. |
|---|
| 3787 | */ |
|---|
| 3788 | while ( false == bSearchForStartOfNextGop |
|---|
| 3789 | && true == BXVD_Decoder_S_ContextQ_PeekAtNextElement( hXvdCh, &pstPicCntxt ) |
|---|
| 3790 | ) |
|---|
| 3791 | { |
|---|
| 3792 | /* Check that the Unified Q has enough room. |
|---|
| 3793 | */ |
|---|
| 3794 | uiUniQFreeElements = BXVD_Decoder_S_UnifiedQ_GetFreeCount( hXvdCh ); |
|---|
| 3795 | |
|---|
| 3796 | if ( pstPicCntxt->uiSetCount > uiUniQFreeElements ) |
|---|
| 3797 | { |
|---|
| 3798 | BXVD_DBG_ERR(hXvdCh, ("BXVD_Decoder_S_UnifiedQ_Update Unified Q does not have enough room.")); |
|---|
| 3799 | break; |
|---|
| 3800 | } |
|---|
| 3801 | |
|---|
| 3802 | /* During the vetting of the delivery queue, mismatched sets of pictures |
|---|
| 3803 | * will be marked for dropping. The actual drop occurs here. |
|---|
| 3804 | */ |
|---|
| 3805 | if ( true == pstPicCntxt->bDropPicture ) |
|---|
| 3806 | { |
|---|
| 3807 | BXVD_Decoder_P_UnifiedPictureContext stUnifiedContext; |
|---|
| 3808 | |
|---|
| 3809 | /* Initialize "stUnifiedContext", in particular need to be certain that |
|---|
| 3810 | * "pstDependentUniContext" is NULL. For the normal code flow, this reset |
|---|
| 3811 | * is handled in "BXVD_Decoder_S_UnifiedQ_InvalidateElement. |
|---|
| 3812 | */ |
|---|
| 3813 | BKNI_Memset( &stUnifiedContext, 0, sizeof( BXVD_Decoder_P_UnifiedPictureContext ) ); |
|---|
| 3814 | |
|---|
| 3815 | |
|---|
| 3816 | BXVD_Decoder_S_Printf("edrop ", NULL ); |
|---|
| 3817 | |
|---|
| 3818 | |
|---|
| 3819 | BXVD_Decoder_S_UnifiedQ_ValidatePicture( hXvdCh, pstPicCntxt, &stUnifiedContext, true ); |
|---|
| 3820 | |
|---|
| 3821 | /* Remove the picture from the delivery queue. This could have been done in the |
|---|
| 3822 | * preceeding loop, but it is done here to keep the manipulation of the deliver |
|---|
| 3823 | * queue in as few places as possible. |
|---|
| 3824 | */ |
|---|
| 3825 | BXVD_Decoder_S_DeliveryQ_UpdateReadOffset( hXvdCh, pstLocalState, 1 ); |
|---|
| 3826 | |
|---|
| 3827 | /* Add the PPB to the release queue. */ |
|---|
| 3828 | |
|---|
| 3829 | BXVD_Decoder_S_ReleaseQ_AddPPB( hXvdCh, pstPicCntxt->stPPB.pPPBPhysical ); |
|---|
| 3830 | |
|---|
| 3831 | } |
|---|
| 3832 | else |
|---|
| 3833 | { |
|---|
| 3834 | /* Note: will only get complete sets of pictures at this point. |
|---|
| 3835 | * The following call adds the complete set of pictures to the Unified Queue. |
|---|
| 3836 | */ |
|---|
| 3837 | BXVD_Decoder_S_UnifiedQ_AddPicture( hXvdCh, pstPicCntxt, true ); |
|---|
| 3838 | |
|---|
| 3839 | /* Remove the picture(s) from the delivery queue. */ |
|---|
| 3840 | |
|---|
| 3841 | BXVD_Decoder_S_DeliveryQ_UpdateReadOffset( hXvdCh, pstLocalState, pstPicCntxt->uiSetCount ); |
|---|
| 3842 | |
|---|
| 3843 | } |
|---|
| 3844 | |
|---|
| 3845 | |
|---|
| 3846 | } /* end of while ( pictures on the context queue ) */ |
|---|
| 3847 | |
|---|
| 3848 | |
|---|
| 3849 | BXVD_Decoder_S_Printf("\t end validation:: Tail:%d Head:%d\n", |
|---|
| 3850 | pstUnifiedQueue->pstContextTail->uiIndex, |
|---|
| 3851 | pstUnifiedQueue->pstContextHead->uiIndex |
|---|
| 3852 | ); |
|---|
| 3853 | |
|---|
| 3854 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncUQ_Val ); |
|---|
| 3855 | |
|---|
| 3856 | return; |
|---|
| 3857 | |
|---|
| 3858 | } /* end of BXVD_Decoder_S_UnifiedQ_Update() */ |
|---|
| 3859 | |
|---|
| 3860 | |
|---|
| 3861 | |
|---|
| 3862 | static void BXVD_Decoder_S_DeliveryQ_UpdateReadOffset( |
|---|
| 3863 | BXVD_ChannelHandle hXvdCh, |
|---|
| 3864 | BXVD_Decoder_P_LocalState* pstLocalState, |
|---|
| 3865 | uint32_t uiDeltaChange |
|---|
| 3866 | ) |
|---|
| 3867 | { |
|---|
| 3868 | uint32_t uiReadOffset; |
|---|
| 3869 | |
|---|
| 3870 | BXVD_Decoder_P_DQTContext * pDQTCntxt = &( hXvdCh->stDecoderContext.stDqtCntxt ); |
|---|
| 3871 | |
|---|
| 3872 | BSTD_UNUSED( pstLocalState ); |
|---|
| 3873 | |
|---|
| 3874 | BDBG_ENTER( BXVD_Decoder_S_DeliveryQ_UpdateReadOffset ); |
|---|
| 3875 | |
|---|
| 3876 | BXVD_AVD_P_DELIVERY_QUEUE_GET_READ_OFFSET( hXvdCh, uiReadOffset ); |
|---|
| 3877 | |
|---|
| 3878 | /* If reading backwards from the display queue, update the "uiReverseReadOffset" |
|---|
| 3879 | * Othewise just update the standard "read offset". |
|---|
| 3880 | */ |
|---|
| 3881 | if ( true == pDQTCntxt->bDqtEnabled ) |
|---|
| 3882 | { |
|---|
| 3883 | |
|---|
| 3884 | BXVD_Decoder_S_Printf("\nUpRdOff:: Rr=%d Qr=%d revPlay %d :: ", |
|---|
| 3885 | pDQTCntxt->uiReverseReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 3886 | uiReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 3887 | pDQTCntxt->bConvertGopToUniPics |
|---|
| 3888 | ); |
|---|
| 3889 | |
|---|
| 3890 | if ( true == pDQTCntxt->bConvertGopToUniPics ) |
|---|
| 3891 | { |
|---|
| 3892 | if ( pDQTCntxt->uiReverseReadOffset == uiReadOffset ) |
|---|
| 3893 | { |
|---|
| 3894 | /* If "uiReverseReadOffset" is equal to "*puiReadOffset", we've processed the |
|---|
| 3895 | * entire "head" of the GOP. |
|---|
| 3896 | * |
|---|
| 3897 | * Flag that we are done and jump the read offsets ahead to the "end" of |
|---|
| 3898 | * the GOP. |
|---|
| 3899 | * |
|---|
| 3900 | * Note: we could still be cleaning up pictures at the "tail" of this GOP. |
|---|
| 3901 | */ |
|---|
| 3902 | pDQTCntxt->bConvertGopToUniPics = false; |
|---|
| 3903 | |
|---|
| 3904 | uiReadOffset = pDQTCntxt->uiEndOfGopOffset; |
|---|
| 3905 | BXVD_AVD_P_DELIVERY_QUEUE_SET_READ_OFFSET( hXvdCh, uiReadOffset ); |
|---|
| 3906 | |
|---|
| 3907 | pDQTCntxt->uiReverseReadOffset = pDQTCntxt->uiEndOfGopOffset; |
|---|
| 3908 | |
|---|
| 3909 | /* For debug. */ |
|---|
| 3910 | hXvdCh->stDecoderContext.stLogData.uiPicturesFromAvd += uiDeltaChange; |
|---|
| 3911 | |
|---|
| 3912 | BXVD_Decoder_S_Printf("( done Rr=%d Qr=%d ) ", |
|---|
| 3913 | pDQTCntxt->uiReverseReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 3914 | uiReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE |
|---|
| 3915 | ); |
|---|
| 3916 | } |
|---|
| 3917 | else |
|---|
| 3918 | { |
|---|
| 3919 | /* Still processing this GOP, simply decrement the read ahead offset. */ |
|---|
| 3920 | |
|---|
| 3921 | BXVD_Decoder_S_Decrement_2BasedOffset( |
|---|
| 3922 | &(pDQTCntxt->uiReverseReadOffset), |
|---|
| 3923 | uiDeltaChange, |
|---|
| 3924 | BXVD_P_DISP_FIFO_DEPTH |
|---|
| 3925 | ); |
|---|
| 3926 | |
|---|
| 3927 | /* For debug. */ |
|---|
| 3928 | hXvdCh->stDecoderContext.stLogData.uiPicturesFromAvd += uiDeltaChange; |
|---|
| 3929 | |
|---|
| 3930 | BXVD_Decoder_S_Printf("( just inc Rr=%d ) ", |
|---|
| 3931 | pDQTCntxt->uiReverseReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE |
|---|
| 3932 | ); |
|---|
| 3933 | } |
|---|
| 3934 | |
|---|
| 3935 | } |
|---|
| 3936 | else |
|---|
| 3937 | { |
|---|
| 3938 | /* If "bDqtEnabled" is true and "bConvertGopToUniPics" is false, |
|---|
| 3939 | * the entire GOP has not been delivered to the display queue. |
|---|
| 3940 | * Other logic should prevent this case from being reached. |
|---|
| 3941 | */ |
|---|
| 3942 | BXVD_Decoder_S_Printf("\nUpRdOff:: not supposed to be here:: Rr=%d Qr=%d inRev = %d ", |
|---|
| 3943 | pDQTCntxt->uiReverseReadOffset, |
|---|
| 3944 | uiReadOffset, |
|---|
| 3945 | pDQTCntxt->bConvertGopToUniPics |
|---|
| 3946 | ); |
|---|
| 3947 | } |
|---|
| 3948 | |
|---|
| 3949 | |
|---|
| 3950 | } /* end if ( bDqtEnabled )*/ |
|---|
| 3951 | else |
|---|
| 3952 | { |
|---|
| 3953 | /* Normal play, simply increment the "read offset" */ |
|---|
| 3954 | |
|---|
| 3955 | BXVD_Decoder_S_Printf("\nUpRdOff:: %d(%d) ", uiReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, uiDeltaChange ); |
|---|
| 3956 | |
|---|
| 3957 | BXVD_AVD_P_INCREMENT_2BASED_OFFSET( uiReadOffset, uiDeltaChange ); |
|---|
| 3958 | |
|---|
| 3959 | BXVD_AVD_P_DELIVERY_QUEUE_SET_READ_OFFSET( hXvdCh, uiReadOffset ); |
|---|
| 3960 | |
|---|
| 3961 | /* For debug. */ |
|---|
| 3962 | hXvdCh->stDecoderContext.stLogData.uiPicturesFromAvd += uiDeltaChange; |
|---|
| 3963 | |
|---|
| 3964 | /* Keep these values in lock step to avoid issues when transistioning into DQT. */ |
|---|
| 3965 | pDQTCntxt->uiEndOfGopOffset = uiReadOffset; |
|---|
| 3966 | pDQTCntxt->uiReverseReadOffset = uiReadOffset; |
|---|
| 3967 | |
|---|
| 3968 | } |
|---|
| 3969 | |
|---|
| 3970 | BDBG_LEAVE( BXVD_Decoder_S_DeliveryQ_UpdateReadOffset ); |
|---|
| 3971 | |
|---|
| 3972 | return; |
|---|
| 3973 | |
|---|
| 3974 | } |
|---|
| 3975 | |
|---|
| 3976 | static void BXVD_Decoder_S_ReleaseQ_AddPPB( |
|---|
| 3977 | BXVD_ChannelHandle hXvdCh, |
|---|
| 3978 | BXVD_P_PPB *pPPBPhysical |
|---|
| 3979 | ) |
|---|
| 3980 | { |
|---|
| 3981 | uint32_t uiReleaseWriteOffset; |
|---|
| 3982 | uint32_t uiTempWriteOffset; |
|---|
| 3983 | |
|---|
| 3984 | BXVD_P_PictureReleaseQueue * pReleaseQue; |
|---|
| 3985 | |
|---|
| 3986 | BDBG_ENTER( BXVD_Decoder_S_ReleaseQ_AddPPB ); |
|---|
| 3987 | |
|---|
| 3988 | BDBG_ASSERT(pPPBPhysical); |
|---|
| 3989 | |
|---|
| 3990 | /* Initialize the local variables. */ |
|---|
| 3991 | BXVD_AVD_P_RELEASE_QUEUE_GET_ADDR( hXvdCh, pReleaseQue ); |
|---|
| 3992 | BXVD_AVD_P_RELEASE_QUEUE_GET_SHADOW_WRITE_OFFSET( hXvdCh, uiReleaseWriteOffset ) |
|---|
| 3993 | |
|---|
| 3994 | /* Verify that the offset in in range */ |
|---|
| 3995 | |
|---|
| 3996 | if ( ( uiReleaseWriteOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE ) >= BXVD_P_MAX_ELEMENTS_IN_DISPLAY_QUEUE ) |
|---|
| 3997 | { |
|---|
| 3998 | BXVD_DBG_ERR(hXvdCh,("BXVD_Decoder_S_ReleaseQ_AddPPB: out of range offset %d", uiReleaseWriteOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE)); |
|---|
| 3999 | goto Done; |
|---|
| 4000 | } |
|---|
| 4001 | |
|---|
| 4002 | /* "pPPBPhysical" should always be valid. */ |
|---|
| 4003 | |
|---|
| 4004 | if ( ( NULL != pPPBPhysical ) ) |
|---|
| 4005 | { |
|---|
| 4006 | |
|---|
| 4007 | BXVD_Decoder_S_Printf("relOffset:%d 0x%x \n", |
|---|
| 4008 | uiReleaseWriteOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4009 | pPPBPhysical |
|---|
| 4010 | ); |
|---|
| 4011 | |
|---|
| 4012 | /* Add the the element to the release queue. */ |
|---|
| 4013 | |
|---|
| 4014 | pReleaseQue->display_elements[ uiReleaseWriteOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE ] = pPPBPhysical; |
|---|
| 4015 | |
|---|
| 4016 | /* Increment the release queue write offset. */ |
|---|
| 4017 | |
|---|
| 4018 | BXVD_AVD_P_INCREMENT_2BASED_OFFSET( uiReleaseWriteOffset, 1 ); |
|---|
| 4019 | BXVD_AVD_P_RELEASE_QUEUE_SET_SHADOW_WRITE_OFFSET( hXvdCh, uiReleaseWriteOffset ) |
|---|
| 4020 | |
|---|
| 4021 | /* Read the value back to insure that the MIPS write buffer has been flushed to memory |
|---|
| 4022 | * TODO: still needed? |
|---|
| 4023 | */ |
|---|
| 4024 | uiTempWriteOffset = uiReleaseWriteOffset; |
|---|
| 4025 | |
|---|
| 4026 | /* For debug. */ |
|---|
| 4027 | hXvdCh->stDecoderContext.stLogData.uiPicturesToAvd++; |
|---|
| 4028 | |
|---|
| 4029 | } |
|---|
| 4030 | |
|---|
| 4031 | Done: |
|---|
| 4032 | |
|---|
| 4033 | BDBG_LEAVE( BXVD_Decoder_S_ReleaseQ_AddPPB ); |
|---|
| 4034 | |
|---|
| 4035 | return; |
|---|
| 4036 | |
|---|
| 4037 | } /* End of BXVD_Decoder_S_ReleaseQ_AddPPB() */ |
|---|
| 4038 | |
|---|
| 4039 | |
|---|
| 4040 | void BXVD_Decoder_S_DqtInit( BXVD_ChannelHandle hXvdCh ) |
|---|
| 4041 | { |
|---|
| 4042 | BDBG_ASSERT(hXvdCh); |
|---|
| 4043 | |
|---|
| 4044 | /* |
|---|
| 4045 | * initialize the DQTM parameters |
|---|
| 4046 | */ |
|---|
| 4047 | hXvdCh->stDecoderContext.stDqtCntxt.bConvertGopToUniPics = false; |
|---|
| 4048 | hXvdCh->stDecoderContext.stDqtCntxt.uiPreviousWrOffset = 0; |
|---|
| 4049 | hXvdCh->stDecoderContext.stDqtCntxt.uiTimesOffsetRepeated = 0; |
|---|
| 4050 | |
|---|
| 4051 | hXvdCh->stDecoderContext.stDqtCntxt.bDqtEnabled = hXvdCh->stDecoderContext.bReversePlayback; |
|---|
| 4052 | |
|---|
| 4053 | hXvdCh->stDecoderContext.stDqtCntxt.uiDeadlockThreshold = BXVD_DECODER_DQT_DEADLOCK_THRESHOLD; |
|---|
| 4054 | hXvdCh->stDecoderContext.stDqtCntxt.bTruncatingGop = false; |
|---|
| 4055 | hXvdCh->stDecoderContext.stDqtCntxt.uiCurrentPicTag = -1; |
|---|
| 4056 | hXvdCh->stDecoderContext.stDqtCntxt.bValidPicTag = false; |
|---|
| 4057 | |
|---|
| 4058 | BXVD_AVD_P_DELIVERY_QUEUE_GET_READ_OFFSET( |
|---|
| 4059 | hXvdCh, |
|---|
| 4060 | hXvdCh->stDecoderContext.stDqtCntxt.uiReverseReadOffset |
|---|
| 4061 | ); |
|---|
| 4062 | return; |
|---|
| 4063 | |
|---|
| 4064 | } |
|---|
| 4065 | |
|---|
| 4066 | |
|---|
| 4067 | static bool BXVD_Decoder_S_DeliveryQ_CheckForDeadlock( |
|---|
| 4068 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4069 | uint32_t uiNumPicturesToProcess |
|---|
| 4070 | ) |
|---|
| 4071 | { |
|---|
| 4072 | bool bDeadLock = false; |
|---|
| 4073 | uint32_t uiPicturesOnUniQue; |
|---|
| 4074 | |
|---|
| 4075 | BXVD_Decoder_P_DQTContext * pDQTCntxt = &( hXvdCh->stDecoderContext.stDqtCntxt ); |
|---|
| 4076 | |
|---|
| 4077 | uiPicturesOnUniQue = BXVD_Decoder_S_UnifiedQ_GetPictureCount( hXvdCh ); |
|---|
| 4078 | |
|---|
| 4079 | /* |
|---|
| 4080 | * There are two potential deadlock conditions. |
|---|
| 4081 | * |
|---|
| 4082 | * One is at the end of a stream. Since we only mark the beginning of |
|---|
| 4083 | * GOPs and not their end, the DQT code will not push out the last |
|---|
| 4084 | * GOP since it doesn't see the start of the next one. |
|---|
| 4085 | * |
|---|
| 4086 | * The other could occur when the firmware is waiting for a PPB to be freed |
|---|
| 4087 | * and the DQT code is waiting for the start of the next GOP. |
|---|
| 4088 | * |
|---|
| 4089 | * The system is not deadlocked if there are more pictures to process as |
|---|
| 4090 | * indicated by "uiNumPicturesToProcess". The system is not deadlocked |
|---|
| 4091 | * if XDM is still working on the previous GOP as indicated by "uiPicturesOnUniQue". |
|---|
| 4092 | * If "uiPicturesOnUniQue" is equal to 1, the picture could be from the previous |
|---|
| 4093 | * decode (i.e. hold last picture). |
|---|
| 4094 | * This is a crude approach, but we declare a deadlock situation if the Display Queue |
|---|
| 4095 | * write pointer has not advanced in "uiDeadlockThreshold" vsync's. |
|---|
| 4096 | */ |
|---|
| 4097 | if (( 0 != uiNumPicturesToProcess ) || ( uiPicturesOnUniQue > 1 )) |
|---|
| 4098 | { |
|---|
| 4099 | pDQTCntxt->uiTimesOffsetRepeated = 0; |
|---|
| 4100 | } |
|---|
| 4101 | else |
|---|
| 4102 | { |
|---|
| 4103 | pDQTCntxt->uiTimesOffsetRepeated++; |
|---|
| 4104 | |
|---|
| 4105 | if ( pDQTCntxt->uiTimesOffsetRepeated > pDQTCntxt->uiDeadlockThreshold ) |
|---|
| 4106 | { |
|---|
| 4107 | bDeadLock = true; |
|---|
| 4108 | |
|---|
| 4109 | BXVD_Decoder_S_Printf("\ndeadlock!!!\n", NULL ); |
|---|
| 4110 | } |
|---|
| 4111 | } |
|---|
| 4112 | |
|---|
| 4113 | return bDeadLock; |
|---|
| 4114 | |
|---|
| 4115 | } |
|---|
| 4116 | |
|---|
| 4117 | static void BXVD_Decoder_S_DeliveryQ_ReleaseGopTail( |
|---|
| 4118 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4119 | BXVD_Decoder_P_LocalState * pstLocalState |
|---|
| 4120 | ) |
|---|
| 4121 | { |
|---|
| 4122 | bool bDoneProcessingGop; |
|---|
| 4123 | bool bNonDependentPicture; |
|---|
| 4124 | BXVD_P_DisplayElement stDisplayElement; |
|---|
| 4125 | BXVD_Decoder_P_DQTContext * pDQTCntxt; |
|---|
| 4126 | bool bPicturesToDrop; |
|---|
| 4127 | |
|---|
| 4128 | uint32_t uiDqReadOffset; |
|---|
| 4129 | uint32_t uiWriteOffset; |
|---|
| 4130 | uint32_t uiTempOffset; |
|---|
| 4131 | |
|---|
| 4132 | BXVD_P_PictureDeliveryQueue * pstDeliveryQueue; |
|---|
| 4133 | |
|---|
| 4134 | BXVD_Decoder_P_PictureContextQueue * pstContextQueue = &(hXvdCh->stDecoderContext.stPictureContextQueue); |
|---|
| 4135 | |
|---|
| 4136 | BXVD_Decoder_P_PictureContext * pstTempPicCntxt; |
|---|
| 4137 | |
|---|
| 4138 | BXVD_AVD_P_DELIVERY_QUEUE_GET_READ_OFFSET( hXvdCh, uiDqReadOffset ); |
|---|
| 4139 | |
|---|
| 4140 | BXVD_AVD_P_DELIVERY_QUEUE_GET_ADDR( hXvdCh, pstDeliveryQueue ); |
|---|
| 4141 | |
|---|
| 4142 | uiWriteOffset = pstLocalState->uiDeliveryQueueWriteOffset; |
|---|
| 4143 | |
|---|
| 4144 | /* |
|---|
| 4145 | * Initialize the local variables. |
|---|
| 4146 | */ |
|---|
| 4147 | pDQTCntxt = &( hXvdCh->stDecoderContext.stDqtCntxt ); |
|---|
| 4148 | |
|---|
| 4149 | |
|---|
| 4150 | /* This routine is called when a GOP is being truncated. |
|---|
| 4151 | * While the pictures at the head of the GOP are being converted to |
|---|
| 4152 | * unified pictures, this routine releases the pictures at the tail. |
|---|
| 4153 | */ |
|---|
| 4154 | |
|---|
| 4155 | /* Are we done processing this GOP? |
|---|
| 4156 | * If the offset used to read the queue in reverse (uiReverseReadOffset) is |
|---|
| 4157 | * equal to the Delivery Queue read offset (uiDqReadOffset), all the PPB's |
|---|
| 4158 | * have been converted to Unified Pictures. |
|---|
| 4159 | * The check of "bConvertGopToUniPics" was needed for the implementation |
|---|
| 4160 | * prior to XDM. It should be redundant at this time, but I want to do some |
|---|
| 4161 | * more testing before I remove it. |
|---|
| 4162 | */ |
|---|
| 4163 | bDoneProcessingGop = ( pDQTCntxt->uiReverseReadOffset == uiDqReadOffset ); |
|---|
| 4164 | bDoneProcessingGop &= ( false == pDQTCntxt->bConvertGopToUniPics ); |
|---|
| 4165 | |
|---|
| 4166 | bPicturesToDrop = ( pDQTCntxt->uiEndOfGopOffset != uiWriteOffset ); |
|---|
| 4167 | |
|---|
| 4168 | if ( true == bPicturesToDrop ) |
|---|
| 4169 | { |
|---|
| 4170 | BXVD_Decoder_S_Printf("\nrelTail enter: Rr=%d DQ:%d/%d CQwr=%d Eog=%d done=%d\n", |
|---|
| 4171 | pDQTCntxt->uiReverseReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4172 | uiDqReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4173 | uiWriteOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4174 | pstContextQueue->uiWriteOffset, |
|---|
| 4175 | pDQTCntxt->uiEndOfGopOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4176 | bDoneProcessingGop |
|---|
| 4177 | ); |
|---|
| 4178 | } |
|---|
| 4179 | |
|---|
| 4180 | /* |
|---|
| 4181 | ** There are still pictures to throw away if "uiEndOfGopOffset" hasn't caught up to |
|---|
| 4182 | ** the delivery queue write offset (i.e. "ui32WrPtr") |
|---|
| 4183 | */ |
|---|
| 4184 | while( pDQTCntxt->uiEndOfGopOffset != uiWriteOffset ) |
|---|
| 4185 | { |
|---|
| 4186 | |
|---|
| 4187 | /* Get the address of the PPB */ |
|---|
| 4188 | stDisplayElement.pPPBPhysical = (BXVD_P_PPB *)pstDeliveryQueue->display_elements[ pDQTCntxt->uiEndOfGopOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE]; |
|---|
| 4189 | |
|---|
| 4190 | BMEM_ConvertOffsetToAddress( |
|---|
| 4191 | hXvdCh->hSystemHeap, |
|---|
| 4192 | (uint32_t)( stDisplayElement.pPPBPhysical ), |
|---|
| 4193 | (void *)&( stDisplayElement.pPPB ) |
|---|
| 4194 | ); |
|---|
| 4195 | |
|---|
| 4196 | |
|---|
| 4197 | /* Determine the picture type; only look at the picture tag for |
|---|
| 4198 | * "non-dependent" pictures. |
|---|
| 4199 | */ |
|---|
| 4200 | if ( !( stDisplayElement.pPPB->flags & BXVD_P_PPB_MULTIVIEW_FIELD_MASK ) |
|---|
| 4201 | || ( stDisplayElement.pPPB->flags & BXVD_P_PPB_MULTIVIEW_BASE_FLAG ) |
|---|
| 4202 | ) |
|---|
| 4203 | { |
|---|
| 4204 | bNonDependentPicture = true; |
|---|
| 4205 | } |
|---|
| 4206 | else |
|---|
| 4207 | { |
|---|
| 4208 | bNonDependentPicture = false; |
|---|
| 4209 | } |
|---|
| 4210 | |
|---|
| 4211 | /* |
|---|
| 4212 | ** If "picture_tag" doesn't match the saved value, we've reached the start of |
|---|
| 4213 | ** the next GOP. We're done cleaning up this GOP, update the appropriate offsets. |
|---|
| 4214 | ** If a "dependent" picture, simply drop it. GOPs always start on a "single" or base picture. |
|---|
| 4215 | */ |
|---|
| 4216 | if ( pDQTCntxt->uiCurrentPicTag != stDisplayElement.pPPB->picture_tag |
|---|
| 4217 | && true == bNonDependentPicture |
|---|
| 4218 | ) |
|---|
| 4219 | { |
|---|
| 4220 | pDQTCntxt->bTruncatingGop = false; |
|---|
| 4221 | |
|---|
| 4222 | BXVD_Decoder_S_Printf("\t old tag = %u new tag =%u\n", pDQTCntxt->uiCurrentPicTag, stDisplayElement.pPPB->picture_tag ); |
|---|
| 4223 | |
|---|
| 4224 | if ( bDoneProcessingGop ) |
|---|
| 4225 | { |
|---|
| 4226 | /* |
|---|
| 4227 | ** We'll hit this block only if the entire "head" of the GOP has been processed. |
|---|
| 4228 | ** If the "head" is still being processed, the logic in "BXVD_Decoder_S_DqtReadOffsetUpdate()" |
|---|
| 4229 | ** will update the read offsets. |
|---|
| 4230 | */ |
|---|
| 4231 | uiDqReadOffset = pDQTCntxt->uiEndOfGopOffset; |
|---|
| 4232 | BXVD_AVD_P_DELIVERY_QUEUE_SET_READ_OFFSET( hXvdCh, uiDqReadOffset ); |
|---|
| 4233 | pDQTCntxt->uiReverseReadOffset = pDQTCntxt->uiEndOfGopOffset; |
|---|
| 4234 | } |
|---|
| 4235 | |
|---|
| 4236 | break; |
|---|
| 4237 | } |
|---|
| 4238 | |
|---|
| 4239 | /* Release the picture and invalidate the entry in the picture context queue. */ |
|---|
| 4240 | |
|---|
| 4241 | BXVD_Decoder_S_Printf("\t releaseTail:: eog %d ", pDQTCntxt->uiEndOfGopOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE ); |
|---|
| 4242 | |
|---|
| 4243 | BXVD_Decoder_S_ReleaseQ_AddPPB( hXvdCh, stDisplayElement.pPPBPhysical ); |
|---|
| 4244 | |
|---|
| 4245 | pstTempPicCntxt = &(pstContextQueue->astPictureContext[ pDQTCntxt->uiEndOfGopOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE ]); |
|---|
| 4246 | |
|---|
| 4247 | /* |
|---|
| 4248 | * Increment the "uiEndOfGopOffset" offset. |
|---|
| 4249 | */ |
|---|
| 4250 | BXVD_AVD_P_INCREMENT_2BASED_OFFSET( pDQTCntxt->uiEndOfGopOffset, 1 ); |
|---|
| 4251 | |
|---|
| 4252 | /* For debug. */ |
|---|
| 4253 | hXvdCh->stDecoderContext.stLogData.uiPicturesFromAvd++; |
|---|
| 4254 | |
|---|
| 4255 | /* |
|---|
| 4256 | * Jump the Picture Context Queue write pointer ahead if it is lagging. |
|---|
| 4257 | * This is the normal mode of operation once "uiEndOfGopOffset" has caught |
|---|
| 4258 | * up to "pstUnifiedQueue->uiWriteOffset". |
|---|
| 4259 | * It can also happen if a PPB is added to the delivery queue between the call |
|---|
| 4260 | * to "BXVD_Decoder_P_UpdatePictureContextQueue() and this routine. |
|---|
| 4261 | */ |
|---|
| 4262 | uiTempOffset = pstContextQueue->uiWriteOffset + BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 4263 | |
|---|
| 4264 | if ( pDQTCntxt->uiEndOfGopOffset <= uiWriteOffset |
|---|
| 4265 | && ( uiTempOffset < pDQTCntxt->uiEndOfGopOffset |
|---|
| 4266 | || uiTempOffset > uiWriteOffset ) |
|---|
| 4267 | ) |
|---|
| 4268 | { |
|---|
| 4269 | pstContextQueue->uiWriteOffset = pDQTCntxt->uiEndOfGopOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 4270 | } |
|---|
| 4271 | else if ( uiTempOffset < pDQTCntxt->uiEndOfGopOffset && uiTempOffset > uiWriteOffset ) |
|---|
| 4272 | { |
|---|
| 4273 | pstContextQueue->uiWriteOffset = pDQTCntxt->uiEndOfGopOffset - BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 4274 | } |
|---|
| 4275 | |
|---|
| 4276 | } |
|---|
| 4277 | |
|---|
| 4278 | |
|---|
| 4279 | if ( bDoneProcessingGop && ( pDQTCntxt->uiEndOfGopOffset == uiWriteOffset )) |
|---|
| 4280 | { |
|---|
| 4281 | /* |
|---|
| 4282 | ** We'll hit this block if |
|---|
| 4283 | ** - the entire "head" of the GOP has been processed |
|---|
| 4284 | ** - the "tail" is being cleaned up |
|---|
| 4285 | ** - the first picture of the next GOP has NOT been found |
|---|
| 4286 | ** |
|---|
| 4287 | ** The preceding can happen if |
|---|
| 4288 | ** - the video decoder is really slow delivering the pictures in a GOP |
|---|
| 4289 | ** - or we've made it to the beginning of the stream and need to restart at the end |
|---|
| 4290 | ** |
|---|
| 4291 | ** If the "head" is still being processed, the logic in "BXVD_Decoder_S_DqtReadOffsetUpdate()" |
|---|
| 4292 | ** will update the read offsets. |
|---|
| 4293 | */ |
|---|
| 4294 | uiDqReadOffset = pDQTCntxt->uiEndOfGopOffset; |
|---|
| 4295 | BXVD_AVD_P_DELIVERY_QUEUE_SET_READ_OFFSET( hXvdCh, uiDqReadOffset ); |
|---|
| 4296 | |
|---|
| 4297 | pDQTCntxt->uiReverseReadOffset = pDQTCntxt->uiEndOfGopOffset; |
|---|
| 4298 | } |
|---|
| 4299 | |
|---|
| 4300 | if ( true == bPicturesToDrop ) |
|---|
| 4301 | { |
|---|
| 4302 | BXVD_Decoder_S_Printf("relTail exit: Rr=%d DQ:%d/%d CQwr=%d Eog=%d playRev=%d\n", |
|---|
| 4303 | pDQTCntxt->uiReverseReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4304 | uiDqReadOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4305 | uiWriteOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4306 | pstContextQueue->uiWriteOffset, |
|---|
| 4307 | pDQTCntxt->uiEndOfGopOffset-BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE, |
|---|
| 4308 | pDQTCntxt->bConvertGopToUniPics |
|---|
| 4309 | ); |
|---|
| 4310 | } |
|---|
| 4311 | |
|---|
| 4312 | |
|---|
| 4313 | return; |
|---|
| 4314 | |
|---|
| 4315 | } |
|---|
| 4316 | |
|---|
| 4317 | /*************************************************************************** |
|---|
| 4318 | * |
|---|
| 4319 | * |
|---|
| 4320 | * |
|---|
| 4321 | ***************************************************************************/ |
|---|
| 4322 | |
|---|
| 4323 | |
|---|
| 4324 | |
|---|
| 4325 | /*************************************************************************** |
|---|
| 4326 | * |
|---|
| 4327 | * Public Routines |
|---|
| 4328 | * |
|---|
| 4329 | ***************************************************************************/ |
|---|
| 4330 | |
|---|
| 4331 | /* |
|---|
| 4332 | * Returns the number of pictures on the unified picture queue. For MVC, |
|---|
| 4333 | * this will be the number of picture "sets", i.e. the dependent pictures |
|---|
| 4334 | * are not included in the count. |
|---|
| 4335 | */ |
|---|
| 4336 | BERR_Code BXVD_Decoder_GetPictureCount_isr( |
|---|
| 4337 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4338 | uint32_t *puiPictureCount |
|---|
| 4339 | ) |
|---|
| 4340 | { |
|---|
| 4341 | BDBG_ENTER( BXVD_Decoder_GetPictureCount_isr ); |
|---|
| 4342 | |
|---|
| 4343 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncGetPicCount ); |
|---|
| 4344 | |
|---|
| 4345 | |
|---|
| 4346 | if ( true == hXvdCh->stDecoderContext.bDecoderHasBeenInitialized ) |
|---|
| 4347 | { |
|---|
| 4348 | *puiPictureCount = BXVD_Decoder_S_UnifiedQ_GetPictureCount( hXvdCh ); |
|---|
| 4349 | } |
|---|
| 4350 | else |
|---|
| 4351 | { |
|---|
| 4352 | *puiPictureCount = 0; |
|---|
| 4353 | } |
|---|
| 4354 | |
|---|
| 4355 | BXVD_Decoder_S_Printf("_GetPictureCount_isr:: count = %d\n", *puiPictureCount ); |
|---|
| 4356 | |
|---|
| 4357 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncGetPicCount ); |
|---|
| 4358 | |
|---|
| 4359 | BDBG_LEAVE( BXVD_Decoder_GetPictureCount_isr ); |
|---|
| 4360 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4361 | |
|---|
| 4362 | } /* end of BXVD_Decoder_GetPictureCount_isr */ |
|---|
| 4363 | |
|---|
| 4364 | |
|---|
| 4365 | /* |
|---|
| 4366 | * |
|---|
| 4367 | */ |
|---|
| 4368 | BERR_Code BXVD_Decoder_PeekAtPicture_isr( |
|---|
| 4369 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4370 | uint32_t uiIndex, |
|---|
| 4371 | BXDM_Picture **pUnifiedPicture |
|---|
| 4372 | ) |
|---|
| 4373 | { |
|---|
| 4374 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext; |
|---|
| 4375 | |
|---|
| 4376 | BDBG_ENTER( BXVD_Decoder_PeekAtPicture_isr ); |
|---|
| 4377 | |
|---|
| 4378 | /* TODO: add code to use the index */ |
|---|
| 4379 | BSTD_UNUSED( uiIndex ); |
|---|
| 4380 | |
|---|
| 4381 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncPeekAtPic ); |
|---|
| 4382 | |
|---|
| 4383 | BXVD_Decoder_S_UnifiedQ_UnifiedContextGet( hXvdCh, &pstUnifiedContext, false ); |
|---|
| 4384 | |
|---|
| 4385 | *pUnifiedPicture = &(pstUnifiedContext->stUnifiedPicture); |
|---|
| 4386 | |
|---|
| 4387 | BDBG_LEAVE( BXVD_Decoder_PeekAtPicture_isr ); |
|---|
| 4388 | |
|---|
| 4389 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncPeekAtPic ); |
|---|
| 4390 | |
|---|
| 4391 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4392 | |
|---|
| 4393 | } /* end of BXVD_Decoder_PeekAtPicture_isr */ |
|---|
| 4394 | |
|---|
| 4395 | /* |
|---|
| 4396 | * |
|---|
| 4397 | */ |
|---|
| 4398 | BERR_Code BXVD_Decoder_GetNextPicture_isr( |
|---|
| 4399 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4400 | BXDM_Picture **pUnifiedPicture |
|---|
| 4401 | ) |
|---|
| 4402 | { |
|---|
| 4403 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext; |
|---|
| 4404 | |
|---|
| 4405 | BDBG_ENTER( BXVD_Decoder_GetNextPicture_isr ); |
|---|
| 4406 | |
|---|
| 4407 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncGetNextPic ); |
|---|
| 4408 | |
|---|
| 4409 | BXVD_Decoder_S_Printf("_GetNextPicture_isr:: ", NULL ); |
|---|
| 4410 | |
|---|
| 4411 | BXVD_Decoder_S_UnifiedQ_UnifiedContextGet( hXvdCh, &pstUnifiedContext, true ); |
|---|
| 4412 | |
|---|
| 4413 | *pUnifiedPicture = &(pstUnifiedContext->stUnifiedPicture); |
|---|
| 4414 | |
|---|
| 4415 | /* |
|---|
| 4416 | * Now that the PPB is being "processed", enqueue any user data. |
|---|
| 4417 | */ |
|---|
| 4418 | if( pstUnifiedContext->pPPB->user_data ) |
|---|
| 4419 | { |
|---|
| 4420 | BXVD_DecoderTimer_P_SnapshotCallbackStartTime( hXvdCh, BXVD_DecoderTimer_P_eCbUserData ); |
|---|
| 4421 | |
|---|
| 4422 | /* |
|---|
| 4423 | * uiSerialNumber is passed to userdata where it is stored as uiDecoderPictureId. |
|---|
| 4424 | * See Jira SW7425-1780 for an explanation. |
|---|
| 4425 | */ |
|---|
| 4426 | BXVD_P_Userdata_EnqueueDataPointer( |
|---|
| 4427 | hXvdCh, |
|---|
| 4428 | pstUnifiedContext->pPPB->protocol, |
|---|
| 4429 | (unsigned long)pstUnifiedContext->pPPB->user_data , |
|---|
| 4430 | pstUnifiedContext->pPPB->flags, |
|---|
| 4431 | pstUnifiedContext->pPPB->pulldown, |
|---|
| 4432 | pstUnifiedContext->pPPB->pts, |
|---|
| 4433 | pstUnifiedContext->stUnifiedPicture.uiSerialNumber); |
|---|
| 4434 | |
|---|
| 4435 | BXVD_DecoderTimer_P_SnapshotCallbackEndTime( hXvdCh, BXVD_DecoderTimer_P_eCbUserData ); |
|---|
| 4436 | } |
|---|
| 4437 | |
|---|
| 4438 | /* For debug. */ |
|---|
| 4439 | hXvdCh->stDecoderContext.stLogData.uiPicturesToPP++; |
|---|
| 4440 | |
|---|
| 4441 | #if BXVD_DM_ENABLE_YUV_GRAB_MODE |
|---|
| 4442 | |
|---|
| 4443 | if( true == hXvdCh->stDecoderContext.bGrabPpb ) |
|---|
| 4444 | BXVD_Decoder_S_Dbg_DumpPPB( pstUnifiedContext->pPPB ); |
|---|
| 4445 | |
|---|
| 4446 | if( true == hXvdCh->stDecoderContext.bGrabYuv ) |
|---|
| 4447 | BXVD_Decoder_S_Dbg_DumpYUV( hXvdCh, pstUnifiedContext->pPPB ); |
|---|
| 4448 | |
|---|
| 4449 | if( true == hXvdCh->stDecoderContext.bGrabRvc ) |
|---|
| 4450 | BXVD_Decoder_S_Dbg_DumpRVC( hXvdCh ); |
|---|
| 4451 | |
|---|
| 4452 | #endif |
|---|
| 4453 | |
|---|
| 4454 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncGetNextPic ); |
|---|
| 4455 | |
|---|
| 4456 | |
|---|
| 4457 | BDBG_LEAVE( BXVD_Decoder_GetNextPicture_isr ); |
|---|
| 4458 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4459 | |
|---|
| 4460 | } /* end of BXVD_Decoder_GetNextPicture_isr */ |
|---|
| 4461 | |
|---|
| 4462 | /* |
|---|
| 4463 | * |
|---|
| 4464 | */ |
|---|
| 4465 | BERR_Code BXVD_Decoder_ReleasePicture_isr( |
|---|
| 4466 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4467 | BXDM_Picture *pUnifiedPicture, |
|---|
| 4468 | const BXDM_Decoder_ReleasePictureInfo *pReleasePictureInfo |
|---|
| 4469 | ) |
|---|
| 4470 | { |
|---|
| 4471 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext; |
|---|
| 4472 | |
|---|
| 4473 | BDBG_ENTER( BXVD_Decoder_ReleasePicture_isr ); |
|---|
| 4474 | |
|---|
| 4475 | BSTD_UNUSED(pReleasePictureInfo); |
|---|
| 4476 | |
|---|
| 4477 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncReleasePic ); |
|---|
| 4478 | |
|---|
| 4479 | BXVD_Decoder_S_Printf("_ReleasePicture_isr:: ", NULL ); |
|---|
| 4480 | |
|---|
| 4481 | pstUnifiedContext = pUnifiedPicture->pPrivateContext; |
|---|
| 4482 | |
|---|
| 4483 | BXVD_Decoder_S_UnifiedQ_UnifiedContextRelease( hXvdCh, pstUnifiedContext ); |
|---|
| 4484 | |
|---|
| 4485 | /* For debug. */ |
|---|
| 4486 | hXvdCh->stDecoderContext.stLogData.uiPicturesFromPP++; |
|---|
| 4487 | |
|---|
| 4488 | |
|---|
| 4489 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncReleasePic ); |
|---|
| 4490 | |
|---|
| 4491 | BDBG_LEAVE( BXVD_Decoder_ReleasePicture_isr ); |
|---|
| 4492 | |
|---|
| 4493 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4494 | |
|---|
| 4495 | } /* end of BXVD_Decoder_ReleasePicture_isr */ |
|---|
| 4496 | |
|---|
| 4497 | |
|---|
| 4498 | /* |
|---|
| 4499 | * |
|---|
| 4500 | */ |
|---|
| 4501 | BERR_Code |
|---|
| 4502 | BXVD_Decoder_GetPictureDropPendingCount_isr( |
|---|
| 4503 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4504 | uint32_t *puiPictureDropPendingCount |
|---|
| 4505 | ) |
|---|
| 4506 | { |
|---|
| 4507 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext; |
|---|
| 4508 | |
|---|
| 4509 | uint32_t uiNumToBeDropped; |
|---|
| 4510 | |
|---|
| 4511 | BXVD_AVD_P_GET_DROP_COUNT( hXvdCh, uiNumToBeDropped ); |
|---|
| 4512 | |
|---|
| 4513 | BDBG_ENTER( BXVD_Decoder_GetPictureDropPendingCount_isr ); |
|---|
| 4514 | |
|---|
| 4515 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4516 | BDBG_ASSERT( puiPictureDropPendingCount ); |
|---|
| 4517 | |
|---|
| 4518 | /* The "pending drop count" is difference between the number of pictures |
|---|
| 4519 | * that the Picture Provider has requested to be dropped and the number |
|---|
| 4520 | * that AVD has actually dropped. |
|---|
| 4521 | * When this value transistions from non-zero to zero, the Picture Provider |
|---|
| 4522 | * will transistion from VSYNC to TSM mode. At this point, the PP will need |
|---|
| 4523 | * a valid coded PTS. For this reason, "uiDropCount" is a sampled version of |
|---|
| 4524 | * "n_drop" which is only updated when a PPB contains a coded PTS. |
|---|
| 4525 | * |
|---|
| 4526 | * Never allow the pending drop count to be less than '0'. If more pictures have been |
|---|
| 4527 | * dropped than was requested, return a pending drop of '0'. |
|---|
| 4528 | * |
|---|
| 4529 | * SW7405-3929/-3925: Check that there are pictures in the queue, before asking for the context |
|---|
| 4530 | * (contents of the returned context are invalid if no pictures available) |
|---|
| 4531 | * If this is not done, pending drops can "ping-pong" between current value |
|---|
| 4532 | * and zero, causing selection mode to ping-pong between vTSM and TSM mode |
|---|
| 4533 | */ |
|---|
| 4534 | if ( BXVD_Decoder_S_UnifiedQ_GetPictureCount(hXvdCh) ) |
|---|
| 4535 | { |
|---|
| 4536 | BXVD_Decoder_S_UnifiedQ_UnifiedContextGet( hXvdCh, &pstUnifiedContext, false ); |
|---|
| 4537 | |
|---|
| 4538 | if ( uiNumToBeDropped < pstUnifiedContext->uiDropCount ) |
|---|
| 4539 | { |
|---|
| 4540 | *puiPictureDropPendingCount = 0; |
|---|
| 4541 | } |
|---|
| 4542 | else |
|---|
| 4543 | { |
|---|
| 4544 | *puiPictureDropPendingCount = uiNumToBeDropped - pstUnifiedContext->uiDropCount; |
|---|
| 4545 | } |
|---|
| 4546 | } |
|---|
| 4547 | else |
|---|
| 4548 | { |
|---|
| 4549 | /* No pictures available in the unified Q, so we need to use previous data to supply the drop count ... */ |
|---|
| 4550 | if ( uiNumToBeDropped < hXvdCh->stDecoderContext.uiDropCountSnapshot) |
|---|
| 4551 | { |
|---|
| 4552 | *puiPictureDropPendingCount = 0; |
|---|
| 4553 | } |
|---|
| 4554 | else |
|---|
| 4555 | { |
|---|
| 4556 | *puiPictureDropPendingCount = uiNumToBeDropped - hXvdCh->stDecoderContext.uiDropCountSnapshot; |
|---|
| 4557 | } |
|---|
| 4558 | } |
|---|
| 4559 | |
|---|
| 4560 | BDBG_LEAVE( BXVD_Decoder_GetPictureDropPendingCount_isr ); |
|---|
| 4561 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4562 | |
|---|
| 4563 | } /* end of BXVD_Decoder_GetPictureDropPendingCount_isr */ |
|---|
| 4564 | |
|---|
| 4565 | /* |
|---|
| 4566 | * |
|---|
| 4567 | */ |
|---|
| 4568 | BERR_Code |
|---|
| 4569 | BXVD_Decoder_RequestPictureDrop_isr( |
|---|
| 4570 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4571 | uint32_t *puiPictureDropRequestCount |
|---|
| 4572 | ) |
|---|
| 4573 | { |
|---|
| 4574 | uint32_t uiDropsRequested = 0; |
|---|
| 4575 | |
|---|
| 4576 | uint32_t uiDropCount; |
|---|
| 4577 | |
|---|
| 4578 | BXVD_AVD_P_GET_DROP_COUNT( hXvdCh, uiDropCount ); |
|---|
| 4579 | |
|---|
| 4580 | BDBG_ENTER( BXVD_Decoder_RequestPictureDrop_isr ); |
|---|
| 4581 | |
|---|
| 4582 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4583 | |
|---|
| 4584 | /* We only request more drops if the decoder has caught up with the previous drop request. |
|---|
| 4585 | */ |
|---|
| 4586 | if ( uiDropCount <= hXvdCh->stDecoderContext.uiDropCountSnapshot ) |
|---|
| 4587 | { |
|---|
| 4588 | if ( *puiPictureDropRequestCount > BXVD_DECODER_MAX_FIELDS_TO_DROP ) |
|---|
| 4589 | { |
|---|
| 4590 | /* PR47521: We need to cap the max requested drop count to prevent scenarious where a |
|---|
| 4591 | * large drop@decode request would occur that would normally recover on it's own. |
|---|
| 4592 | * (e.g. a unmarked stream discontinuity or stream wrap.). |
|---|
| 4593 | * We really only want to do a drop@decode if the stream is muxed poorly and/or we're |
|---|
| 4594 | * trying to do STC fast forward trick modes. In such scenarioes, if we still need |
|---|
| 4595 | * more drops to catch up, the Picture Provider can always request more after the |
|---|
| 4596 | * initial drop has occurred. |
|---|
| 4597 | */ |
|---|
| 4598 | uiDropsRequested = BXVD_DECODER_MAX_FIELDS_TO_DROP; |
|---|
| 4599 | |
|---|
| 4600 | } |
|---|
| 4601 | else |
|---|
| 4602 | { |
|---|
| 4603 | /* The decoder drops 2 fields at a time; ensure that "uiPictureDropRequestCount" |
|---|
| 4604 | * is an even value. |
|---|
| 4605 | */ |
|---|
| 4606 | uiDropsRequested = *puiPictureDropRequestCount & ~0x01; |
|---|
| 4607 | } |
|---|
| 4608 | |
|---|
| 4609 | uiDropCount += uiDropsRequested; |
|---|
| 4610 | BXVD_AVD_P_SET_DROP_COUNT( hXvdCh, uiDropCount ); |
|---|
| 4611 | |
|---|
| 4612 | } |
|---|
| 4613 | |
|---|
| 4614 | /* SE7405-3925: Update the actual number of drops requested from the decoder, to allow the caller |
|---|
| 4615 | to accurately update the drop request count status ... */ |
|---|
| 4616 | *puiPictureDropRequestCount = uiDropsRequested; |
|---|
| 4617 | |
|---|
| 4618 | BDBG_LEAVE( BXVD_Decoder_RequestPictureDrop_isr ); |
|---|
| 4619 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4620 | |
|---|
| 4621 | } /* end of BXVD_Decoder_RequestPictureDrop_isr */ |
|---|
| 4622 | |
|---|
| 4623 | /* |
|---|
| 4624 | * |
|---|
| 4625 | */ |
|---|
| 4626 | BERR_Code |
|---|
| 4627 | BXVD_Decoder_DisplayInterruptEvent_isr( |
|---|
| 4628 | BXVD_ChannelHandle hXvdCh |
|---|
| 4629 | ) |
|---|
| 4630 | { |
|---|
| 4631 | BXVD_Decoder_P_LocalState stLocalDecoderState; |
|---|
| 4632 | BXVD_Decoder_P_LocalState * pstLocalState; |
|---|
| 4633 | |
|---|
| 4634 | BDBG_ENTER( BXVD_Decoder_DisplayInterruptEvent_isr ); |
|---|
| 4635 | |
|---|
| 4636 | BDBG_ASSERT(hXvdCh); |
|---|
| 4637 | |
|---|
| 4638 | /* Hold off processing until the queues have been intialized. */ |
|---|
| 4639 | |
|---|
| 4640 | if ( true == hXvdCh->stDecoderContext.bDecoderHasBeenInitialized ) |
|---|
| 4641 | { |
|---|
| 4642 | BXVD_DecoderTimer_P_SnapshotFunctionStartTime( hXvdCh, BXVD_DecoderTimer_P_eFuncDisplayIsr ); |
|---|
| 4643 | |
|---|
| 4644 | /* Initialize the local variable(s). */ |
|---|
| 4645 | |
|---|
| 4646 | pstLocalState = &(stLocalDecoderState); |
|---|
| 4647 | |
|---|
| 4648 | hXvdCh->stDecoderContext.stCounters.uiVsyncCount++; |
|---|
| 4649 | |
|---|
| 4650 | /* Snapshot the delivery queue write offset so that it |
|---|
| 4651 | * is constant during the execution of the decoder ISR. |
|---|
| 4652 | */ |
|---|
| 4653 | BXVD_AVD_P_DELIVERY_QUEUE_GET_WRITE_OFFSET( hXvdCh, pstLocalState->uiDeliveryQueueWriteOffset ); |
|---|
| 4654 | |
|---|
| 4655 | BXVD_Decoder_S_UnifiedQ_Update( hXvdCh, pstLocalState ); |
|---|
| 4656 | |
|---|
| 4657 | BXVD_Decoder_S_Log_Print( hXvdCh, pstLocalState ); |
|---|
| 4658 | |
|---|
| 4659 | BXVD_DecoderTimer_P_SnapshotFunctionEndTime( hXvdCh, BXVD_DecoderTimer_P_eFuncDisplayIsr ); |
|---|
| 4660 | BXVD_DecoderTimer_P_PrintResults( hXvdCh ); |
|---|
| 4661 | |
|---|
| 4662 | } |
|---|
| 4663 | |
|---|
| 4664 | BDBG_LEAVE( BXVD_Decoder_DisplayInterruptEvent_isr ); |
|---|
| 4665 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4666 | |
|---|
| 4667 | } /* end of BXVD_Decoder_DisplayInterruptEvent_isr */ |
|---|
| 4668 | |
|---|
| 4669 | /* |
|---|
| 4670 | * |
|---|
| 4671 | */ |
|---|
| 4672 | BERR_Code |
|---|
| 4673 | BXVD_Decoder_GetDMInterface( |
|---|
| 4674 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4675 | BXDM_Decoder_Interface *pstDecoderInterface, |
|---|
| 4676 | void **pPrivateContext |
|---|
| 4677 | ) |
|---|
| 4678 | { |
|---|
| 4679 | BDBG_ENTER( BXVD_Decoder_GetDMInterface ); |
|---|
| 4680 | |
|---|
| 4681 | BDBG_ASSERT( pstDecoderInterface ); |
|---|
| 4682 | BDBG_ASSERT( pPrivateContext ); |
|---|
| 4683 | |
|---|
| 4684 | BKNI_Memset( pstDecoderInterface, 0, sizeof( BXDM_Decoder_Interface ) ); |
|---|
| 4685 | |
|---|
| 4686 | pstDecoderInterface->getPictureCount_isr = (BXDM_Decoder_GetPictureCount_isr) BXVD_Decoder_GetPictureCount_isr; |
|---|
| 4687 | pstDecoderInterface->peekAtPicture_isr = (BXDM_Decoder_PeekAtPicture_isr) BXVD_Decoder_PeekAtPicture_isr; |
|---|
| 4688 | pstDecoderInterface->getNextPicture_isr = (BXDM_Decoder_GetNextPicture_isr) BXVD_Decoder_GetNextPicture_isr; |
|---|
| 4689 | pstDecoderInterface->releasePicture_isr = (BXDM_Decoder_ReleasePicture_isr) BXVD_Decoder_ReleasePicture_isr; |
|---|
| 4690 | pstDecoderInterface->getPictureDropPendingCount_isr = (BXDM_Decoder_GetPictureDropPendingCount_isr) BXVD_Decoder_GetPictureDropPendingCount_isr; |
|---|
| 4691 | pstDecoderInterface->requestPictureDrop_isr = (BXDM_Decoder_RequestPictureDrop_isr) BXVD_Decoder_RequestPictureDrop_isr; |
|---|
| 4692 | pstDecoderInterface->displayInterruptEvent_isr = (BXDM_Decoder_DisplayInterruptEvent_isr) BXVD_Decoder_DisplayInterruptEvent_isr; |
|---|
| 4693 | pstDecoderInterface->displayInterruptStatus_isr = NULL; |
|---|
| 4694 | |
|---|
| 4695 | *pPrivateContext = hXvdCh; |
|---|
| 4696 | |
|---|
| 4697 | BXVD_Decoder_S_OpenChannel( hXvdCh ); |
|---|
| 4698 | |
|---|
| 4699 | BDBG_LEAVE( BXVD_Decoder_GetDMInterface ); |
|---|
| 4700 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4701 | |
|---|
| 4702 | } /* end of BXVD_Decoder_GetDMInterface */ |
|---|
| 4703 | |
|---|
| 4704 | /* |
|---|
| 4705 | * |
|---|
| 4706 | */ |
|---|
| 4707 | BERR_Code BXVD_Decoder_GetPPBParameterQueueInfo_isr( |
|---|
| 4708 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4709 | const BXVD_PPBParameterInfo* apstPPBParameterInfo[], |
|---|
| 4710 | uint32_t uiPPBParameterInfoCount, |
|---|
| 4711 | uint32_t *puiValidPPBParameterInfoCount |
|---|
| 4712 | ) |
|---|
| 4713 | { |
|---|
| 4714 | uint32_t i; |
|---|
| 4715 | BXVD_Decoder_P_UnifiedPictureQueue * pstUnifiedQueue = &hXvdCh->stDecoderContext.stUnifiedPictureQueue; |
|---|
| 4716 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext; |
|---|
| 4717 | |
|---|
| 4718 | BDBG_ENTER( BXVD_Decoder_GetPPBParameterQueueInfo_isr ); |
|---|
| 4719 | |
|---|
| 4720 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4721 | BDBG_ASSERT(apstPPBParameterInfo); |
|---|
| 4722 | BDBG_ASSERT(puiValidPPBParameterInfoCount); |
|---|
| 4723 | BDBG_ASSERT(uiPPBParameterInfoCount > 0); |
|---|
| 4724 | |
|---|
| 4725 | *puiValidPPBParameterInfoCount = 0; |
|---|
| 4726 | |
|---|
| 4727 | pstUnifiedContext = pstUnifiedQueue->pstContextTail; |
|---|
| 4728 | |
|---|
| 4729 | for (i = 0; i < uiPPBParameterInfoCount; i++) |
|---|
| 4730 | { |
|---|
| 4731 | /* Note: when DQT is enabled, the pictures are returned in display order, which |
|---|
| 4732 | * is reverse. |
|---|
| 4733 | */ |
|---|
| 4734 | |
|---|
| 4735 | if ( NULL != pstUnifiedContext |
|---|
| 4736 | && true == pstUnifiedContext->bInUse ) |
|---|
| 4737 | { |
|---|
| 4738 | apstPPBParameterInfo[i] = &(pstUnifiedContext->stUnifiedPicture); |
|---|
| 4739 | (*puiValidPPBParameterInfoCount)++; |
|---|
| 4740 | |
|---|
| 4741 | /*Note: this returns the dependent pictures as well. */ |
|---|
| 4742 | pstUnifiedContext = pstUnifiedContext->pstNextUniContext; |
|---|
| 4743 | } |
|---|
| 4744 | else |
|---|
| 4745 | { |
|---|
| 4746 | apstPPBParameterInfo[i] = NULL; |
|---|
| 4747 | } |
|---|
| 4748 | } |
|---|
| 4749 | |
|---|
| 4750 | BDBG_LEAVE( BXVD_Decoder_GetPPBParameterQueueInfo_isr ); |
|---|
| 4751 | return BERR_TRACE( BERR_SUCCESS ); |
|---|
| 4752 | |
|---|
| 4753 | } /* end of BXVD_Decoder_GetPPBParameterQueueInfo_isr */ |
|---|
| 4754 | |
|---|
| 4755 | /* |
|---|
| 4756 | * |
|---|
| 4757 | */ |
|---|
| 4758 | BERR_Code |
|---|
| 4759 | BXVD_Decoder_SetCRCMode_isr( |
|---|
| 4760 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4761 | bool bEnable) |
|---|
| 4762 | { |
|---|
| 4763 | BERR_Code rc = BERR_SUCCESS; |
|---|
| 4764 | |
|---|
| 4765 | BDBG_ENTER(BXVD_Decoder_SetCRCMode_isr); |
|---|
| 4766 | |
|---|
| 4767 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4768 | |
|---|
| 4769 | hXvdCh->stDecoderContext.bCRCMode = bEnable; |
|---|
| 4770 | |
|---|
| 4771 | BXVD_Decoder_S_Printf("BXVD_Decoder_SetCRCMode_isr(%d)\n", bEnable); |
|---|
| 4772 | |
|---|
| 4773 | BDBG_LEAVE(BXVD_Decoder_SetCRCMode_isr); |
|---|
| 4774 | |
|---|
| 4775 | return BERR_TRACE( rc ); |
|---|
| 4776 | } |
|---|
| 4777 | |
|---|
| 4778 | /* |
|---|
| 4779 | * |
|---|
| 4780 | */ |
|---|
| 4781 | BERR_Code |
|---|
| 4782 | BXVD_Decoder_GetCRCMode_isr( |
|---|
| 4783 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4784 | bool *pbEnable) |
|---|
| 4785 | { |
|---|
| 4786 | BERR_Code rc = BERR_SUCCESS; |
|---|
| 4787 | |
|---|
| 4788 | BDBG_ENTER(BXVD_Decoder_GetCRCMode_isr); |
|---|
| 4789 | |
|---|
| 4790 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4791 | BDBG_ASSERT( pbEnable ); |
|---|
| 4792 | |
|---|
| 4793 | *pbEnable = hXvdCh->stDecoderContext.bCRCMode; |
|---|
| 4794 | |
|---|
| 4795 | BDBG_LEAVE(BXVD_Decoder_GetCRCMode_isr); |
|---|
| 4796 | |
|---|
| 4797 | return BERR_TRACE( rc ); |
|---|
| 4798 | } |
|---|
| 4799 | |
|---|
| 4800 | /* |
|---|
| 4801 | * |
|---|
| 4802 | */ |
|---|
| 4803 | BERR_Code BXVD_Decoder_StartDecode_isr( |
|---|
| 4804 | BXVD_ChannelHandle hXvdCh |
|---|
| 4805 | ) |
|---|
| 4806 | { |
|---|
| 4807 | BERR_Code rc = BERR_SUCCESS; |
|---|
| 4808 | |
|---|
| 4809 | BDBG_ENTER(BXVD_Decoder_StartDecode_isr); |
|---|
| 4810 | |
|---|
| 4811 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4812 | BSTD_UNUSED(hXvdCh); |
|---|
| 4813 | |
|---|
| 4814 | BXVD_Decoder_S_Printf("BXVD_Decoder_StartDecode_isr\n", NULL ); |
|---|
| 4815 | |
|---|
| 4816 | /* Nothing to do for the Unified Picture Queue, it is intialized |
|---|
| 4817 | * in "BXVD_Decoder_S_OpenChannel". Also keep in mind that XDM |
|---|
| 4818 | * could still be holding onto pictures from a previous stream. |
|---|
| 4819 | * If the queue was reset, the decoder would not be able to return |
|---|
| 4820 | * the PPB's to the decoder. |
|---|
| 4821 | */ |
|---|
| 4822 | |
|---|
| 4823 | /* TODO: should a snapshot be taken at start decode time instead of changing |
|---|
| 4824 | * on the fly? |
|---|
| 4825 | */ |
|---|
| 4826 | /*hXvdCh->stDecoderContext.bCRCMode = hXvdCh->sDecodeSettings.bCrcMode;*/ |
|---|
| 4827 | |
|---|
| 4828 | #if 0 /* From DM V2. */ |
|---|
| 4829 | if (!hXvdCh->stDMState.stChannel.bDMVersionDisplayed) |
|---|
| 4830 | { |
|---|
| 4831 | BXVD_DBG_WRN(hXvdCh,("Display Manager: [v%02d.%02d.%04d]", |
|---|
| 4832 | BXVD_DM_P_VERSION_MAJOR, |
|---|
| 4833 | BXVD_DM_P_VERSION_MINOR, |
|---|
| 4834 | BXVD_DM_P_VERSION_SUBMINOR)); |
|---|
| 4835 | hXvdCh->stDMState.stChannel.bDMVersionDisplayed = true; |
|---|
| 4836 | } |
|---|
| 4837 | |
|---|
| 4838 | BXVD_DMDBG_P_PrintNodes(hXvdCh); |
|---|
| 4839 | |
|---|
| 4840 | |
|---|
| 4841 | /* TODO: NA - We should probably remove the bPointerInitDone |
|---|
| 4842 | * variable altogether. Right now, BXVD_INTR checks it before |
|---|
| 4843 | * calling into DM, so we'll leave it in to be compatible with the |
|---|
| 4844 | * old DM */ |
|---|
| 4845 | hXvdCh->stDMStatus.bPointerInitDone = true; |
|---|
| 4846 | |
|---|
| 4847 | #endif |
|---|
| 4848 | |
|---|
| 4849 | /* Initialize the DQT logic */ |
|---|
| 4850 | |
|---|
| 4851 | BXVD_Decoder_S_DqtInit( hXvdCh ); |
|---|
| 4852 | |
|---|
| 4853 | |
|---|
| 4854 | /* Initialize the picture context queue. */ |
|---|
| 4855 | |
|---|
| 4856 | BXVD_AVD_P_DELIVERY_QUEUE_GET_READ_OFFSET( |
|---|
| 4857 | hXvdCh, |
|---|
| 4858 | hXvdCh->stDecoderContext.stPictureContextQueue.uiWriteOffset |
|---|
| 4859 | ); |
|---|
| 4860 | |
|---|
| 4861 | hXvdCh->stDecoderContext.stPictureContextQueue.uiWriteOffset -= BXVD_P_INITIAL_OFFSET_DISPLAY_QUEUE; |
|---|
| 4862 | |
|---|
| 4863 | /* Need to initialize in case the first PPB(s) don't contain a coded PTS. */ |
|---|
| 4864 | hXvdCh->stDecoderContext.uiDropCountSnapshot = 0; |
|---|
| 4865 | |
|---|
| 4866 | /* Reset drop request count */ |
|---|
| 4867 | BXVD_AVD_P_SET_DROP_COUNT( hXvdCh, 0 ); |
|---|
| 4868 | |
|---|
| 4869 | /* Used to hold off processing in "BXVD_Decoder_DisplayInterruptEvent_isr" |
|---|
| 4870 | * until this routine has been called. Implicit at this point of execution |
|---|
| 4871 | * is that the AVD queues have been initialized as well. This is |
|---|
| 4872 | * essentially the old "eVideoState = BXVD_P_VideoState_DecodeStarted". |
|---|
| 4873 | */ |
|---|
| 4874 | hXvdCh->stDecoderContext.bDecoderHasBeenInitialized = true; |
|---|
| 4875 | |
|---|
| 4876 | |
|---|
| 4877 | /* Conditionally initialize the decoder counter(s) */ |
|---|
| 4878 | if ( false == hXvdCh->bPreserveCounters ) |
|---|
| 4879 | { |
|---|
| 4880 | BKNI_Memset( &(hXvdCh->stDecoderContext.stCounters), 0, sizeof( BXVD_Decoder_Counters ) ); |
|---|
| 4881 | } |
|---|
| 4882 | |
|---|
| 4883 | /* For debug. */ |
|---|
| 4884 | BXVD_Decoder_S_Log_Init( hXvdCh ); |
|---|
| 4885 | |
|---|
| 4886 | BKNI_Memset( &(hXvdCh->stDecoderContext.stLogData.stTimerData), 0, sizeof(BXVD_DecoderTimer_P_Data) ); |
|---|
| 4887 | |
|---|
| 4888 | |
|---|
| 4889 | #if BXVD_DM_ENABLE_YUV_GRAB_MODE |
|---|
| 4890 | |
|---|
| 4891 | hXvdCh->stDecoderContext.bGrabPpb = ( NULL == getenv("grabppb")) ? false : true; |
|---|
| 4892 | hXvdCh->stDecoderContext.bGrabYuv = ( NULL == getenv("grabyuv")) ? false : true; |
|---|
| 4893 | hXvdCh->stDecoderContext.bGrabRvc = ( NULL == getenv("grabrvc")) ? false : true; |
|---|
| 4894 | |
|---|
| 4895 | if ( true == hXvdCh->stDecoderContext.bGrabRvc ) |
|---|
| 4896 | { |
|---|
| 4897 | BXVD_Reg_Write32_isr (hXvdCh->pXvd, hXvdCh->pXvd->stPlatformInfo.stReg.uiDecode_RVCCtl, 0x01); |
|---|
| 4898 | } |
|---|
| 4899 | #endif |
|---|
| 4900 | |
|---|
| 4901 | BDBG_LEAVE(BXVD_Decoder_StartDecode_isr); |
|---|
| 4902 | |
|---|
| 4903 | return BERR_TRACE( rc ); |
|---|
| 4904 | |
|---|
| 4905 | } |
|---|
| 4906 | |
|---|
| 4907 | /* |
|---|
| 4908 | * |
|---|
| 4909 | */ |
|---|
| 4910 | BERR_Code BXVD_Decoder_StopDecode_isr( |
|---|
| 4911 | BXVD_ChannelHandle hXvdCh |
|---|
| 4912 | ) |
|---|
| 4913 | { |
|---|
| 4914 | BERR_Code rc = BERR_SUCCESS; |
|---|
| 4915 | BXVD_Decoder_P_UnifiedPictureContext * pstUnifiedContext; |
|---|
| 4916 | BXVD_Decoder_P_DQTContext * pDQTCntxt = &( hXvdCh->stDecoderContext.stDqtCntxt ); |
|---|
| 4917 | |
|---|
| 4918 | |
|---|
| 4919 | BDBG_ENTER(BXVD_Decoder_StopDecode_isr); |
|---|
| 4920 | |
|---|
| 4921 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4922 | |
|---|
| 4923 | BXVD_Decoder_S_Printf("BXVD_Decoder_StopDecode_isr:: ", NULL ); |
|---|
| 4924 | |
|---|
| 4925 | /* Hold off processing in "BXVD_Decoder_DisplayInterruptEvent_isr" |
|---|
| 4926 | * until the queues have been reinitialized. |
|---|
| 4927 | */ |
|---|
| 4928 | hXvdCh->stDecoderContext.bDecoderHasBeenInitialized = false; |
|---|
| 4929 | |
|---|
| 4930 | /* |
|---|
| 4931 | * Release any pictures on the Unified Picture Queue. |
|---|
| 4932 | * XDM could still be holding onto pictures, don't reset the queue. |
|---|
| 4933 | */ |
|---|
| 4934 | while ( BXVD_Decoder_S_UnifiedQ_GetPictureCount( hXvdCh ) ) |
|---|
| 4935 | { |
|---|
| 4936 | BXVD_Decoder_S_UnifiedQ_UnifiedContextGet( hXvdCh, &pstUnifiedContext, true ); |
|---|
| 4937 | BXVD_Decoder_S_UnifiedQ_UnifiedContextRelease( hXvdCh, pstUnifiedContext ); |
|---|
| 4938 | } |
|---|
| 4939 | |
|---|
| 4940 | /* |
|---|
| 4941 | * Conditionally clear the PVR state. |
|---|
| 4942 | */ |
|---|
| 4943 | if ( false == hXvdCh->bPreserveState ) |
|---|
| 4944 | { |
|---|
| 4945 | /* Disable the reverse playback of GOPs */ |
|---|
| 4946 | hXvdCh->stDecoderContext.bReversePlayback = false; |
|---|
| 4947 | |
|---|
| 4948 | hXvdCh->stDecoderContext.bHostSparseMode = false; |
|---|
| 4949 | } |
|---|
| 4950 | |
|---|
| 4951 | /* In the event the Display Manager was cleaning up a "truncated" GOP, |
|---|
| 4952 | * clear the flags now. Any pictures that remain at the end of the GOP |
|---|
| 4953 | * (in the delivery queue) will be cleaned up by the decoder. |
|---|
| 4954 | */ |
|---|
| 4955 | pDQTCntxt->bTruncatingGop = false; |
|---|
| 4956 | pDQTCntxt->bValidPicTag = false; |
|---|
| 4957 | |
|---|
| 4958 | BDBG_LEAVE(BXVD_Decoder_StopDecode_isr); |
|---|
| 4959 | |
|---|
| 4960 | return BERR_TRACE( rc ); |
|---|
| 4961 | } |
|---|
| 4962 | |
|---|
| 4963 | /* |
|---|
| 4964 | * |
|---|
| 4965 | */ |
|---|
| 4966 | BERR_Code BXVD_Decoder_WatchdogReset_isr( |
|---|
| 4967 | BXVD_ChannelHandle hXvdCh |
|---|
| 4968 | ) |
|---|
| 4969 | { |
|---|
| 4970 | BDBG_ENTER(BXVD_Decoder_WatchdogReset_isr); |
|---|
| 4971 | |
|---|
| 4972 | BDBG_ASSERT( hXvdCh ); |
|---|
| 4973 | |
|---|
| 4974 | BXVD_Decoder_S_Printf("BXVD_Decoder_WatchdogReset_isr:: ", NULL ); |
|---|
| 4975 | |
|---|
| 4976 | /* Hold off processing in "BXVD_Decoder_DisplayInterruptEvent_isr" |
|---|
| 4977 | * until the queues have been reinitialized. |
|---|
| 4978 | */ |
|---|
| 4979 | hXvdCh->stDecoderContext.bDecoderHasBeenInitialized = false; |
|---|
| 4980 | |
|---|
| 4981 | /* |
|---|
| 4982 | * Reset the Unified Picture Queue. |
|---|
| 4983 | */ |
|---|
| 4984 | BXVD_Decoder_S_UnifiedQ_Initialize( hXvdCh ); |
|---|
| 4985 | |
|---|
| 4986 | BDBG_LEAVE(BXVD_Decoder_WatchdogReset_isr); |
|---|
| 4987 | |
|---|
| 4988 | return BERR_SUCCESS; |
|---|
| 4989 | } |
|---|
| 4990 | |
|---|
| 4991 | /* |
|---|
| 4992 | * |
|---|
| 4993 | */ |
|---|
| 4994 | BERR_Code BXVD_Decoder_GetCounters_isr( |
|---|
| 4995 | BXVD_ChannelHandle hXvdCh, |
|---|
| 4996 | BXVD_Decoder_Counters * pstCounters |
|---|
| 4997 | ) |
|---|
| 4998 | { |
|---|
| 4999 | BDBG_ENTER(BXVD_Decoder_GetCounters_isr); |
|---|
| 5000 | |
|---|
| 5001 | BDBG_ASSERT( hXvdCh ); |
|---|
| 5002 | |
|---|
| 5003 | *pstCounters = hXvdCh->stDecoderContext.stCounters; |
|---|
| 5004 | |
|---|
| 5005 | BDBG_LEAVE(BXVD_Decoder_GetCounters_isr); |
|---|
| 5006 | |
|---|
| 5007 | return BERR_SUCCESS; |
|---|
| 5008 | } |
|---|
| 5009 | |
|---|
| 5010 | /* |
|---|
| 5011 | * Routines to support the "grab" debug mode. |
|---|
| 5012 | */ |
|---|
| 5013 | #if BXVD_DM_ENABLE_YUV_GRAB_MODE |
|---|
| 5014 | |
|---|
| 5015 | /* |
|---|
| 5016 | * BXVD_Decoder_S_Dbg_SwapLong |
|---|
| 5017 | */ |
|---|
| 5018 | static uint32_t BXVD_Decoder_S_Dbg_SwapLong ( |
|---|
| 5019 | uint32_t a |
|---|
| 5020 | ) |
|---|
| 5021 | { |
|---|
| 5022 | return ((a >> 24) & 0x000000FF) |
|---|
| 5023 | | ((a >> 8) & 0x0000FF00) |
|---|
| 5024 | | ((a << 8) & 0x00FF0000) |
|---|
| 5025 | | ((a << 24) & 0xFF000000); |
|---|
| 5026 | } |
|---|
| 5027 | |
|---|
| 5028 | /* |
|---|
| 5029 | * BXVD_Decoder_S_Dbg_DestripeSection |
|---|
| 5030 | */ |
|---|
| 5031 | static int32_t BXVD_Decoder_S_Dbg_DestripeSection ( |
|---|
| 5032 | unsigned char *from, |
|---|
| 5033 | unsigned char *to, |
|---|
| 5034 | int32_t image_wid, |
|---|
| 5035 | int32_t image_hgt, |
|---|
| 5036 | int32_t stripe_wid, |
|---|
| 5037 | int32_t stripe_hgt, |
|---|
| 5038 | uint32_t ulRangeRemapping |
|---|
| 5039 | ) |
|---|
| 5040 | { |
|---|
| 5041 | int32_t stripe_size = stripe_wid * stripe_hgt; |
|---|
| 5042 | int32_t pixels = image_wid * image_hgt; |
|---|
| 5043 | |
|---|
| 5044 | int32_t i; |
|---|
| 5045 | int32_t scol; |
|---|
| 5046 | int32_t icol; |
|---|
| 5047 | int32_t lpel; |
|---|
| 5048 | unsigned char *ptr, pel; |
|---|
| 5049 | |
|---|
| 5050 | /* memset (to, 0, pixels); */ |
|---|
| 5051 | scol = 0; |
|---|
| 5052 | icol = 0; |
|---|
| 5053 | ptr = from; |
|---|
| 5054 | |
|---|
| 5055 | for (i = 0; i < pixels; i++) |
|---|
| 5056 | { |
|---|
| 5057 | /* apply range mapping equation */ |
|---|
| 5058 | |
|---|
| 5059 | pel = ptr [scol]; |
|---|
| 5060 | if (ulRangeRemapping != 8) |
|---|
| 5061 | { |
|---|
| 5062 | lpel = (uint32_t) pel; |
|---|
| 5063 | |
|---|
| 5064 | lpel = ((((lpel - 128) * (int32_t) ulRangeRemapping) + 4) >> 3) + 128; |
|---|
| 5065 | if (lpel > 255) pel = 255; |
|---|
| 5066 | else if (lpel < 0) pel = 0; |
|---|
| 5067 | else pel = (unsigned char) lpel; |
|---|
| 5068 | } |
|---|
| 5069 | |
|---|
| 5070 | *to++ = pel; |
|---|
| 5071 | |
|---|
| 5072 | /* If we reach the end of a stripe, move down to the |
|---|
| 5073 | * next strip to continue this row. |
|---|
| 5074 | */ |
|---|
| 5075 | if (++scol == stripe_wid) |
|---|
| 5076 | { |
|---|
| 5077 | scol = 0; |
|---|
| 5078 | ptr += stripe_size; |
|---|
| 5079 | } |
|---|
| 5080 | |
|---|
| 5081 | /* If we reach the end of a row, go back to the 1st |
|---|
| 5082 | * stripe, but move down a row. Reset everything. |
|---|
| 5083 | */ |
|---|
| 5084 | if (++icol == image_wid) |
|---|
| 5085 | { |
|---|
| 5086 | int32_t edge_pixel, cnt; |
|---|
| 5087 | |
|---|
| 5088 | /* need to handle non four pixel align case */ |
|---|
| 5089 | |
|---|
| 5090 | edge_pixel = (icol & 3); |
|---|
| 5091 | |
|---|
| 5092 | if ( edge_pixel ) |
|---|
| 5093 | { |
|---|
| 5094 | to -= edge_pixel; |
|---|
| 5095 | scol -= edge_pixel; |
|---|
| 5096 | |
|---|
| 5097 | for (cnt = 0; cnt < edge_pixel; cnt++) |
|---|
| 5098 | { |
|---|
| 5099 | pel = ptr [scol+3-cnt]; |
|---|
| 5100 | |
|---|
| 5101 | if (ulRangeRemapping != 8) |
|---|
| 5102 | { |
|---|
| 5103 | lpel = (uint32_t) pel; |
|---|
| 5104 | |
|---|
| 5105 | lpel = ((((lpel - 128) * (int32_t) ulRangeRemapping) + 4) >> 3) + 128; |
|---|
| 5106 | if (lpel > 255) pel = 255; |
|---|
| 5107 | else if (lpel < 0) pel = 0; |
|---|
| 5108 | else pel = (unsigned char) lpel; |
|---|
| 5109 | } |
|---|
| 5110 | |
|---|
| 5111 | *to++ = pel; |
|---|
| 5112 | } |
|---|
| 5113 | } |
|---|
| 5114 | |
|---|
| 5115 | from += stripe_wid; |
|---|
| 5116 | ptr = from; |
|---|
| 5117 | |
|---|
| 5118 | icol = 0; |
|---|
| 5119 | scol = 0; |
|---|
| 5120 | } |
|---|
| 5121 | } |
|---|
| 5122 | |
|---|
| 5123 | return 0; |
|---|
| 5124 | |
|---|
| 5125 | } /* end of BXVD_Decoder_S_Dbg_DestripeSection() */ |
|---|
| 5126 | |
|---|
| 5127 | /* |
|---|
| 5128 | * BXVD_Decoder_S_Dbg_DumpYUV |
|---|
| 5129 | */ |
|---|
| 5130 | void BXVD_Decoder_S_Dbg_DumpYUV( |
|---|
| 5131 | BXVD_ChannelHandle hXvdCh, |
|---|
| 5132 | BXVD_P_PPB *ppb |
|---|
| 5133 | ) |
|---|
| 5134 | { |
|---|
| 5135 | unsigned char *pYData; |
|---|
| 5136 | unsigned char *pUVData; |
|---|
| 5137 | uint32_t ulLumaRangeRemapping, ulChromaRangeRemapping; |
|---|
| 5138 | int32_t stripe_size = BXVD_P_StripeWidthLUT[hXvdCh->pXvd->uiDecode_StripeWidth]; |
|---|
| 5139 | int32_t height; |
|---|
| 5140 | int32_t width; |
|---|
| 5141 | int32_t i, j; |
|---|
| 5142 | |
|---|
| 5143 | static FILE *fpYUV = NULL; |
|---|
| 5144 | static unsigned char pBuf[1920*1088], *pSwap; |
|---|
| 5145 | |
|---|
| 5146 | if (fpYUV== NULL) |
|---|
| 5147 | { |
|---|
| 5148 | if ((fpYUV=fopen("/Work/output.yuv", "wb"))==NULL) |
|---|
| 5149 | { |
|---|
| 5150 | BDBG_WRN(("Could not open output.yuv")); |
|---|
| 5151 | return; |
|---|
| 5152 | } |
|---|
| 5153 | } |
|---|
| 5154 | |
|---|
| 5155 | BDBG_WRN(("*** grabbing pic with width %d height %d, stripe_size: %d stripe height: %d", |
|---|
| 5156 | ppb->video_width, ppb->video_height, stripe_size, ppb->luma_stripe_height)); |
|---|
| 5157 | |
|---|
| 5158 | height = ppb->video_height; |
|---|
| 5159 | width = ppb->video_width; |
|---|
| 5160 | |
|---|
| 5161 | /* Support range remapping during YUV grab */ |
|---|
| 5162 | ulLumaRangeRemapping = 0x08; |
|---|
| 5163 | ulChromaRangeRemapping = 0x08; |
|---|
| 5164 | |
|---|
| 5165 | if (ppb->protocol == BAVC_VideoCompressionStd_eVC1) |
|---|
| 5166 | { |
|---|
| 5167 | ulLumaRangeRemapping = ppb->other.vc1.range_remapping_ratio >> 16; |
|---|
| 5168 | ulChromaRangeRemapping = ppb->other.vc1.range_remapping_ratio & 0xffff; |
|---|
| 5169 | } |
|---|
| 5170 | |
|---|
| 5171 | BKNI_Printf("%d %d \n", ulLumaRangeRemapping, ulChromaRangeRemapping); |
|---|
| 5172 | |
|---|
| 5173 | /* Convert the two video buffers to logical addresses */ |
|---|
| 5174 | BMEM_ConvertOffsetToAddress( hXvdCh->hPictureHeap, (uint32_t)ppb->luma_video_address, (void *)&pYData); |
|---|
| 5175 | BMEM_ConvertOffsetToAddress( hXvdCh->hPictureHeap, (uint32_t)ppb->chroma_video_address, (void *)&pUVData); |
|---|
| 5176 | |
|---|
| 5177 | BXVD_Decoder_S_Dbg_DestripeSection(pYData, pBuf, width, height, stripe_size, ppb->luma_stripe_height, ulLumaRangeRemapping); |
|---|
| 5178 | |
|---|
| 5179 | /* byte swap here */ |
|---|
| 5180 | /* if (bByteSwap) */ |
|---|
| 5181 | #if 0 |
|---|
| 5182 | { |
|---|
| 5183 | for (i = 0; i < width * height; i+=4) |
|---|
| 5184 | *((uint32_t *)(pBuf + i)) = BXVD_Decoder_S_Dbg_SwapLong(*((uint32_t *)(pBuf + i))); |
|---|
| 5185 | } |
|---|
| 5186 | #endif |
|---|
| 5187 | /* need to handle non four pixel align case |
|---|
| 5188 | */ |
|---|
| 5189 | { |
|---|
| 5190 | pSwap = pBuf; |
|---|
| 5191 | for (i = 0; i < height; i++) |
|---|
| 5192 | { |
|---|
| 5193 | for (j = 0; j < (width & 0xfffc); j+=4) |
|---|
| 5194 | { |
|---|
| 5195 | *((uint32_t *)pSwap) = BXVD_Decoder_S_Dbg_SwapLong(*((uint32_t *)pSwap)); |
|---|
| 5196 | pSwap+=4; |
|---|
| 5197 | } |
|---|
| 5198 | pSwap += (width & 0x3); |
|---|
| 5199 | } |
|---|
| 5200 | } |
|---|
| 5201 | |
|---|
| 5202 | /* Write the Y data */ |
|---|
| 5203 | fwrite (pBuf, 1, width * height, fpYUV); |
|---|
| 5204 | |
|---|
| 5205 | BXVD_Decoder_S_Dbg_DestripeSection(pUVData, pBuf, width, height / 2, stripe_size, ppb->chroma_stripe_height, ulChromaRangeRemapping); |
|---|
| 5206 | |
|---|
| 5207 | /* byte swap here */ |
|---|
| 5208 | #if 0 |
|---|
| 5209 | /* if (bByteSwap) */ |
|---|
| 5210 | { |
|---|
| 5211 | for (i = 0; i < width * height; i+=4) |
|---|
| 5212 | *((uint32_t *)(pBuf + i)) = BXVD_Decoder_S_Dbg_SwapLong(*((uint32_t *)(pBuf + i))); |
|---|
| 5213 | } |
|---|
| 5214 | #endif |
|---|
| 5215 | |
|---|
| 5216 | /* need to handle non four pixel align case |
|---|
| 5217 | */ |
|---|
| 5218 | { |
|---|
| 5219 | pSwap = pBuf; |
|---|
| 5220 | for (i = 0; i < height/2; i++) |
|---|
| 5221 | { |
|---|
| 5222 | for (j = 0; j < (width & 0xfffc); j+=4) |
|---|
| 5223 | { |
|---|
| 5224 | *((uint32_t *)pSwap) = BXVD_Decoder_S_Dbg_SwapLong(*((uint32_t *)pSwap)); |
|---|
| 5225 | pSwap+=4; |
|---|
| 5226 | } |
|---|
| 5227 | pSwap += (width & 0x3); |
|---|
| 5228 | } |
|---|
| 5229 | } |
|---|
| 5230 | |
|---|
| 5231 | /* Write the UV data (this also deinterleaves the UV writing first U than V */ |
|---|
| 5232 | for (i = 0; i < (width * height) / 2; i+=2) |
|---|
| 5233 | fwrite(pBuf + i, 1, 1, fpYUV); |
|---|
| 5234 | for (i = 1; i < (width * height) / 2; i+=2) |
|---|
| 5235 | fwrite(pBuf + i, 1, 1, fpYUV); |
|---|
| 5236 | fflush(fpYUV); |
|---|
| 5237 | |
|---|
| 5238 | } /* end of BXVD_Decoder_S_Dbg_DumpYUV() */ |
|---|
| 5239 | |
|---|
| 5240 | /* |
|---|
| 5241 | * BXVD_Decoder_S_Dbg_DumpRVC |
|---|
| 5242 | */ |
|---|
| 5243 | void BXVD_Decoder_S_Dbg_DumpRVC( |
|---|
| 5244 | BXVD_ChannelHandle hXvdCh |
|---|
| 5245 | ) |
|---|
| 5246 | { |
|---|
| 5247 | uint32_t size, start, end; |
|---|
| 5248 | uint32_t currptr, buf_start, buf_end, buf_size; |
|---|
| 5249 | int32_t contig; |
|---|
| 5250 | uint32_t written; |
|---|
| 5251 | static unsigned char *pRVCdata = 0; |
|---|
| 5252 | static uint32_t lastrvcptr = 0xffffffff; |
|---|
| 5253 | static FILE *fpRVC= NULL; |
|---|
| 5254 | |
|---|
| 5255 | currptr = BXVD_Reg_Read32_isr(hXvdCh->pXvd, hXvdCh->pXvd->stPlatformInfo.stReg.uiDecode_RVCPut); |
|---|
| 5256 | buf_start = BXVD_Reg_Read32_isr(hXvdCh->pXvd, hXvdCh->pXvd->stPlatformInfo.stReg.uiDecode_RVCBase); |
|---|
| 5257 | buf_end = BXVD_Reg_Read32_isr(hXvdCh->pXvd, hXvdCh->pXvd->stPlatformInfo.stReg.uiDecode_RVCEnd); |
|---|
| 5258 | buf_end += 1; |
|---|
| 5259 | |
|---|
| 5260 | /* BDBG_WRN(("rvc registers (curr, start, end): 0x%x %x %x", currptr, buf_start, buf_end )); */ |
|---|
| 5261 | |
|---|
| 5262 | buf_size = buf_end - buf_start; |
|---|
| 5263 | if (buf_size <= 1) |
|---|
| 5264 | return; |
|---|
| 5265 | |
|---|
| 5266 | /* for the initial case we set it to the start */ |
|---|
| 5267 | if (0xffffffff == lastrvcptr) |
|---|
| 5268 | lastrvcptr = buf_start; |
|---|
| 5269 | |
|---|
| 5270 | /* check pointer */ |
|---|
| 5271 | if ((currptr > buf_end) || (currptr < buf_start)) |
|---|
| 5272 | return; |
|---|
| 5273 | |
|---|
| 5274 | /* calculate size to read */ |
|---|
| 5275 | start = lastrvcptr; |
|---|
| 5276 | end = currptr; |
|---|
| 5277 | lastrvcptr = currptr; |
|---|
| 5278 | if (end >= start) |
|---|
| 5279 | { |
|---|
| 5280 | contig = 1; |
|---|
| 5281 | size = end - start; |
|---|
| 5282 | } |
|---|
| 5283 | else |
|---|
| 5284 | { |
|---|
| 5285 | contig = 0; |
|---|
| 5286 | size = (buf_end - start) + (end - buf_start); |
|---|
| 5287 | } |
|---|
| 5288 | |
|---|
| 5289 | if (0 == size) |
|---|
| 5290 | return; |
|---|
| 5291 | |
|---|
| 5292 | if (fpRVC == NULL) |
|---|
| 5293 | { |
|---|
| 5294 | if ((fpRVC=fopen("/Work/rvc.bin", "wb"))==NULL) |
|---|
| 5295 | { |
|---|
| 5296 | return; |
|---|
| 5297 | } |
|---|
| 5298 | } |
|---|
| 5299 | |
|---|
| 5300 | /* pRVCdata contains a virtual pointer to the data */ |
|---|
| 5301 | BMEM_ConvertOffsetToAddress( hXvdCh->hPictureHeap, start, (void *)&pRVCdata); |
|---|
| 5302 | |
|---|
| 5303 | if (contig) |
|---|
| 5304 | { |
|---|
| 5305 | /* BCM_MBDL_MemRead_ToBuffer (start, size, buf, 1, D011, boardnum); */ |
|---|
| 5306 | written = fwrite(pRVCdata, 1, size, fpRVC); |
|---|
| 5307 | } |
|---|
| 5308 | else |
|---|
| 5309 | { |
|---|
| 5310 | /* get the first chunk */ |
|---|
| 5311 | written = fwrite(pRVCdata, 1, buf_end - start, fpRVC); |
|---|
| 5312 | |
|---|
| 5313 | /* get the second chunk */ |
|---|
| 5314 | /* the seond chunks starts at the buffer beginning - get its address */ |
|---|
| 5315 | BMEM_ConvertOffsetToAddress( hXvdCh->hPictureHeap, buf_start, (void *)&pRVCdata); |
|---|
| 5316 | written += fwrite(pRVCdata, 1, end - buf_start, fpRVC); |
|---|
| 5317 | } |
|---|
| 5318 | |
|---|
| 5319 | /* update the Get Pointer */ |
|---|
| 5320 | BXVD_Reg_Write32_isr(hXvdCh->pXvd, hXvdCh->pXvd->stPlatformInfo.stReg.uiDecode_RVCGet, end); |
|---|
| 5321 | |
|---|
| 5322 | if (size != written) |
|---|
| 5323 | { |
|---|
| 5324 | BDBG_WRN (("GrabRvcFrame - error writing file size = %d written %d", size, written)); |
|---|
| 5325 | } |
|---|
| 5326 | else |
|---|
| 5327 | { |
|---|
| 5328 | BDBG_WRN (("GrabRvcFrame - write %d bytes", size)); |
|---|
| 5329 | } |
|---|
| 5330 | |
|---|
| 5331 | return; |
|---|
| 5332 | |
|---|
| 5333 | } /* end of BXVD_Decoder_S_Dbg_DumpRVC() */ |
|---|
| 5334 | |
|---|
| 5335 | /* |
|---|
| 5336 | * BXVD_Decoder_S_Dbg_DumpPPB |
|---|
| 5337 | */ |
|---|
| 5338 | void BXVD_Decoder_S_Dbg_DumpPPB( |
|---|
| 5339 | BXVD_P_PPB *ppb |
|---|
| 5340 | ) |
|---|
| 5341 | { |
|---|
| 5342 | static FILE *fpPPB = NULL; |
|---|
| 5343 | |
|---|
| 5344 | if (fpPPB == NULL) |
|---|
| 5345 | { |
|---|
| 5346 | if ((fpPPB=fopen("/Work/ppb_capture.bin", "wb"))==NULL) |
|---|
| 5347 | { |
|---|
| 5348 | return; |
|---|
| 5349 | } |
|---|
| 5350 | } |
|---|
| 5351 | |
|---|
| 5352 | fwrite(ppb, sizeof(BXVD_P_PPB), 1, fpPPB); |
|---|
| 5353 | |
|---|
| 5354 | } /* end of BXVD_Decoder_S_Dbg_DumpPPB() */ |
|---|
| 5355 | |
|---|
| 5356 | #endif /* End of BXVD_DM_ENABLE_YUV_GRAB_MODE */ |
|---|
| 5357 | |
|---|