(packetData: Uint8Array)
| 222 | |
| 223 | /** Builds an AvcDecoderConfigurationRecord from an AVC packet in Annex B format. */ |
| 224 | export const extractAvcDecoderConfigurationRecord = (packetData: Uint8Array): AvcDecoderConfigurationRecord | null => { |
| 225 | try { |
| 226 | const nalUnits = findNalUnitsInAnnexB(packetData); |
| 227 | |
| 228 | const spsUnits = nalUnits.filter(unit => extractNalUnitTypeForAvc(unit) === AvcNalUnitType.SPS); |
| 229 | const ppsUnits = nalUnits.filter(unit => extractNalUnitTypeForAvc(unit) === AvcNalUnitType.PPS); |
| 230 | const spsExtUnits = nalUnits.filter(unit => extractNalUnitTypeForAvc(unit) === AvcNalUnitType.SPS_EXT); |
| 231 | |
| 232 | if (spsUnits.length === 0) { |
| 233 | return null; |
| 234 | } |
| 235 | |
| 236 | if (ppsUnits.length === 0) { |
| 237 | return null; |
| 238 | } |
| 239 | |
| 240 | // Let's get the first SPS for profile and level information |
| 241 | const spsData = spsUnits[0]; |
| 242 | const spsInfo = parseAvcSps(spsData); |
| 243 | assert(spsInfo !== null); |
| 244 | |
| 245 | const hasExtendedData = spsInfo.profileIdc === 100 |
| 246 | || spsInfo.profileIdc === 110 |
| 247 | || spsInfo.profileIdc === 122 |
| 248 | || spsInfo.profileIdc === 144; |
| 249 | |
| 250 | return { |
| 251 | configurationVersion: 1, |
| 252 | avcProfileIndication: spsInfo.profileIdc, |
| 253 | profileCompatibility: spsInfo.constraintFlags, |
| 254 | avcLevelIndication: spsInfo.levelIdc, |
| 255 | lengthSizeMinusOne: 3, // Typically 4 bytes for length field |
| 256 | sequenceParameterSets: spsUnits, |
| 257 | pictureParameterSets: ppsUnits, |
| 258 | chromaFormat: hasExtendedData ? spsInfo.chromaFormatIdc : null, |
| 259 | bitDepthLumaMinus8: hasExtendedData ? spsInfo.bitDepthLumaMinus8 : null, |
| 260 | bitDepthChromaMinus8: hasExtendedData ? spsInfo.bitDepthChromaMinus8 : null, |
| 261 | sequenceParameterSetExt: hasExtendedData ? spsExtUnits : null, |
| 262 | }; |
| 263 | } catch (error) { |
| 264 | console.error('Error building AVC Decoder Configuration Record:', error); |
| 265 | return null; |
| 266 | } |
| 267 | }; |
| 268 | |
| 269 | export const generateAvcCodecString = (record: AvcDecoderConfigurationRecord) => { |
| 270 | const bytes = new Uint8Array([ |
no test coverage detected