From 31492031c11d113e7e882a672343aba84a740123 Mon Sep 17 00:00:00 2001 From: Ian Baker Date: Wed, 26 Apr 2023 15:53:58 +0100 Subject: [PATCH] Merge pull request #313 from pengbins:fix_ts_h265reader_parse_sps PiperOrigin-RevId: 527259619 (cherry picked from commit fab134f0b3194349aaac702f4c582ee20356b1dc) --- RELEASENOTES.md | 4 + .../exoplayer/e2etest/TsPlaybackTest.java | 1 + .../media3/extractor/ts/H265Reader.java | 213 +----------------- .../media3/extractor/ts/TsExtractorTest.java | 6 + .../ts/sample_h265_rps_pred.ts.0.dump | 81 +++++++ .../ts/sample_h265_rps_pred.ts.1.dump | 65 ++++++ .../ts/sample_h265_rps_pred.ts.2.dump | 45 ++++ .../ts/sample_h265_rps_pred.ts.3.dump | 25 ++ ...ample_h265_rps_pred.ts.unknown_length.dump | 78 +++++++ .../assets/media/ts/sample_h265_rps_pred.ts | Bin 0 -> 15416 bytes .../ts/sample_h265_rps_pred.ts.dump | 0 11 files changed, 317 insertions(+), 201 deletions(-) create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.0.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.1.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.2.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.3.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.unknown_length.dump create mode 100644 libraries/test_data/src/test/assets/media/ts/sample_h265_rps_pred.ts create mode 100644 libraries/test_data/src/test/assets/playbackdumps/ts/sample_h265_rps_pred.ts.dump diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7b2b47b91e..8eb95c496a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -8,6 +8,10 @@ * Fix issue where last frame may not be rendered if the last sample with frames is dequeued without reading the 'end of stream' sample. ([#11079](https://github.com/google/ExoPlayer/issues/11079)). +* Extractors: + * Fix parsing of H.265 SPS in MPEG-TS files by re-using the parsing logic + already used by RTSP and MP4 extractors + ([#303](https://github.com/androidx/media/issues/303)). * Session: * Fix issue where `MediaController` doesn't update its available commands when connected to a legacy `MediaSessionCompat` that updates its diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/TsPlaybackTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/TsPlaybackTest.java index c20a248b34..893630a8a2 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/TsPlaybackTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/TsPlaybackTest.java @@ -63,6 +63,7 @@ public class TsPlaybackTest { "sample_h264_mpeg_audio.ts", "sample_h264_no_access_unit_delimiters.ts", "sample_h265.ts", + "sample_h265_rps_pred.ts", "sample_latm.ts", "sample_scte35.ts", "sample_with_id3.adts", diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java index a0ab3aaa8d..17c0cc7281 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/H265Reader.java @@ -15,15 +15,12 @@ */ package androidx.media3.extractor.ts; -import static java.lang.Math.min; - import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.MimeTypes; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.CodecSpecificDataUtil; -import androidx.media3.common.util.Log; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; @@ -246,216 +243,30 @@ public final class H265Reader implements ElementaryStreamReader { System.arraycopy(sps.nalData, 0, csdData, vps.nalLength, sps.nalLength); System.arraycopy(pps.nalData, 0, csdData, vps.nalLength + sps.nalLength, pps.nalLength); - // Parse the SPS NAL unit, as per H.265/HEVC (2014) 7.3.2.2.1. - ParsableNalUnitBitArray bitArray = new ParsableNalUnitBitArray(sps.nalData, 0, sps.nalLength); - bitArray.skipBits(40 + 4); // NAL header, sps_video_parameter_set_id - int maxSubLayersMinus1 = bitArray.readBits(3); - bitArray.skipBit(); // sps_temporal_id_nesting_flag - int generalProfileSpace = bitArray.readBits(2); - boolean generalTierFlag = bitArray.readBit(); - int generalProfileIdc = bitArray.readBits(5); - int generalProfileCompatibilityFlags = 0; - for (int i = 0; i < 32; i++) { - if (bitArray.readBit()) { - generalProfileCompatibilityFlags |= (1 << i); - } - } - int[] constraintBytes = new int[6]; - for (int i = 0; i < constraintBytes.length; ++i) { - constraintBytes[i] = bitArray.readBits(8); - } - int generalLevelIdc = bitArray.readBits(8); - int toSkip = 0; - for (int i = 0; i < maxSubLayersMinus1; i++) { - if (bitArray.readBit()) { // sub_layer_profile_present_flag[i] - toSkip += 89; - } - if (bitArray.readBit()) { // sub_layer_level_present_flag[i] - toSkip += 8; - } - } - bitArray.skipBits(toSkip); - if (maxSubLayersMinus1 > 0) { - bitArray.skipBits(2 * (8 - maxSubLayersMinus1)); - } - - bitArray.readUnsignedExpGolombCodedInt(); // sps_seq_parameter_set_id - int chromaFormatIdc = bitArray.readUnsignedExpGolombCodedInt(); - if (chromaFormatIdc == 3) { - bitArray.skipBit(); // separate_colour_plane_flag - } - int picWidthInLumaSamples = bitArray.readUnsignedExpGolombCodedInt(); - int picHeightInLumaSamples = bitArray.readUnsignedExpGolombCodedInt(); - if (bitArray.readBit()) { // conformance_window_flag - int confWinLeftOffset = bitArray.readUnsignedExpGolombCodedInt(); - int confWinRightOffset = bitArray.readUnsignedExpGolombCodedInt(); - int confWinTopOffset = bitArray.readUnsignedExpGolombCodedInt(); - int confWinBottomOffset = bitArray.readUnsignedExpGolombCodedInt(); - // H.265/HEVC (2014) Table 6-1 - int subWidthC = chromaFormatIdc == 1 || chromaFormatIdc == 2 ? 2 : 1; - int subHeightC = chromaFormatIdc == 1 ? 2 : 1; - picWidthInLumaSamples -= subWidthC * (confWinLeftOffset + confWinRightOffset); - picHeightInLumaSamples -= subHeightC * (confWinTopOffset + confWinBottomOffset); - } - bitArray.readUnsignedExpGolombCodedInt(); // bit_depth_luma_minus8 - bitArray.readUnsignedExpGolombCodedInt(); // bit_depth_chroma_minus8 - int log2MaxPicOrderCntLsbMinus4 = bitArray.readUnsignedExpGolombCodedInt(); - // for (i = sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1; ...) - for (int i = bitArray.readBit() ? 0 : maxSubLayersMinus1; i <= maxSubLayersMinus1; i++) { - bitArray.readUnsignedExpGolombCodedInt(); // sps_max_dec_pic_buffering_minus1[i] - bitArray.readUnsignedExpGolombCodedInt(); // sps_max_num_reorder_pics[i] - bitArray.readUnsignedExpGolombCodedInt(); // sps_max_latency_increase_plus1[i] - } - bitArray.readUnsignedExpGolombCodedInt(); // log2_min_luma_coding_block_size_minus3 - bitArray.readUnsignedExpGolombCodedInt(); // log2_diff_max_min_luma_coding_block_size - bitArray.readUnsignedExpGolombCodedInt(); // log2_min_luma_transform_block_size_minus2 - bitArray.readUnsignedExpGolombCodedInt(); // log2_diff_max_min_luma_transform_block_size - bitArray.readUnsignedExpGolombCodedInt(); // max_transform_hierarchy_depth_inter - bitArray.readUnsignedExpGolombCodedInt(); // max_transform_hierarchy_depth_intra - // if (scaling_list_enabled_flag) { if (sps_scaling_list_data_present_flag) {...}} - boolean scalingListEnabled = bitArray.readBit(); - if (scalingListEnabled && bitArray.readBit()) { - skipScalingList(bitArray); - } - bitArray.skipBits(2); // amp_enabled_flag (1), sample_adaptive_offset_enabled_flag (1) - if (bitArray.readBit()) { // pcm_enabled_flag - // pcm_sample_bit_depth_luma_minus1 (4), pcm_sample_bit_depth_chroma_minus1 (4) - bitArray.skipBits(8); - bitArray.readUnsignedExpGolombCodedInt(); // log2_min_pcm_luma_coding_block_size_minus3 - bitArray.readUnsignedExpGolombCodedInt(); // log2_diff_max_min_pcm_luma_coding_block_size - bitArray.skipBit(); // pcm_loop_filter_disabled_flag - } - // Skips all short term reference picture sets. - skipShortTermRefPicSets(bitArray); - if (bitArray.readBit()) { // long_term_ref_pics_present_flag - // num_long_term_ref_pics_sps - for (int i = 0; i < bitArray.readUnsignedExpGolombCodedInt(); i++) { - int ltRefPicPocLsbSpsLength = log2MaxPicOrderCntLsbMinus4 + 4; - // lt_ref_pic_poc_lsb_sps[i], used_by_curr_pic_lt_sps_flag[i] - bitArray.skipBits(ltRefPicPocLsbSpsLength + 1); - } - } - bitArray.skipBits(2); // sps_temporal_mvp_enabled_flag, strong_intra_smoothing_enabled_flag - float pixelWidthHeightRatio = 1; - if (bitArray.readBit()) { // vui_parameters_present_flag - if (bitArray.readBit()) { // aspect_ratio_info_present_flag - int aspectRatioIdc = bitArray.readBits(8); - if (aspectRatioIdc == NalUnitUtil.EXTENDED_SAR) { - int sarWidth = bitArray.readBits(16); - int sarHeight = bitArray.readBits(16); - if (sarWidth != 0 && sarHeight != 0) { - pixelWidthHeightRatio = (float) sarWidth / sarHeight; - } - } else if (aspectRatioIdc < NalUnitUtil.ASPECT_RATIO_IDC_VALUES.length) { - pixelWidthHeightRatio = NalUnitUtil.ASPECT_RATIO_IDC_VALUES[aspectRatioIdc]; - } else { - Log.w(TAG, "Unexpected aspect_ratio_idc value: " + aspectRatioIdc); - } - } - if (bitArray.readBit()) { // overscan_info_present_flag - bitArray.skipBit(); // overscan_appropriate_flag - } - if (bitArray.readBit()) { // video_signal_type_present_flag - bitArray.skipBits(4); // video_format, video_full_range_flag - if (bitArray.readBit()) { // colour_description_present_flag - // colour_primaries, transfer_characteristics, matrix_coeffs - bitArray.skipBits(24); - } - } - if (bitArray.readBit()) { // chroma_loc_info_present_flag - bitArray.readUnsignedExpGolombCodedInt(); // chroma_sample_loc_type_top_field - bitArray.readUnsignedExpGolombCodedInt(); // chroma_sample_loc_type_bottom_field - } - bitArray.skipBit(); // neutral_chroma_indication_flag - if (bitArray.readBit()) { // field_seq_flag - // field_seq_flag equal to 1 indicates that the coded video sequence conveys pictures that - // represent fields, which means that frame height is double the picture height. - picHeightInLumaSamples *= 2; - } - } + // Skip the 3-byte NAL unit start code synthesised by the NalUnitTargetBuffer constructor. + NalUnitUtil.H265SpsData spsData = + NalUnitUtil.parseH265SpsNalUnit(sps.nalData, /* nalOffset= */ 3, sps.nalLength); String codecs = CodecSpecificDataUtil.buildHevcCodecString( - generalProfileSpace, - generalTierFlag, - generalProfileIdc, - generalProfileCompatibilityFlags, - constraintBytes, - generalLevelIdc); + spsData.generalProfileSpace, + spsData.generalTierFlag, + spsData.generalProfileIdc, + spsData.generalProfileCompatibilityFlags, + spsData.constraintBytes, + spsData.generalLevelIdc); return new Format.Builder() .setId(formatId) .setSampleMimeType(MimeTypes.VIDEO_H265) .setCodecs(codecs) - .setWidth(picWidthInLumaSamples) - .setHeight(picHeightInLumaSamples) - .setPixelWidthHeightRatio(pixelWidthHeightRatio) + .setWidth(spsData.width) + .setHeight(spsData.height) + .setPixelWidthHeightRatio(spsData.pixelWidthHeightRatio) .setInitializationData(Collections.singletonList(csdData)) .build(); } - /** Skips scaling_list_data(). See H.265/HEVC (2014) 7.3.4. */ - private static void skipScalingList(ParsableNalUnitBitArray bitArray) { - for (int sizeId = 0; sizeId < 4; sizeId++) { - for (int matrixId = 0; matrixId < 6; matrixId += sizeId == 3 ? 3 : 1) { - if (!bitArray.readBit()) { // scaling_list_pred_mode_flag[sizeId][matrixId] - // scaling_list_pred_matrix_id_delta[sizeId][matrixId] - bitArray.readUnsignedExpGolombCodedInt(); - } else { - int coefNum = min(64, 1 << (4 + (sizeId << 1))); - if (sizeId > 1) { - // scaling_list_dc_coef_minus8[sizeId - 2][matrixId] - bitArray.readSignedExpGolombCodedInt(); - } - for (int i = 0; i < coefNum; i++) { - bitArray.readSignedExpGolombCodedInt(); // scaling_list_delta_coef - } - } - } - } - } - - /** - * Reads the number of short term reference picture sets in a SPS as ue(v), then skips all of - * them. See H.265/HEVC (2014) 7.3.7. - */ - private static void skipShortTermRefPicSets(ParsableNalUnitBitArray bitArray) { - int numShortTermRefPicSets = bitArray.readUnsignedExpGolombCodedInt(); - boolean interRefPicSetPredictionFlag = false; - int numNegativePics; - int numPositivePics; - // As this method applies in a SPS, the only element of NumDeltaPocs accessed is the previous - // one, so we just keep track of that rather than storing the whole array. - // RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1) and delta_idx_minus1 is always zero in SPS. - int previousNumDeltaPocs = 0; - for (int stRpsIdx = 0; stRpsIdx < numShortTermRefPicSets; stRpsIdx++) { - if (stRpsIdx != 0) { - interRefPicSetPredictionFlag = bitArray.readBit(); - } - if (interRefPicSetPredictionFlag) { - bitArray.skipBit(); // delta_rps_sign - bitArray.readUnsignedExpGolombCodedInt(); // abs_delta_rps_minus1 - for (int j = 0; j <= previousNumDeltaPocs; j++) { - if (bitArray.readBit()) { // used_by_curr_pic_flag[j] - bitArray.skipBit(); // use_delta_flag[j] - } - } - } else { - numNegativePics = bitArray.readUnsignedExpGolombCodedInt(); - numPositivePics = bitArray.readUnsignedExpGolombCodedInt(); - previousNumDeltaPocs = numNegativePics + numPositivePics; - for (int i = 0; i < numNegativePics; i++) { - bitArray.readUnsignedExpGolombCodedInt(); // delta_poc_s0_minus1[i] - bitArray.skipBit(); // used_by_curr_pic_s0_flag[i] - } - for (int i = 0; i < numPositivePics; i++) { - bitArray.readUnsignedExpGolombCodedInt(); // delta_poc_s1_minus1[i] - bitArray.skipBit(); // used_by_curr_pic_s1_flag[i] - } - } - } - } - @EnsuresNonNull({"output", "sampleReader"}) private void assertTracksCreated() { Assertions.checkStateNotNull(output); diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java index 3b372c63be..0cd2e9cd30 100644 --- a/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java +++ b/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java @@ -92,6 +92,12 @@ public final class TsExtractorTest { ExtractorAsserts.assertBehavior(TsExtractor::new, "media/ts/sample_h265.ts", simulationConfig); } + @Test + public void sampleWithH265RpsPred() throws Exception { + ExtractorAsserts.assertBehavior( + TsExtractor::new, "media/ts/sample_h265_rps_pred.ts", simulationConfig); + } + @Test public void sampleWithScte35() throws Exception { ExtractorAsserts.assertBehavior( diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.0.dump new file mode 100644 index 0000000000..d4dc0a7863 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.0.dump @@ -0,0 +1,81 @@ +seekMap: + isSeekable = true + duration = 1000000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(500000) = [[timeUs=500000, position=7134]] + getPosition(1000000) = [[timeUs=1000000, position=14457]] +numberOfTracks = 1 +track 256: + total output bytes = 10004 + sample count = 15 + format 0: + id = 1/256 + sampleMimeType = video/hevc + codecs = hvc1.1.6.L63.90 + width = 914 + height = 686 + pixelWidthHeightRatio = 1.0003651 + initializationData: + data = length 146, hash 61554FEF + sample 0: + time = 266666 + flags = 1 + data = length 7464, hash EBF8518B + sample 1: + time = 1200000 + flags = 0 + data = length 1042, hash F69C93E1 + sample 2: + time = 733333 + flags = 0 + data = length 465, hash 2B469969 + sample 3: + time = 466666 + flags = 0 + data = length 177, hash 79777966 + sample 4: + time = 333333 + flags = 0 + data = length 65, hash 63DA4886 + sample 5: + time = 400000 + flags = 0 + data = length 33, hash EFE759C6 + sample 6: + time = 600000 + flags = 0 + data = length 88, hash 98333D02 + sample 7: + time = 533333 + flags = 0 + data = length 49, hash F9A023E1 + sample 8: + time = 666666 + flags = 0 + data = length 58, hash 74F1E9D9 + sample 9: + time = 933333 + flags = 0 + data = length 114, hash FA033C4D + sample 10: + time = 800000 + flags = 0 + data = length 87, hash 1A1C57E4 + sample 11: + time = 866666 + flags = 0 + data = length 65, hash 59F937BE + sample 12: + time = 1066666 + flags = 0 + data = length 94, hash 5D02AC81 + sample 13: + time = 1000000 + flags = 0 + data = length 57, hash 2750D207 + sample 14: + time = 1133333 + flags = 0 + data = length 46, hash CE770A40 +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.1.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.1.dump new file mode 100644 index 0000000000..cfe07b53a9 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.1.dump @@ -0,0 +1,65 @@ +seekMap: + isSeekable = true + duration = 1000000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(500000) = [[timeUs=500000, position=7134]] + getPosition(1000000) = [[timeUs=1000000, position=14457]] +numberOfTracks = 1 +track 256: + total output bytes = 856 + sample count = 11 + format 0: + id = 1/256 + sampleMimeType = video/hevc + codecs = hvc1.1.6.L63.90 + width = 914 + height = 686 + pixelWidthHeightRatio = 1.0003651 + initializationData: + data = length 146, hash 61554FEF + sample 0: + time = 333333 + flags = 0 + data = length 65, hash 63DA4886 + sample 1: + time = 400000 + flags = 0 + data = length 33, hash EFE759C6 + sample 2: + time = 600000 + flags = 0 + data = length 88, hash 98333D02 + sample 3: + time = 533333 + flags = 0 + data = length 49, hash F9A023E1 + sample 4: + time = 666666 + flags = 0 + data = length 58, hash 74F1E9D9 + sample 5: + time = 933333 + flags = 0 + data = length 114, hash FA033C4D + sample 6: + time = 800000 + flags = 0 + data = length 87, hash 1A1C57E4 + sample 7: + time = 866666 + flags = 0 + data = length 65, hash 59F937BE + sample 8: + time = 1066666 + flags = 0 + data = length 94, hash 5D02AC81 + sample 9: + time = 1000000 + flags = 0 + data = length 57, hash 2750D207 + sample 10: + time = 1133333 + flags = 0 + data = length 46, hash CE770A40 +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.2.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.2.dump new file mode 100644 index 0000000000..c3e8198155 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.2.dump @@ -0,0 +1,45 @@ +seekMap: + isSeekable = true + duration = 1000000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(500000) = [[timeUs=500000, position=7134]] + getPosition(1000000) = [[timeUs=1000000, position=14457]] +numberOfTracks = 1 +track 256: + total output bytes = 563 + sample count = 6 + format 0: + id = 1/256 + sampleMimeType = video/hevc + codecs = hvc1.1.6.L63.90 + width = 914 + height = 686 + pixelWidthHeightRatio = 1.0003651 + initializationData: + data = length 146, hash 61554FEF + sample 0: + time = 933333 + flags = 0 + data = length 114, hash FA033C4D + sample 1: + time = 800000 + flags = 0 + data = length 87, hash 1A1C57E4 + sample 2: + time = 866666 + flags = 0 + data = length 65, hash 59F937BE + sample 3: + time = 1066666 + flags = 0 + data = length 94, hash 5D02AC81 + sample 4: + time = 1000000 + flags = 0 + data = length 57, hash 2750D207 + sample 5: + time = 1133333 + flags = 0 + data = length 46, hash CE770A40 +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.3.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.3.dump new file mode 100644 index 0000000000..d10958f482 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.3.dump @@ -0,0 +1,25 @@ +seekMap: + isSeekable = true + duration = 1000000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(500000) = [[timeUs=500000, position=7134]] + getPosition(1000000) = [[timeUs=1000000, position=14457]] +numberOfTracks = 1 +track 256: + total output bytes = 146 + sample count = 1 + format 0: + id = 1/256 + sampleMimeType = video/hevc + codecs = hvc1.1.6.L63.90 + width = 914 + height = 686 + pixelWidthHeightRatio = 1.0003651 + initializationData: + data = length 146, hash 61554FEF + sample 0: + time = 1133333 + flags = 0 + data = length 46, hash CE770A40 +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.unknown_length.dump new file mode 100644 index 0000000000..85ddd41279 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_h265_rps_pred.ts.unknown_length.dump @@ -0,0 +1,78 @@ +seekMap: + isSeekable = false + duration = UNSET TIME + getPosition(0) = [[timeUs=0, position=0]] +numberOfTracks = 1 +track 256: + total output bytes = 10004 + sample count = 15 + format 0: + id = 1/256 + sampleMimeType = video/hevc + codecs = hvc1.1.6.L63.90 + width = 914 + height = 686 + pixelWidthHeightRatio = 1.0003651 + initializationData: + data = length 146, hash 61554FEF + sample 0: + time = 266666 + flags = 1 + data = length 7464, hash EBF8518B + sample 1: + time = 1200000 + flags = 0 + data = length 1042, hash F69C93E1 + sample 2: + time = 733333 + flags = 0 + data = length 465, hash 2B469969 + sample 3: + time = 466666 + flags = 0 + data = length 177, hash 79777966 + sample 4: + time = 333333 + flags = 0 + data = length 65, hash 63DA4886 + sample 5: + time = 400000 + flags = 0 + data = length 33, hash EFE759C6 + sample 6: + time = 600000 + flags = 0 + data = length 88, hash 98333D02 + sample 7: + time = 533333 + flags = 0 + data = length 49, hash F9A023E1 + sample 8: + time = 666666 + flags = 0 + data = length 58, hash 74F1E9D9 + sample 9: + time = 933333 + flags = 0 + data = length 114, hash FA033C4D + sample 10: + time = 800000 + flags = 0 + data = length 87, hash 1A1C57E4 + sample 11: + time = 866666 + flags = 0 + data = length 65, hash 59F937BE + sample 12: + time = 1066666 + flags = 0 + data = length 94, hash 5D02AC81 + sample 13: + time = 1000000 + flags = 0 + data = length 57, hash 2750D207 + sample 14: + time = 1133333 + flags = 0 + data = length 46, hash CE770A40 +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/media/ts/sample_h265_rps_pred.ts b/libraries/test_data/src/test/assets/media/ts/sample_h265_rps_pred.ts new file mode 100644 index 0000000000000000000000000000000000000000..b5d336564d877dac33530f0583638681eb9af9db GIT binary patch literal 15416 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 X2SV8QBFg7-O|UAY@c1Dvz&QUe#l&M+ literal 0 HcmV?d00001 diff --git a/libraries/test_data/src/test/assets/playbackdumps/ts/sample_h265_rps_pred.ts.dump b/libraries/test_data/src/test/assets/playbackdumps/ts/sample_h265_rps_pred.ts.dump new file mode 100644 index 0000000000..e69de29bb2