Skip to content

Commit

Permalink
fix(HLS): Get the correct video codec for TS segments (#5598)
Browse files Browse the repository at this point in the history
  • Loading branch information
avelad authored and joeyparrish committed Sep 8, 2023
1 parent 17f6015 commit 0020afe
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
12 changes: 8 additions & 4 deletions lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,7 @@ shaka.hls.HlsParser = class {
const uint8ArrayData = shaka.util.BufferUtils.toUint8(response.data);
const tsParser = new shaka.util.TsParser().parse(uint8ArrayData);
const tsCodecs = tsParser.getCodecs();
const videoInfo = tsParser.getVideoInfo();
const codecs = [];
let hasAudio = false;
let hasVideo = false;
Expand All @@ -923,7 +924,11 @@ shaka.hls.HlsParser = class {
}
switch (tsCodecs.video) {
case 'avc':
codecs.push('avc1.42E01E');
if (videoInfo.codec) {
codecs.push(videoInfo.codec);
} else {
codecs.push('avc1.42E01E');
}
hasVideo = true;
break;
case 'hvc':
Expand All @@ -935,14 +940,13 @@ shaka.hls.HlsParser = class {
return null;
}
const onlyAudio = hasAudio && !hasVideo;
const videoResolution = tsParser.getVideoResolution();
return {
type: onlyAudio ? 'audio' : 'video',
mimeType: 'video/mp2t',
codecs: codecs.join(', '),
language: null,
height: videoResolution.height,
width: videoResolution.width,
height: videoInfo.height,
width: videoInfo.width,
channelCount: null,
sampleRate: null,
};
Expand Down
48 changes: 40 additions & 8 deletions lib/util/ts_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

goog.provide('shaka.util.TsParser');

goog.require('shaka.Deprecate');
goog.require('shaka.log');
goog.require('shaka.util.ExpGolomb');
goog.require('shaka.util.Id3Utils');
Expand Down Expand Up @@ -660,29 +661,47 @@ shaka.util.TsParser = class {
* @export
*/
getVideoResolution() {
shaka.Deprecate.deprecateFeature(5,
'TsParser',
'Please use getVideoInfo function instead.');
const videoInfo = this.getVideoInfo();
return {
height: videoInfo.height,
width: videoInfo.width,
};
}

/**
* Return the video information
*
* @return {{height: ?string, width: ?string, codec: ?string}}
* @export
*/
getVideoInfo() {
const TsParser = shaka.util.TsParser;
const resolution = {
const videoInfo = {
height: null,
width: null,
codec: null,
};
const videoNalus = this.getVideoNalus();
if (!videoNalus.length) {
return resolution;
return videoInfo;
}
const spsNalu = videoNalus.find((nalu) => {
return nalu.type == TsParser.H264_NALU_TYPE_SPS_;
});
if (!spsNalu) {
return resolution;
return videoInfo;
}

const expGolombDecoder = new shaka.util.ExpGolomb(spsNalu.data);
// profile_idc
const profileIdc = expGolombDecoder.readUnsignedByte();
// constraint_set[0-5]_flag
expGolombDecoder.readUnsignedByte();
const profileCompatibility = expGolombDecoder.readUnsignedByte();
// level_idc u(8)
expGolombDecoder.readUnsignedByte();
const levelIdc = expGolombDecoder.readUnsignedByte();
// seq_parameter_set_id
expGolombDecoder.skipExpGolomb();

Expand Down Expand Up @@ -768,13 +787,26 @@ shaka.util.TsParser = class {
frameCropBottomOffset = expGolombDecoder.readUnsignedExpGolomb();
}

resolution.height = String(((2 - frameMbsOnlyFlag) *
videoInfo.height = String(((2 - frameMbsOnlyFlag) *
(picHeightInMapUnitsMinus1 + 1) * 16) - (frameCropTopOffset * 2) -
(frameCropBottomOffset * 2));
resolution.width = String(((picWidthInMbsMinus1 + 1) * 16) -
videoInfo.width = String(((picWidthInMbsMinus1 + 1) * 16) -
frameCropLeftOffset * 2 - frameCropRightOffset * 2);
videoInfo.codec = 'avc1.' + this.byteToHex_(profileIdc) +
this.byteToHex_(profileCompatibility) + this.byteToHex_(levelIdc);

return videoInfo;
}

return resolution;
/**
* Convert a byte to 2 digits of hex. (Only handles values 0-255.)
*
* @param {number} x
* @return {string}
* @private
*/
byteToHex_(x) {
return ('0' + x.toString(16).toUpperCase()).slice(-2);
}

/**
Expand Down

0 comments on commit 0020afe

Please sign in to comment.